summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Linton <jeremy.linton@arm.com>2025-07-18 23:37:33 -0500
committerCatalin Marinas <catalin.marinas@arm.com>2025-07-23 12:08:17 +0100
commitcbbcfb94c55c02a8c4ce52b5da0770b5591a314c (patch)
tree823f14506ce5d725ea6fb346bd8bc337daa4096a
parent1a665a71ef0fb043c6cfafbf6a6cc9cdc2357505 (diff)
arm64/gcs: task_gcs_el0_enable() should use passed task
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>
-rw-r--r--arch/arm64/include/asm/gcs.h2
-rw-r--r--arch/arm64/kernel/process.c6
2 files changed, 4 insertions, 4 deletions
diff --git a/arch/arm64/include/asm/gcs.h b/arch/arm64/include/asm/gcs.h
index f50660603ecf5..5bc432234d3ab 100644
--- a/arch/arm64/include/asm/gcs.h
+++ b/arch/arm64/include/asm/gcs.h
@@ -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);
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index f53608ecaf4b6..665e1f96501b9 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -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;
}