From acd8d8ebdaf0f34f8c9cdb2aee2f38f8d888645f Mon Sep 17 00:00:00 2001 From: Krzysztof Chruscinski Date: Thu, 15 Apr 2021 13:04:25 +0200 Subject: [PATCH] tests: kernel: fatal: Add no multithreading test Added test which verifies that when multithreading is disabled exception as correctly handled by the kernel. Signed-off-by: Krzysztof Chruscinski --- .../fatal/no-multithreading/CMakeLists.txt | 13 ++ tests/kernel/fatal/no-multithreading/README | 2 + tests/kernel/fatal/no-multithreading/prj.conf | 4 + .../kernel/fatal/no-multithreading/src/main.c | 146 ++++++++++++++++++ .../fatal/no-multithreading/testcase.yaml | 25 +++ 5 files changed, 190 insertions(+) create mode 100644 tests/kernel/fatal/no-multithreading/CMakeLists.txt create mode 100644 tests/kernel/fatal/no-multithreading/README create mode 100644 tests/kernel/fatal/no-multithreading/prj.conf create mode 100644 tests/kernel/fatal/no-multithreading/src/main.c create mode 100644 tests/kernel/fatal/no-multithreading/testcase.yaml diff --git a/tests/kernel/fatal/no-multithreading/CMakeLists.txt b/tests/kernel/fatal/no-multithreading/CMakeLists.txt new file mode 100644 index 00000000000..5bbc8926744 --- /dev/null +++ b/tests/kernel/fatal/no-multithreading/CMakeLists.txt @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.13.1) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(fatal_no_mt) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) + +target_include_directories(app PRIVATE + ${ZEPHYR_BASE}/kernel/include + ${ZEPHYR_BASE}/arch/${ARCH}/include + ) diff --git a/tests/kernel/fatal/no-multithreading/README b/tests/kernel/fatal/no-multithreading/README new file mode 100644 index 00000000000..33128c4f240 --- /dev/null +++ b/tests/kernel/fatal/no-multithreading/README @@ -0,0 +1,2 @@ +This test case verifies that kernel fatal error handling works correctly +when CONFIG_MULTITHREADING=n. diff --git a/tests/kernel/fatal/no-multithreading/prj.conf b/tests/kernel/fatal/no-multithreading/prj.conf new file mode 100644 index 00000000000..b9f5efeec95 --- /dev/null +++ b/tests/kernel/fatal/no-multithreading/prj.conf @@ -0,0 +1,4 @@ +CONFIG_ZTEST=y +CONFIG_COVERAGE=n +CONFIG_TEST_USERSPACE=n +CONFIG_MULTITHREADING=n diff --git a/tests/kernel/fatal/no-multithreading/src/main.c b/tests/kernel/fatal/no-multithreading/src/main.c new file mode 100644 index 00000000000..7287357e0c4 --- /dev/null +++ b/tests/kernel/fatal/no-multithreading/src/main.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +static ZTEST_DMEM volatile int expected_reason = -1; + +void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *pEsf) +{ + int rv = TC_PASS; + + TC_PRINT("Caught system error -- reason %d\n", reason); + if (reason != expected_reason) { + TC_PRINT("Unexpected reason (exp: %d)\n", expected_reason); + rv = TC_FAIL; + } + + TC_END_REPORT(rv); + arch_system_halt(reason); +} + +static void entry_cpu_exception(void) +{ + expected_reason = K_ERR_CPU_EXCEPTION; + + TC_PRINT("cpu exception\n"); +#if defined(CONFIG_X86) + __asm__ volatile ("ud2"); +#elif defined(CONFIG_NIOS2) + __asm__ volatile ("trap"); +#elif defined(CONFIG_ARC) + __asm__ volatile ("swi"); +#else + /* Triggers usage fault on ARM, illegal instruction on RISCV + * and xtensa + */ + { + volatile long illegal = 0; + ((void(*)(void))&illegal)(); + } +#endif +} + +static void entry_oops(void) +{ + unsigned int key; + + TC_PRINT("oops\n"); + expected_reason = K_ERR_KERNEL_OOPS; + + key = irq_lock(); + k_oops(); + irq_unlock(key); +} + +static void entry_panic(void) +{ + unsigned int key; + + TC_PRINT("panic\n"); + expected_reason = K_ERR_KERNEL_PANIC; + + key = irq_lock(); + k_panic(); + irq_unlock(key); +} + +static void entry_zephyr_assert(void) +{ + TC_PRINT("assert\n"); + expected_reason = K_ERR_KERNEL_PANIC; + + __ASSERT(0, "intentionally failed assertion"); +} + +static void entry_arbitrary_reason(void) +{ + unsigned int key; + + TC_PRINT("arbitrary reason\n"); + expected_reason = INT_MAX; + + key = irq_lock(); + z_except_reason(INT_MAX); + irq_unlock(key); +} + +static void entry_arbitrary_reason_negative(void) +{ + unsigned int key; + + TC_PRINT("arbitrary reason (negative)\n"); + expected_reason = -2; + + key = irq_lock(); + z_except_reason(-2); + irq_unlock(key); +} + +typedef void (*exc_trigger_func_t)(void); + +static const exc_trigger_func_t exc_trigger_func[] = { + entry_cpu_exception, + entry_oops, + entry_panic, + entry_zephyr_assert, + entry_arbitrary_reason, + entry_arbitrary_reason_negative, +}; + +/** + * @brief Test the kernel fatal error handling works correctly + * @details Manually trigger the crash with various ways and check + * that the kernel is handling that properly or not. Also the crash reason + * should match. + * + * @ingroup kernel_common_tests + */ +void test_fatal(void) +{ +#ifdef VIA_TWISTER +#define EXC_TRIGGER_FUNC_IDX VIA_TWISTER +#else +#define EXC_TRIGGER_FUNC_IDX 0 +#endif + exc_trigger_func[EXC_TRIGGER_FUNC_IDX](); + + ztest_test_fail(); + TC_END_REPORT(TC_FAIL); +} + +/*test case main entry*/ +void test_main(void) +{ + ztest_test_suite(fatal_no_mt, + ztest_unit_test(test_fatal)); + ztest_run_test_suite(fatal_no_mt); +} diff --git a/tests/kernel/fatal/no-multithreading/testcase.yaml b/tests/kernel/fatal/no-multithreading/testcase.yaml new file mode 100644 index 00000000000..ee548d7d5e0 --- /dev/null +++ b/tests/kernel/fatal/no-multithreading/testcase.yaml @@ -0,0 +1,25 @@ +tests: + kernel.no-mt.cpu_exception: + platform_allow: qemu_cortex_m3 + tags: kernel ignore_faults + extra_args: EXTRA_CPPFLAGS=-DVIA_TWISTER=0 + kernel.no-mt.oops: + platform_allow: qemu_cortex_m3 + tags: kernel ignore_faults + extra_args: EXTRA_CPPFLAGS=-DVIA_TWISTER=1 + kernel.no-mt.panic: + platform_allow: qemu_cortex_m3 + tags: kernel ignore_faults + extra_args: EXTRA_CPPFLAGS=-DVIA_TWISTER=2 + kernel.no-mt.zephyr_assert: + platform_allow: qemu_cortex_m3 + tags: kernel ignore_faults + extra_args: EXTRA_CPPFLAGS=-DVIA_TWISTER=3 + kernel.no-mt.arbitrary_reason: + platform_allow: qemu_cortex_m3 + tags: kernel ignore_faults + extra_args: EXTRA_CPPFLAGS=-DVIA_TWISTER=4 + kernel.no-mt.arbitrary_reason_negative: + platform_allow: qemu_cortex_m3 + tags: kernel ignore_faults + extra_args: EXTRA_CPPFLAGS=-DVIA_TWISTER=5