From 9e223ca5d020102ee55121b018fa7ca1dd99e964 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 8 Feb 2026 12:47:28 +0000 Subject: [PATCH] x86_64: implement syscall instruction init and dispatch --- arch/x86_64/irq.c | 79 +++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/arch/x86_64/irq.c b/arch/x86_64/irq.c index f16c748..320bd8e 100644 --- a/arch/x86_64/irq.c +++ b/arch/x86_64/irq.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -20,6 +21,27 @@ static struct idt idt; static int idt_initialised = 0; static uintptr_t int_entry_points[NR_IDT_ENTRIES]; +static void set_syscall_gate(uintptr_t rip) +{ + uint64_t user_cs = 0x13; + uint64_t kernel_cs = 0x8; + + uintptr_t star_reg = 0xC0000081; + uintptr_t lstar_reg = 0xC0000082; + uintptr_t sfmask_reg = 0xC0000084; + + uint64_t selectors = 0; + selectors |= (user_cs) << 48; + selectors |= (kernel_cs) << 32; + + /* disable interrupts */ + uint64_t flag_mask = 0x200; + + wrmsr(star_reg, selectors); + wrmsr(lstar_reg, rip); + wrmsr(sfmask_reg, flag_mask); +} + static void set_idt_gate( struct idt *idt, uint8_t index, @@ -65,33 +87,6 @@ static void pf_handler(struct ml_cpu_context *regs) regs->err_no); } -#if 0 -static void set_syscall_gate(uintptr_t rip) -{ - /* sysret adds 0x10 to this to get cs, and 0x8 to get ss - * note that the CPU should force the RPL to 3 when loading - * the selector by using user_cs | 3. However, this doesn't happen - * in certain scenarios (specifically, QEMU + KVM on a Ryzen 5 1600X). */ - uint64_t user_cs = 0x13; - uint64_t kernel_cs = 0x8; - - uintptr_t star_reg = 0xC0000081; - uintptr_t lstar_reg = 0xC0000082; - uintptr_t sfmask_reg = 0xC0000084; - - uint64_t selectors = 0; - selectors |= (user_cs) << 48; - selectors |= (kernel_cs) << 32; - - /* disable interrupts */ - uint64_t flag_mask = 0x200; - - write_msr(star_reg, selectors); - write_msr(lstar_reg, rip); - write_msr(sfmask_reg, flag_mask); -} -#endif - static void init_pic(void) { // Remap the PIC @@ -180,6 +175,36 @@ void irq_dispatch(struct ml_cpu_context *regs) void syscall_dispatch(struct ml_cpu_context *regs) { + unsigned int sysid = regs->rax; + virt_addr_t syscall_impl = 0; // TODO + + if (syscall_impl == 0) { + regs->rax = KERN_UNSUPPORTED; + return; + } + +#define SYSCALL_SIGNATURE(...) \ + intptr_t (*__VA_ARGS__)( \ + uintptr_t, \ + uintptr_t, \ + uintptr_t, \ + uintptr_t, \ + uintptr_t, \ + uintptr_t, \ + uintptr_t, \ + uintptr_t) + + SYSCALL_SIGNATURE(fn) = (SYSCALL_SIGNATURE())syscall_impl; + + regs->rax + = fn(regs->rdi, + regs->rsi, + regs->rdx, + regs->r12, + regs->r8, + regs->r9, + regs->r13, + regs->r14); } void hook_irq(enum irq_vector vec, struct irq_hook *hook)