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 <Ioannis.Glaropoulos@nordicsemi.no>
This commit is contained in:
parent
84b1bba8ee
commit
4a58fa1186
2 changed files with 18 additions and 0 deletions
|
@ -418,6 +418,14 @@ _do_syscall:
|
||||||
ldr r6, =K_SYSCALL_BAD
|
ldr r6, =K_SYSCALL_BAD
|
||||||
|
|
||||||
valid_syscall_id:
|
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 */
|
/* set mode to privileged, r2 still contains value from CONTROL */
|
||||||
bic r2, #1
|
bic r2, #1
|
||||||
msr CONTROL, r2
|
msr CONTROL, r2
|
||||||
|
@ -427,6 +435,7 @@ valid_syscall_id:
|
||||||
* instructions with the previous privilege.
|
* instructions with the previous privilege.
|
||||||
*/
|
*/
|
||||||
isb
|
isb
|
||||||
|
pop {r0, r1}
|
||||||
|
|
||||||
/* return from SVC to the modified LR - _arm_do_syscall */
|
/* return from SVC to the modified LR - _arm_do_syscall */
|
||||||
bx lr
|
bx lr
|
||||||
|
|
|
@ -242,6 +242,14 @@ dispatch_syscall:
|
||||||
ldr ip, [sp,#8]
|
ldr ip, [sp,#8]
|
||||||
msr PSP, ip
|
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 */
|
/* drop privileges by setting bit 0 in CONTROL */
|
||||||
mrs ip, CONTROL
|
mrs ip, CONTROL
|
||||||
orrs ip, ip, #1
|
orrs ip, ip, #1
|
||||||
|
@ -252,6 +260,7 @@ dispatch_syscall:
|
||||||
* instructions with the previous privilege.
|
* instructions with the previous privilege.
|
||||||
*/
|
*/
|
||||||
isb
|
isb
|
||||||
|
pop {r0, r1}
|
||||||
|
|
||||||
/* Zero out volatile (caller-saved) registers so as to not leak state from
|
/* Zero out volatile (caller-saved) registers so as to not leak state from
|
||||||
* kernel mode. The C calling convention for the syscall handler will
|
* kernel mode. The C calling convention for the syscall handler will
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue