Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommufd/selftest: Add IOMMU_TEST_OP_ACCESS_REPLACE_IOAS coverage

Add a new IOMMU_TEST_OP_ACCESS_REPLACE_IOAS to allow replacing the
access->ioas, corresponding to the iommufd_access_replace() helper.

Then add replace coverage as a part of user_copy test case, which
basically repeats the copy test after replacing the old ioas with a new
one.

Link: https://lore.kernel.org/r/a4897f93d41c34b972213243b8dbf4c3832842e4.1690523699.git.nicolinc@nvidia.com
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

authored by

Nicolin Chen and committed by
Jason Gunthorpe
c154660b 70c16123

+69 -2
+4
drivers/iommu/iommufd/iommufd_test.h
··· 18 18 IOMMU_TEST_OP_ACCESS_RW, 19 19 IOMMU_TEST_OP_SET_TEMP_MEMORY_LIMIT, 20 20 IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE, 21 + IOMMU_TEST_OP_ACCESS_REPLACE_IOAS, 21 22 }; 22 23 23 24 enum { ··· 92 91 struct { 93 92 __u32 limit; 94 93 } memory_limit; 94 + struct { 95 + __u32 ioas_id; 96 + } access_replace_ioas; 95 97 }; 96 98 __u32 last; 97 99 };
+19
drivers/iommu/iommufd/selftest.c
··· 785 785 return rc; 786 786 } 787 787 788 + static int iommufd_test_access_replace_ioas(struct iommufd_ucmd *ucmd, 789 + unsigned int access_id, 790 + unsigned int ioas_id) 791 + { 792 + struct selftest_access *staccess; 793 + int rc; 794 + 795 + staccess = iommufd_access_get(access_id); 796 + if (IS_ERR(staccess)) 797 + return PTR_ERR(staccess); 798 + 799 + rc = iommufd_access_replace(staccess->access, ioas_id); 800 + fput(staccess->file); 801 + return rc; 802 + } 803 + 788 804 /* Check that the pages in a page array match the pages in the user VA */ 789 805 static int iommufd_test_check_pages(void __user *uptr, struct page **pages, 790 806 size_t npages) ··· 1016 1000 case IOMMU_TEST_OP_CREATE_ACCESS: 1017 1001 return iommufd_test_create_access(ucmd, cmd->id, 1018 1002 cmd->create_access.flags); 1003 + case IOMMU_TEST_OP_ACCESS_REPLACE_IOAS: 1004 + return iommufd_test_access_replace_ioas( 1005 + ucmd, cmd->id, cmd->access_replace_ioas.ioas_id); 1019 1006 case IOMMU_TEST_OP_ACCESS_PAGES: 1020 1007 return iommufd_test_access_pages( 1021 1008 ucmd, cmd->id, cmd->access_pages.iova,
+27 -2
tools/testing/selftests/iommu/iommufd.c
··· 1283 1283 .dst_iova = MOCK_APERTURE_START, 1284 1284 .length = BUFFER_SIZE, 1285 1285 }; 1286 - unsigned int ioas_id; 1286 + struct iommu_ioas_unmap unmap_cmd = { 1287 + .size = sizeof(unmap_cmd), 1288 + .ioas_id = self->ioas_id, 1289 + .iova = MOCK_APERTURE_START, 1290 + .length = BUFFER_SIZE, 1291 + }; 1292 + unsigned int new_ioas_id, ioas_id; 1287 1293 1288 1294 /* Pin the pages in an IOAS with no domains then copy to an IOAS with domains */ 1289 1295 test_ioctl_ioas_alloc(&ioas_id); ··· 1307 1301 ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_COPY, &copy_cmd)); 1308 1302 check_mock_iova(buffer, MOCK_APERTURE_START, BUFFER_SIZE); 1309 1303 1304 + /* Now replace the ioas with a new one */ 1305 + test_ioctl_ioas_alloc(&new_ioas_id); 1306 + test_ioctl_ioas_map_id(new_ioas_id, buffer, BUFFER_SIZE, 1307 + &copy_cmd.src_iova); 1308 + test_cmd_access_replace_ioas(access_cmd.id, new_ioas_id); 1309 + 1310 + /* Destroy the old ioas and cleanup copied mapping */ 1311 + ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_UNMAP, &unmap_cmd)); 1312 + test_ioctl_destroy(ioas_id); 1313 + 1314 + /* Then run the same test again with the new ioas */ 1315 + access_cmd.access_pages.iova = copy_cmd.src_iova; 1316 + ASSERT_EQ(0, 1317 + ioctl(self->fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES), 1318 + &access_cmd)); 1319 + copy_cmd.src_ioas_id = new_ioas_id; 1320 + ASSERT_EQ(0, ioctl(self->fd, IOMMU_IOAS_COPY, &copy_cmd)); 1321 + check_mock_iova(buffer, MOCK_APERTURE_START, BUFFER_SIZE); 1322 + 1310 1323 test_cmd_destroy_access_pages( 1311 1324 access_cmd.id, access_cmd.access_pages.out_access_pages_id); 1312 1325 test_cmd_destroy_access(access_cmd.id); 1313 1326 1314 - test_ioctl_destroy(ioas_id); 1327 + test_ioctl_destroy(new_ioas_id); 1315 1328 } 1316 1329 1317 1330 TEST_F(iommufd_mock_domain, replace)
+19
tools/testing/selftests/iommu/iommufd_utils.h
··· 119 119 #define test_cmd_hwpt_alloc(device_id, pt_id, hwpt_id) \ 120 120 ASSERT_EQ(0, _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, hwpt_id)) 121 121 122 + static int _test_cmd_access_replace_ioas(int fd, __u32 access_id, 123 + unsigned int ioas_id) 124 + { 125 + struct iommu_test_cmd cmd = { 126 + .size = sizeof(cmd), 127 + .op = IOMMU_TEST_OP_ACCESS_REPLACE_IOAS, 128 + .id = access_id, 129 + .access_replace_ioas = { .ioas_id = ioas_id }, 130 + }; 131 + int ret; 132 + 133 + ret = ioctl(fd, IOMMU_TEST_CMD, &cmd); 134 + if (ret) 135 + return ret; 136 + return 0; 137 + } 138 + #define test_cmd_access_replace_ioas(access_id, ioas_id) \ 139 + ASSERT_EQ(0, _test_cmd_access_replace_ioas(self->fd, access_id, ioas_id)) 140 + 122 141 static int _test_cmd_create_access(int fd, unsigned int ioas_id, 123 142 __u32 *access_id, unsigned int flags) 124 143 {