From 63a051dd30f5fa61514e2a7278a0efdce7050664 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sat, 9 Sep 2023 13:28:04 -0300 Subject: [PATCH] x86-64 syscall: fix very specific triple fault --- kernel-src/arch/x86-64/syscall.asm | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm index c4d9cbe8..a560a006 100644 --- a/kernel-src/arch/x86-64/syscall.asm +++ b/kernel-src/arch/x86-64/syscall.asm @@ -99,19 +99,22 @@ global arch_syscall_entry ; rax has return value arch_syscall_entry: swapgs - ; save return address on user stack - push rcx - mov rcx, [gs:0x0] ; thread pointer - mov rcx, [rcx] ; kernel stack top - xchg rsp, rcx ; switch stack pointers + ; saving the syscall number on cr2 is cursed but we need this extra register + ; and taking a page fault here would result in a triple fault anyways + ; because it's still using the user stack + mov cr2, rax + ; rax can be used just fine now + mov rax, [gs:0x0] ; thread pointer + mov rax, [rax] ; kernel stack top + xchg rsp, rax ; switch stack pointers ; push context push qword 0x1b ; user SS - push qword rcx ; user RSP - add qword [rsp], 8 ; correct the old stack pointer to before the return address push + push qword rax ; user RSP + mov rax, cr2 ; restore syscall number push r11 ; rflags is stored in r11 push qword 0x23 ; user CS - push qword [rcx] ; save return RIP + push qword rcx ; save return RIP push qword 0 ; error push rbp push rsi @@ -169,13 +172,11 @@ arch_syscall_entry: cli ; call return logging function - mov rdi, rax mov rsi, rdx extern arch_syscall_log_return call arch_syscall_log_return ; compiled with __attribute__((no_caller_saved_registers)) - ; restore context add rsp, 32 ; r9 argument, cr2, gs, and fs are not popped. pop rbx