Re: [RFC] MPU support for debugging

Boie, Andrew P

On Tue, 2017-03-14 at 17:29 +0100, Piotr Mienkowski wrote:
I would like to add one more point to the discussion. It is maybe not directly
related to the topic but should likely be considered when designing MPU

Occasionally, mainly in case of device drivers, on MCUs that have cache it is
required to use the so called non-cacheable RAM regions. A memory region for
which caching has been turned off. This task is typically done by MPU/MMU and
Zephyr MPU architecture should also support it. I.e. as a developer I would
like to have a possibility to place a specific variable / set of variables in
a non-cacheable RAM region.
This is a great topic to bring up. In addition to an MPU policy to protect
threads for debugging, we do need to specify a system-level policy that get
applied at boot, even if we are not protecting individual threads.

Are you thinking that this would be something declared at the SOC level? I think
because of the size and alignment constraints of MPU regions, we may want to
configure these reasons in a central area. You may be interested to look at
Vincenzo's patches, which define MPU regions for a few ARM SOCs at boot:

This brings up another thing we need to consider: for thread-level debugging,
what is the minimum number of free MPU regions necessary to make it work?

For example, on an ARM Cortex-M, AFAIK you can only configure 8 MPU regions
total, each of which must be aligned to a multiple of their size. If 5 or 6 of
them are already used for system-wide MPU policy, it may be not be feasible to
introduce all the thread-level protection ideas that have been discussed so far.

Looking at this another way, maybe we need to consider different levels of
memory protection support, each building on top of the previous level. What
level any given board target supports will be determined by the available memory
protection hardware and its capabilities, as well as how much extra RAM we can
waste to accommodate the alignment constraints of the MPU hardware:

1) No memory protection

2) System-wide memory protection policy, set at boot by board or SOC code.

3) Per-thread stack overflow protection. We configure the MPU, on a per-thread
basis, to trigger an exception if the thread tries to write past its available
stack space. I think this should only require 1 extra region, just a sentinel
area immediately before the thread's stack to catch writes, with the struct
k_thread stored elsewhere. I think this is something simple we can do which will
make a lot of people happy given how painful stack overflows can be to debug if
you don't know they are happening.

4) Per-thread memory protection. User threads can only write to their own stack
+ additional runtime-configurable memory regions. System calls to interact with
the kernel, whose memory is otherwise untouchable. Basically what we have been
talking about so far.

5) Virtualized memory (MMU). Application and kernel run in different virtualized
memory spaces. Introduce the possibility of different isolated zephyr processes.

We may never need or want to get as far as #5, although I think whatever design
we come up with ought to leave the door open for it.


Join { to automatically receive all group messages.