summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeepak0414 <deepak0414@users.noreply.github.com>2023-02-02 12:51:50 -0800
committerGitHub <noreply@github.com>2023-02-02 12:51:50 -0800
commit982f93f5c55f6e7931c01afb082f5ca42cffddab (patch)
tree2e4fab47bcd19bccb66d2945761f237d334245d1
parent34a1175291f9531e85afdb89aaa77707f45fc8e4 (diff)
downloadenv-982f93f5c55f6e7931c01afb082f5ca42cffddab.zip
env-982f93f5c55f6e7931c01afb082f5ca42cffddab.tar.gz
env-982f93f5c55f6e7931c01afb082f5ca42cffddab.tar.bz2
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 <debug@rivosinc.com>
-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];