tests: fatal/exception: pin stack before stack overflow test

For hardware stack overflow test, pin the whole stack if
demand paging is enabled and generic sections are not all present
at boot. The whole stack may not be in memory at the time of
test, which would result in double fault (exception being
handled + page fault). So make sure the stack is in physical
memory and mapped before doing any tests.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2021-07-16 15:38:01 -07:00 committed by Christopher Friedt
commit b70d44c94d

View file

@ -13,6 +13,7 @@
#include <assert.h>
#if defined(CONFIG_USERSPACE)
#include <sys/mem_manage.h>
#include <syscall_handler.h>
#include "test_syscalls.h"
#endif
@ -446,6 +447,54 @@ void test_fatal(void)
/*test case main entry*/
void test_main(void)
{
#if defined(CONFIG_DEMAND_PAGING) && \
!defined(CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT)
uintptr_t pin_addr;
size_t pin_size, obj_size;
/* Need to pin the whole stack object (including reserved
* space), or else it would cause double faults: exception
* being processed while page faults on the stacks.
*
* Same applies for some variables needed during exception
* processing.
*/
#if defined(CONFIG_STACK_SENTINEL) && !defined(CONFIG_ARCH_POSIX)
obj_size = K_THREAD_STACK_SIZEOF(overflow_stack);
#if defined(CONFIG_USERSPACE)
obj_size = Z_THREAD_STACK_SIZE_ADJUST(obj_size);
#endif
k_mem_region_align(&pin_addr, &pin_size,
POINTER_TO_UINT(&overflow_stack),
obj_size, CONFIG_MMU_PAGE_SIZE);
k_mem_pin(UINT_TO_POINTER(pin_addr), pin_size);
#endif /* CONFIG_STACK_SENTINEL && !CONFIG_ARCH_POSIX */
obj_size = K_THREAD_STACK_SIZEOF(alt_stack);
#if defined(CONFIG_USERSPACE)
obj_size = Z_THREAD_STACK_SIZE_ADJUST(obj_size);
#endif
k_mem_region_align(&pin_addr, &pin_size,
POINTER_TO_UINT(&alt_stack),
obj_size,
CONFIG_MMU_PAGE_SIZE);
k_mem_pin(UINT_TO_POINTER(pin_addr), pin_size);
k_mem_region_align(&pin_addr, &pin_size,
POINTER_TO_UINT((void *)&expected_reason),
sizeof(expected_reason),
CONFIG_MMU_PAGE_SIZE);
k_mem_pin(UINT_TO_POINTER(pin_addr), pin_size);
#endif /* CONFIG_DEMAND_PAGING
* && !CONFIG_LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT
*/
ztest_test_suite(fatal,
ztest_unit_test(test_fatal));
ztest_run_test_suite(fatal);