Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions kernel/arch/aarch64/trap/trap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "timer/timer.h"
#include "sched/sched.h"
#include "sched/task.h"
#include "mm/mm.h"

// Forward declaration of syscall dispatch
extern "C" void stlx_aarch64_syscall_dispatch(aarch64::trap_frame* tf);
Expand Down Expand Up @@ -79,6 +80,35 @@ void stlx_aarch64_el0_sync_handler(aarch64::trap_frame* tf) {
return;
}

// If it's a page fault, attempt to handle it for on-demand paging
if (in_user_code && (
ec == aarch64::EC_DATA_ABORT_LOWER ||
ec == aarch64::EC_INST_ABORT_LOWER)
) {
uintptr_t fault_addr = aarch64::get_far(tf);
uint32_t pf_flags = 0;

// DFSC[5:0] is in ESR.ISS bits [5:0] for data/instruction aborts.
uint32_t dfsc = esr & 0x3F;
uint32_t fault_class = dfsc >> 2; // top 4 bits identify the class
if (fault_class == 0b0011) pf_flags |= mm::PF_FLAG_PRESENT; // permission fault

// ESR.ISS bit 6 = WnR (Write not Read) for data aborts.
if (ec == aarch64::EC_DATA_ABORT_LOWER && (esr & (1u << 6))) {
pf_flags |= mm::PF_FLAG_WRITE;
}

if (ec == aarch64::EC_INST_ABORT_LOWER) {
pf_flags |= mm::PF_FLAG_INSTRUCTION;
}

if (mm::handle_user_pf(guard.task_core->mm_ctx, fault_addr, pf_flags)) {
// Fault has been handled successfully, restart instruction
restore_post_trap_elevation_state();
return;
}
}

if (in_user_code && (
ec == aarch64::EC_DATA_ABORT_LOWER ||
ec == aarch64::EC_INST_ABORT_LOWER ||
Expand Down
20 changes: 19 additions & 1 deletion kernel/arch/x86_64/trap/trap.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "trap_frame.h"
#include "trap/trap_frame.h"
#include "defs/vectors.h"
#include "irq/irq.h"
#include "io/serial.h"
Expand All @@ -10,6 +10,7 @@
#include "msi/msi.h"
#include "sched/sched.h"
#include "sched/task.h"
#include "mm/mm.h"

namespace sched {
__PRIVILEGED_CODE void on_yield(x86::trap_frame* tf);
Expand Down Expand Up @@ -90,6 +91,23 @@ extern "C" __PRIVILEGED_CODE void stlx_x86_64_trap_handler(x86::trap_frame* tf)
return;
}

// If it's a page fault, attempt to handle it for on-demand paging
if (in_user_code && tf->vector == x86::EXC_PAGE_FAULT) {
uintptr_t fault_addr = x86::read_cr2();
uint64_t ec = tf->error_code;
uint32_t pf_flags = 0;
if (ec & 0x1) pf_flags |= mm::PF_FLAG_PRESENT;
if (ec & 0x2) pf_flags |= mm::PF_FLAG_WRITE;
if (ec & 0x10) pf_flags |= mm::PF_FLAG_INSTRUCTION;

if (mm::handle_user_pf(irq_task_core->mm_ctx, fault_addr, pf_flags)) {
// Fault has been handled successfully, restart instruction
irq_task_core->flags &= ~sched::TASK_FLAG_IN_IRQ;
restore_post_trap_elevation_state();
return;
}
}

if (in_user_code && (
tf->vector == x86::EXC_PAGE_FAULT ||
tf->vector == x86::EXC_GENERAL_PROTECTION ||
Expand Down
1 change: 1 addition & 0 deletions kernel/drivers/graphics/gfxfb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "fs/fs.h"
#include "fs/node.h"
#include "mm/heap.h"
#include "mm/mm.h"
#include "mm/paging_types.h"
#include "mm/pmm_types.h"
#include "mm/uaccess.h"
Expand Down
1 change: 1 addition & 0 deletions kernel/exec/elf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "mm/heap.h"
#include "mm/paging.h"
#include "mm/pmm.h"
#include "mm/mm.h"
#include "mm/vma.h"
#include "dynpriv/dynpriv.h"
#include "common/string.h"
Expand Down
Loading
Loading