Repository: tock/tock (language: rust)

Issue:
ARMv6m: Thread mode not set to privileged execution in certain ISRs
I'm opening this issue following the discussion in #4242.

I believe that the following ISRs need to set the special `CONTROL` register to `0` before exception return, similar to [the `systick_handler`](https://github.com/tock/tock/blob/a1966b8ddaa1ce819b80f2f7bea466eb76e5b46c/arch/cortex-m0/src/lib.rs#L189) on [line 193](https://github.com/tock/tock/blob/a1966b8ddaa1ce819b80f2f7bea466eb76e5b46c/arch/cortex-m0/src/lib.rs#L193)

- [Generic ISR](https://github.com/tock/tock/blob/a1966b8ddaa1ce819b80f2f7bea466eb76e5b46c/arch/cortex-m0/src/lib.rs#L89)
     - I think that this is canceled out by #4245., since we return to the process rather than the kernel when coming from a process. 
- [SVC Handler](https://github.com/tock/tock/blob/a1966b8ddaa1ce819b80f2f7bea466eb76e5b46c/arch/cortex-m0/src/lib.rs#L226)      
     - My hunch here is that we should be setting thread mode to privileged execution in the case we are coming from a process and need to return to the kernel to handle a syscall. I think setting the `CONTROL` register to `0` [here](https://github.com/tock/tock/blob/a1966b8ddaa1ce819b80f2f7bea466eb76e5b46c/arch/cortex-m0/src/lib.rs#L233) should do the trick. Similar to how the `v7m svc handler`  does [here](https://github.com/tock/tock/blob/a1966b8ddaa1ce819b80f2f7bea466eb76e5b46c/arch/cortex-v7m/src/lib.rs#L121).
    - It might also be a good idea to ensure that we set thread mode to unprivileged execution when we go from kernel to process. It seems like the `v7m svc handler` does this [here](https://github.com/tock/tock/blob/a1966b8ddaa1ce819b80f2f7bea466eb76e5b46c/arch/cortex-v7m/src/lib.rs#L90).




Discussion / hints:
Looking into it.
Looking at the code, it seems that:
- `generic_isr` has the bug, fixing it now
- `svc_handler` from` cortex_m0` has the bug, but is never used, we use the `svc_handler_m0p` function

Fix patch:
diff --git a/arch/cortex-m0/src/lib.rs b/arch/cortex-m0/src/lib.rs
index ab380fcb5d..6277cd2cbb 100644
--- a/arch/cortex-m0/src/lib.rs
+++ b/arch/cortex-m0/src/lib.rs
@@ -92,6 +92,13 @@ core::arch::global_asm!(
     cmp lr, r0
     bne 100f
 
+    /* We need to make sure the kernel cotinues the execution after this ISR */
+    movs r0, #0
+    msr CONTROL, r0
+    /* CONTROL writes must be followed by ISB */
+    /* https://developer.arm.com/documentation/dui0662/b/The-Cortex-M0--Processor/Programmers-model/Core-registers */
+    isb
+
     /* We need the most recent kernel's version of r1, which points */
     /* to the Process struct's stored registers field. The kernel's r1 */
     /* lives in the second word of the hardware stacked registers on MSP */
@@ -114,6 +121,7 @@ core::arch::global_asm!(
     pop {{r4-r7}}
 
     ldr r0, 200f // MEXC_RETURN_MSP
+    mov lr, r0
 100: // _ggeneric_isr_no_stacking
     /* Find the ISR number by looking at the low byte of the IPSR registers */
     mrs r0, IPSR
@@ -227,10 +235,20 @@ svc_handler:
   ldr r0, 200f // EXC_RETURN_MSP
   cmp lr, r0
   bne 100f
+  movs r0, #1
+  msr CONTROL, r0
+  /* CONTROL writes must be followed by ISB */
+    /* https://developer.arm.com/documentation/dui0662/b/The-Cortex-M0--Processor/Programmers-model/Core-registers */
+  isb
   ldr r1, 300f // EXC_RETURN_PSP
   bx r1
 
 100: // to_kernel
+  movs r0, #0
+  msr CONTROL, r0
+  /* CONTROL writes must be followed by ISB */
+    /* https://developer.arm.com/documentation/dui0662/b/The-Cortex-M0--Processor/Programmers-model/Core-registers */
+  isb
   ldr r0, =SYSCALL_FIRED
   movs r1, #1
   str r1, [r0, #0]


Test patch: