Browse Source
This patch adds the mpu_stack_guard_test to the available samples. The purpose of this test is to exercize the thread stack guard enabled via MPU on arm platforms. Change-Id: I4665a20956d9e6d0dd4b5cc862e82040a53afafc Signed-off-by: Vincenzo Frascino <vincenzo.frascino@linaro.org>pull/38/merge
8 changed files with 159 additions and 0 deletions
@ -0,0 +1,4 @@ |
|||||||
|
BOARD ?= v2m_beetle |
||||||
|
CONF_FILE = prj.conf |
||||||
|
|
||||||
|
include ${ZEPHYR_BASE}/Makefile.test |
@ -0,0 +1,67 @@ |
|||||||
|
.. _mpu_stack_guard_test: |
||||||
|
|
||||||
|
MPU Stack Guard Test |
||||||
|
#################### |
||||||
|
|
||||||
|
Overview |
||||||
|
******** |
||||||
|
|
||||||
|
This is a simple application that demonstrates basic thread stack guarding on |
||||||
|
the supported platforms. |
||||||
|
A thread spawned by the main task recursively calls a function that fills the |
||||||
|
thread stack up to where it overwrites a preposed canary. |
||||||
|
If the MPU is enabled and the Stack Guard feature is present the test succeeds |
||||||
|
because an MEM Faults exception prevents the canary from being overwritten. |
||||||
|
If the MPU is disabled the test fails because the canary is overwritten. |
||||||
|
|
||||||
|
Building and Running |
||||||
|
******************** |
||||||
|
|
||||||
|
This project outputs to the console. |
||||||
|
To build the test with the MPU disabled: |
||||||
|
|
||||||
|
.. code-block:: console |
||||||
|
|
||||||
|
$ cd samples/mpu_stack_guard_test |
||||||
|
$ make |
||||||
|
|
||||||
|
To build the test with the MPU enabled and the stack guard feature present: |
||||||
|
|
||||||
|
.. code-block:: console |
||||||
|
|
||||||
|
$ cd samples/mpu_stack_guard_test |
||||||
|
$ make CONF_FILE=prj_stack_guard.conf |
||||||
|
|
||||||
|
Sample Output |
||||||
|
============= |
||||||
|
|
||||||
|
With the MPU disabled: |
||||||
|
|
||||||
|
.. code-block:: console |
||||||
|
|
||||||
|
***** BOOTING ZEPHYR OS v1.7.99 - BUILD: Mar 29 2017 11:07:09 ***** |
||||||
|
MPU STACK GUARD Test |
||||||
|
Canary Initial Value = 0xf0cacc1a |
||||||
|
Canary = 0x200003a8 Test not passed. |
||||||
|
... |
||||||
|
|
||||||
|
With the MPU enabled and the stack guard feature present: |
||||||
|
|
||||||
|
.. code-block:: console |
||||||
|
|
||||||
|
***** BOOTING ZEPHYR OS v1.7.99 - BUILD: Mar 29 2017 11:20:10 ***** |
||||||
|
MPU STACK GUARD Test |
||||||
|
Canary Initial Value = 0xf0cacc1a |
||||||
|
[general] [DBG] arm_core_mpu_configure: Region info: 0x200003ac 0x400 |
||||||
|
***** MPU FAULT ***** |
||||||
|
Executing thread ID (thread): 0x200003ac |
||||||
|
Faulting instruction address: 0x0 |
||||||
|
Stacking error |
||||||
|
Fatal fault in thread 0x200003ac! Aborting. |
||||||
|
***** HARD FAULT ***** |
||||||
|
Fault escalation (see below) |
||||||
|
***** MPU FAULT ***** |
||||||
|
Executing thread ID (thread): 0x200003ac |
||||||
|
Faulting instruction address: 0x8000466 |
||||||
|
Stacking error |
||||||
|
Fatal fault in ISR! Spinning... |
@ -0,0 +1,5 @@ |
|||||||
|
CONFIG_STDOUT_CONSOLE=y |
||||||
|
CONFIG_MPU_STACK_GUARD=y |
||||||
|
CONFIG_SYS_LOG=y |
||||||
|
CONFIG_SYS_LOG_DEFAULT_LEVEL=4 |
||||||
|
CONFIG_SYS_LOG_OVERRIDE_LEVEL=4 |
@ -0,0 +1,70 @@ |
|||||||
|
/* main.c - Hello World demo */ |
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012-2014 Wind River Systems, Inc. |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <zephyr.h> |
||||||
|
#include <misc/printk.h> |
||||||
|
|
||||||
|
/* size of stack area used by each thread */ |
||||||
|
#define STACKSIZE 1024 |
||||||
|
|
||||||
|
/* scheduling priority used by each thread */ |
||||||
|
#define PRIORITY 7 |
||||||
|
|
||||||
|
/* delay between greetings (in ms) */ |
||||||
|
#define SLEEPTIME 500 |
||||||
|
|
||||||
|
/* Focaccia tastes better than DEEDBEEF ;-) */ |
||||||
|
#define STACK_GUARD_CANARY 0xF0CACC1A |
||||||
|
|
||||||
|
struct stack_guard_buffer { |
||||||
|
/* Make sure canary is not optimized by the compiler */ |
||||||
|
volatile u32_t canary; |
||||||
|
u8_t stack[STACKSIZE]; |
||||||
|
}; |
||||||
|
|
||||||
|
struct stack_guard_buffer buf; |
||||||
|
|
||||||
|
u32_t recursive_loop(u32_t counter) |
||||||
|
{ |
||||||
|
if (buf.canary != STACK_GUARD_CANARY) { |
||||||
|
printk("Canary = 0x%08x\tTest not passed.\n", buf.canary); |
||||||
|
|
||||||
|
while (1) { |
||||||
|
k_sleep(SLEEPTIME); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
counter++; |
||||||
|
|
||||||
|
return recursive_loop(counter) + recursive_loop(counter); |
||||||
|
} |
||||||
|
|
||||||
|
/* stack_guard_thread is a dynamic thread */ |
||||||
|
void stack_guard_thread(void *dummy1, void *dummy2, void *dummy3) |
||||||
|
{ |
||||||
|
ARG_UNUSED(dummy1); |
||||||
|
ARG_UNUSED(dummy2); |
||||||
|
ARG_UNUSED(dummy3); |
||||||
|
|
||||||
|
u32_t result = recursive_loop(0); |
||||||
|
|
||||||
|
/* We will never arrive here */ |
||||||
|
printk("Result: %d", result); |
||||||
|
} |
||||||
|
|
||||||
|
void main(void) |
||||||
|
{ |
||||||
|
buf.canary = STACK_GUARD_CANARY; |
||||||
|
|
||||||
|
printk("MPU STACK GUARD Test\n"); |
||||||
|
printk("Canary Initial Value = 0x%x\n", buf.canary); |
||||||
|
|
||||||
|
/* spawn stack_guard_thread */ |
||||||
|
k_thread_spawn(buf.stack, STACKSIZE, stack_guard_thread, NULL, NULL, |
||||||
|
NULL, PRIORITY, 0, K_NO_WAIT); |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
[test] |
||||||
|
build_only = true |
||||||
|
tags = apps |
||||||
|
|
||||||
|
[test_stack_guard] |
||||||
|
build_only = true |
||||||
|
extra_args = CONF_FILE=prj_stack_guard.conf |
||||||
|
tags = apps |
||||||
|
arch_whitelist = arm |
||||||
|
filter = CONFIG_MPU_STACK_GUARD and CONFIG_ARM_MPU |
Loading…
Reference in new issue