diff options
author | Doug Gilbert <dgilbert@us.ibm.com> | 2016-12-08 13:22:44 -0600 |
---|---|---|
committer | Sachin Gupta <sgupta2m@in.ibm.com> | 2017-01-17 21:31:53 -0500 |
commit | 64a4edd5b79f0f1f8e41fea892ebd7757e04fa6e (patch) | |
tree | 2744664183b8bacc80ff26fa53d2ba2ec6fc549f | |
parent | 9fdc3a73b8cfc52f5c1ea0c15e9e526be7b7c7c0 (diff) | |
download | talos-sbe-64a4edd5b79f0f1f8e41fea892ebd7757e04fa6e.tar.gz talos-sbe-64a4edd5b79f0f1f8e41fea892ebd7757e04fa6e.zip |
PK stack checking
This commit adds a thread stack check when a thread is preempted. Another
check is done to the kernel stack when back-to-back interrupts are processesed.
These checks are done at a time and location in the code where it is
inexpensive to do the check, and in the case of the thread stack, a likely
place for an stack overflow to occurr. A trap will happen if stack overflow is
detected.
Two new macros have been made available
that can be used to do stack checking at any point in code. These are more
expensive so their use needs to be limited. They are currently not yet used.
Change-Id: I4b4229a358c3c75a2c1c0cba89bc3a38e6252384
RTC:160103
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33624
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Reviewed-by: YUE DU <daviddu@us.ibm.com>
Reviewed-by: ASHISH A. MORE <ashish.more@in.ibm.com>
Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33635
Reviewed-by: Hostboot Team <hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
5 files changed, 50 insertions, 9 deletions
diff --git a/src/import/chips/p9/procedures/ppe/pk/kernel/pk_init.c b/src/import/chips/p9/procedures/ppe/pk/kernel/pk_init.c index d2220946..e965c87b 100644 --- a/src/import/chips/p9/procedures/ppe/pk/kernel/pk_init.c +++ b/src/import/chips/p9/procedures/ppe/pk/kernel/pk_init.c @@ -135,6 +135,8 @@ pk_initialize(PkAddress kernel_stack, //timebase frequency (versus what was hardcoded) pk_set_timebase_rshift(timebase_frequency_hz); + __pk_kernel_stack_limit = kernel_stack; + rc = __pk_stack_init(&kernel_stack, &kernel_stack_size); if (rc) diff --git a/src/import/chips/p9/procedures/ppe/pk/kernel/pk_kernel.h b/src/import/chips/p9/procedures/ppe/pk/kernel/pk_kernel.h index e7305a7d..fbcba39f 100644 --- a/src/import/chips/p9/procedures/ppe/pk/kernel/pk_kernel.h +++ b/src/import/chips/p9/procedures/ppe/pk/kernel/pk_kernel.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* Contributors Listed Below - COPYRIGHT 2015,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -66,6 +66,10 @@ UNLESS__PK_CORE_C__(extern) volatile PkAddress __pk_kernel_stack; +UNLESS__PK_CORE_C__(extern) +volatile +PkAddress __pk_kernel_stack_limit; + /// This is the run queue - the queue of mapped runnable tasks. UNLESS__PK_CORE_C__(extern) volatile @@ -232,6 +236,17 @@ int __pk_stack_init(PkAddress* stack, size_t* size); +void +__pk_stack_check(uint32_t stack_base, uint32_t stack_limit); + +#define PK_KERNEL_STACK_CHECK() __pk_stack_check(__pk_kernel_stack, __pk_kernel_stack_limit) + +#define PK_THREAD_STACK_CHECK() \ + { \ + PkThread* thread = (PkThread*)__pk_current_thread; \ + if (thread) __pk_stack_check(thread->stack_base, thread->stack_limit); \ + } + /// Machine-specific thread context initialization. void diff --git a/src/import/chips/p9/procedures/ppe/pk/kernel/pk_stack_init.c b/src/import/chips/p9/procedures/ppe/pk/kernel/pk_stack_init.c index b11860b3..44774e0d 100644 --- a/src/import/chips/p9/procedures/ppe/pk/kernel/pk_stack_init.c +++ b/src/import/chips/p9/procedures/ppe/pk/kernel/pk_stack_init.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* Contributors Listed Below - COPYRIGHT 2015,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -112,3 +112,15 @@ __pk_stack_init(PkAddress* stack, return PK_OK; } + +void __pk_stack_check(uint32_t stack_base, uint32_t stack_limit) +{ + uint32_t stack_addr; + asm volatile ("mr %0, 1" : "=r" (stack_addr) : :); + + if(stack_addr > stack_base || stack_addr < stack_limit) + { + PK_PANIC(PK_STACK_OVERFLOW); + } +} + diff --git a/src/import/chips/p9/procedures/ppe/pk/ppe42/pk_panic_codes.h b/src/import/chips/p9/procedures/ppe/pk/ppe42/pk_panic_codes.h index 0ca6ad28..d17efc07 100644 --- a/src/import/chips/p9/procedures/ppe/pk/ppe42/pk_panic_codes.h +++ b/src/import/chips/p9/procedures/ppe/pk/ppe42/pk_panic_codes.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -333,7 +333,7 @@ typedef enum #define PK_BOOT_VECTORS_NOT_ALIGNED 0x0005 #define PPE42_ILLEGAL_INSTRUCTION 0x001c - +#define PK_STACK_OVERFLOW 0x0305 #endif // __ASSEMBLER__ diff --git a/src/import/chips/p9/procedures/ppe/pk/ppe42/ppe42_exceptions.S b/src/import/chips/p9/procedures/ppe/pk/ppe42/ppe42_exceptions.S index 6f3e2358..2d729f11 100644 --- a/src/import/chips/p9/procedures/ppe/pk/ppe42/ppe42_exceptions.S +++ b/src/import/chips/p9/procedures/ppe/pk/ppe42/ppe42_exceptions.S @@ -5,7 +5,7 @@ /* */ /* OpenPOWER sbe Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* Contributors Listed Below - COPYRIGHT 2015,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -368,7 +368,7 @@ ctx_continue_push: ## If the 'processing interrupt' bit is set then we were already ## using the kernel stack and don't need to modify or save the current ## stack pointer. - bb1wi %r3, PPE42_PROC_IRQ_BIT, ctx_push_completed + bb1wi %r3, PPE42_PROC_IRQ_BIT, kernel_stack_check ## load the pointer to the current thread control block _lwzsd %r4, __pk_current_thread @@ -381,6 +381,12 @@ ctx_continue_push: ## pointer stw %r1, PK_THREAD_OFFSET_SAVED_STACK_POINTER(%r4) + ## Check thread stack overflow + lwz %r7, PK_THREAD_OFFSET_STACK_LIMIT(%r4) + cmplwblt %r7, %r1, stack_good + _pk_panic PK_STACK_OVERFLOW +stack_good: + #ifdef HWMACRO_GPE ## Save the context of the PBASLVCTL reg _liw %r7, PBA_SLVCTLN(PBASLVCTLN) @@ -392,11 +398,17 @@ ctx_continue_push: switch_to_kernel_stack: _stwsd %r1, __pk_saved_sp _lwzsd %r1, __pk_kernel_stack + blr + +kernel_stack_check: + _lwzsd %r7, __pk_kernel_stack_limit + cmplwblt %r7, %r1, ctx_push_complete + _pk_panic PK_STACK_OVERFLOW -ctx_push_completed: +ctx_push_complete: blr -__get_ext_irq: +__get_ext_irq: ## Entry invariants: ## 1. external interupts are disabled; @@ -407,7 +419,7 @@ __get_ext_irq: ## This is HW Macro specific code that is responsible for finding the ## IRQ # and storing it in r4 (phantom IRQ's are assigned a value of EXTERNAL_IRQS). - hwmacro_get_ext_irq + hwmacro_get_ext_irq ## An active or phantom IRQ was found. ## R3 has the context of the interrupted thread or bottom half |