From 4a58fa11862448e5b93e16f06e1826b31e805ff5 Mon Sep 17 00:00:00 2001 From: Ioannis Glaropoulos Date: Mon, 1 Apr 2019 12:40:23 +0200 Subject: [PATCH] arch: arm: update arch.mode in user thread system calls This commit updates the thread.mode variable, in system calls, whenever we modify the execution privilege level. We need to do this, in order to be able to properly handle context-switching triggered by ISRs, while doing the system calls. The commit ensures that a context-switch, triggered by an ISR during or after,a system call will preserve the right privilege level. Signed-off-by: Ioannis Glaropoulos --- arch/arm/core/swap_helper.S | 9 +++++++++ arch/arm/core/userspace.S | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/arch/arm/core/swap_helper.S b/arch/arm/core/swap_helper.S index 7705352bfc6..7d1cc48481f 100644 --- a/arch/arm/core/swap_helper.S +++ b/arch/arm/core/swap_helper.S @@ -418,6 +418,14 @@ _do_syscall: ldr r6, =K_SYSCALL_BAD valid_syscall_id: + push {r0, r1} + ldr r0, =_kernel + ldr r0, [r0, #_kernel_offset_to_current] + ldr r1, [r0, #_thread_offset_to_mode] + bic r1, #1 + /* Store (privileged) mode in thread's mode state variable */ + str r1, [r0, #_thread_offset_to_mode] + dsb /* set mode to privileged, r2 still contains value from CONTROL */ bic r2, #1 msr CONTROL, r2 @@ -427,6 +435,7 @@ valid_syscall_id: * instructions with the previous privilege. */ isb + pop {r0, r1} /* return from SVC to the modified LR - _arm_do_syscall */ bx lr diff --git a/arch/arm/core/userspace.S b/arch/arm/core/userspace.S index 996e08b08aa..c2a1fce8196 100644 --- a/arch/arm/core/userspace.S +++ b/arch/arm/core/userspace.S @@ -242,6 +242,14 @@ dispatch_syscall: ldr ip, [sp,#8] msr PSP, ip + push {r0, r1} + ldr r0, =_kernel + ldr r0, [r0, #_kernel_offset_to_current] + ldr r1, [r0, #_thread_offset_to_mode] + orrs r1, r1, #1 + /* Store (unprivileged) mode in thread's mode state variable */ + str r1, [r0, #_thread_offset_to_mode] + dsb /* drop privileges by setting bit 0 in CONTROL */ mrs ip, CONTROL orrs ip, ip, #1 @@ -252,6 +260,7 @@ dispatch_syscall: * instructions with the previous privilege. */ isb + pop {r0, r1} /* Zero out volatile (caller-saved) registers so as to not leak state from * kernel mode. The C calling convention for the syscall handler will