# Kernel Bug - Nested MPU wrapper calls generate an exception

**URL:** <https://forums.freertos.org/t/kernel-bug-nested-mpu-wrapper-calls-generate-an-exception/10391>\
**Category:** Kernel\
**Tags:** tracealyzer\
**Created:** [July 30, 2020, 7:59pm UTC](https://forums.freertos.org/t/kernel-bug-nested-mpu-wrapper-calls-generate-an-exception/10391 "2020-07-30T19:59:59Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![GBerthDana](https://avatars.discourse-cdn.com/v4/letter/g/9de053/32.png) [@GBerthDana](https://forums.freertos.org/u/GBerthDana)\
**Post date:** [July 30, 2020, 8:00pm UTC](https://forums.freertos.org/t/kernel-bug-nested-mpu-wrapper-calls-generate-an-exception/10391/1 "2020-07-30T20:00:00Z")

</div>

Hi,

I think I found a bug in the `mpu_wrappers.c` of the TI Hercules FreeRTOS port.

## Context

I’m trying to use Tracealyzer in snapshot mode with the FreeRTOS Kernel 10.3.1 and a TI Hercules TMS570LS1224 microcontroller. Please note that this microcontroller has an MPU on it.

While doing so I encountered an unhandled prefetchEntry exception. Using the CP15 (AMR) register, I was able to conclude it was a permission fault that caused the exception.  
Using my debugger, I was able to reproduce the bug.  
Here’s the call stack that is causing the problem:

```auto
TO MPU_ucQueueGetQueueType(struct QueueDefinition *)() 
      prvTraceGetQueueType(void *)() 
      prvInitialiseNewQueue(unsigned long, unsigned long, unsigned char *, int, struct QueueDefinition *)() 
      xQueueGenericCreate(unsigned long, unsigned long, int)() 
      MPU_xQueueGenericCreate(unsigned long, unsigned long, int)() 
FROM my_freertos_task(void *)() 

```

As you can see, there are 2 calls to `MPU_*` API, which switch from user mode to privileged mode.

## Problem (bug?)

When in privileged mode, the `xPortRaisePrivilege()` function returns `15` instead of `pdTRUE` (1).

 ![running_priv](https://d2v6vdsk2p900z.cloudfront.net/original/1X/67a779c9e24781b00e4a80cc6d077e7c49e2da90.png)

This can cause problem when trying to reset to the correct mode.  
As the `vPortResetPrivilege()` function is implemented has follows:

```auto
void vPortResetPrivilege( BaseType_t xRunningPrivileged )
{
	if( xRunningPrivileged != pdTRUE )
	{
	    portSWITCH_TO_USER_MODE();
	}
}

```

The nested MPU function will switch to user mode.  
The expected behaviour would be to stay in a privileged mode, as we are in a nested MPU call.

## Fix

I’m not good enough with assembly to explain why the function was not designed to return a bool, but here’s my quick fix:

```auto
void vPortResetPrivilege( BaseType_t xRunningPrivileged )
{
	if( xRunningPrivileged == pdFALSE)
	{
	    portSWITCH_TO_USER_MODE();
	}
}

```

With this, I don’t get any exception.

## Closing

I would like to have yours thought on this bug and how to fix it.  
Also, I’m not sure if this forum is the correct place to post this kind of bug, but I hope it’s helpful to somebody else.

Regards,  
Gabriel

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [July 30, 2020, 8:39pm UTC](https://forums.freertos.org/t/kernel-bug-nested-mpu-wrapper-calls-generate-an-exception/10391/2 "2020-07-30T20:39:42Z")

</div>

This definition of `xIsPrivileged` should only return 0 or 1: [https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/master/portable/GCC/ARM\_CM4\_MPU/port.c#L775](https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/master/portable/GCC/ARM_CM4_MPU/port.c#L775).

Return value of 15 indicates something else going wrong. Let us find out the reason for that. Would you please tell me which FreeRTOS port (i.e. which port files in portable directory) are you using?

Thanks.

---

<div class="post-metadata">

**Author:** ![GBerthDana](https://avatars.discourse-cdn.com/v4/letter/g/9de053/32.png) [@GBerthDana](https://forums.freertos.org/u/GBerthDana)\
**Post date:** [July 30, 2020, 8:55pm UTC](https://forums.freertos.org/t/kernel-bug-nested-mpu-wrapper-calls-generate-an-exception/10391/3 "2020-07-30T20:55:51Z")

</div>

Thanks for your answer.

I’m using a modified version of the TI SDK generated by [HALcodeGEN](https://www.ti.com/tool/HALCOGEN).  
As the TI SDK only support FreeRTOS 9, we ported FreeRTOS to the 10.3.1 version.

Please note that we didn’t touch the assembly files. Therefore the `portASM.asm` is the same between the official TI FreeRTOS port and ours.

The specific function:

```auto
;-------------------------------------------------------------------------------
; swiRaisePrivilege

; Must return zero in R0 if caller was in user mode
        .asmfunc
swiRaisePrivilege
        mrs r12, spsr
        ands r0, r12, #0x0F ; return value
        orreq r12, r12, #0x1F
        msreq spsr_c, r12
        bx r14
        .endasmfunc

```

I’m not sure why we expect a bool considering the `ands r0, r12, #0x0F` line.

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [July 30, 2020, 9:57pm UTC](https://forums.freertos.org/t/kernel-bug-nested-mpu-wrapper-calls-generate-an-exception/10391/4 "2020-07-30T21:57:16Z")

</div>

This explains the behavior you see. The above piece of assembly roughly is:

```auto
r12 = SPSR /* [SPSR=Saved Program Status Register] */
r0 = r0 & 0x0F;
if( r0 == 0 ) /* If the processor is not privileged. */
{
    r12 = r12 | 0x1F; /* Set last 5 bits. */
    CPSR = r12; /* [CPSR =Current Program Status Register] */
}
return r0;

```

Last 5 bits in Program Status Register tell the processor mode:

- 0x10000 - user mode or unprivileged mode
- 0x11111 - system mode or privileged mode

According to the above assembly, if the processor is privileged, the return value will be 0x0F (Decimal 15).

The expected behavior of `portIS_PRIVILEGED` is:

- return 0 if the processor is not running privileged.
- return 1 if the processor is running privileged.

This above assembly function does not implement it correctly in the second case when the processor is running privileged. It should be fixed in TI’s code.

However, the change you suggested above looks harmless to other ports and it will fix your problem. So I have incorporated it in this PR: [https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/109](https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/109)

Thanks,  
Gaurav

---

<div class="post-metadata">

**Author:** ![GBerthDana](https://avatars.discourse-cdn.com/v4/letter/g/9de053/32.png) [@GBerthDana](https://forums.freertos.org/u/GBerthDana)\
**Post date:** [July 31, 2020, 12:47pm UTC](https://forums.freertos.org/t/kernel-bug-nested-mpu-wrapper-calls-generate-an-exception/10391/5 "2020-07-31T12:47:37Z")

</div>

Thanks for your support Gaurav.  
I’m gonna report the potential bug to TI.

Regards,  
Garbiel

---

<div class="post-metadata">

**Author:** ![GBerthDana](https://avatars.discourse-cdn.com/v4/letter/g/9de053/32.png) [@GBerthDana](https://forums.freertos.org/u/GBerthDana)\
**Post date:** [July 31, 2020, 6:49pm UTC](https://forums.freertos.org/t/kernel-bug-nested-mpu-wrapper-calls-generate-an-exception/10391/6 "2020-07-31T18:49:50Z")

</div>

Update:

TI engineers have been inform of the problem.  
[https://e2e.ti.com/support/microcontrollers/hercules/f/312/p/928049/3428925#3428925](https://e2e.ti.com/support/microcontrollers/hercules/f/312/p/928049/3428925#3428925)

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [July 31, 2020, 10:00pm UTC](https://forums.freertos.org/t/kernel-bug-nested-mpu-wrapper-calls-generate-an-exception/10391/7 "2020-07-31T22:00:03Z")

</div>

Thank you for taking time to report the problem to TI.
