diff options
author | dzwdz | 2023-09-15 00:29:11 +0200 |
---|---|---|
committer | dzwdz | 2023-09-15 00:29:11 +0200 |
commit | 458978e7b8a6d50566fc8b68558f76f6b0465c52 (patch) | |
tree | 0b2decb03e5f07fa790d7add0fc16679472012de | |
parent | 8757321821d05d2958160e1428250daf19c119e9 (diff) |
kern: fix GDT order for 64bit sysret
-rw-r--r-- | src/kernel/arch/amd64/32/gdt.c | 3 | ||||
-rw-r--r-- | src/kernel/arch/amd64/boot.h | 13 | ||||
-rw-r--r-- | src/kernel/arch/amd64/boot64.s | 2 | ||||
-rw-r--r-- | src/kernel/arch/amd64/sysenter.s | 4 | ||||
-rw-r--r-- | src/kernel/proc.c | 2 |
5 files changed, 14 insertions, 10 deletions
diff --git a/src/kernel/arch/amd64/32/gdt.c b/src/kernel/arch/amd64/32/gdt.c index bd5fa48..e643f27 100644 --- a/src/kernel/arch/amd64/32/gdt.c +++ b/src/kernel/arch/amd64/32/gdt.c @@ -75,8 +75,9 @@ void gdt_init(void) { gdt_fillout(&GDT[SEG_r0code], 0, true); gdt_fillout(&GDT[SEG_r0data], 0, false); - gdt_fillout(&GDT[SEG_r3code], 3, true); + gdt_fillout(&GDT[SEG_r3code32], 3, true); gdt_fillout(&GDT[SEG_r3data], 3, false); + gdt_fillout(&GDT[SEG_r3code], 3, true); lgdt_arg.limit = sizeof(GDT) - 1; lgdt_arg.base = (uint64_t)&GDT; diff --git a/src/kernel/arch/amd64/boot.h b/src/kernel/arch/amd64/boot.h index 7c36cd3..fac4ab6 100644 --- a/src/kernel/arch/amd64/boot.h +++ b/src/kernel/arch/amd64/boot.h @@ -3,12 +3,13 @@ enum gdt_segs { SEG_null, /* order dictated by SYSENTER */ - SEG_r0code, - SEG_r0data, - SEG_r3code, - SEG_r3data, - SEG_TSS, - SEG_TSS2, + SEG_r0code = 1, + SEG_r0data = 2, + SEG_r3code32 = 3, + SEG_r3data = 4, + SEG_r3code = 5, + SEG_TSS = 6, + SEG_TSS2 = 7, SEG_end }; diff --git a/src/kernel/arch/amd64/boot64.s b/src/kernel/arch/amd64/boot64.s index af05ffe..9bd9f0c 100644 --- a/src/kernel/arch/amd64/boot64.s +++ b/src/kernel/arch/amd64/boot64.s @@ -1,7 +1,7 @@ .global boot64 boot64: lgdt (lgdt_arg) // try reloading gdt again - mov $(5 << 3 | 3), %ax // SEG_TSS + mov $(6 << 3 | 3), %ax // SEG_TSS ltr %ax push %rdi // preserve multiboot struct diff --git a/src/kernel/arch/amd64/sysenter.s b/src/kernel/arch/amd64/sysenter.s index 6b6d684..c1af69f 100644 --- a/src/kernel/arch/amd64/sysenter.s +++ b/src/kernel/arch/amd64/sysenter.s @@ -1,6 +1,6 @@ // gdt.h .set SEG_r0code, 1 -.set SEG_r3code, 3 +.set SEG_r3code32, 3 .set SEG_r3data, 4 .set IA32_STAR, 0xC0000081 @@ -15,7 +15,7 @@ sysenter_setup: // the intel docs don't mention the lower 32 bits mov $0, %eax - mov $( ((SEG_r3code << 3 | 3) << 16) | (SEG_r0code << 3) ), %edx + mov $( ((SEG_r3code32 << 3 | 3) << 16) | (SEG_r0code << 3) ), %edx mov $IA32_STAR, %rcx wrmsr diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 4164874..ee99603 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -44,7 +44,9 @@ Proc *proc_seed(void *data, size_t datalen) { void __user *init_base = (userptr_t)0x200000; for (uintptr_t off = 0; off < datalen; off += PAGE_SIZE) pagedir_map(proc_first->pages, init_base + off, data + off, true, true); + proc_first->regs.rcx = (uintptr_t)init_base; // SYSRET jumps to %rcx + // proc_first->regs.r11 |= 1<<9; /* enable interrupts */ return proc_first; } |