]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
arm64/gcs: task_gcs_el0_enable() should use passed task
authorJeremy Linton <jeremy.linton@arm.com>
Sat, 19 Jul 2025 04:37:33 +0000 (23:37 -0500)
committerCatalin Marinas <catalin.marinas@arm.com>
Wed, 23 Jul 2025 11:08:17 +0000 (12:08 +0100)
Mark Rutland noticed that the task parameter is ignored and
'current' is being used instead. Since this is usually
what its passed, it hasn't yet been causing problems but likely
will as the code gets more testing.

But, once this is fixed, it creates a new bug in copy_thread_gcs()
since the gcs_el_mode isn't yet set for the task before its being
checked. Move gcs_alloc_thread_stack() after the new task's
gcs_el0_mode initialization to avoid this.

Fixes: fc84bc5378a8 ("arm64/gcs: Context switch GCS state for EL0")
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20250719043740.4548-2-jeremy.linton@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/gcs.h
arch/arm64/kernel/process.c

index f50660603ecf5dc09a92740062df3a089b02b219..5bc432234d3abaf39ba9492feb5d2c7ad1c520a1 100644 (file)
@@ -58,7 +58,7 @@ static inline u64 gcsss2(void)
 
 static inline bool task_gcs_el0_enabled(struct task_struct *task)
 {
-       return current->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE;
+       return task->thread.gcs_el0_mode & PR_SHADOW_STACK_ENABLE;
 }
 
 void gcs_set_el0_mode(struct task_struct *task);
index f53608ecaf4b6320a1ce0dbbff30c3636ef5938e..665e1f96501b91e8ec657990657d3bddbee0d8f5 100644 (file)
@@ -305,13 +305,13 @@ static int copy_thread_gcs(struct task_struct *p,
        p->thread.gcs_base = 0;
        p->thread.gcs_size = 0;
 
+       p->thread.gcs_el0_mode = current->thread.gcs_el0_mode;
+       p->thread.gcs_el0_locked = current->thread.gcs_el0_locked;
+
        gcs = gcs_alloc_thread_stack(p, args);
        if (IS_ERR_VALUE(gcs))
                return PTR_ERR((void *)gcs);
 
-       p->thread.gcs_el0_mode = current->thread.gcs_el0_mode;
-       p->thread.gcs_el0_locked = current->thread.gcs_el0_locked;
-
        return 0;
 }