[kernel] Give threads initial arguments

This commit changes the add_user_thunk to point to a new routine,
initialize_user_cpu, which sets all the registers that were previously
unset when starting a new user thread. The values for rdi and rsi are
popped off the initial stack values that add_user_thunk sets up, so that
user thread procs can take up to two arguments.

To suppor this, j6_thread_create gained two new arguments, which are
passed on to the thread.

This also let me finally get rid of the hack of passing an argument in
rsp when starting init.
This commit is contained in:
Justin C. Miller
2023-02-08 23:10:17 -08:00
parent 1cb8f1258d
commit 4125175870
10 changed files with 81 additions and 51 deletions

View File

@@ -9,7 +9,7 @@
#include "objects/vm_area.h"
#include "scheduler.h"
extern "C" void kernel_to_user_trampoline();
extern "C" void initialize_user_cpu();
extern obj::vm_area_guarded &g_kernel_stacks;
@@ -113,7 +113,7 @@ thread::add_thunk_kernel(uintptr_t rip)
}
void
thread::add_thunk_user(uintptr_t rip3, uintptr_t rip0, uint64_t flags)
thread::add_thunk_user(uintptr_t rip3, uint64_t arg0, uint64_t arg1, uintptr_t rip0, uint64_t flags)
{
// This sets up the stack to:
// a) come out of task_switch and return to rip0 (default is the
@@ -126,19 +126,22 @@ thread::add_thunk_user(uintptr_t rip3, uintptr_t rip0, uint64_t flags)
flags |= 0x200;
m_tcb.rflags3 = flags;
m_tcb.rsp -= sizeof(uintptr_t) * 7;
m_tcb.rsp -= sizeof(uintptr_t) * 9;
uintptr_t *stack = reinterpret_cast<uintptr_t*>(m_tcb.rsp);
stack[6] = rip3; // return rip in rcx
stack[5] = m_tcb.rsp3; // rbp
stack[4] = 0xbbbbbbbb; // rbx
stack[3] = 0x12121212; // r12
stack[2] = 0x13131313; // r13
stack[1] = 0x14141414; // r14
stack[0] = 0x15151515; // r15
stack[8] = rip3; // return rip in rcx
stack[7] = m_tcb.rsp3; // rbp
stack[6] = 0xbbbbbbbb; // rbx
stack[5] = 0x12121212; // r12
stack[4] = 0x13131313; // r13
stack[3] = 0x14141414; // r14
stack[2] = 0x15151515; // r15
stack[1] = arg1; // rsi
stack[0] = arg0; // rdi
static const uintptr_t trampoline =
reinterpret_cast<uintptr_t>(kernel_to_user_trampoline);
reinterpret_cast<uintptr_t>(initialize_user_cpu);
add_thunk_kernel(rip0 ? rip0 : trampoline);
}
@@ -149,8 +152,8 @@ thread::setup_kernel_stack()
using mem::kernel_stack_pages;
static constexpr size_t stack_bytes = kernel_stack_pages * frame_size;
constexpr unsigned null_frame_entries = 2;
constexpr size_t null_frame_size = null_frame_entries * sizeof(uint64_t);
static constexpr unsigned null_frame_entries = 2;
static constexpr size_t null_frame_size = null_frame_entries * sizeof(uint64_t);
uintptr_t stack_addr = g_kernel_stacks.get_section();
uintptr_t stack_end = stack_addr + stack_bytes;

View File

@@ -152,9 +152,16 @@ public:
/// Add a stack header that returns to the given address in user space
/// via a function in kernel space.
/// \arg rip3 The user space address to return to
/// \arg arg0 An argument passed to the userspace function
/// \arg arg1 An argument passed to the userspace function
/// \arg rip0 The kernel function to pass through, optional
/// \arg flags Extra RFLAGS values to set, optional
void add_thunk_user(uintptr_t rip3, uintptr_t rip0 = 0, uint64_t flags = 0);
void add_thunk_user(
uintptr_t rip3,
uint64_t arg0 = 0,
uint64_t arg1 = 0,
uintptr_t rip0 = 0,
uint64_t flags = 0);
/// Get the handle representing this thread to its process
j6_handle_t self_handle() const { return m_self_handle; }