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
This commit is contained in:
Dave Airlie 2026-06-03 16:28:42 +10:00
commit fe017012c5
6 changed files with 101 additions and 23 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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.

View File

@ -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;

View File

@ -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)");