Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arch: arc: fix the bug in prologue of sys call handling #21364

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions arch/arc/core/fault_s.S
Original file line number Diff line number Diff line change
@@ -153,7 +153,7 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
#ifdef CONFIG_USERSPACE
cmp ilink, _TRAP_S_CALL_SYSTEM_CALL
bne _do_non_syscall_trap
/* do sys_call */
/* do sys_call */
mov ilink, K_SYSCALL_LIMIT
cmp r6, ilink
blt valid_syscall_id
@@ -162,21 +162,26 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
mov r6, K_SYSCALL_BAD

valid_syscall_id:
/* create a sys call frame
* caller regs (r0 - 12) are saved in _create_irq_stack_frame
* ok to use them later
*/
_create_irq_stack_frame
#ifdef CONFIG_ARC_HAS_SECURE
lr ilink, [_ARC_V2_ERSEC_STAT]
push ilink
lr r0, [_ARC_V2_ERSEC_STAT]
st_s r0, [sp, ___isf_t_sec_stat_OFFSET]
#endif
lr ilink, [_ARC_V2_ERET]
push ilink
lr ilink, [_ARC_V2_ERSTATUS]
push ilink
lr r0, [_ARC_V2_ERET]
st_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
lr r0, [_ARC_V2_ERSTATUS]
st_s r0, [sp, ___isf_t_status32_OFFSET]


bclr ilink, ilink, _ARC_V2_STATUS32_U_BIT
sr ilink, [_ARC_V2_ERSTATUS]
bclr r0, r0, _ARC_V2_STATUS32_U_BIT
sr r0, [_ARC_V2_ERSTATUS]

mov ilink, _arc_do_syscall
sr ilink, [_ARC_V2_ERET]
mov r0, _arc_do_syscall
sr r0, [_ARC_V2_ERET]

rtie

45 changes: 26 additions & 19 deletions arch/arc/core/userspace.S
Original file line number Diff line number Diff line change
@@ -202,40 +202,47 @@ return_loc_userspace_enter:
*
*/
SECTION_FUNC(TEXT, _arc_do_syscall)
/* r0-r5: arg1-arg6, r6 is call id */
/* the call id is already checked in trap_s handler */
push_s blink
/*
* r0-r5: arg1-arg6, r6 is call id which is already checked in
* trap_s handler, r7 is the system call stack frame pointer
* need to recover r0, r1, r2 because they will be modified in
* _create_irq_stack_frame. If a specific syscall frame (different
* with irq stack frame) is defined, the cover of r0, r1, r2 can be
* optimized.
*/
ld_s r0, [sp, ___isf_t_r0_OFFSET]
ld_s r1, [sp, ___isf_t_r1_OFFSET]
ld_s r2, [sp, ___isf_t_r2_OFFSET]

mov r7, sp

mov blink, _k_syscall_table
ld.as r6, [blink, r6]

jl [r6]

/*
* no need to clear callee regs, as they will be saved and restored
* automatically
*/
clear_scratch_regs
/* save return value */
st_s r0, [sp, ___isf_t_r0_OFFSET]

mov r29, 0
mov r30, 0

pop_s blink

/* through fake exception return, go back to the caller */
kflag _ARC_V2_STATUS32_AE
lr r0, [_ARC_V2_STATUS32]
bset r0, r0, _ARC_V2_STATUS32_AE_BIT
kflag r0

/* the status and return address are saved in trap_s handler */
pop r6
sr r6, [_ARC_V2_ERSTATUS]
pop r6
sr r6, [_ARC_V2_ERET]
#ifdef CONFIG_ARC_HAS_SECURE
pop r6
sr r6, [_ARC_V2_ERSEC_STAT]
ld_s r0, [sp, ___isf_t_sec_stat_OFFSET]
sr r0, [_ARC_V2_ERSEC_STAT]
#endif
ld_s r0, [sp, ___isf_t_status32_OFFSET]
sr r0, [_ARC_V2_ERSTATUS]

mov r6, 0
ld_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
sr r0, [_ARC_V2_ERET]

_pop_irq_stack_frame

rtie