Skip to content

Commit

Permalink
sch: Try to address segment selector corruption
Browse files Browse the repository at this point in the history
  • Loading branch information
marv7000 committed Dec 19, 2024
1 parent 60e7a33 commit 7311688
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 5 deletions.
4 changes: 2 additions & 2 deletions kernel/arch/x86_64/system/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ void lapic_init(usize cpu_id)
// Set timer init counter to -1
lapic_write(0x380, 0xFFFFFFFF);

// See how many ticks pass in 100 microseconds.
clock_wait(100 * 10000);
// See how many ticks pass in 10 milliseconds.
clock_wait(10 * 1000000);

// Stop the APIC timer
lapic_write(0x320, 0x10000);
Expand Down
7 changes: 4 additions & 3 deletions kernel/arch/x86_64/system/arch.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

/* Swaps GSBASE if CPL == KERNEL */
.macro swapgs_if_necessary
cmpw $0x8, 0x8(%rsp)
cmpw $0x8, 0x18(%rsp)
je 1f
swapgs
1:
Expand Down Expand Up @@ -88,19 +88,20 @@ interrupt_internal:
call isr_handler /* Call interrupt handler */
mov %rax, %rsp /* interrupt_handler returns a pointer to the new context. */
pop_all_regs
add $0x10, %rsp /* Skip Context.error and Context.isr fields. */
swapgs_if_necessary /* Change GS back to user mode if we came from user mode. */
add $0x8, %rsp /* Skip Context.isr field. */
add $0x8, %rsp /* Skip Context.error field. */
iretq

/* Define 256 interrupt stubs using the macro above. */
.rept 256
.align 0x10
interrupt_\+:
swapgs_if_necessary /* Change GS to kernel mode if we're coming from user mode. */
.if !(\+ == 8 || (\+ >= 10 && \+ <= 14) || \+ == 17 || \+ == 21 || \+ == 29 || \+ == 30)
pushq $0 /* If this is an interrupt that doesn't push an error code, push one ourselves. */
.endif
pushq $\+ /* Push the ISR to the stack. */
swapgs_if_necessary /* Change GS to kernel mode if we're coming from user mode. */
jmp interrupt_internal
.endr

Expand Down
4 changes: 4 additions & 0 deletions kernel/arch/x86_64/system/gdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
void gdt_init(Gdt* gdt_table, TaskStateSegment* tss)
{
// clang-format off
asm_interrupt_disable();

// Kernel Code
GDT_ENCODE(gdt_table->kernel_code,
Expand Down Expand Up @@ -49,10 +50,12 @@ void gdt_init(Gdt* gdt_table, TaskStateSegment* tss)
0);

// clang-format on
asm_interrupt_enable();
}

void gdt_load(Gdt* gdt_table)
{
asm_interrupt_disable();
GdtRegister gdtr = {
.limit = sizeof(Gdt) - 1,
.base = gdt_table,
Expand All @@ -61,4 +64,5 @@ void gdt_load(Gdt* gdt_table)
asm_gdt_set(gdtr);
tss_reload();
asm_flush_segment_regs(offsetof(Gdt, kernel_code), offsetof(Gdt, kernel_data));
asm_interrupt_enable();
}
4 changes: 4 additions & 0 deletions kernel/system/sch/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ Context* sch_reschedule(Context* context)
cur->thread = running;
sch_arch_update(cur, running);

//! TODO: Nasty workaround. Need to figure out what's corrupting CS and SS values on interrupt entry.
if (running->registers.ss == 0x20)
running->registers.ss = 0x23;

// Load new page map.
vm_set_page_map(running->parent->page_map);
return &running->registers;
Expand Down

0 comments on commit 7311688

Please sign in to comment.