• Jason Gunthorpe's avatar
    iommufd/selftest: Don't check map/unmap pairing with HUGE_PAGES · bb04d133
    Jason Gunthorpe authored
    Since MOCK_HUGE_PAGE_SIZE was introduced it allows the core code to invoke
    mock with large page sizes. This confuses the validation logic that checks
    that map/unmap are paired.
    
    This is because the page size computed for map is based on the physical
    address and in many cases will always be the base page size, however the
    entire range generated by iommufd will be passed to map.
    
    Randomly iommufd can see small groups of physically contiguous pages,
    (say 8k unaligned and grouped together), but that group crosses a huge
    page boundary. The map side will observe this as a contiguous run and mark
    it accordingly, but there is a chance the unmap side will end up
    terminating interior huge pages in the middle of that group and trigger a
    validation failure. Meaning the validation only works if the core code
    passes the iova/length directly from iommufd to mock.
    
    syzkaller randomly hits this with failures like:
    
      WARNING: CPU: 0 PID: 11568 at drivers/iommu/iommufd/selftest.c:461 mock_domain_unmap_pages+0x1c0/0x250
      Modules linked in:
      CPU: 0 PID: 11568 Comm: syz-executor.0 Not tainted 6.8.0-rc3+ #4
      Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
      RIP: 0010:mock_domain_unmap_pages+0x1c0/0x250
      Code: 2b e8 94 37 0f ff 48 d1 eb 31 ff 48 b8 00 00 00 00 00 00 20 00 48 21 c3 48 89 de e8 aa 32 0f ff 48 85 db 75 07 e8 70 37 0f ff <0f> 0b e8 69 37 0f ff 31 f6 31 ff e8 90 32 0f ff e8 5b 37 0f ff 4c
      RSP: 0018:ffff88800e707490 EFLAGS: 00010293
      RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff822dfae6
      RDX: ffff88800cf86400 RSI: ffffffff822dfaf0 RDI: 0000000000000007
      RBP: ffff88800e7074d8 R08: 0000000000000000 R09: ffffed1001167c90
      R10: 0000000000000000 R11: 0000000000000000 R12: 0000000001500000
      R13: 0000000000083000 R14: 0000000000000001 R15: 0000000000000800
      FS:  0000555556048480(0000) GS:ffff88806d400000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: 0000001b2dc23000 CR3: 0000000008cbb000 CR4: 0000000000350eb0
      Call Trace:
       <TASK>
       __iommu_unmap+0x281/0x520
       iommu_unmap+0xc9/0x180
       iopt_area_unmap_domain_range+0x1b1/0x290
       iopt_area_unpin_domain+0x590/0x800
       __iopt_area_unfill_domain+0x22e/0x650
       iopt_area_unfill_domain+0x47/0x60
       iopt_unfill_domain+0x187/0x590
       iopt_table_remove_domain+0x267/0x2d0
       iommufd_hwpt_paging_destroy+0x1f1/0x370
       iommufd_object_remove+0x2a3/0x490
       iommufd_device_detach+0x23a/0x2c0
       iommufd_selftest_destroy+0x7a/0xf0
       iommufd_fops_release+0x1d3/0x340
       __fput+0x272/0xb50
       __fput_sync+0x4b/0x60
       __x64_sys_close+0x8b/0x110
       do_syscall_64+0x71/0x140
       entry_SYSCALL_64_after_hwframe+0x46/0x4e
    
    Do the simple thing and just disable the validation when the huge page
    tests are being run.
    
    Fixes: 7db521e2 ("iommufd/selftest: Hugepage mock domain support")
    Link: https://lore.kernel.org/r/0-v1-1e17e60a5c8a+103fb-iommufd_mock_hugepg_jgg@nvidia.comReviewed-by: default avatarJoao Martins <joao.m.martins@oracle.com>
    Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
    Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
    bb04d133
selftest.c 38 KB