summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/cpu/idt.S23
-rw-r--r--kernel/include/comus/cpu.h6
-rw-r--r--kernel/procs.c2
3 files changed, 23 insertions, 8 deletions
diff --git a/kernel/cpu/idt.S b/kernel/cpu/idt.S
index 177d3b1..06c70a0 100644
--- a/kernel/cpu/idt.S
+++ b/kernel/cpu/idt.S
@@ -1,5 +1,5 @@
.global isr_stub_table
- .global isr_restore
+ .global syscall_return
.global awd
.extern idt_exception_handler
@@ -8,6 +8,7 @@
.extern idt_pic_mouse
.extern idt_pic_eoi
.extern syscall_handler
+ .extern current_pcb
.macro PUSHALL
pushq %rax
@@ -88,7 +89,7 @@ isr_stub_\num:
cld
movq %rsp, %rdi # top of stack
callq syscall_handler
- jmp isr_restore
+ jmp syscall_return
.endm
.macro PICGeneric num
@@ -419,12 +420,18 @@ isr_stub_table:
.code64
# isr restore
-isr_restore:
- movw $(0x20 | 3), %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
+syscall_return:
+ movq current_pcb, %rbx // return user stack
+ movq 0(%rbx), %rsp // esp
+ movq 8(%rbx), %rcx // pml4
+ movq (%rcx), %rcx
+ movq %rcx, %cr3
+
+ movw $(0x20 | 3), %ax
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
POPALL
iretq
diff --git a/kernel/include/comus/cpu.h b/kernel/include/comus/cpu.h
index ffc1782..8f485be 100644
--- a/kernel/include/comus/cpu.h
+++ b/kernel/include/comus/cpu.h
@@ -89,4 +89,10 @@ void cpu_feats(struct cpu_feat *feats);
*/
void cpu_print_regs(struct cpu_regs *regs);
+/**
+ * Return from a syscall handler back into userspace
+ */
+__attribute__((noreturn))
+void syscall_return(void);
+
#endif /* cpu.h */
diff --git a/kernel/procs.c b/kernel/procs.c
index 9cde22f..8cd44a4 100644
--- a/kernel/procs.c
+++ b/kernel/procs.c
@@ -472,4 +472,6 @@ void dispatch(void)
// set the process up for success
current_pcb->state = PROC_STATE_RUNNING;
current_pcb->ticks = 3; // ticks per process
+
+ syscall_return();
}