From: Sebastian Brzezinka <sebastian.brzezinka@intel.com>
To: Krzysztof Karas <krzysztof.karas@intel.com>,
<intel-gfx@lists.freedesktop.org>
Cc: Andi Shyti <andi.shyti@linux.intel.com>,
Sebastian Brzezinka <sebastian.brzezinka@intel.com>,
Krzysztof Niemiec <krzysztof.niemiec@intel.com>,
Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Subject: Re: [PATCH v7 1/2] drm/i915/selftests: Prevent userspace mapping invalidation
Date: Fri, 24 Apr 2026 12:06:27 +0200 [thread overview]
Message-ID: <DI1AUT3OG3YM.1KQREBT065NFV@intel.com> (raw)
In-Reply-To: <20260421061716.3341529-2-krzysztof.karas@intel.com>
Hi Krzysztof,
On Tue Apr 21, 2026 at 8:17 AM CEST, Krzysztof Karas wrote:
> Migration testing in i915 assumes current task's address space
> to allocate new userspace mapping and uses it without
> registering real user for that address space in mm_struct.
> On single NUMA node setups PCI probe executes in the same
> context as userspace process calling the test (i915_selftest
> from IGT), but when multiple nodes are available, the PCI code
> puts probe into a kernel workqueue. This switches execution to
> a kworker, which does not have its own address space in
> userspace and must borrow such memory from another process, so
> "current->active_mm" is unknown at the start of the test.
>
> It was observed that mm->mm_users would occasionally be 0
> or drop to 0 during the test due to short delay between
> scheduling and executing work in forked process, which reaped
> userspace mappings, further leading to failures upon reading
> from userland memory.
>
> Prevent this by adding a PID parameter to a trusted task, so its
> mm struct may be used if needed.
>
> Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14204
> Fixes: 34b1c1c71d37 ("i915/selftest/igt_mmap: let mmap tests run in kthread")
> Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
> ---
> v5 (Janusz):
> * Remove missing PID warning.
>
> v6:
> * Move mm handling to a separate function. (Andi)
> * Validate user provided PID. (Janusz)
>
> v7 (Andi):
> * Add missing mm reference release on error path.
>
> drivers/gpu/drm/i915/i915_selftest.h | 1 +
> .../gpu/drm/i915/selftests/i915_selftest.c | 62 ++++++++++++++++++-
> 2 files changed, 62 insertions(+), 1 deletion(-)
>
> 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..71f61328e14b 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_selftest.c
> +++ b/drivers/gpu/drm/i915/selftests/i915_selftest.c
> @@ -181,11 +181,48 @@ __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_mm(int u_pid_nr)
> +{
> + struct pid *u_pid = find_get_pid(u_pid_nr);
> + struct task_struct *task;
> + struct mm_struct *mm;
> +
> + 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)
> {
> + int u_pid_nr = i915_selftest.userspace_pid;
> + struct mm_struct *mm = NULL;
> int err = 0;
>
> while (!i915_selftest.random_seed)
> @@ -201,14 +238,32 @@ 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);
>
> + /**
I’m not entirely sure, but ** might be used for documentation comments.
> + * 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) {
> + mm = get_mm(u_pid_nr);
> + if (mm) {
> + kthread_use_mm(mm);
> + mmput_async(mm);
I don’t understand the use of mmput_async here. Why are we calling
mmput at this point? You keep using this mm, so the refcount can’t
actually drop. I would rather expect a pattern like kthread_unuse_mm
-> mmput_async ...
> + if (unlikely(!current->mm))
> + 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);
... here
> return -EINTR;
> + }
>
> pr_info(DRIVER_NAME ": Running %s\n", st->name);
> if (data)
> @@ -226,6 +281,9 @@ static int __run_selftests(const char *name,
> st->name, err))
> err = -1;
>
> + if (mm)
> + kthread_unuse_mm(mm);
... and here
--
Best regards,
Sebastian
next prev parent reply other threads:[~2026-04-24 10:06 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-21 6:17 [PATCH v7 0/2] drm/i915/selftests: Use safe userspace memory for mappings Krzysztof Karas
2026-04-21 6:17 ` [PATCH v7 1/2] drm/i915/selftests: Prevent userspace mapping invalidation Krzysztof Karas
2026-04-24 10:06 ` Sebastian Brzezinka [this message]
2026-04-24 11:21 ` Janusz Krzysztofik
2026-04-29 6:12 ` Krzysztof Karas
2026-04-28 14:57 ` Andi Shyti
2026-04-21 6:17 ` [PATCH v7 2/2] drm/i915/selftests: Run vma tests only if current->mm is present Krzysztof Karas
2026-04-24 9:52 ` Sebastian Brzezinka
2026-04-28 15:03 ` Andi Shyti
2026-04-22 8:51 ` ✓ i915.CI.BAT: success for drm/i915/selftests: Use safe userspace memory for mappings Patchwork
2026-04-22 14:45 ` ✓ i915.CI.Full: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DI1AUT3OG3YM.1KQREBT065NFV@intel.com \
--to=sebastian.brzezinka@intel.com \
--cc=andi.shyti@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=janusz.krzysztofik@linux.intel.com \
--cc=krzysztof.karas@intel.com \
--cc=krzysztof.niemiec@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.