x86: page-aligned stacks with guard page
Subsequent patches will set this guard page as unmapped, triggering a page fault on access. If this is due to stack overflow, a double fault will be triggered, which we are now capable of handling with a switch to a know good stack. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
befb0695ba
commit
0fab8a6dc5
4 changed files with 35 additions and 14 deletions
|
@ -204,6 +204,9 @@ void _new_thread(struct k_thread *thread, char *pStackMem, size_t stackSize,
|
|||
|
||||
unsigned long *pInitialThread;
|
||||
|
||||
#if _STACK_GUARD_SIZE
|
||||
pStackMem += _STACK_GUARD_SIZE;
|
||||
#endif
|
||||
_new_thread_init(thread, pStackMem, stackSize, priority, options);
|
||||
|
||||
/* carve the thread entry struct from the "base" of the stack */
|
||||
|
|
|
@ -20,6 +20,8 @@ extern "C" {
|
|||
#define STACK_ROUND_UP(x) ROUND_UP(x, STACK_ALIGN_SIZE)
|
||||
#define STACK_ROUND_DOWN(x) ROUND_DOWN(x, STACK_ALIGN_SIZE)
|
||||
|
||||
extern K_THREAD_STACK_DEFINE(_interrupt_stack, CONFIG_ISR_STACK_SIZE);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Performs architecture-specific initialization
|
||||
|
@ -32,10 +34,9 @@ extern "C" {
|
|||
*/
|
||||
static inline void kernel_arch_init(void)
|
||||
{
|
||||
extern char _interrupt_stack[CONFIG_ISR_STACK_SIZE];
|
||||
|
||||
_kernel.nested = 0;
|
||||
_kernel.irq_stack = _interrupt_stack + CONFIG_ISR_STACK_SIZE;
|
||||
_kernel.irq_stack = K_THREAD_STACK_BUFFER(_interrupt_stack) +
|
||||
CONFIG_ISR_STACK_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <arch/x86/irq_controller.h>
|
||||
#include <kernel_arch_thread.h>
|
||||
#include <generated_dts_board.h>
|
||||
#include <mmustructs.h>
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <arch/x86/asm_inline.h>
|
||||
|
@ -530,25 +531,38 @@ extern FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
|
|||
const NANO_ESF * pEsf);
|
||||
|
||||
|
||||
#ifdef CONFIG_X86_STACK_PROTECTION
|
||||
#define _STACK_GUARD_SIZE MMU_PAGE_SIZE
|
||||
#define _STACK_BASE_ALIGN MMU_PAGE_SIZE
|
||||
#else
|
||||
#define _STACK_GUARD_SIZE 0
|
||||
#define _STACK_BASE_ALIGN STACK_ALIGN
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* All thread stacks, regardless of whether owned by application or kernel,
|
||||
* go in the .stacks input section, which will end up in the kernel's
|
||||
* noinit.
|
||||
*/
|
||||
|
||||
#define _ARCH_THREAD_STACK_DEFINE(sym, size) \
|
||||
char _GENERIC_SECTION(.stacks) __aligned(STACK_ALIGN) sym[size]
|
||||
char _GENERIC_SECTION(.stacks) __aligned(_STACK_BASE_ALIGN) \
|
||||
sym[size + _STACK_GUARD_SIZE]
|
||||
|
||||
#define _ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
||||
char _GENERIC_SECTION(.stacks) __aligned(STACK_ALIGN) sym[nmemb][size]
|
||||
char _GENERIC_SECTION(.stacks) __aligned(_STACK_BASE_ALIGN) \
|
||||
sym[nmemb][ROUND_UP(size, _STACK_BASE_ALIGN) + \
|
||||
_STACK_GUARD_SIZE]
|
||||
|
||||
#define _ARCH_THREAD_STACK_MEMBER(sym, size) \
|
||||
char __aligned(STACK_ALIGN) sym[size]
|
||||
char __aligned(_STACK_BASE_ALIGN) sym[size + _STACK_GUARD_SIZE]
|
||||
|
||||
#define _ARCH_THREAD_STACK_SIZEOF(sym) \
|
||||
sizeof(sym)
|
||||
(sizeof(sym) - _STACK_GUARD_SIZE)
|
||||
|
||||
#define _ARCH_THREAD_STACK_BUFFER(sym) \
|
||||
sym
|
||||
(sym + _STACK_GUARD_SIZE)
|
||||
|
||||
#if CONFIG_X86_KERNEL_OOPS
|
||||
#define _ARCH_EXCEPT(reason_p) do { \
|
||||
|
|
|
@ -121,14 +121,16 @@ K_THREAD_STACK_DEFINE(_interrupt_stack, CONFIG_ISR_STACK_SIZE);
|
|||
|
||||
extern void idle(void *unused1, void *unused2, void *unused3);
|
||||
|
||||
void k_call_stacks_analyze(void)
|
||||
{
|
||||
#if defined(CONFIG_INIT_STACKS) && defined(CONFIG_PRINTK)
|
||||
extern char sys_work_q_stack[CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE];
|
||||
extern K_THREAD_STACK_DEFINE(sys_work_q_stack,
|
||||
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE);
|
||||
#if defined(CONFIG_ARC) && CONFIG_RGF_NUM_BANKS != 1
|
||||
extern char _firq_stack[CONFIG_FIRQ_STACK_SIZE];
|
||||
extern K_THREAD_STACK_DEFINE(_firq_stack, CONFIG_FIRQ_STACK_SIZE);
|
||||
#endif /* CONFIG_ARC */
|
||||
|
||||
|
||||
void k_call_stacks_analyze(void)
|
||||
{
|
||||
printk("Kernel stacks:\n");
|
||||
STACK_ANALYZE("main ", _main_stack);
|
||||
STACK_ANALYZE("idle ", _idle_stack);
|
||||
|
@ -137,9 +139,10 @@ void k_call_stacks_analyze(void)
|
|||
#endif /* CONFIG_ARC */
|
||||
STACK_ANALYZE("interrupt", _interrupt_stack);
|
||||
STACK_ANALYZE("workqueue", sys_work_q_stack);
|
||||
|
||||
#endif /* CONFIG_INIT_STACKS && CONFIG_PRINTK */
|
||||
}
|
||||
#else
|
||||
void k_call_stacks_analyze(void) { }
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue