From 43c6ffa04e0e29142c99295cd5be1d597685f3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Gr=C3=A9goire?= Date: Fri, 24 Apr 2026 14:33:06 -0400 Subject: [PATCH] feat(mm): add query --- src/mm/pmap.zig | 5 +++++ src/mm/radix_pmap.zig | 21 ++++++++++++++++++++- src/mm/um/impl.zig | 10 ++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/mm/pmap.zig b/src/mm/pmap.zig index 82e088f..b655e0a 100644 --- a/src/mm/pmap.zig +++ b/src/mm/pmap.zig @@ -112,4 +112,9 @@ pub const PMap = struct { pub fn activate(self: *Self) void { self.impl.activate(); } + + /// Given a virtual page, return its physical page, if present. + pub fn query(self: *Self, va: r.VAddr) ?r.PAddr { + return self.impl.query(va); + } }; diff --git a/src/mm/radix_pmap.zig b/src/mm/radix_pmap.zig index b184192..c8ce93b 100644 --- a/src/mm/radix_pmap.zig +++ b/src/mm/radix_pmap.zig @@ -90,6 +90,25 @@ pub fn RadixPmap(comptime Impl: type) type { } } + pub fn query(self: *Self, va: r.VAddr) ?r.PAddr { + var c = self.cursor(va); + + var level: usize = num_levels - 1; + while (true) { + const idx = index_for_level(va, level); + const pte = c.tables[level][idx]; + + if (!pte.present) return null; + + if (level == 0 or leaf_level_enabled(level)) { + return pte.address() + (va & (page_size(level) - 1)); + } + + if (!c.walk_down_resolve(level - 1)) return null; + level -= 1; + } + } + /// Ensure all intermediate page tables down to `target_level` exist for /// the given virtual address range, allocating them as needed. Useful for /// pre-populating a shared region (e.g. the kernel half of a user pmap) @@ -148,7 +167,7 @@ pub fn RadixPmap(comptime Impl: type) type { } } - fn walk_down_resolve(self: *Cursor, target_level: usize) bool { + pub fn walk_down_resolve(self: *Cursor, target_level: usize) bool { self.walk_down(target_level, false) catch return false; return true; } diff --git a/src/mm/um/impl.zig b/src/mm/um/impl.zig index 1b499be..62e4bd5 100644 --- a/src/mm/um/impl.zig +++ b/src/mm/um/impl.zig @@ -6,6 +6,8 @@ pub var kernel_heap_base: usize = 0; pub var pfndb_base: usize = 0; pub const hhdm_minimum_max_address: usize = 0; +var page_table: std.AutoHashMap(usize, usize) = .init(std.heap.page_allocator); + pub fn init_kernel() void { kernel_heap_base = linux.mmap( null, @@ -62,9 +64,17 @@ pub const PMap = struct { @bitCast(item.pa), ); + page_table.put(va & ~@as(usize, 0xFFF), item.pa) catch unreachable; + remain -|= item.len; } } + pub fn query(_: *Self, va: r.VAddr) ?r.PAddr { + const page = va & ~@as(usize, 0xFFF); + const pa = page_table.get(page) orelse return null; + return pa; + } + pub fn activate(_: *Self) void {} };