arc: fix CONFIG_ARC_STACK_CHECKING
- There's no clear need to disable frame pointers if this feature is used, remove this directive. - The 'top' and 'base' terms are reversed. The 'base' is the high address of the stack. The top is the lowest address, where we cannot push further down. Fixup member and offset names to correspond to how these terms are used in hardware documentation. - Use correct pointers for stack top location - Fatal exceptions now go through _NanoFatalErrorHandler to report the faulting ip and thread. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
41c68ece83
commit
9175d20ceb
|
@ -111,6 +111,7 @@ config FIRQ_STACK_SIZE
|
|||
config ARC_STACK_CHECKING
|
||||
bool "Enable Stack Checking"
|
||||
depends on CPU_ARCV2
|
||||
select THREAD_STACK_INFO
|
||||
default n
|
||||
help
|
||||
ARCV2 has a special feature allowing to check stack overflows. This
|
||||
|
|
|
@ -5,7 +5,6 @@ cflags-y += $(call cc-option,-ffunction-sections,) $(call cc-option,-fdata-secti
|
|||
# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63691
|
||||
cflags-y += $(call cc-option,-fno-delete-null-pointer-checks)
|
||||
|
||||
cflags-$(CONFIG_ARC_STACK_CHECKING) = $(call cc-option,-fomit-frame-pointer)
|
||||
cflags-$(CONFIG_LTO) = $(call cc-option,-flto,)
|
||||
|
||||
include $(srctree)/arch/$(ARCH)/soc/$(SOC_PATH)/Makefile
|
||||
|
|
|
@ -227,11 +227,11 @@ _firq_reschedule:
|
|||
st_s r2, [r1, _kernel_offset_to_current]
|
||||
|
||||
#ifdef CONFIG_ARC_STACK_CHECKING
|
||||
/* Use stack top and down registers from restored context */
|
||||
add r3, r2, _K_THREAD_NO_FLOAT_SIZEOF
|
||||
sr r3, [_ARC_V2_KSTACK_TOP]
|
||||
ld_s r3, [r2, _thread_offset_to_stack_top]
|
||||
/* Use stack top and base registers from restored context */
|
||||
ld r3, [r2, _thread_offset_to_stack_base]
|
||||
sr r3, [_ARC_V2_KSTACK_BASE]
|
||||
ld r3, [r2, _thread_offset_to_stack_top]
|
||||
sr r3, [_ARC_V2_KSTACK_TOP]
|
||||
#endif
|
||||
/*
|
||||
* _load_callee_saved_regs expects incoming thread in r2.
|
||||
|
|
|
@ -41,11 +41,14 @@ FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
|
|||
const NANO_ESF *pEsf)
|
||||
{
|
||||
switch (reason) {
|
||||
case _NANO_ERR_HW_EXCEPTION:
|
||||
break;
|
||||
|
||||
case _NANO_ERR_INVALID_TASK_EXIT:
|
||||
printk("***** Invalid Exit Software Error! *****\n");
|
||||
break;
|
||||
|
||||
#if defined(CONFIG_STACK_CANARIES)
|
||||
#if defined(CONFIG_STACK_CANARIES) || defined(CONFIG_ARC_STACK_CHECKING)
|
||||
case _NANO_ERR_STACK_CHK_FAIL:
|
||||
printk("***** Stack Check Fail! *****\n");
|
||||
break;
|
||||
|
|
|
@ -17,50 +17,7 @@
|
|||
|
||||
#include <kernel.h>
|
||||
#include <kernel_structs.h>
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
#include <misc/printk.h>
|
||||
#define PR_EXC(...) printk(__VA_ARGS__)
|
||||
#else
|
||||
#define PR_EXC(...)
|
||||
#endif /* CONFIG_PRINTK */
|
||||
|
||||
#if (CONFIG_FAULT_DUMP > 0)
|
||||
#define FAULT_DUMP(esf, fault) _FaultDump(esf, fault)
|
||||
#else
|
||||
#define FAULT_DUMP(esf, fault) \
|
||||
do { \
|
||||
(void) esf; \
|
||||
(void) fault; \
|
||||
} while ((0))
|
||||
#endif
|
||||
|
||||
#if (CONFIG_FAULT_DUMP > 0)
|
||||
/*
|
||||
* @brief Dump information regarding fault (FAULT_DUMP > 0)
|
||||
*
|
||||
* Dump information regarding the fault when CONFIG_FAULT_DUMP is set to 1
|
||||
* (short form).
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
void _FaultDump(const NANO_ESF *esf, int fault)
|
||||
{
|
||||
ARG_UNUSED(esf);
|
||||
ARG_UNUSED(fault);
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
u32_t exc_addr = _arc_v2_aux_reg_read(_ARC_V2_EFA);
|
||||
u32_t ecr = _arc_v2_aux_reg_read(_ARC_V2_ECR);
|
||||
|
||||
PR_EXC("Exception vector: 0x%x, cause code: 0x%x, parameter 0x%x\n",
|
||||
_ARC_V2_ECR_VECTOR(ecr),
|
||||
_ARC_V2_ECR_CODE(ecr),
|
||||
_ARC_V2_ECR_PARAMETER(ecr));
|
||||
PR_EXC("Address 0x%x\n", exc_addr);
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_FAULT_DUMP */
|
||||
|
||||
/*
|
||||
* @brief Fault handler
|
||||
|
@ -74,9 +31,24 @@ void _FaultDump(const NANO_ESF *esf, int fault)
|
|||
*/
|
||||
void _Fault(void)
|
||||
{
|
||||
u32_t vector, code, parameter;
|
||||
u32_t exc_addr = _arc_v2_aux_reg_read(_ARC_V2_EFA);
|
||||
u32_t ecr = _arc_v2_aux_reg_read(_ARC_V2_ECR);
|
||||
|
||||
FAULT_DUMP(&_default_esf, ecr);
|
||||
vector = _ARC_V2_ECR_VECTOR(ecr);
|
||||
code = _ARC_V2_ECR_CODE(ecr);
|
||||
parameter = _ARC_V2_ECR_PARAMETER(ecr);
|
||||
|
||||
_SysFatalErrorHandler(_NANO_ERR_HW_EXCEPTION, &_default_esf);
|
||||
printk("Exception vector: 0x%x, cause code: 0x%x, parameter 0x%x\n",
|
||||
vector, code, parameter);
|
||||
printk("Address 0x%x\n", exc_addr);
|
||||
#ifdef CONFIG_ARC_STACK_CHECKING
|
||||
/* Vector 6 = EV_ProV. Regardless of code, parameter 2 means stack
|
||||
* check violation
|
||||
*/
|
||||
if (vector == 6 && parameter == 2) {
|
||||
_NanoFatalErrorHandler(_NANO_ERR_STACK_CHK_FAIL, &_default_esf);
|
||||
}
|
||||
#endif
|
||||
_NanoFatalErrorHandler(_NANO_ERR_HW_EXCEPTION, &_default_esf);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ GEN_OFFSET_SYM(_thread_arch_t, intlock_key);
|
|||
GEN_OFFSET_SYM(_thread_arch_t, relinquish_cause);
|
||||
GEN_OFFSET_SYM(_thread_arch_t, return_value);
|
||||
#ifdef CONFIG_ARC_STACK_CHECKING
|
||||
GEN_OFFSET_SYM(_thread_arch_t, stack_top);
|
||||
GEN_OFFSET_SYM(_thread_arch_t, stack_base);
|
||||
#endif
|
||||
|
||||
/* ARCv2-specific IRQ stack frame structure member offsets */
|
||||
|
|
|
@ -158,11 +158,11 @@ _rirq_common_interrupt_swap:
|
|||
/* r2 contains pointer to new thread */
|
||||
|
||||
#ifdef CONFIG_ARC_STACK_CHECKING
|
||||
/* Use stack top and down registers from restored context */
|
||||
add r3, r2, _K_THREAD_NO_FLOAT_SIZEOF
|
||||
sr r3, [_ARC_V2_KSTACK_TOP]
|
||||
ld_s r3, [r2, _thread_offset_to_stack_top]
|
||||
/* Use stack top and base registers from restored context */
|
||||
ld r3, [r2, _thread_offset_to_stack_base]
|
||||
sr r3, [_ARC_V2_KSTACK_BASE]
|
||||
ld r3, [r2, _thread_offset_to_stack_top]
|
||||
sr r3, [_ARC_V2_KSTACK_TOP]
|
||||
#endif
|
||||
/*
|
||||
* _load_callee_saved_regs expects incoming thread in r2.
|
||||
|
|
|
@ -99,11 +99,11 @@ SECTION_FUNC(TEXT, __swap)
|
|||
|
||||
/* entering here, r2 contains the new current thread */
|
||||
#ifdef CONFIG_ARC_STACK_CHECKING
|
||||
/* Use stack top and down registers from restored context */
|
||||
add r3, r2, _K_THREAD_NO_FLOAT_SIZEOF
|
||||
sr r3, [_ARC_V2_KSTACK_TOP]
|
||||
ld_s r3, [r2, _thread_offset_to_stack_top]
|
||||
/* Use stack top and base registers from restored context */
|
||||
ld r3, [r2, _thread_offset_to_stack_base]
|
||||
sr r3, [_ARC_V2_KSTACK_BASE]
|
||||
ld r3, [r2, _thread_offset_to_stack_top]
|
||||
sr r3, [_ARC_V2_KSTACK_TOP]
|
||||
#endif
|
||||
/* XXX - can be moved to delay slot of _CAUSE_RIRQ ? */
|
||||
st_s r2, [r1, _kernel_offset_to_current]
|
||||
|
|
|
@ -84,7 +84,7 @@ void _new_thread(struct k_thread *thread, char *pStackMem, size_t stackSize,
|
|||
*/
|
||||
#ifdef CONFIG_ARC_STACK_CHECKING
|
||||
pInitCtx->status32 = _ARC_V2_STATUS32_SC | _ARC_V2_STATUS32_E(_ARC_V2_DEF_IRQ_LEVEL);
|
||||
thread->arch.stack_top = (u32_t) stackEnd;
|
||||
thread->arch.stack_base = (u32_t) stackEnd;
|
||||
#else
|
||||
pInitCtx->status32 = _ARC_V2_STATUS32_E(_ARC_V2_DEF_IRQ_LEVEL);
|
||||
#endif
|
||||
|
|
|
@ -58,8 +58,10 @@ struct _thread_arch {
|
|||
unsigned int return_value;
|
||||
|
||||
#ifdef CONFIG_ARC_STACK_CHECKING
|
||||
/* top of stack for hardware stack checking */
|
||||
u32_t stack_top;
|
||||
/* High address of stack region, stack grows downward from this
|
||||
* location. Usesd for hardware stack checking
|
||||
*/
|
||||
u32_t stack_base;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -26,12 +26,14 @@
|
|||
#define _thread_offset_to_return_value \
|
||||
(___thread_t_arch_OFFSET + ___thread_arch_t_return_value_OFFSET)
|
||||
|
||||
#define _thread_offset_to_stack_top \
|
||||
(___thread_t_arch_OFFSET + ___thread_arch_t_stack_top_OFFSET)
|
||||
#define _thread_offset_to_stack_base \
|
||||
(___thread_t_arch_OFFSET + ___thread_arch_t_stack_base_OFFSET)
|
||||
|
||||
#define _thread_offset_to_sp \
|
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_sp_OFFSET)
|
||||
|
||||
#define _thread_offset_to_stack_top \
|
||||
(___thread_t_stack_info_OFFSET + ___thread_stack_info_t_start_OFFSET)
|
||||
|
||||
/* end - threads */
|
||||
|
||||
|
|
Loading…
Reference in a new issue