diff options
author | Will Deacon <will@kernel.org> | 2020-05-15 14:11:05 +0100 |
---|---|---|
committer | Will Deacon <will@kernel.org> | 2020-05-18 17:47:22 +0100 |
commit | 51189c7a7ed1b4ed4493e27275d466ff60406d3a (patch) | |
tree | c06448db0ce33c2d4a5ae1494806a3b81082aa96 /include/linux/scs.h | |
parent | cc49c71d2abe99c1c2c9bedf0693ad2d3ee4a067 (diff) | |
download | linux-stable-51189c7a7ed1b4ed4493e27275d466ff60406d3a.tar.gz linux-stable-51189c7a7ed1b4ed4493e27275d466ff60406d3a.tar.bz2 linux-stable-51189c7a7ed1b4ed4493e27275d466ff60406d3a.zip |
arm64: scs: Store absolute SCS stack pointer value in thread_info
Storing the SCS information in thread_info as a {base,offset} pair
introduces an additional load instruction on the ret-to-user path,
since the SCS stack pointer in x18 has to be converted back to an offset
by subtracting the base.
Replace the offset with the absolute SCS stack pointer value instead
and avoid the redundant load.
Tested-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Diffstat (limited to 'include/linux/scs.h')
-rw-r--r-- | include/linux/scs.h | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/include/linux/scs.h b/include/linux/scs.h index 3f3662621a27..0eb2485ef832 100644 --- a/include/linux/scs.h +++ b/include/linux/scs.h @@ -27,7 +27,7 @@ #define SCS_END_MAGIC (0x5f6UL + POISON_POINTER_DELTA) #define task_scs(tsk) (task_thread_info(tsk)->scs_base) -#define task_scs_offset(tsk) (task_thread_info(tsk)->scs_offset) +#define task_scs_sp(tsk) (task_thread_info(tsk)->scs_sp) void scs_init(void); int scs_prepare(struct task_struct *tsk, int node); @@ -39,7 +39,7 @@ static inline void scs_task_reset(struct task_struct *tsk) * Reset the shadow stack to the base address in case the task * is reused. */ - task_scs_offset(tsk) = 0; + task_scs_sp(tsk) = task_scs(tsk); } static inline unsigned long *__scs_magic(void *s) @@ -50,9 +50,9 @@ static inline unsigned long *__scs_magic(void *s) static inline bool scs_corrupted(struct task_struct *tsk) { unsigned long *magic = __scs_magic(task_scs(tsk)); + unsigned long sz = task_scs_sp(tsk) - task_scs(tsk); - return (task_scs_offset(tsk) >= SCS_SIZE - 1 || - READ_ONCE_NOCHECK(*magic) != SCS_END_MAGIC); + return sz >= SCS_SIZE - 1 || READ_ONCE_NOCHECK(*magic) != SCS_END_MAGIC; } #else /* CONFIG_SHADOW_CALL_STACK */ |