FOLL_LONGTERM pinning fails for some memory types, such as file-backed guest memory. As a result, kvm_s390_adapter_map() returns -EINVAL and irqfd adapter registration fails even though interrupt delivery could still work via the existing non-atomic path. When FOLL_LONGTERM pinning fails, verify that the page is accessible using a short-term pin instead. If the short-term pin succeeds, immediately unpin the page and return success. The non-atomic irqfd path already performs short-term pinning for interrupt delivery, so this restores the previous behavior for memory that cannot be pinned long-term. Fixes: adcd5b3e758b ("KVM: s390: Add map/unmap ioctl and clean mappings post-guest") Signed-off-by: Jaehoon Kim --- arch/s390/kvm/interrupt.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 9e3e6b0d72ad..4b68e0cb51f6 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -2520,8 +2520,19 @@ static int kvm_s390_adapter_map(struct kvm *kvm, unsigned int id, __u64 addr) map->addr = host_addr; map->page = pin_map_page(kvm, host_addr, FOLL_LONGTERM); if (!map->page) { - ret = -EINVAL; - goto out; + /* + * Long-term pinning may fail for memory types such as file-backed + * memory. Check whether short-term pinning is possible so that the + * non-atomic irqfd path can handle interrupt injection. + */ + map->page = pin_map_page(kvm, host_addr, 0); + if (!map->page) { + ret = -EINVAL; + goto out; + } + unpin_user_page(map->page); + kfree(map); + return 0; } spin_lock_irqsave(&adapter->maps_lock, flags); if (adapter->nr_maps < MAX_S390_ADAPTER_MAPS) { -- 2.43.0