From 67b3be973247938e765849ed43bfa0546834410d Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 8 Feb 2026 13:03:28 +0000 Subject: [PATCH] x86_64: add pmap_handle_fault to route user-mode page faults to vm-region to resolve --- arch/x86_64/pmap.c | 66 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/arch/x86_64/pmap.c b/arch/x86_64/pmap.c index a4736b8..0ed104e 100644 --- a/arch/x86_64/pmap.c +++ b/arch/x86_64/pmap.c @@ -1,9 +1,13 @@ #include +#include #include #include #include +#include #include #include +#include +#include #include /* some helpful datasize constants */ @@ -296,13 +300,73 @@ void pmap_bootstrap(void) pmap_t pmap_create(void) { - return 0; + pmap_t pmap = alloc_pmap(); + pmap_t kernel_pmap = get_kernel_pmap(); + + struct pml4t *pml4t = vm_phys_to_virt(pmap); + struct pml4t *kernel_pml4t = vm_phys_to_virt(kernel_pmap); + + for (unsigned int i = 256; i < 512; i++) { + pml4t->p_entries[i] = kernel_pml4t->p_entries[i]; + } + + return pmap; } void pmap_destroy(pmap_t pmap) { } +static void log_fault(virt_addr_t fault_addr, enum pmap_fault_flags flags) +{ + char flag_str[128] = {0}; + size_t p = 0; + + if (flags & PMAP_FAULT_PRESENT) { + p += snprintf(flag_str + p, sizeof flag_str - p, " PRESENT"); + } else { + p += snprintf(flag_str + p, sizeof flag_str - p, " MISSING"); + } + + if (flags & PMAP_FAULT_USER) { + p += snprintf(flag_str + p, sizeof flag_str - p, " USER"); + } else { + p += snprintf(flag_str + p, sizeof flag_str - p, " SVR"); + } + + if (flags & PMAP_FAULT_WRITE) { + p += snprintf(flag_str + p, sizeof flag_str - p, " WRITE"); + } else { + p += snprintf(flag_str + p, sizeof flag_str - p, " READ"); + } + + if (flags & PMAP_FAULT_IFETCH) { + p += snprintf(flag_str + p, sizeof flag_str - p, " IFETCH"); + } + + if (flags & PMAP_FAULT_BADCFG) { + p += snprintf(flag_str + p, sizeof flag_str - p, " BADCFG"); + } + + printk("pmap: fault at 0x%llx (%s)", fault_addr, flag_str); +} + +kern_status_t pmap_handle_fault( + virt_addr_t fault_addr, + enum pmap_fault_flags flags) +{ + // log_fault(fault_addr, flags); + + if (flags & PMAP_FAULT_PRESENT) { + return KERN_FATAL_ERROR; + } + + struct task *task = current_task(); + struct vm_region *space = task->t_address_space; + + return vm_region_demand_map(space, fault_addr, flags); +} + kern_status_t pmap_add( pmap_t pmap, virt_addr_t p,