x86_64: add pmap_handle_fault to route user-mode page faults to vm-region to resolve
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
#include <mango/compiler.h>
|
||||
#include <mango/libc/stdio.h>
|
||||
#include <mango/memblock.h>
|
||||
#include <mango/pmap.h>
|
||||
#include <mango/printk.h>
|
||||
#include <mango/sched.h>
|
||||
#include <mango/status.h>
|
||||
#include <mango/types.h>
|
||||
#include <mango/vm-object.h>
|
||||
#include <mango/vm-region.h>
|
||||
#include <mango/vm.h>
|
||||
|
||||
/* 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,
|
||||
|
||||
Reference in New Issue
Block a user