diff options
| author | Dave Airlie <airlied@redhat.com> | 2026-06-03 16:28:42 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2026-06-03 16:28:43 +1000 |
| commit | fe017012c5825f22bd856249e4f3cf57e31027b8 (patch) | |
| tree | 59f05ec5cc216f7c58c1a3126a5e688c53011fb6 /drivers/gpu | |
| parent | 61cd9291cab2fe34b6260d092d633f891c32bf9c (diff) | |
| parent | 6c064db893f548d57036fce17c6493808396e620 (diff) | |
Merge tag 'drm-intel-gt-next-2026-05-29' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
Cross-subsystem Changes:
- Backmerge of drm-next to pull in a commit to revert
Driver Changes:
- Avoid skipping already signaled fence after reset (Sebastian)
- Fix potential UAF in TTM object purge (Janusz)
- Fix refcount underflow in intel_engine_park_heartbeat (Sebastian)
- Drop check for changed VM in EXECBUF (Joonas)
- Revert the "else vma = NULL" patch for being superseded (Joonas)
- Selfest improvements (Janusz, Krzysztof)
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patch.msgid.link/ahlc1R5bzJvmBLlZ@jlahtine-mobl
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 28 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/gt/selftest_workarounds.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_selftest.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/selftests/i915_selftest.c | 74 |
6 files changed, 101 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 05997e8bbb29..1f303d4eaa4d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -898,8 +898,6 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle) vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle); if (likely(vma)) vma = i915_vma_tryget(vma); - else - vma = NULL; rcu_read_unlock(); if (likely(vma)) return vma; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index de70517b4ef2..df3fcc2b1248 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -419,8 +419,6 @@ void i915_ttm_free_cached_io_rsgt(struct drm_i915_gem_object *obj) int i915_ttm_purge(struct drm_i915_gem_object *obj) { struct ttm_buffer_object *bo = i915_gem_to_ttm(obj); - struct i915_ttm_tt *i915_tt = - container_of(bo->ttm, typeof(*i915_tt), ttm); struct ttm_operation_ctx ctx = { .interruptible = true, .no_wait_gpu = false, @@ -435,16 +433,22 @@ int i915_ttm_purge(struct drm_i915_gem_object *obj) if (ret) return ret; - if (bo->ttm && i915_tt->filp) { - /* - * The below fput(which eventually calls shmem_truncate) might - * be delayed by worker, so when directly called to purge the - * pages(like by the shrinker) we should try to be more - * aggressive and release the pages immediately. - */ - shmem_truncate_range(file_inode(i915_tt->filp), - 0, (loff_t)-1); - fput(fetch_and_zero(&i915_tt->filp)); + if (bo->ttm) { + struct i915_ttm_tt *i915_tt = + container_of(bo->ttm, typeof(*i915_tt), ttm); + + if (i915_tt->filp) { + /* + * The below fput(which eventually calls shmem_truncate) + * might be delayed by worker, so when directly called + * to purge the pages(like by the shrinker) we should + * try to be more aggressive and release the pages + * immediately. + */ + shmem_truncate_range(file_inode(i915_tt->filp), + 0, (loff_t)-1); + fput(fetch_and_zero(&i915_tt->filp)); + } } obj->write_domain = 0; diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c index 9d454d0b46f2..d01acfb7d93d 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -1847,11 +1847,12 @@ static int igt_mmap_revoke(void *arg) int i915_gem_mman_live_selftests(struct drm_i915_private *i915) { int ret; - bool unuse_mm = false; static const struct i915_subtest tests[] = { SUBTEST(igt_partial_tiling), SUBTEST(igt_smoke_tiling), SUBTEST(igt_mmap_offset_exhaustion), + }; + static const struct i915_subtest vma_tests[] = { SUBTEST(igt_mmap), SUBTEST(igt_mmap_migrate), SUBTEST(igt_mmap_access), @@ -1859,15 +1860,14 @@ int i915_gem_mman_live_selftests(struct drm_i915_private *i915) SUBTEST(igt_mmap_gpu), }; - if (!current->mm) { - kthread_use_mm(current->active_mm); - unuse_mm = true; - } - ret = i915_live_subtests(tests, i915); + if (ret) + return ret; - if (unuse_mm) - kthread_unuse_mm(current->active_mm); + if (current->mm) + ret = i915_live_subtests(vma_tests, i915); + else + pr_warn("No current->mm to safely borrow userspace memory from. Skipping VMA tests.\n"); return ret; } diff --git a/drivers/gpu/drm/i915/gt/selftest_workarounds.c b/drivers/gpu/drm/i915/gt/selftest_workarounds.c index 81cdecd38346..4e4c420ae67f 100644 --- a/drivers/gpu/drm/i915/gt/selftest_workarounds.c +++ b/drivers/gpu/drm/i915/gt/selftest_workarounds.c @@ -1064,6 +1064,9 @@ static int live_isolated_whitelist(void *arg) enum intel_engine_id id; int i, err = 0; + if (IS_DG2(gt->i915) || IS_METEORLAKE(gt->i915)) + return 0; + /* * Check that a write into a whitelist register works, but * invisible to a second context. diff --git a/drivers/gpu/drm/i915/i915_selftest.h b/drivers/gpu/drm/i915/i915_selftest.h index 72922028f4ba..e29ca298e7eb 100644 --- a/drivers/gpu/drm/i915/i915_selftest.h +++ b/drivers/gpu/drm/i915/i915_selftest.h @@ -35,6 +35,7 @@ struct i915_selftest { unsigned long timeout_jiffies; unsigned int timeout_ms; unsigned int random_seed; + unsigned int userspace_pid; char *filter; int mock; int live; diff --git a/drivers/gpu/drm/i915/selftests/i915_selftest.c b/drivers/gpu/drm/i915/selftests/i915_selftest.c index 8460f0a70d04..3adcfdab75ae 100644 --- a/drivers/gpu/drm/i915/selftests/i915_selftest.c +++ b/drivers/gpu/drm/i915/selftests/i915_selftest.c @@ -181,13 +181,56 @@ __wait_gsc_huc_load_completed(struct drm_i915_private *i915) pr_warn(DRIVER_NAME "Timed out waiting for huc load via GSC!\n"); } +static struct mm_struct *get_selftest_mm(int u_pid_nr) +{ + struct task_struct *task = NULL; + struct mm_struct *mm = NULL; + struct pid *u_pid = NULL; + + if (u_pid_nr < 1) + return NULL; + + u_pid = find_get_pid(u_pid_nr); + if (!u_pid) { + pr_warn("Could not find PID: %d\n", u_pid_nr); + return NULL; + } + + task = get_pid_task(u_pid, PIDTYPE_PID); + put_pid(u_pid); + if (!task) { + pr_warn("Could not find task for PID: %d\n", u_pid_nr); + return NULL; + } + + if (task->flags & PF_KTHREAD) { + pr_warn("Task not in userspace: %d\n", u_pid_nr); + put_task_struct(task); + return NULL; + } + + mm = get_task_mm(task); + put_task_struct(task); + if (!mm) { + pr_warn("Could not find address space of task with PID: %d\n", u_pid_nr); + return NULL; + } + + return mm; +} + static int __run_selftests(const char *name, struct selftest *st, unsigned int count, void *data) { + struct mm_struct *mm = NULL; + int u_pid_nr = -1; int err = 0; + if (i915_selftest.userspace_pid) + u_pid_nr = i915_selftest.userspace_pid; + while (!i915_selftest.random_seed) i915_selftest.random_seed = get_random_u32(); @@ -201,14 +244,36 @@ static int __run_selftests(const char *name, pr_info(DRIVER_NAME ": Performing %s selftests with st_random_seed=0x%x st_timeout=%u\n", name, i915_selftest.random_seed, i915_selftest.timeout_ms); + /* + * If we are running in a kthread on a multi NUMA system and the user passed + * a valid PID of a userspace task, then we may borrow its address space + * to prepare a safe environment for the mmap selftests. + */ + if (!current->mm && u_pid_nr > 0) { + mm = get_selftest_mm(u_pid_nr); + if (mm) { + kthread_use_mm(mm); + if (unlikely(!current->mm)) { + mmput(mm); + mm = NULL; + pr_warn("Could not set mm as current->mm\n"); + } + } + } + /* Tests are listed in order in i915_*_selftests.h */ for (; count--; st++) { if (!st->enabled) continue; cond_resched(); - if (signal_pending(current)) + if (signal_pending(current)) { + if (mm) { + kthread_unuse_mm(mm); + mmput_async(mm); + } return -EINTR; + } pr_info(DRIVER_NAME ": Running %s\n", st->name); if (data) @@ -226,6 +291,11 @@ static int __run_selftests(const char *name, st->name, err)) err = -1; + if (mm) { + kthread_unuse_mm(mm); + mmput_async(mm); + } + return err; } @@ -507,6 +577,8 @@ void igt_hexdump(const void *buf, size_t len) module_param_named(st_random_seed, i915_selftest.random_seed, uint, 0400); module_param_named(st_timeout, i915_selftest.timeout_ms, uint, 0400); module_param_named(st_filter, i915_selftest.filter, charp, 0400); +module_param_named(st_userspace_pid, i915_selftest.userspace_pid, uint, 0400); +MODULE_PARM_DESC(st_userspace_pid, "For usage in tests that map userspace memory and require address space with controllable lifetime."); module_param_named_unsafe(mock_selftests, i915_selftest.mock, int, 0400); MODULE_PARM_DESC(mock_selftests, "Run selftests before loading, using mock hardware (0:disabled [default], 1:run tests then load driver, -1:run tests then leave dummy module)"); |
