From 71664fd8d2d2550a56cc6a9c2b81797bfe90d613 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 17 Nov 2014 18:22:04 +1100 Subject: Stack checking extensions This patch adds: - Normal builds are done with -fstack-protector (we want to investigate using -fstack-protector-strong on gcc4.9 but for now we just use that - Build with STACK_CHECK=1 will use -fstack-protector-all and -pg and will check the stack in mcount Signed-off-by: Benjamin Herrenschmidt --- include/compiler.h | 2 ++ include/cpu.h | 7 +++++-- include/skiboot.h | 5 +++++ include/stack.h | 12 ++++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/compiler.h b/include/compiler.h index c1557d8..ab6e28e 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -35,6 +35,8 @@ #define offsetof(type,m) __builtin_offsetof(type,m) #endif +#define __nomcount __attribute__((no_instrument_function)) + /* Compiler barrier */ static inline void barrier(void) { diff --git a/include/cpu.h b/include/cpu.h index 7895e96..8cb17be 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -56,10 +56,13 @@ struct cpu_thread { void *icp_regs; uint32_t con_suspend; bool con_need_flush; + bool in_mcount; uint32_t hbrt_spec_wakeup; /* primary only */ uint64_t save_l2_fir_action1; uint64_t current_token; - + int64_t stack_bot_mark; + uint64_t stack_bot_pc; + uint64_t stack_bot_tok; struct lock job_lock; struct list_head job_queue; }; @@ -138,7 +141,7 @@ extern struct cpu_thread *next_available_core_in_chip(struct cpu_thread *cpu, u3 /* Return the caller CPU (only after init_cpu_threads) */ register struct cpu_thread *__this_cpu asm("r13"); -static inline struct cpu_thread *this_cpu(void) +static inline __nomcount struct cpu_thread *this_cpu(void) { return __this_cpu; } diff --git a/include/skiboot.h b/include/skiboot.h index 1a1f96f..53660af 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -122,6 +122,11 @@ extern void *boot_stack_top; /* For use by debug code */ extern void backtrace(void); extern void __backtrace(char *bt_buf, int bt_buf_len); +#ifdef STACK_CHECK_ENABLED +extern void check_stacks(void); +#else +static inline void check_stacks(void) { } +#endif /* Convert a 4-bit number to a hex char */ extern char tohex(uint8_t nibble); diff --git a/include/stack.h b/include/stack.h index 6eedc01..57771b4 100644 --- a/include/stack.h +++ b/include/stack.h @@ -17,6 +17,8 @@ #ifndef __STACKFRAME_H #define __STACKFRAME_H +#include + #define STACK_ENTRY_OPAL_API 0 /* OPAL call */ #define STACK_ENTRY_MCHECK 0x0200 /* Machine check */ #define STACK_ENTRY_HMI 0x0e60 /* Hypervisor maintainance */ @@ -39,6 +41,16 @@ /* Offset to get to machine check CPU stacks */ #define CPU_MC_STACKS_OFFSET (CPU_STACKS_BASE + STACK_SIZE - STACK_TOP_GAP) +/* Gap below the stack. If our stack checker sees the stack below that + * gap, it will flag a stack overflow + */ +#define STACK_SAFETY_GAP 512 + +/* Warning threshold, if stack goes below that on mcount, print a + * warning + */ +#define STACK_WARNING_GAP 1024 + #ifndef __ASSEMBLY__ #include -- cgit v1.1