mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
s390/pci: Fix s390_mmio_read/write syscall page fault handling
The s390 MMIO syscalls when using the classic PCI instructions do not cause a page fault when follow_pfnmap_start() fails due to the page not being present. Besides being a general deficiency this breaks vfio-pci's mmap() handling once VFIO_PCI_MMAP gets enabled as this lazily maps on first access. Fix this by following a failed follow_pfnmap_start() with fixup_user_page() and retrying the follow_pfnmap_start(). Also fix a VM_READ vs VM_WRITE mixup in the read syscall. Link: https://lore.kernel.org/r/20250226-vfio_pci_mmap-v7-1-c5c0f1d26efd@linux.ibm.com Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
This commit is contained in:
parent
04d50d953a
commit
41a0926e82
|
|
@ -175,8 +175,12 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr,
|
|||
args.address = mmio_addr;
|
||||
args.vma = vma;
|
||||
ret = follow_pfnmap_start(&args);
|
||||
if (ret)
|
||||
goto out_unlock_mmap;
|
||||
if (ret) {
|
||||
fixup_user_fault(current->mm, mmio_addr, FAULT_FLAG_WRITE, NULL);
|
||||
ret = follow_pfnmap_start(&args);
|
||||
if (ret)
|
||||
goto out_unlock_mmap;
|
||||
}
|
||||
|
||||
io_addr = (void __iomem *)((args.pfn << PAGE_SHIFT) |
|
||||
(mmio_addr & ~PAGE_MASK));
|
||||
|
|
@ -315,14 +319,18 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr,
|
|||
if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
|
||||
goto out_unlock_mmap;
|
||||
ret = -EACCES;
|
||||
if (!(vma->vm_flags & VM_WRITE))
|
||||
if (!(vma->vm_flags & VM_READ))
|
||||
goto out_unlock_mmap;
|
||||
|
||||
args.vma = vma;
|
||||
args.address = mmio_addr;
|
||||
ret = follow_pfnmap_start(&args);
|
||||
if (ret)
|
||||
goto out_unlock_mmap;
|
||||
if (ret) {
|
||||
fixup_user_fault(current->mm, mmio_addr, 0, NULL);
|
||||
ret = follow_pfnmap_start(&args);
|
||||
if (ret)
|
||||
goto out_unlock_mmap;
|
||||
}
|
||||
|
||||
io_addr = (void __iomem *)((args.pfn << PAGE_SHIFT) |
|
||||
(mmio_addr & ~PAGE_MASK));
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user