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/compiler.h>
|
||||||
|
#include <mango/libc/stdio.h>
|
||||||
#include <mango/memblock.h>
|
#include <mango/memblock.h>
|
||||||
#include <mango/pmap.h>
|
#include <mango/pmap.h>
|
||||||
#include <mango/printk.h>
|
#include <mango/printk.h>
|
||||||
|
#include <mango/sched.h>
|
||||||
#include <mango/status.h>
|
#include <mango/status.h>
|
||||||
#include <mango/types.h>
|
#include <mango/types.h>
|
||||||
|
#include <mango/vm-object.h>
|
||||||
|
#include <mango/vm-region.h>
|
||||||
#include <mango/vm.h>
|
#include <mango/vm.h>
|
||||||
|
|
||||||
/* some helpful datasize constants */
|
/* some helpful datasize constants */
|
||||||
@@ -296,13 +300,73 @@ void pmap_bootstrap(void)
|
|||||||
|
|
||||||
pmap_t pmap_create(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)
|
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(
|
kern_status_t pmap_add(
|
||||||
pmap_t pmap,
|
pmap_t pmap,
|
||||||
virt_addr_t p,
|
virt_addr_t p,
|
||||||
|
|||||||
Reference in New Issue
Block a user