core: Check the stack is in user memory before changing it to kernel space
Otherwise, we're just adding the physical base to an address that's already in the higher half.
This commit is contained in:
parent
785335bd9a
commit
8156ff57fe
@ -1,7 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const interrupts = @import("interrupts.zig");
|
const interrupts = @import("interrupts.zig");
|
||||||
|
|
||||||
pub inline fn enterTask(regs: *interrupts.InterruptStackFrame, comptime base: u64, directory: u64) noreturn {
|
pub inline fn enterTask(regs: *interrupts.InterruptStackFrame, base: u64, directory: u64) noreturn {
|
||||||
asm volatile (
|
asm volatile (
|
||||||
\\ addq %[base], %rsp
|
\\ addq %[base], %rsp
|
||||||
\\ push %[ss]
|
\\ push %[ss]
|
||||||
@ -47,6 +47,13 @@ pub fn idleLoop() callconv(.Naked) noreturn {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn readStackPointer() usize {
|
||||||
|
return asm volatile (
|
||||||
|
\\ mov %rsp, %[result]
|
||||||
|
: [result] "=r" (-> usize),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn setAddress(regs: *interrupts.InterruptStackFrame, address: u64) void {
|
pub fn setAddress(regs: *interrupts.InterruptStackFrame, address: u64) void {
|
||||||
regs.rip = address;
|
regs.rip = address;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,13 @@ pub fn enterTask(task: *ThreadControlBlock) noreturn {
|
|||||||
|
|
||||||
task.state = .Running;
|
task.state = .Running;
|
||||||
|
|
||||||
arch.enterTask(&task.regs, vmm.PHYSICAL_MAPPING_BASE, table.address);
|
// If the stack is in user memory, then we need a pointer to its higher-half version. If it's already in kernel memory, no need to do anything.
|
||||||
|
var base: usize = 0;
|
||||||
|
if (arch.readStackPointer() < vmm.PHYSICAL_MAPPING_BASE) {
|
||||||
|
base += vmm.PHYSICAL_MAPPING_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
arch.enterTask(&task.regs, base, table.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn switchTask(regs: *interrupts.InterruptStackFrame, new_task: *ThreadControlBlock) void {
|
fn switchTask(regs: *interrupts.InterruptStackFrame, new_task: *ThreadControlBlock) void {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user