aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/riscv64/kernel/entry.S21
-rw-r--r--common/uapi/ipc.c1
-rw-r--r--docs/doxygen.conf3
-rw-r--r--include/arch/proc.h10
4 files changed, 34 insertions, 1 deletions
diff --git a/arch/riscv64/kernel/entry.S b/arch/riscv64/kernel/entry.S
index 32a04f6..2f9a9e6 100644
--- a/arch/riscv64/kernel/entry.S
+++ b/arch/riscv64/kernel/entry.S
@@ -149,3 +149,24 @@ _load_context:
/* assume supervisor for now */
sret
+
+.global ret_userspace_fast
+ret_userspace_fast:
+ lr sp, offsetof_regs(tp)
+ addi sp, sp, -sizeof_registers
+
+ lr s0, offsetof_exec(tp)
+ csrw CSR_SEPC, s0
+
+ csrw CSR_SSCRATCH, tp
+
+ lr a0, offsetof_a0(sp)
+ lr a1, offsetof_a1(sp)
+ lr a2, offsetof_a2(sp)
+ lr a3, offsetof_a3(sp)
+ lr a4, offsetof_a4(sp)
+ lr a5, offsetof_a5(sp)
+
+ lr sp, offsetof_sp(sp)
+
+ sret
diff --git a/common/uapi/ipc.c b/common/uapi/ipc.c
index 36f2941..1d48f71 100644
--- a/common/uapi/ipc.c
+++ b/common/uapi/ipc.c
@@ -255,6 +255,7 @@ static void do_ipc(struct tcb *t,
t->eid = t->pid;
finalize_rpc(t, r, sd);
+ ret_userspace_fast();
}
/**
* IPC request syscall handler.
diff --git a/docs/doxygen.conf b/docs/doxygen.conf
index 71a053c..3cb6ca3 100644
--- a/docs/doxygen.conf
+++ b/docs/doxygen.conf
@@ -2337,7 +2337,8 @@ INCLUDE_FILE_PATTERNS =
PREDEFINED = DEBUG \
__GNUC__ \
riscv64 \
- riscv32
+ riscv32 \
+ ASSERT
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
diff --git a/include/arch/proc.h b/include/arch/proc.h
index 493b168..c9b54db 100644
--- a/include/arch/proc.h
+++ b/include/arch/proc.h
@@ -113,4 +113,14 @@ void adjust_syscall(struct tcb *t);
*/
__noreturn void run_init(struct tcb *t, void *fdt);
+/**
+ * Return to userspace fast.
+ * Doesn't load registers besides arguments.
+ * Mainly for do_ipc().
+ * Note that this skips canary checking,
+ * but at least do_ipc() uses basically zero stack space
+ * so I'm not too worried.
+ */
+__noreturn void ret_userspace_fast();
+
#endif /* KMI_ARCH_PROC_H */