Skip to content

Commit e26eed4

Browse files
committed
iommufd: Add some fault injection points
This increases the coverage the fail_nth test gets, as well as via syzkaller. Link: https://lore.kernel.org/r/[email protected] Tested-by: Matthew Rosato <[email protected]> # s390 Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent f4b20bb commit e26eed4

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

drivers/iommu/iommufd/main.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ struct iommufd_object *iommufd_get_object(struct iommufd_ctx *ictx, u32 id,
102102
{
103103
struct iommufd_object *obj;
104104

105+
if (iommufd_should_fail())
106+
return ERR_PTR(-ENOENT);
107+
105108
xa_lock(&ictx->objects);
106109
obj = xa_load(&ictx->objects, id);
107110
if (!obj || (type != IOMMUFD_OBJ_ANY && obj->type != type) ||

drivers/iommu/iommufd/pages.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ static void *temp_kmalloc(size_t *size, void *backup, size_t backup_len)
8080

8181
if (*size < backup_len)
8282
return backup;
83+
84+
if (!backup && iommufd_should_fail())
85+
return NULL;
86+
8387
*size = min_t(size_t, *size, TEMP_MEMORY_LIMIT);
8488
res = kmalloc(*size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
8589
if (res)
@@ -544,13 +548,23 @@ static int pages_to_xarray(struct xarray *xa, unsigned long start_index,
544548
unsigned long last_index, struct page **pages)
545549
{
546550
struct page **end_pages = pages + (last_index - start_index) + 1;
551+
struct page **half_pages = pages + (end_pages - pages) / 2;
547552
XA_STATE(xas, xa, start_index);
548553

549554
do {
550555
void *old;
551556

552557
xas_lock(&xas);
553558
while (pages != end_pages) {
559+
/* xarray does not participate in fault injection */
560+
if (pages == half_pages && iommufd_should_fail()) {
561+
xas_set_err(&xas, -EINVAL);
562+
xas_unlock(&xas);
563+
/* aka xas_destroy() */
564+
xas_nomem(&xas, GFP_KERNEL);
565+
goto err_clear;
566+
}
567+
554568
old = xas_store(&xas, xa_mk_value(page_to_pfn(*pages)));
555569
if (xas_error(&xas))
556570
break;
@@ -561,6 +575,7 @@ static int pages_to_xarray(struct xarray *xa, unsigned long start_index,
561575
xas_unlock(&xas);
562576
} while (xas_nomem(&xas, GFP_KERNEL));
563577

578+
err_clear:
564579
if (xas_error(&xas)) {
565580
if (xas.xa_index != start_index)
566581
clear_xarray(xa, start_index, xas.xa_index - 1);
@@ -728,6 +743,10 @@ static int pfn_reader_user_pin(struct pfn_reader_user *user,
728743
npages = min_t(unsigned long, last_index - start_index + 1,
729744
user->upages_len / sizeof(*user->upages));
730745

746+
747+
if (iommufd_should_fail())
748+
return -EFAULT;
749+
731750
uptr = (uintptr_t)(pages->uptr + start_index * PAGE_SIZE);
732751
if (!remote_mm)
733752
rc = pin_user_pages_fast(uptr, npages, user->gup_flags,
@@ -872,6 +891,8 @@ static int pfn_reader_user_update_pinned(struct pfn_reader_user *user,
872891
npages = pages->last_npinned - pages->npinned;
873892
inc = false;
874893
} else {
894+
if (iommufd_should_fail())
895+
return -ENOMEM;
875896
npages = pages->npinned - pages->last_npinned;
876897
inc = true;
877898
}
@@ -1721,6 +1742,11 @@ static int iopt_pages_rw_page(struct iopt_pages *pages, unsigned long index,
17211742
return iopt_pages_rw_slow(pages, index, index, offset, data,
17221743
length, flags);
17231744

1745+
if (iommufd_should_fail()) {
1746+
rc = -EINVAL;
1747+
goto out_mmput;
1748+
}
1749+
17241750
mmap_read_lock(pages->source_mm);
17251751
rc = pin_user_pages_remote(
17261752
pages->source_mm, (uintptr_t)(pages->uptr + index * PAGE_SIZE),

0 commit comments

Comments
 (0)