diff options
author | Laura Abbott <labbott@redhat.com> | 2018-07-20 23:41:53 +0200 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2018-07-26 12:36:07 +0200 |
commit | 8a1ccfbc9e0256baafbbce85ccdb72ec89af2aab (patch) | |
tree | f1da058d47dd6f0952f4aa8143a5d2eb05f3f8ea /arch/arm64/kernel/sdei.c | |
parent | arm64: fix ACPI dependencies (diff) | |
download | linux-8a1ccfbc9e0256baafbbce85ccdb72ec89af2aab.tar.xz linux-8a1ccfbc9e0256baafbbce85ccdb72ec89af2aab.zip |
arm64: Add stack information to on_accessible_stack
In preparation for enabling the stackleak plugin on arm64,
we need a way to get the bounds of the current stack. Extend
on_accessible_stack to get this information.
Acked-by: Alexander Popov <alex.popov@linux.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Laura Abbott <labbott@redhat.com>
[will: folded in fix for allmodconfig build breakage w/ sdei]
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/kernel/sdei.c')
-rw-r--r-- | arch/arm64/kernel/sdei.c | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/arch/arm64/kernel/sdei.c b/arch/arm64/kernel/sdei.c index 6b8d90d5ceae..a94a868f0532 100644 --- a/arch/arm64/kernel/sdei.c +++ b/arch/arm64/kernel/sdei.c @@ -13,6 +13,7 @@ #include <asm/mmu.h> #include <asm/ptrace.h> #include <asm/sections.h> +#include <asm/stacktrace.h> #include <asm/sysreg.h> #include <asm/vmap_stack.h> @@ -88,23 +89,55 @@ static int init_sdei_stacks(void) return err; } -bool _on_sdei_stack(unsigned long sp) +bool on_sdei_normal_stack(unsigned long sp, + struct stack_info *info) { - unsigned long low, high; + unsigned long low = (unsigned long)raw_cpu_read(sdei_stack_normal_ptr); + unsigned long high = low + SDEI_STACK_SIZE; - if (!IS_ENABLED(CONFIG_VMAP_STACK)) + if (sp < low || sp >= high) return false; - low = (unsigned long)raw_cpu_read(sdei_stack_critical_ptr); - high = low + SDEI_STACK_SIZE; + if (info) { + info->low = low; + info->high = high; + info->type = STACK_TYPE_SDEI_NORMAL; + } - if (low <= sp && sp < high) + return true; +} + +bool on_sdei_critical_stack(unsigned long sp, + struct stack_info *info) +{ + unsigned long low = (unsigned long)raw_cpu_read(sdei_stack_critical_ptr); + unsigned long high = low + SDEI_STACK_SIZE; + + if (sp < low || sp >= high) + return false; + + if (info) { + info->low = low; + info->high = high; + info->type = STACK_TYPE_SDEI_CRITICAL; + } + + return true; +} + +bool _on_sdei_stack(unsigned long sp, + struct stack_info *info) +{ + if (!IS_ENABLED(CONFIG_VMAP_STACK)) + return false; + + if (on_sdei_critical_stack(sp, info)) return true; - low = (unsigned long)raw_cpu_read(sdei_stack_normal_ptr); - high = low + SDEI_STACK_SIZE; + if (on_sdei_normal_stack(sp, info)) + return true; - return (low <= sp && sp < high); + return false; } unsigned long sdei_arch_get_entry_point(int conduit) |