summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--p/riscv_test.h2
-rw-r--r--v/riscv_test.h10
-rw-r--r--v/vm.c15
3 files changed, 27 insertions, 0 deletions
diff --git a/p/riscv_test.h b/p/riscv_test.h
index fe14f08..a8c50c7 100644
--- a/p/riscv_test.h
+++ b/p/riscv_test.h
@@ -153,6 +153,8 @@
#define EXTRA_TVEC_MACHINE
#define EXTRA_INIT
#define EXTRA_INIT_TIMER
+#define FILTER_TRAP
+#define FILTER_PAGE_FAULT
#define INTERRUPT_HANDLER j other_exception /* No interrupts should occur */
diff --git a/v/riscv_test.h b/v/riscv_test.h
index c74e05d..e39123c 100644
--- a/v/riscv_test.h
+++ b/v/riscv_test.h
@@ -24,6 +24,16 @@
extra_boot: \
EXTRA_INIT \
ret; \
+.global trap_filter; \
+trap_filter: \
+ FILTER_TRAP \
+ li a0, 0; \
+ ret; \
+.global pf_filter; \
+pf_filter: \
+ FILTER_PAGE_FAULT \
+ li a0, 0; \
+ ret; \
.global userstart; \
userstart: \
init
diff --git a/v/vm.c b/v/vm.c
index 277b67c..178d90b 100644
--- a/v/vm.c
+++ b/v/vm.c
@@ -136,8 +136,14 @@ static void evict(unsigned long addr)
}
}
+extern int pf_filter(uintptr_t addr, uintptr_t *pte, int *copy);
+extern int trap_filter(trapframe_t *tf);
+
void handle_fault(uintptr_t addr, uintptr_t cause)
{
+ uintptr_t filter_encodings = 0;
+ int copy_page = 1;
+
assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
addr = addr/PGSIZE*PGSIZE;
@@ -159,6 +165,11 @@ void handle_fault(uintptr_t addr, uintptr_t cause)
freelist_tail = 0;
uintptr_t new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X;
+
+ if (pf_filter(addr, &filter_encodings, &copy_page)) {
+ new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | filter_encodings;
+ }
+
user_llpt[addr/PGSIZE] = new_pte | PTE_A | PTE_D;
flush_page(addr);
@@ -177,6 +188,10 @@ void handle_fault(uintptr_t addr, uintptr_t cause)
void handle_trap(trapframe_t* tf)
{
+ if (trap_filter(tf)) {
+ pop_tf(tf);
+ }
+
if (tf->cause == CAUSE_USER_ECALL)
{
int n = tf->gpr[10];