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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd

Pull iommufd updates from Jason Gunthorpe:
"No major functionality this cycle:

- iommufd part of the domain_alloc_paging_flags() conversion

- Move IOMMU_HWPT_FAULT_ID_VALID processing out of drivers

- Increase a timeout waiting for other threads to drop transient
refcounts that syzkaller was hitting

- Fix a UBSAN hit in iova_bitmap due to shift out of bounds

- Add missing cleanup of fault events during FD shutdown, fixing a
memory leak

- Improve the fault delivery flow to have a smaller locking critical
region that does not include copy_to_user()

- Fix 32 bit ABI breakage due to missed implicit padding, and fix the
stack memory leakage"

* tag 'for-linus-iommufd' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd:
iommufd: Fix struct iommu_hwpt_pgfault init and padding
iommufd/fault: Use a separate spinlock to protect fault->deliver list
iommufd/fault: Destroy response and mutex in iommufd_fault_destroy()
iommufd: Keep OBJ/IOCTL lists in an alphabetical order
iommufd/iova_bitmap: Fix shift-out-of-bounds in iova_bitmap_offset_to_index()
iommu: iommufd: fix WARNING in iommufd_device_unbind
iommufd: Deal with IOMMU_HWPT_FAULT_ID_VALID in iommufd core
iommufd/selftest: Remove domain_alloc_paging()

