From 982f93f5c55f6e7931c01afb082f5ca42cffddab Mon Sep 17 00:00:00 2001 From: deepak0414 Date: Thu, 2 Feb 2023 12:51:50 -0800 Subject: env: trap and page fault filter mechanism (#40) Certain tests (particularly negative) may require a fault to occur. However in order to pass the tests, page fault and traps must return back to the tests. This patch add support for page fault and trap filtering in env. Signed-off-by: Deepak Gupta --- p/riscv_test.h | 2 ++ v/riscv_test.h | 10 ++++++++++ v/vm.c | 15 +++++++++++++++ 3 files changed, 27 insertions(+) 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, ©_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]; -- cgit v1.1