From 4dd7abb188a1587bc2086409e0445ef11e834feb Mon Sep 17 00:00:00 2001 From: Danny Holman Date: Fri, 16 Feb 2024 12:49:05 -0600 Subject: arch: i386: gdt.c: fix a bug in userspace jump Fix a bug in the GDT that prevented the kernel from jumping to userspace correctly. Signed-off-by: Danny Holman --- arch/i386/boot/gdt.c | 64 ++++++++++------------------------------------------ 1 file changed, 12 insertions(+), 52 deletions(-) diff --git a/arch/i386/boot/gdt.c b/arch/i386/boot/gdt.c index f84c767..c0cf127 100644 --- a/arch/i386/boot/gdt.c +++ b/arch/i386/boot/gdt.c @@ -1,55 +1,11 @@ +#include +#include #include -#include - -struct gdt_entry { - uint16_t limit_low; - uint16_t base_low; - uint8_t base_middle; - uint8_t access; - uint8_t gran; - uint8_t base_high; -} __attribute__((packed)); - -struct gdt_ptr { - uint16_t limit; - uint32_t base; -} __attribute__((packed)); - -struct tss_entry { - uint32_t link; - uint32_t esp0; - uint32_t ss0; - uint32_t esp1; - uint32_t ss2; - uint32_t cr3; - uint32_t eip; - uint32_t eflags; - uint32_t eax; - uint32_t ecx; - uint32_t edx; - uint32_t ebx; - uint32_t esp; - uint32_t ebp; - uint32_t esi; - uint32_t edi; - uint32_t es; - uint32_t cs; - uint32_t ss; - uint32_t ds; - uint32_t fs; - uint32_t gs; - uint32_t ldtr; - uint16_t trap; - uint16_t iomap_base; -} __attribute__((packed)); struct gdt_entry desc[6]; struct gdt_ptr gp; struct tss_entry tss_entry; -extern void flush_gdt(void); -extern void flush_tss(void); - void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) { desc[num].base_low = (base & 0xFFFF); desc[num].base_middle = (base >> 16) & 0xFF; @@ -61,11 +17,11 @@ void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_ desc[num].access = access; } -void write_tss(int num, uint16_t ss0, uint16_t esp0) { +void write_tss(int num, uint32_t ss0, uint32_t esp0) { uint32_t base = (uint32_t)&tss_entry; uint32_t limit = base + sizeof(struct tss_entry); - gdt_set_gate(num, base, limit, 0xE9, 0x00); + gdt_set_gate(num, base, limit, 0x89, 0x00); memset(&tss_entry, 0x0, sizeof(tss_entry)); tss_entry.ss0 = ss0; @@ -79,15 +35,19 @@ void write_tss(int num, uint16_t ss0, uint16_t esp0) { tss_entry.iomap_base = sizeof(tss_entry); } +void set_kernel_esp(uint32_t esp) { + tss_entry.esp0 = esp; +} + void gdt_install(void) { gp.limit = (sizeof(struct gdt_entry) * 6) - 1; gp.base = (uint32_t)&desc; gdt_set_gate(0, 0, 0, 0, 0); - gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); - gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); - gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); - gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); + gdt_set_gate(1, 0, 0xFFFFF, 0x9A, 0xCF); + gdt_set_gate(2, 0, 0xFFFFF, 0x92, 0xCF); + gdt_set_gate(3, 0, 0xFFFFF, 0xFA, 0xCF); + gdt_set_gate(4, 0, 0xFFFFF, 0xF2, 0xCF); uint32_t esp; __asm__ volatile("movl %%esp, %0" : "=r"(esp)); -- cgit v1.2.3