+103 -74
+1 -7
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
··· 178 178 const struct iommu_user_data *user_data) 179 179 { 180 180 struct arm_vsmmu *vsmmu = container_of(viommu, struct arm_vsmmu, core); 181 - const u32 SUPPORTED_FLAGS = IOMMU_HWPT_FAULT_ID_VALID; 182 181 struct arm_smmu_nested_domain *nested_domain; 183 182 struct iommu_hwpt_arm_smmuv3 arg; 184 183 bool enable_ats = false; 185 184 int ret; 186 185 187 - /* 188 - * Faults delivered to the nested domain are faults that originated by 189 - * the S1 in the domain. The core code will match all PASIDs when 190 - * delivering the fault due to user_pasid_table 191 - */ 192 - if (flags & ~SUPPORTED_FLAGS) 186 + if (flags) 193 187 return ERR_PTR(-EOPNOTSUPP); 194 188 195 189 ret = iommu_copy_struct_from_user(&arg, user_data,
+1 -2
drivers/iommu/intel/iommu.c
··· 3338 3338 bool first_stage; 3339 3339 3340 3340 if (flags & 3341 - (~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING 3342 - | IOMMU_HWPT_FAULT_ID_VALID))) 3341 + (~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING))) 3343 3342 return ERR_PTR(-EOPNOTSUPP); 3344 3343 if (nested_parent && !nested_supported(iommu)) 3345 3344 return ERR_PTR(-EOPNOTSUPP);
+31 -13
drivers/iommu/iommufd/fault.c
··· 103 103 { 104 104 struct iommufd_fault *fault = hwpt->fault; 105 105 struct iopf_group *group, *next; 106 + struct list_head free_list; 106 107 unsigned long index; 107 108 108 109 if (!fault) 109 110 return; 111 + INIT_LIST_HEAD(&free_list); 110 112 111 113 mutex_lock(&fault->mutex); 114 + spin_lock(&fault->lock); 112 115 list_for_each_entry_safe(group, next, &fault->deliver, node) { 113 116 if (group->attach_handle != &handle->handle) 114 117 continue; 118 + list_move(&group->node, &free_list); 119 + } 120 + spin_unlock(&fault->lock); 121 + 122 + list_for_each_entry_safe(group, next, &free_list, node) { 115 123 list_del(&group->node); 116 124 iopf_group_response(group, IOMMU_PAGE_RESP_INVALID); 117 125 iopf_free_group(group); ··· 221 213 { 222 214 struct iommufd_fault *fault = container_of(obj, struct iommufd_fault, obj); 223 215 struct iopf_group *group, *next; 216 + unsigned long index; 224 217 225 218 /* 226 219 * The iommufd object's reference count is zero at this point. ··· 234 225 iopf_group_response(group, IOMMU_PAGE_RESP_INVALID); 235 226 iopf_free_group(group); 236 227 } 228 + xa_for_each(&fault->response, index, group) { 229 + xa_erase(&fault->response, index); 230 + iopf_group_response(group, IOMMU_PAGE_RESP_INVALID); 231 + iopf_free_group(group); 232 + } 233 + xa_destroy(&fault->response); 234 + mutex_destroy(&fault->mutex); 237 235 } 238 236 239 237 static void iommufd_compose_fault_message(struct iommu_fault *fault, ··· 263 247 { 264 248 size_t fault_size = sizeof(struct iommu_hwpt_pgfault); 265 249 struct iommufd_fault *fault = filep->private_data; 266 - struct iommu_hwpt_pgfault data; 250 + struct iommu_hwpt_pgfault data = {}; 267 251 struct iommufd_device *idev; 268 252 struct iopf_group *group; 269 253 struct iopf_fault *iopf; ··· 274 258 return -ESPIPE; 275 259 276 260 mutex_lock(&fault->mutex); 277 - while (!list_empty(&fault->deliver) && count > done) { 278 - group = list_first_entry(&fault->deliver, 279 - struct iopf_group, node); 280 - 281 - if (group->fault_count * fault_size > count - done) 261 + while ((group = iommufd_fault_deliver_fetch(fault))) { 262 + if (done >= count || 263 + group->fault_count * fault_size > count - done) { 264 + iommufd_fault_deliver_restore(fault, group); 282 265 break; 266 + } 283 267 284 268 rc = xa_alloc(&fault->response, &group->cookie, group, 285 269 xa_limit_32b, GFP_KERNEL); 286 - if (rc) 270 + if (rc) { 271 + iommufd_fault_deliver_restore(fault, group); 287 272 break; 273 + } 288 274 289 275 idev = to_iommufd_handle(group->attach_handle)->idev; 290 276 list_for_each_entry(iopf, &group->faults, list) { ··· 295 277 group->cookie); 296 278 if (copy_to_user(buf + done, &data, fault_size)) { 297 279 xa_erase(&fault->response, group->cookie); 280 + iommufd_fault_deliver_restore(fault, group); 298 281 rc = -EFAULT; 299 282 break; 300 283 } 301 284 done += fault_size; 302 285 } 303 - 304 - list_del(&group->node); 305 286 } 306 287 mutex_unlock(&fault->mutex); 307 288 ··· 358 341 __poll_t pollflags = EPOLLOUT; 359 342 360 343 poll_wait(filep, &fault->wait_queue, wait); 361 - mutex_lock(&fault->mutex); 344 + spin_lock(&fault->lock); 362 345 if (!list_empty(&fault->deliver)) 363 346 pollflags |= EPOLLIN | EPOLLRDNORM; 364 - mutex_unlock(&fault->mutex); 347 + spin_unlock(&fault->lock); 365 348 366 349 return pollflags; 367 350 } ··· 403 386 INIT_LIST_HEAD(&fault->deliver); 404 387 xa_init_flags(&fault->response, XA_FLAGS_ALLOC1); 405 388 mutex_init(&fault->mutex); 389 + spin_lock_init(&fault->lock); 406 390 init_waitqueue_head(&fault->wait_queue); 407 391 408 392 filep = anon_inode_getfile("[iommufd-pgfault]", &iommufd_fault_fops, ··· 452 434 hwpt = group->attach_handle->domain->fault_data; 453 435 fault = hwpt->fault; 454 436 455 - mutex_lock(&fault->mutex); 437 + spin_lock(&fault->lock); 456 438 list_add_tail(&group->node, &fault->deliver); 457 - mutex_unlock(&fault->mutex); 439 + spin_unlock(&fault->lock); 458 440 459 441 wake_up_interruptible(&fault->wait_queue); 460 442
+7 -3
drivers/iommu/iommufd/hw_pagetable.c
··· 140 140 hwpt_paging->nest_parent = flags & IOMMU_HWPT_ALLOC_NEST_PARENT; 141 141 142 142 if (ops->domain_alloc_paging_flags) { 143 - hwpt->domain = ops->domain_alloc_paging_flags(idev->dev, flags, 144 - user_data); 143 + hwpt->domain = ops->domain_alloc_paging_flags(idev->dev, 144 + flags & ~IOMMU_HWPT_FAULT_ID_VALID, user_data); 145 145 if (IS_ERR(hwpt->domain)) { 146 146 rc = PTR_ERR(hwpt->domain); 147 147 hwpt->domain = NULL; ··· 280 280 struct iommufd_hw_pagetable *hwpt; 281 281 int rc; 282 282 283 + if (flags & ~IOMMU_HWPT_FAULT_ID_VALID) 284 + return ERR_PTR(-EOPNOTSUPP); 283 285 if (!user_data->len) 284 286 return ERR_PTR(-EOPNOTSUPP); 285 287 if (!viommu->ops || !viommu->ops->alloc_domain_nested) ··· 298 296 hwpt_nested->parent = viommu->hwpt; 299 297 300 298 hwpt->domain = 301 - viommu->ops->alloc_domain_nested(viommu, flags, user_data); 299 + viommu->ops->alloc_domain_nested(viommu, 300 + flags & ~IOMMU_HWPT_FAULT_ID_VALID, 301 + user_data); 302 302 if (IS_ERR(hwpt->domain)) { 303 303 rc = PTR_ERR(hwpt->domain); 304 304 hwpt->domain = NULL;
+27 -2
drivers/iommu/iommufd/iommufd_private.h
··· 443 443 struct iommufd_ctx *ictx; 444 444 struct file *filep; 445 445 446 - /* The lists of outstanding faults protected by below mutex. */ 447 - struct mutex mutex; 446 + spinlock_t lock; /* protects the deliver list */ 448 447 struct list_head deliver; 448 + struct mutex mutex; /* serializes response flows */ 449 449 struct xarray response; 450 450 451 451 struct wait_queue_head wait_queue; 452 452 }; 453 + 454 + /* Fetch the first node out of the fault->deliver list */ 455 + static inline struct iopf_group * 456 + iommufd_fault_deliver_fetch(struct iommufd_fault *fault) 457 + { 458 + struct list_head *list = &fault->deliver; 459 + struct iopf_group *group = NULL; 460 + 461 + spin_lock(&fault->lock); 462 + if (!list_empty(list)) { 463 + group = list_first_entry(list, struct iopf_group, node); 464 + list_del(&group->node); 465 + } 466 + spin_unlock(&fault->lock); 467 + return group; 468 + } 469 + 470 + /* Restore a node back to the head of the fault->deliver list */ 471 + static inline void iommufd_fault_deliver_restore(struct iommufd_fault *fault, 472 + struct iopf_group *group) 473 + { 474 + spin_lock(&fault->lock); 475 + list_add(&group->node, &fault->deliver); 476 + spin_unlock(&fault->lock); 477 + } 453 478 454 479 struct iommufd_attach_handle { 455 480 struct iommu_attach_handle handle;
+1 -1
drivers/iommu/iommufd/iova_bitmap.c
··· 130 130 static unsigned long iova_bitmap_offset_to_index(struct iova_bitmap *bitmap, 131 131 unsigned long iova) 132 132 { 133 - unsigned long pgsize = 1 << bitmap->mapped.pgshift; 133 + unsigned long pgsize = 1UL << bitmap->mapped.pgshift; 134 134 135 135 return iova / (BITS_PER_TYPE(*bitmap->bitmap) * pgsize); 136 136 }
+15 -17
drivers/iommu/iommufd/main.c
··· 104 104 if (wait_event_timeout(ictx->destroy_wait, 105 105 refcount_read(&to_destroy->shortterm_users) == 106 106 0, 107 - msecs_to_jiffies(10000))) 107 + msecs_to_jiffies(60000))) 108 108 return 0; 109 109 110 110 pr_crit("Time out waiting for iommufd object to become free\n"); ··· 307 307 struct iommu_ioas_map map; 308 308 struct iommu_ioas_unmap unmap; 309 309 struct iommu_option option; 310 + struct iommu_vdevice_alloc vdev; 310 311 struct iommu_vfio_ioas vfio_ioas; 311 312 struct iommu_viommu_alloc viommu; 312 - struct iommu_vdevice_alloc vdev; 313 313 #ifdef CONFIG_IOMMUFD_TEST 314 314 struct iommu_test_cmd test; 315 315 #endif ··· 333 333 } 334 334 static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = { 335 335 IOCTL_OP(IOMMU_DESTROY, iommufd_destroy, struct iommu_destroy, id), 336 - IOCTL_OP(IOMMU_FAULT_QUEUE_ALLOC, iommufd_fault_alloc, struct iommu_fault_alloc, 337 - out_fault_fd), 336 + IOCTL_OP(IOMMU_FAULT_QUEUE_ALLOC, iommufd_fault_alloc, 337 + struct iommu_fault_alloc, out_fault_fd), 338 338 IOCTL_OP(IOMMU_GET_HW_INFO, iommufd_get_hw_info, struct iommu_hw_info, 339 339 __reserved), 340 340 IOCTL_OP(IOMMU_HWPT_ALLOC, iommufd_hwpt_alloc, struct iommu_hwpt_alloc, ··· 355 355 src_iova), 356 356 IOCTL_OP(IOMMU_IOAS_IOVA_RANGES, iommufd_ioas_iova_ranges, 357 357 struct iommu_ioas_iova_ranges, out_iova_alignment), 358 - IOCTL_OP(IOMMU_IOAS_MAP, iommufd_ioas_map, struct iommu_ioas_map, 359 - iova), 358 + IOCTL_OP(IOMMU_IOAS_MAP, iommufd_ioas_map, struct iommu_ioas_map, iova), 360 359 IOCTL_OP(IOMMU_IOAS_MAP_FILE, iommufd_ioas_map_file, 361 360 struct iommu_ioas_map_file, iova), 362 361 IOCTL_OP(IOMMU_IOAS_UNMAP, iommufd_ioas_unmap, struct iommu_ioas_unmap, 363 362 length), 364 - IOCTL_OP(IOMMU_OPTION, iommufd_option, struct iommu_option, 365 - val64), 363 + IOCTL_OP(IOMMU_OPTION, iommufd_option, struct iommu_option, val64), 364 + IOCTL_OP(IOMMU_VDEVICE_ALLOC, iommufd_vdevice_alloc_ioctl, 365 + struct iommu_vdevice_alloc, virt_id), 366 366 IOCTL_OP(IOMMU_VFIO_IOAS, iommufd_vfio_ioas, struct iommu_vfio_ioas, 367 367 __reserved), 368 368 IOCTL_OP(IOMMU_VIOMMU_ALLOC, iommufd_viommu_alloc_ioctl, 369 369 struct iommu_viommu_alloc, out_viommu_id), 370 - IOCTL_OP(IOMMU_VDEVICE_ALLOC, iommufd_vdevice_alloc_ioctl, 371 - struct iommu_vdevice_alloc, virt_id), 372 370 #ifdef CONFIG_IOMMUFD_TEST 373 371 IOCTL_OP(IOMMU_TEST_CMD, iommufd_test, struct iommu_test_cmd, last), 374 372 #endif ··· 488 490 [IOMMUFD_OBJ_DEVICE] = { 489 491 .destroy = iommufd_device_destroy, 490 492 }, 491 - [IOMMUFD_OBJ_IOAS] = { 492 - .destroy = iommufd_ioas_destroy, 493 + [IOMMUFD_OBJ_FAULT] = { 494 + .destroy = iommufd_fault_destroy, 493 495 }, 494 496 [IOMMUFD_OBJ_HWPT_PAGING] = { 495 497 .destroy = iommufd_hwpt_paging_destroy, ··· 499 501 .destroy = iommufd_hwpt_nested_destroy, 500 502 .abort = iommufd_hwpt_nested_abort, 501 503 }, 502 - [IOMMUFD_OBJ_FAULT] = { 503 - .destroy = iommufd_fault_destroy, 504 - }, 505 - [IOMMUFD_OBJ_VIOMMU] = { 506 - .destroy = iommufd_viommu_destroy, 504 + [IOMMUFD_OBJ_IOAS] = { 505 + .destroy = iommufd_ioas_destroy, 507 506 }, 508 507 [IOMMUFD_OBJ_VDEVICE] = { 509 508 .destroy = iommufd_vdevice_destroy, 509 + }, 510 + [IOMMUFD_OBJ_VIOMMU] = { 511 + .destroy = iommufd_viommu_destroy, 510 512 }, 511 513 #ifdef CONFIG_IOMMUFD_TEST 512 514 [IOMMUFD_OBJ_SELFTEST] = {
+17 -28
drivers/iommu/iommufd/selftest.c
··· 311 311 .read_and_clear_dirty = mock_domain_read_and_clear_dirty, 312 312 }; 313 313 314 - static struct iommu_domain *mock_domain_alloc_paging(struct device *dev) 315 - { 316 - struct mock_dev *mdev = to_mock_dev(dev); 317 - struct mock_iommu_domain *mock; 318 - 319 - mock = kzalloc(sizeof(*mock), GFP_KERNEL); 320 - if (!mock) 321 - return NULL; 322 - mock->domain.geometry.aperture_start = MOCK_APERTURE_START; 323 - mock->domain.geometry.aperture_end = MOCK_APERTURE_LAST; 324 - mock->domain.pgsize_bitmap = MOCK_IO_PAGE_SIZE; 325 - if (dev && mdev->flags & MOCK_FLAGS_DEVICE_HUGE_IOVA) 326 - mock->domain.pgsize_bitmap |= MOCK_HUGE_PAGE_SIZE; 327 - mock->domain.ops = mock_ops.default_domain_ops; 328 - mock->domain.type = IOMMU_DOMAIN_UNMANAGED; 329 - xa_init(&mock->pfns); 330 - return &mock->domain; 331 - } 332 - 333 314 static struct mock_iommu_domain_nested * 334 315 __mock_domain_alloc_nested(const struct iommu_user_data *user_data) 335 316 { ··· 366 385 bool has_dirty_flag = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING; 367 386 const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING | 368 387 IOMMU_HWPT_ALLOC_NEST_PARENT; 369 - bool no_dirty_ops = to_mock_dev(dev)->flags & 370 - MOCK_FLAGS_DEVICE_NO_DIRTY; 371 - struct iommu_domain *domain; 388 + struct mock_dev *mdev = to_mock_dev(dev); 389 + bool no_dirty_ops = mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY; 390 + struct mock_iommu_domain *mock; 372 391 373 392 if (user_data) 374 393 return ERR_PTR(-EOPNOTSUPP); 375 394 if ((flags & ~PAGING_FLAGS) || (has_dirty_flag && no_dirty_ops)) 376 395 return ERR_PTR(-EOPNOTSUPP); 377 396 378 - domain = mock_domain_alloc_paging(dev); 379 - if (!domain) 397 + mock = kzalloc(sizeof(*mock), GFP_KERNEL); 398 + if (!mock) 380 399 return ERR_PTR(-ENOMEM); 400 + mock->domain.geometry.aperture_start = MOCK_APERTURE_START; 401 + mock->domain.geometry.aperture_end = MOCK_APERTURE_LAST; 402 + mock->domain.pgsize_bitmap = MOCK_IO_PAGE_SIZE; 403 + if (dev && mdev->flags & MOCK_FLAGS_DEVICE_HUGE_IOVA) 404 + mock->domain.pgsize_bitmap |= MOCK_HUGE_PAGE_SIZE; 405 + mock->domain.ops = mock_ops.default_domain_ops; 406 + mock->domain.type = IOMMU_DOMAIN_UNMANAGED; 407 + xa_init(&mock->pfns); 408 + 381 409 if (has_dirty_flag) 382 - domain->dirty_ops = &dirty_ops; 383 - return domain; 410 + mock->domain.dirty_ops = &dirty_ops; 411 + return &mock->domain; 384 412 } 385 413 386 414 static void mock_domain_free(struct iommu_domain *domain) ··· 585 595 struct mock_viommu *mock_viommu = to_mock_viommu(viommu); 586 596 struct mock_iommu_domain_nested *mock_nested; 587 597 588 - if (flags & ~IOMMU_HWPT_FAULT_ID_VALID) 598 + if (flags) 589 599 return ERR_PTR(-EOPNOTSUPP); 590 600 591 601 mock_nested = __mock_domain_alloc_nested(user_data); ··· 703 713 .owner = THIS_MODULE, 704 714 .pgsize_bitmap = MOCK_IO_PAGE_SIZE, 705 715 .hw_info = mock_domain_hw_info, 706 - .domain_alloc_paging = mock_domain_alloc_paging, 707 716 .domain_alloc_paging_flags = mock_domain_alloc_paging_flags, 708 717 .domain_alloc_nested = mock_domain_alloc_nested, 709 718 .capable = mock_domain_capable,
+3 -1
include/uapi/linux/iommufd.h
··· 868 868 * @pasid: Process Address Space ID 869 869 * @grpid: Page Request Group Index 870 870 * @perm: Combination of enum iommu_hwpt_pgfault_perm 871 + * @__reserved: Must be 0. 871 872 * @addr: Fault address 872 873 * @length: a hint of how much data the requestor is expecting to fetch. For 873 874 * example, if the PRI initiator knows it is going to do a 10MB ··· 884 883 __u32 pasid; 885 884 __u32 grpid; 886 885 __u32 perm; 887 - __u64 addr; 886 + __u32 __reserved; 887 + __aligned_u64 addr; 888 888 __u32 length; 889 889 __u32 cookie; 890 890 };