Skip to content
Closed
Show file tree
Hide file tree
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
44 changes: 43 additions & 1 deletion components/lwp/arch/risc-v/rv64/lwp_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,41 @@ struct signal_ucontext
struct rt_hw_stack_frame frame;
};

void arch_syscall_restart(void *sp);

void arch_signal_check_erestart(void *eframe, void *ksp)
{
struct rt_hw_stack_frame *exp_frame = eframe;
long rc = exp_frame->a0;
long sys_id = exp_frame->a7;

(void)ksp;
(void)sys_id;

if (rc == -ERESTART)
{
LOG_D("%s(rc=%ld,sys_id=%ld,pid=%d)", __func__, rc, sys_id, lwp_self()->pid);
LOG_D("%s: restart rc = %ld", lwp_get_syscall_name(sys_id), rc);

/* t0 stores the copy of user's first syscall argument */
exp_frame->a0 = exp_frame->t0;

/* adjust for epc auto-increment in syscall_handler */
exp_frame->epc -= 4;

arch_syscall_restart(eframe);
}

return ;
}

static void arch_signal_post_action(struct signal_ucontext *new_sp)
{
arch_signal_check_erestart(&new_sp->frame,0);

return ;
}

void *arch_signal_ucontext_restore(rt_base_t user_sp)
{
struct signal_ucontext *new_sp;
Expand All @@ -266,6 +301,7 @@ void *arch_signal_ucontext_restore(rt_base_t user_sp)
if (lwp_user_accessable(new_sp, sizeof(*new_sp)))
{
lwp_thread_signal_mask(rt_thread_self(), LWP_SIG_MASK_CMD_SET_MASK, &new_sp->save_sigmask, RT_NULL);
arch_signal_post_action(new_sp);
}
else
{
Expand Down Expand Up @@ -320,7 +356,13 @@ void *arch_signal_ucontext_save(int signo, siginfo_t *psiginfo,

void arch_syscall_set_errno(void *eframe, int expected, int code)
{
/* NO support */
struct rt_hw_stack_frame *exp_frame = eframe;

if (exp_frame->a0 == -expected)
{
exp_frame->a0 = -code;
}

return ;
}

Expand Down
19 changes: 19 additions & 0 deletions components/lwp/arch/risc-v/rv64/lwp_gcc.S
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,25 @@ ret_to_user_exit:
// `RESTORE_ALL` also reset sp to user sp, and setup sscratch
sret

.global arch_syscall_restart
arch_syscall_restart:
/* discard kernel context by moving stack pointer */
addi sp, sp, CTX_REG_NR * REGBYTES

/* store kernel stack pointer in exception frame (a0 points to frame) */
STORE sp, FRAME_OFF_SP(a0)

/* switch to user exception frame */
mv sp, a0

/* restore all user registers from exception frame (except sp) */
RESTORE_ALL

/* exchange sp and sscratch */
csrrw sp, sscratch, sp

j trap_entry

/**
* Restore user context from exception frame stroraged in ustack
* And handle pending signals;
Expand Down
2 changes: 1 addition & 1 deletion libcpu/risc-v/common64/syscall_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ void syscall_handler(struct rt_hw_stack_frame *regs)

LOG_I("[0x%lx] %s(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)", rt_thread_self(), syscall_name,
regs->a0, regs->a1, regs->a2, regs->a3, regs->a4, regs->a5, regs->a6);
regs->t0 = regs->a0;
regs->a0 = syscallfunc(regs->a0, regs->a1, regs->a2, regs->a3, regs->a4, regs->a5, regs->a6);
regs->a7 = 0;
regs->epc += 4; // skip ecall instruction
LOG_I("[0x%lx] %s ret: 0x%lx", rt_thread_self(), syscall_name, regs->a0);
}
Expand Down
Loading