From f250a33e9bdc64815afe86ee8abf9d8c9d240752 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Thu, 23 Dec 2021 16:46:47 -0800 Subject: [PATCH] [kernel] Save ring3 rflags in cpu_data, not just stack So that kernel code can modify user rflags, save it in the CPU state data, and save that off to the TCB when switching tasks. --- src/kernel/cpu.h | 1 + src/kernel/objects/thread.h | 1 + src/kernel/syscall.s | 4 ++-- src/kernel/task.s | 8 ++++++++ src/kernel/tasking.inc | 2 ++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/kernel/cpu.h b/src/kernel/cpu.h index 1efbc2a..453fecc 100644 --- a/src/kernel/cpu.h +++ b/src/kernel/cpu.h @@ -28,6 +28,7 @@ struct cpu_data uint32_t reserved; uintptr_t rsp0; uintptr_t rsp3; + uint64_t rflags3; TCB *tcb; thread *thread; process *process; diff --git a/src/kernel/objects/thread.h b/src/kernel/objects/thread.h index 172abe8..66910ea 100644 --- a/src/kernel/objects/thread.h +++ b/src/kernel/objects/thread.h @@ -15,6 +15,7 @@ struct TCB uintptr_t rsp; uintptr_t rsp0; uintptr_t rsp3; + uintptr_t rflags3; uintptr_t pml4; uint8_t priority; diff --git a/src/kernel/syscall.s b/src/kernel/syscall.s index 3fa6451..b442fba 100644 --- a/src/kernel/syscall.s +++ b/src/kernel/syscall.s @@ -31,6 +31,7 @@ syscall_handler_prelude: swapgs mov [gs:CPU_DATA.rsp3], rsp mov rsp, [gs:CPU_DATA.rsp0] + mov [gs:CPU_DATA.rflags3], r11 push rcx push rbp @@ -44,7 +45,6 @@ syscall_handler_prelude: mov rcx, r10 push rbx - push r11 push r12 push r13 push r14 @@ -76,12 +76,12 @@ kernel_to_user_trampoline: pop r14 pop r13 pop r12 - pop r11 pop rbx pop rbp pop rcx + mov r11, [gs:CPU_DATA.rflags3] mov [gs:CPU_DATA.rsp0], rsp mov rsp, [gs:CPU_DATA.rsp3] diff --git a/src/kernel/task.s b/src/kernel/task.s index 88ba926..0796ceb 100644 --- a/src/kernel/task.s +++ b/src/kernel/task.s @@ -20,6 +20,10 @@ task_switch: mov rcx, [gs:CPU_DATA.rsp3] ; rcx: current task's saved user rsp mov [rax + TCB.rsp3], rcx + ; Copy off saved user rflags + mov rcx, [gs:CPU_DATA.rflags3] ; rcx: current task's saved user rflags + mov [rax + TCB.rflags3], rcx + ; Install next task's TCB mov [gs:CPU_DATA.tcb], rdi ; rdi: next TCB (function param) mov rsp, [rdi + TCB.rsp] ; next task's stack pointer @@ -37,6 +41,10 @@ task_switch: mov rcx, [rdi + TCB.rsp3] ; rcx: new task's saved user rsp mov [gs:CPU_DATA.rsp3], rcx + ; Update saved user rflags + mov rcx, [rdi + TCB.rflags3] ; rcx: new task's saved user rflags + mov [gs:CPU_DATA.rflags3], rcx + ; check if we need to update CR3 mov rdx, cr3 ; rdx: old CR3 cmp rax, rdx diff --git a/src/kernel/tasking.inc b/src/kernel/tasking.inc index dd348e1..f70002c 100644 --- a/src/kernel/tasking.inc +++ b/src/kernel/tasking.inc @@ -2,6 +2,7 @@ struc TCB .rsp: resq 1 .rsp0: resq 1 .rsp3: resq 1 +.rflags3: resq 1 .pml4: resq 1 endstruc @@ -12,6 +13,7 @@ struc CPU_DATA .reserved resd 1 .rsp0: resq 1 .rsp3: resq 1 +.rflags3: resq 1 .tcb: resq 1 .thread: resq 1 .process: resq 1