Skip to content

Commit

Permalink
Add tlb shootdown to vmm
Browse files Browse the repository at this point in the history
  • Loading branch information
Ratakor committed Nov 12, 2023
1 parent f5c0af0 commit 30f468f
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 10 deletions.
1 change: 1 addition & 0 deletions kernel/arch/x86_64/cpu.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub const CpuLocal = struct {
lapic_id: u32,
lapic_freq: u64,
tss: gdt.TSS,
tlb_shootdown_cr3: u64,

cpu_model: u32,
cpu_family: u32,
Expand Down
1 change: 1 addition & 0 deletions kernel/arch/x86_64/idt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const exceptions = [_]?[]const u8{
};

// TODO: replace isr with a interrupt dispatcher func?
// -> move all handlers to interrupt.zig?
var isr = [_]InterruptHandler{defaultHandler} ** 256;
var next_vector: u8 = exceptions.len;
pub var panic_ipi_vector: u8 = undefined;
Expand Down
46 changes: 36 additions & 10 deletions kernel/mm/vmm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const alignForward = std.mem.alignForward;
const page_size = std.mem.page_size;
const MAP = std.os.MAP;

// TODO: TLB shootdown?
// TODO: mapRange/unmapRange?
// TODO: move paging code to paging.zig

pub const MapError = error{
OutOfMemory,
Expand Down Expand Up @@ -144,13 +144,9 @@ pub const AddressSpace = struct {
errdefer root.allocator.destroy(addr_space);

const pml4_phys = pmm.alloc(1, true) orelse return error.OutOfMemory;
addr_space.pml4 = @ptrFromInt(pml4_phys + hhdm_offset);
addr_space.lock = .{};
addr_space.mmap_ranges = .{};

for (256..512) |i| {
addr_space.pml4[i] = kaddr_space.pml4[i];
}
addr_space.* = .{ .pml4 = @ptrFromInt(pml4_phys + hhdm_offset) };
@memset(addr_space.pml4[0..256], @bitCast(@as(u64, 0)));
@memcpy(addr_space.pml4[256..512], kaddr_space.pml4[256..512]);

return addr_space;
}
Expand Down Expand Up @@ -312,10 +308,26 @@ pub const AddressSpace = struct {
return @intFromPtr(self.pml4) - hhdm_offset;
}

inline fn flush(self: *AddressSpace, vaddr: u64) void {
if (@intFromPtr(self.pml4) == arch.readRegister("cr3")) {
// TODO: lock?
fn flush(self: *AddressSpace, vaddr: u64) void {
std.debug.assert(arch.interruptState() == false);
// const old_state = arch.toggleInterrupts(false);
// defer _ = arch.toggleInterrupts(old_state);

if (self.cr3() == arch.readRegister("cr3")) {
arch.invlpg(vaddr);
}

if (!smp.initialized) return;

const this_cpu = smp.thisCpu();
for (smp.cpus) |*cpu| {
if (cpu == this_cpu) continue;

cpu.tlb_shootdown_cr3 = self.cr3();
asm volatile ("" ::: "memory");
apic.sendIPI(cpu.lapic_id, .{ .vector = tlb_shootdown_ipi_vector });
}
}

pub fn mmapRange(
Expand Down Expand Up @@ -447,6 +459,7 @@ pub const AddressSpace = struct {

pub var hhdm_offset: u64 = undefined; // set in pmm.zig
pub var kaddr_space: *AddressSpace = undefined;
var tlb_shootdown_ipi_vector: u8 = undefined;

pub fn init() void {
log.info("hhdm offset: 0x{x}", .{hhdm_offset});
Expand All @@ -455,6 +468,7 @@ pub fn init() void {
const pml4_phys = pmm.alloc(1, true) orelse unreachable;
kaddr_space.* = .{ .pml4 = @ptrFromInt(pml4_phys + hhdm_offset) };

@memset(kaddr_space.pml4[0..256], @bitCast(@as(u64, 0)));
for (256..512) |i| {
_ = kaddr_space.pml4[i].getNextLevel(true) catch unreachable;
}
Expand Down Expand Up @@ -488,6 +502,8 @@ pub fn init() void {
}
}

tlb_shootdown_ipi_vector = idt.allocVector();
idt.registerHandler(tlb_shootdown_ipi_vector, tlbShootdownHandler);
switchPageTable(kaddr_space.cr3());
}

Expand Down Expand Up @@ -531,3 +547,13 @@ fn mmapPageInRange(global: *MMapRangeGlobal, vaddr: u64, paddr: u64, prot: i32)
}
}
}

fn tlbShootdownHandler(ctx: *arch.Context) callconv(.SysV) void {
_ = ctx;

if (smp.thisCpu().tlb_shootdown_cr3 == arch.readRegister("cr3")) {
arch.writeRegister("cr3", arch.readRegister("cr3"));
}

apic.eoi();
}
3 changes: 3 additions & 0 deletions kernel/smp.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const log = std.log.scoped(.smp);
pub var bsp_lapic_id: u32 = undefined; // bootstrap processor lapic id
pub var cpus: []CpuLocal = undefined;
var cpus_started: usize = 0;
pub var initialized = false;

pub fn init() void {
const smp = root.smp_request.response.?;
Expand Down Expand Up @@ -38,6 +39,8 @@ pub fn init() void {
while (cpus_started != cpus.len) {
std.atomic.spinLoopHint();
}

initialized = true;
}

pub fn stopAll() void {
Expand Down

0 comments on commit 30f468f

Please sign in to comment.