Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | /* * Copyright (c) 2017 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr.h> #include <tc_util.h> #include <kernel_structs.h> #include <irq_offload.h> #define STACKSIZE 2048 #define MAIN_PRIORITY 7 #define PRIORITY 5 static char __noinit __stack alt_stack[STACKSIZE]; #ifdef CONFIG_STACK_SENTINEL #define OVERFLOW_STACKSIZE 1024 static char *overflow_stack = alt_stack + (STACKSIZE - OVERFLOW_STACKSIZE); #else #define OVERFLOW_STACKSIZE STACKSIZE #endif static struct k_thread alt_thread; volatile int rv; void alt_thread1(void) { #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 RISCV32 * and xtensa */ { int illegal = 0; ((void(*)(void))&illegal)(); } #endif rv = TC_FAIL; } void alt_thread2(void) { int key; key = irq_lock(); k_oops(); rv = TC_FAIL; irq_unlock(key); } void blow_up_stack(void) { char buf[OVERFLOW_STACKSIZE]; printk("posting %zu bytes of junk to stack...\n", sizeof(buf)); memset(buf, 0xbb, sizeof(buf)); } void stack_thread1(void) { /* Test that stack overflow check due to timer interrupt works */ blow_up_stack(); printk("busy waiting...\n"); k_busy_wait(1024 * 1024); printk("should never see this\n"); rv = TC_FAIL; } void stack_thread2(void) { int key = irq_lock(); /* Test that stack overflow check due to swap works */ blow_up_stack(); printk("swapping...\n"); _Swap(irq_lock()); printk("should never see this\n"); rv = TC_FAIL; irq_unlock(key); } void main(void) { rv = TC_PASS; TC_START("test_fatal"); k_thread_priority_set(_current, K_PRIO_PREEMPT(MAIN_PRIORITY)); printk("test alt thread 1: generic CPU exception\n"); k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack), (k_thread_entry_t)alt_thread1, NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0, K_NO_WAIT); if (rv == TC_FAIL) { printk("thread was not aborted\n"); goto out; } else { printk("PASS\n"); } printk("test alt thread 2: initiate kernel oops\n"); k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack), (k_thread_entry_t)alt_thread2, NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0, K_NO_WAIT); if (rv == TC_FAIL) { printk("thread was not aborted\n"); goto out; } else { printk("PASS\n"); } printk("test stack overflow - timer irq\n"); #ifdef CONFIG_STACK_SENTINEL /* When testing stack sentinel feature, the overflow stack is a * smaller section of alt_stack near the end. * In this way when it gets overflowed by blow_up_stack() we don't * corrupt anything else and prevent the test case from completing. */ k_thread_create(&alt_thread, overflow_stack, OVERFLOW_STACKSIZE, #else k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack), #endif (k_thread_entry_t)stack_thread1, NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0, K_NO_WAIT); if (rv == TC_FAIL) { printk("thread was not aborted\n"); goto out; } else { printk("PASS\n"); } printk("test stack overflow - swap\n"); #ifdef CONFIG_STACK_SENTINEL k_thread_create(&alt_thread, overflow_stack, OVERFLOW_STACKSIZE, #else k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack), #endif (k_thread_entry_t)stack_thread2, NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0, K_NO_WAIT); if (rv == TC_FAIL) { printk("thread was not aborted\n"); goto out; } else { printk("PASS\n"); } out: TC_END_RESULT(rv); TC_END_REPORT(rv); } |