Skip to content
This repository has been archived by the owner on May 31, 2021. It is now read-only.

Commit

Permalink
Actually use swapgs; fix some IDT gating stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
klange committed May 26, 2021
1 parent 1f5581c commit d601d0d
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 54 deletions.
102 changes: 51 additions & 51 deletions kernel/arch/x86_64/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,72 +21,72 @@
static struct idt_pointer idtp;
static idt_entry_t idt[256];

void idt_set_gate(uint8_t num, interrupt_handler_t handler, uint16_t selector, uint8_t flags) {
void idt_set_gate(uint8_t num, interrupt_handler_t handler, uint16_t selector, uint8_t flags, int userspace) {
uintptr_t base = (uintptr_t)handler;
idt[num].base_low = (base & 0xFFFF);
idt[num].base_mid = (base >> 16) & 0xFFFF;
idt[num].base_high = (base >> 32) & 0xFFFFFFFF;
idt[num].selector = selector;
idt[num].zero = 0;
idt[num].pad = 0;
idt[num].flags = flags | 0x60;
idt[num].flags = flags | (userspace ? 0x60 : 0);
}

void idt_install(void) {
idtp.limit = sizeof(idt);
idtp.base = (uintptr_t)&idt;

/** ISRs */
idt_set_gate(0, _isr0, 0x08, 0x8E);
idt_set_gate(1, _isr1, 0x08, 0x8E);
idt_set_gate(2, _isr2, 0x08, 0x8E);
idt_set_gate(3, _isr3, 0x08, 0x8E);
idt_set_gate(4, _isr4, 0x08, 0x8E);
idt_set_gate(5, _isr5, 0x08, 0x8E);
idt_set_gate(6, _isr6, 0x08, 0x8E);
idt_set_gate(7, _isr7, 0x08, 0x8E);
idt_set_gate(8, _isr8, 0x08, 0x8E);
idt_set_gate(9, _isr9, 0x08, 0x8E);
idt_set_gate(10, _isr10, 0x08, 0x8E);
idt_set_gate(11, _isr11, 0x08, 0x8E);
idt_set_gate(12, _isr12, 0x08, 0x8E);
idt_set_gate(13, _isr13, 0x08, 0x8E);
idt_set_gate(14, _isr14, 0x08, 0x8E);
idt_set_gate(15, _isr15, 0x08, 0x8E);
idt_set_gate(16, _isr16, 0x08, 0x8E);
idt_set_gate(17, _isr17, 0x08, 0x8E);
idt_set_gate(18, _isr18, 0x08, 0x8E);
idt_set_gate(19, _isr19, 0x08, 0x8E);
idt_set_gate(20, _isr20, 0x08, 0x8E);
idt_set_gate(21, _isr21, 0x08, 0x8E);
idt_set_gate(22, _isr22, 0x08, 0x8E);
idt_set_gate(23, _isr23, 0x08, 0x8E);
idt_set_gate(24, _isr24, 0x08, 0x8E);
idt_set_gate(25, _isr25, 0x08, 0x8E);
idt_set_gate(26, _isr26, 0x08, 0x8E);
idt_set_gate(27, _isr27, 0x08, 0x8E);
idt_set_gate(28, _isr28, 0x08, 0x8E);
idt_set_gate(29, _isr29, 0x08, 0x8E);
idt_set_gate(30, _isr30, 0x08, 0x8E);
idt_set_gate(31, _isr31, 0x08, 0x8E);
idt_set_gate(0, _isr0, 0x08, 0x8E, 0);
idt_set_gate(1, _isr1, 0x08, 0x8E, 0);
idt_set_gate(2, _isr2, 0x08, 0x8E, 0);
idt_set_gate(3, _isr3, 0x08, 0x8E, 0);
idt_set_gate(4, _isr4, 0x08, 0x8E, 0);
idt_set_gate(5, _isr5, 0x08, 0x8E, 0);
idt_set_gate(6, _isr6, 0x08, 0x8E, 0);
idt_set_gate(7, _isr7, 0x08, 0x8E, 0);
idt_set_gate(8, _isr8, 0x08, 0x8E, 0);
idt_set_gate(9, _isr9, 0x08, 0x8E, 0);
idt_set_gate(10, _isr10, 0x08, 0x8E, 0);
idt_set_gate(11, _isr11, 0x08, 0x8E, 0);
idt_set_gate(12, _isr12, 0x08, 0x8E, 0);
idt_set_gate(13, _isr13, 0x08, 0x8E, 0);
idt_set_gate(14, _isr14, 0x08, 0x8E, 0);
idt_set_gate(15, _isr15, 0x08, 0x8E, 0);
idt_set_gate(16, _isr16, 0x08, 0x8E, 0);
idt_set_gate(17, _isr17, 0x08, 0x8E, 0);
idt_set_gate(18, _isr18, 0x08, 0x8E, 0);
idt_set_gate(19, _isr19, 0x08, 0x8E, 0);
idt_set_gate(20, _isr20, 0x08, 0x8E, 0);
idt_set_gate(21, _isr21, 0x08, 0x8E, 0);
idt_set_gate(22, _isr22, 0x08, 0x8E, 0);
idt_set_gate(23, _isr23, 0x08, 0x8E, 0);
idt_set_gate(24, _isr24, 0x08, 0x8E, 0);
idt_set_gate(25, _isr25, 0x08, 0x8E, 0);
idt_set_gate(26, _isr26, 0x08, 0x8E, 0);
idt_set_gate(27, _isr27, 0x08, 0x8E, 0);
idt_set_gate(28, _isr28, 0x08, 0x8E, 0);
idt_set_gate(29, _isr29, 0x08, 0x8E, 0);
idt_set_gate(30, _isr30, 0x08, 0x8E, 0);
idt_set_gate(31, _isr31, 0x08, 0x8E, 0);
idt_set_gate(32, _irq0, 0x08, 0x8E, 0);
idt_set_gate(33, _irq1, 0x08, 0x8E, 0);
idt_set_gate(34, _irq2, 0x08, 0x8E, 0);
idt_set_gate(35, _irq3, 0x08, 0x8E, 0);
idt_set_gate(36, _irq4, 0x08, 0x8E, 0);
idt_set_gate(37, _irq5, 0x08, 0x8E, 0);
idt_set_gate(38, _irq6, 0x08, 0x8E, 0);
idt_set_gate(39, _irq7, 0x08, 0x8E, 0);
idt_set_gate(40, _irq8, 0x08, 0x8E, 0);
idt_set_gate(41, _irq9, 0x08, 0x8E, 0);
idt_set_gate(42, _irq10, 0x08, 0x8E, 0);
idt_set_gate(43, _irq11, 0x08, 0x8E, 0);
idt_set_gate(44, _irq12, 0x08, 0x8E, 0);
idt_set_gate(45, _irq13, 0x08, 0x8E, 0);
idt_set_gate(46, _irq14, 0x08, 0x8E, 0);
idt_set_gate(47, _irq15, 0x08, 0x8E, 0);

idt_set_gate(32, _irq0, 0x08, 0x8E);
idt_set_gate(33, _irq1, 0x08, 0x8E);
idt_set_gate(34, _irq2, 0x08, 0x8E);
idt_set_gate(35, _irq3, 0x08, 0x8E);
idt_set_gate(36, _irq4, 0x08, 0x8E);
idt_set_gate(37, _irq5, 0x08, 0x8E);
idt_set_gate(38, _irq6, 0x08, 0x8E);
idt_set_gate(39, _irq7, 0x08, 0x8E);
idt_set_gate(40, _irq8, 0x08, 0x8E);
idt_set_gate(41, _irq9, 0x08, 0x8E);
idt_set_gate(42, _irq10, 0x08, 0x8E);
idt_set_gate(43, _irq11, 0x08, 0x8E);
idt_set_gate(44, _irq12, 0x08, 0x8E);
idt_set_gate(45, _irq13, 0x08, 0x8E);
idt_set_gate(46, _irq14, 0x08, 0x8E);
idt_set_gate(47, _irq15, 0x08, 0x8E);
idt_set_gate(127, _isr127, 0x08, 0x8E);
idt_set_gate(127, _isr127, 0x08, 0x8E, 1);

asm volatile (
"lidt %0"
Expand Down
13 changes: 10 additions & 3 deletions kernel/arch/x86_64/irq.S
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
.global _irq\index
.type _irq\index, @function
_irq\index:
cli
pushq $0x00
pushq $\byte
jmp isr_common
Expand All @@ -15,7 +14,6 @@
.global _isr\index
.type _isr\index, @function
_isr\index:
cli
pushq $0x00
pushq $\index
jmp isr_common
Expand All @@ -25,7 +23,6 @@
.global _isr\index
.type _isr\index, @function
_isr\index:
cli
pushq $\index
jmp isr_common
.endm
Expand Down Expand Up @@ -81,11 +78,19 @@ IRQ 14, 46
IRQ 15, 47
ISR_NOERR 127

.macro _swapgs
cmpq $8, 24(%rsp)
je 1f
swapgs
1:
.endm

.extern isr_handler
.type isr_handler, @function

isr_common:
/* Save all registers */
_swapgs
push %rax
push %rbx
push %rcx
Expand Down Expand Up @@ -126,6 +131,8 @@ isr_common:
pop %rbx
pop %rax

_swapgs

/* Cleanup error code and interrupt # */
add $16, %rsp

Expand Down
1 change: 1 addition & 0 deletions kernel/arch/x86_64/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ const char * arch_get_loader(void) {
void arch_set_core_base(uintptr_t base) {
asm volatile ("wrmsr" : : "c"(0xc0000101), "d"((uint32_t)(base >> 32)), "a"((uint32_t)(base & 0xFFFFFFFF)));
asm volatile ("wrmsr" : : "c"(0xc0000102), "d"((uint32_t)(base >> 32)), "a"((uint32_t)(base & 0xFFFFFFFF)));
asm volatile ("swapgs");
}

/**
Expand Down
3 changes: 3 additions & 0 deletions kernel/arch/x86_64/user.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ void arch_enter_user(uintptr_t entrypoint, int argc, char * argv[], char * envp[
"pushq %2\n"
"pushq %3\n"
"pushq %4\n"
"swapgs\n"
"iretq"
: : "m"(ret.ss), "m"(ret.rsp), "m"(ret.rflags), "m"(ret.cs), "m"(ret.rip),
"D"(argc), "S"(argv), "d"(envp));
Expand All @@ -39,6 +40,7 @@ void arch_enter_signal_handler(uintptr_t entrypoint, int signum) {
"pushq %2\n"
"pushq %3\n"
"pushq %4\n"
"swapgs\n"
"iretq"
: : "m"(ret.ss), "m"(ret.rsp), "m"(ret.rflags), "m"(ret.cs), "m"(ret.rip),
"D"(signum));
Expand All @@ -64,6 +66,7 @@ void arch_resume_user(void) {
"pop %rbx\n"
"pop %rax\n"
"add $16, %rsp\n"
"swapgs\n"
"iretq\n"
);
__builtin_unreachable();
Expand Down

0 comments on commit d601d0d

Please sign in to comment.