From 4d5fbbc517c470d778d708f17deaedbe86e92b76 Mon Sep 17 00:00:00 2001 From: Leandro Pereira Date: Fri, 6 Apr 2018 16:03:47 -0700 Subject: [PATCH] arch: arm: Flush pipeline after switching privilege levels During the transition of privilege levels while performing syscalls, the ARM documentation recommends flushing the pipeline to avoid pre-fetched instructions from being executed with the previous privilege level. The manual says: 4.16 CONTROL register (...) after programming the CONTROL register, an ISB instruction should be used. (...) This is not implemented in the Cortex M0 processor. Signed-off-by: Leandro Pereira --- arch/arm/core/swap_helper.S | 12 ++++++++++++ arch/arm/core/userspace.S | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/arch/arm/core/swap_helper.S b/arch/arm/core/swap_helper.S index 17911a8ccea..272bc6ba93c 100644 --- a/arch/arm/core/swap_helper.S +++ b/arch/arm/core/swap_helper.S @@ -183,6 +183,12 @@ _thread_irq_disabled: orr r3, r0 msr CONTROL, r3 + /* ISB is not strictly necessary here (stack pointer is not being + * touched), but it's recommended to avoid executing pre-fetched + * instructions with the previous privilege. + */ + isb + /* r2 contains k_thread */ add r0, r2, #0 push {r2, lr} @@ -387,6 +393,12 @@ valid_syscall_id: bic r2, #1 msr CONTROL, r2 + /* ISB is not strictly necessary here (stack pointer is not being + * touched), but it's recommended to avoid executing pre-fetched + * instructions with the previous privilege. + */ + isb + /* return from SVC to the modified LR - _arm_do_syscall */ bx lr #endif diff --git a/arch/arm/core/userspace.S b/arch/arm/core/userspace.S index 3f5030befb3..2bd5fd5d602 100644 --- a/arch/arm/core/userspace.S +++ b/arch/arm/core/userspace.S @@ -94,6 +94,12 @@ SECTION_FUNC(TEXT,_arm_userspace_enter) orrs ip, ip, #1 msr CONTROL, ip + /* ISB is not strictly necessary here (stack pointer is not being + * touched), but it's recommended to avoid executing pre-fetched + * instructions with the previous privilege. + */ + isb + /* jump to _thread_entry entry */ ldr ip, =_thread_entry bx ip @@ -173,6 +179,12 @@ dispatch_syscall: orrs ip, ip, #1 msr CONTROL, ip + /* ISB is not strictly necessary here (stack pointer is not being + * touched), but it's recommended to avoid executing pre-fetched + * instructions with the previous privilege. + */ + isb + /* * return back to original function that called SVC, add 1 to force thumb * mode