arch: arc: fix the bug in prologue of sys call handling
* the old codes may not save the caller saved regs correctly, e.g. r7- r12. Because the sys call entry is called in the form of static inline function. The compiler optimizations may not save all the caller saved regs. * new codes use the irq stack frame as the sys call frame and gurantee all the called saved regs are pushed and popped correctly. * the side effect of new codes are more stack operations and a little overhead. Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
This commit is contained in:
parent
67795b79a2
commit
56650aff7e
2 changed files with 45 additions and 34 deletions
|
@ -196,7 +196,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_s ilink, K_SYSCALL_LIMIT
|
||||
cmp r6, ilink
|
||||
blt valid_syscall_id
|
||||
|
@ -205,21 +205,27 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
|
|||
mov_s 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_SECURE_FIRMWARE
|
||||
lr ilink, [_ARC_V2_ERSEC_STAT]
|
||||
push ilink
|
||||
/* ERSEC_STAT is IOW/RAZ in normal mode */
|
||||
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 r0, r0, _ARC_V2_STATUS32_U_BIT
|
||||
sr r0, [_ARC_V2_ERSTATUS]
|
||||
|
||||
bclr ilink, ilink, _ARC_V2_STATUS32_U_BIT
|
||||
sr ilink, [_ARC_V2_ERSTATUS]
|
||||
|
||||
mov_s ilink, _arc_do_syscall
|
||||
sr ilink, [_ARC_V2_ERET]
|
||||
mov_s r0, _arc_do_syscall
|
||||
sr r0, [_ARC_V2_ERET]
|
||||
|
||||
rtie
|
||||
|
||||
|
|
|
@ -202,46 +202,51 @@ 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_s 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_s r29, 0
|
||||
mov_s r30, 0
|
||||
|
||||
pop_s blink
|
||||
|
||||
/* through fake exception return, go back to the caller */
|
||||
lr r6, [_ARC_V2_STATUS32]
|
||||
bclr r6, r6, _ARC_V2_STATUS32_AE_BIT
|
||||
kflag r6
|
||||
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_SECURE_FIRMWARE
|
||||
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_s r6, 0
|
||||
ld_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
|
||||
sr r0,[_ARC_V2_ERET]
|
||||
|
||||
_pop_irq_stack_frame
|
||||
|
||||
rtie
|
||||
|
||||
|
||||
/*
|
||||
* size_t z_arch_user_string_nlen(const char *s, size_t maxsize, int *err_arg)
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue