x86_64: irq: route user-mode page faults to pmap_handle_fault
This commit is contained in:
@@ -9,7 +9,13 @@
|
|||||||
#include <mango/sched.h>
|
#include <mango/sched.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define MAX_ISR_HANDLERS 16
|
#define MAX_ISR_HANDLERS 16
|
||||||
|
|
||||||
|
#define PF_PRESENT 0x01u
|
||||||
|
#define PF_WRITE 0x02u
|
||||||
|
#define PF_USER 0x04u
|
||||||
|
#define PF_RESERVED_WRITE 0x08u
|
||||||
|
#define PF_IFETCH 0x10u
|
||||||
|
|
||||||
extern void syscall_gate(void);
|
extern void syscall_gate(void);
|
||||||
extern uintptr_t pf_faultptr(void);
|
extern uintptr_t pf_faultptr(void);
|
||||||
@@ -79,10 +85,31 @@ static void gpf_handler(struct ml_cpu_context *regs)
|
|||||||
|
|
||||||
static void pf_handler(struct ml_cpu_context *regs)
|
static void pf_handler(struct ml_cpu_context *regs)
|
||||||
{
|
{
|
||||||
|
enum pmap_fault_flags fault_flags = 0;
|
||||||
|
|
||||||
|
(regs->err_no & PF_PRESENT) && (fault_flags |= PMAP_FAULT_PRESENT);
|
||||||
|
(regs->err_no & PF_USER) && (fault_flags |= PMAP_FAULT_USER);
|
||||||
|
(regs->err_no & PF_WRITE) && (fault_flags |= PMAP_FAULT_WRITE);
|
||||||
|
(regs->err_no & PF_IFETCH) && (fault_flags |= PMAP_FAULT_IFETCH);
|
||||||
|
(regs->err_no & PF_RESERVED_WRITE)
|
||||||
|
&& (fault_flags |= PMAP_FAULT_BADCFG);
|
||||||
|
|
||||||
|
virt_addr_t fault_ptr = pf_faultptr();
|
||||||
|
|
||||||
|
kern_status_t status = KERN_FATAL_ERROR;
|
||||||
|
|
||||||
|
if (regs->err_no & PF_USER) {
|
||||||
|
status = pmap_handle_fault(fault_ptr, fault_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == KERN_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
panic_irq(
|
panic_irq(
|
||||||
regs,
|
regs,
|
||||||
"page fault (%016llx %016llx %016llx)",
|
"page fault (%016llx %016llx %016llx)",
|
||||||
pf_faultptr(),
|
fault_ptr,
|
||||||
regs->rip,
|
regs->rip,
|
||||||
regs->err_no);
|
regs->err_no);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user