From 3050ed28abbd760691d52e046830901818000ff3 Mon Sep 17 00:00:00 2001 From: Deepak Gupta Date: Thu, 13 Oct 2022 11:06:37 -0700 Subject: [PATCH 1/6] cfi_env: some changes needed in encodings and vm.c for cfi Signed-off-by: Deepak Gupta --- encoding.h | 20 ++++++++++++++++++++ v/vm.c | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/encoding.h b/encoding.h index 2aa895b..a55f3a8 100644 --- a/encoding.h +++ b/encoding.h @@ -115,6 +115,21 @@ #define SIP_SSIP MIP_SSIP #define SIP_STIP MIP_STIP +/* CFI CSR bits */ +#define CFISTATUS_MFCFIEN 0x00000001 +#define CFISTATUS_MBCFIEN 0x00000002 +#define CFISTATUS_SFCFIEN 0x00000004 +#define CFISTATUS_SBCFIEN 0x00000008 +#define CFISTATUS_UFCFIEN 0x00000010 +#define CFISTATUS_UBCFIEN 0x00000020 +#define CFISTATUS_MPELP 0x00000040 +#define CFISTATUS_SPELP 0x00000080 +#define CFISTATUS_M_MASK (CFISTATUS_MFCFIEN | CFISTATUS_MBCFIEN | CFISTATUS_SFCFIEN | \ + CFISTATUS_SBCFIEN | CFISTATUS_UFCFIEN | CFISTATUS_UBCFIEN | \ + CFISTATUS_MPELP | CFISTATUS_SPELP) +#define CFISTATUS_S_MASK (CFISTATUS_SPELP | CFISTATUS_SFCFIEN | CFISTATUS_SBCFIEN | \ + CFISTATUS_UFCFIEN | CFISTATUS_UBCFIEN) + #define PRV_U 0 #define PRV_S 1 #define PRV_H 2 @@ -1586,15 +1601,20 @@ #define CSR_USTATUS 0x0 #define CSR_UIE 0x4 #define CSR_UTVEC 0x5 +#define CSR_ULPLR 0x6 #define CSR_VSTART 0x8 #define CSR_VXSAT 0x9 #define CSR_VXRM 0xa #define CSR_VCSR 0xf +#define CSR_USSP 0x20 #define CSR_USCRATCH 0x40 #define CSR_UEPC 0x41 #define CSR_UCAUSE 0x42 #define CSR_UTVAL 0x43 #define CSR_UIP 0x44 +#define CSR_SCFISTATUS 0x10b +#define CSR_VSCFISTATUS 0x20b +#define CSR_MCFISTATUS 0x30b #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 #define CSR_INSTRET 0xc02 diff --git a/v/vm.c b/v/vm.c index 9802fb7..2bb0847 100644 --- a/v/vm.c +++ b/v/vm.c @@ -6,6 +6,8 @@ #include "riscv_test.h" +#define Sv48 + #if __riscv_xlen == 32 # define SATP_MODE_CHOICE SATP_MODE_SV32 #elif defined(Sv48) @@ -136,8 +138,15 @@ static void evict(unsigned long addr) } } -void handle_fault(uintptr_t addr, uintptr_t cause) +void handle_fault(uintptr_t addr, uintptr_t cause, trapframe_t* tf) { + cputstring("\nhandle_fault for address and PC : "); + cputstring("\n"); + printhex(addr); + cputstring("\n"); + printhex(tf->epc); + int copy_page = 1; + assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE); addr = addr/PGSIZE*PGSIZE; @@ -159,20 +168,37 @@ 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 (cause == CAUSE_STORE_PAGE_FAULT) { + //cputstring("Store fault\n"); + uintptr_t prev_sstatus = set_csr(sstatus, SSTATUS_SUM); + if (*(int*)tf->epc == 0x81c0c073) { // if it's a sspush x1 + cputstring("Store fault on sspush, new pte is: "); + new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_W; + copy_page = 0; /* shadow stack page don't need a copy */ + printhex(new_pte); + cputstring("\n"); + } + write_csr(sstatus, prev_sstatus); + } + user_llpt[addr/PGSIZE] = new_pte | PTE_A | PTE_D; flush_page(addr); assert(user_mapping[addr/PGSIZE].addr == 0); user_mapping[addr/PGSIZE] = *node; - uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM); - memcpy((void*)addr, uva2kva(addr), PGSIZE); - write_csr(sstatus, sstatus); + if (copy_page) { + uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM); + memcpy((void*)addr, uva2kva(addr), PGSIZE); + write_csr(sstatus, sstatus); + } user_llpt[addr/PGSIZE] = new_pte; flush_page(addr); asm volatile ("fence.i"); + cputstring("returning from handle_fault\n"); } void handle_trap(trapframe_t* tf) @@ -200,7 +226,7 @@ void handle_trap(trapframe_t* tf) tf->epc += 4; } else if (tf->cause == CAUSE_FETCH_PAGE_FAULT || tf->cause == CAUSE_LOAD_PAGE_FAULT || tf->cause == CAUSE_STORE_PAGE_FAULT) - handle_fault(tf->badvaddr, tf->cause); + handle_fault(tf->badvaddr, tf->cause, tf); else assert(!"unexpected exception"); @@ -225,6 +251,7 @@ static void coherence_torture() void vm_boot(uintptr_t test_addr) { + cputstring ("Entered vm_boot \n"); uint64_t random = ENTROPY; if (read_csr(mhartid) > 0) coherence_torture(); From 48fc691d777501ceca58632bd48a2cebf1decfe8 Mon Sep 17 00:00:00 2001 From: Deepak Gupta Date: Sun, 4 Dec 2022 19:40:54 -0800 Subject: [PATCH 2/6] env: cfi encoding updates, add support for filtering traps and faults Add support for filtering fault and traps in test cases. Some test cases will need such support (like shadow stack in risc-v cfi) Respective test case can implement the FILTER_TRAP or FILTER_PAGE_FAULT macros. add updates for cfi in encodings.h vm_boot updates mstatus instead of clearing of existing bits. extra_boot might have had set some bits in mstatus earlier. Signed-off-by: Deepak Gupta --- encoding.h | 41 +++++++++++++++++++++++------------------ p/riscv_test.h | 2 ++ v/riscv_test.h | 10 ++++++++++ v/vm.c | 34 +++++++++++++++++----------------- 4 files changed, 52 insertions(+), 35 deletions(-) diff --git a/encoding.h b/encoding.h index a55f3a8..9eac035 100644 --- a/encoding.h +++ b/encoding.h @@ -22,6 +22,13 @@ #define MSTATUS_TVM 0x00100000 #define MSTATUS_TW 0x00200000 #define MSTATUS_TSR 0x00400000 +#define MSTATUS_UFCFIEN 0x00800000 /* Zisslpcfi-.01 */ +#define MSTATUS_SFCFIEN 0x01000000 /* Zisslpcfi-.01 */ +#define MSTATUS_MFCFIEN 0x02000000 /* Zisslpcfi-.01 */ +#define MSTATUS_UBCFIEN 0x04000000 /* Zisslpcfi-.01 */ +#define MSTATUS_SBCFIEN 0x08000000 /* Zisslpcfi-.01 */ +#define MSTATUS_SPELP 0x10000000 /* Zisslpcfi-.01 */ +#define MSTATUS_MPELP 0x20000000 /* Zisslpcfi-.01 */ #define MSTATUS32_SD 0x80000000 #define MSTATUS_UXL 0x0000000300000000 #define MSTATUS_SXL 0x0000000C00000000 @@ -37,6 +44,11 @@ #define SSTATUS_XS 0x00018000 #define SSTATUS_SUM 0x00040000 #define SSTATUS_MXR 0x00080000 +#define SSTATUS_UFCFIEN MSTATUS_UFCFIEN /* Zisslpcfi-.01 */ +#define SSTATUS_SFCFIEN MSTATUS_SFCFIEN /* Zisslpcfi-.01 */ +#define SSTATUS_UBCFIEN MSTATUS_UBCFIEN /* Zisslpcfi-.01 */ +#define SSTATUS_SBCFIEN MSTATUS_SFCFIEN /* Zisslpcfi-.01 */ +#define SSTATUS_SPELP MSTATUS_SPELP /* Zisslpcfi-.01 */ #define SSTATUS32_SD 0x80000000 #define SSTATUS_UXL 0x0000000300000000 #define SSTATUS64_SD 0x8000000000000000 @@ -116,19 +128,12 @@ #define SIP_STIP MIP_STIP /* CFI CSR bits */ -#define CFISTATUS_MFCFIEN 0x00000001 -#define CFISTATUS_MBCFIEN 0x00000002 -#define CFISTATUS_SFCFIEN 0x00000004 -#define CFISTATUS_SBCFIEN 0x00000008 -#define CFISTATUS_UFCFIEN 0x00000010 -#define CFISTATUS_UBCFIEN 0x00000020 -#define CFISTATUS_MPELP 0x00000040 -#define CFISTATUS_SPELP 0x00000080 -#define CFISTATUS_M_MASK (CFISTATUS_MFCFIEN | CFISTATUS_MBCFIEN | CFISTATUS_SFCFIEN | \ - CFISTATUS_SBCFIEN | CFISTATUS_UFCFIEN | CFISTATUS_UBCFIEN | \ - CFISTATUS_MPELP | CFISTATUS_SPELP) -#define CFISTATUS_S_MASK (CFISTATUS_SPELP | CFISTATUS_SFCFIEN | CFISTATUS_SBCFIEN | \ - CFISTATUS_UFCFIEN | CFISTATUS_UBCFIEN) +#define CFISTATUS_M_MASK (MSTATUS_MFCFIEN | MSTATUS_SFCFIEN | MSTATUS_SBCFIEN | \ + MSTATUS_UFCFIEN | MSTATUS_UBCFIEN | MSTATUS_MPELP | \ + MSTATUS_SPELP) +#define CFISTATUS_S_MASK (SSTATUS_SFCFIEN | SSTATUS_SBCFIEN | SSTATUS_UFCFIEN | \ + SSTATUS_UBCFIEN | SSTATUS_SPELP) +#define MENVCFG_CFI (1UL<<60) #define PRV_U 0 #define PRV_S 1 @@ -1601,20 +1606,19 @@ #define CSR_USTATUS 0x0 #define CSR_UIE 0x4 #define CSR_UTVEC 0x5 -#define CSR_ULPLR 0x6 +#define CSR_LPLR 0x6 #define CSR_VSTART 0x8 #define CSR_VXSAT 0x9 #define CSR_VXRM 0xa #define CSR_VCSR 0xf -#define CSR_USSP 0x20 +#define CSR_SSP 0x20 #define CSR_USCRATCH 0x40 #define CSR_UEPC 0x41 #define CSR_UCAUSE 0x42 #define CSR_UTVAL 0x43 #define CSR_UIP 0x44 -#define CSR_SCFISTATUS 0x10b -#define CSR_VSCFISTATUS 0x20b -#define CSR_MCFISTATUS 0x30b +#define CSR_MENVCFG 0x30A +#define CSR_HENVCFG 0x60A #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 #define CSR_INSTRET 0xc02 @@ -2832,6 +2836,7 @@ DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H) DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H) DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H) DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H) +DECLARE_CSR(ussp, CSR_USSP) #endif #ifdef DECLARE_CAUSE DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) diff --git a/p/riscv_test.h b/p/riscv_test.h index a08f49e..d35d73d 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 2bb0847..e532eb6 100644 --- a/v/vm.c +++ b/v/vm.c @@ -138,6 +138,8 @@ static void evict(unsigned long addr) } } +extern int pf_filter(uintptr_t addr, uintptr_t *pte, int *copy); + void handle_fault(uintptr_t addr, uintptr_t cause, trapframe_t* tf) { cputstring("\nhandle_fault for address and PC : "); @@ -146,6 +148,7 @@ void handle_fault(uintptr_t addr, uintptr_t cause, trapframe_t* tf) cputstring("\n"); printhex(tf->epc); int copy_page = 1; + uintptr_t filter_encodings = 0; assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE); addr = addr/PGSIZE*PGSIZE; @@ -169,17 +172,9 @@ void handle_fault(uintptr_t addr, uintptr_t cause, trapframe_t* tf) uintptr_t new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X; - if (cause == CAUSE_STORE_PAGE_FAULT) { - //cputstring("Store fault\n"); - uintptr_t prev_sstatus = set_csr(sstatus, SSTATUS_SUM); - if (*(int*)tf->epc == 0x81c0c073) { // if it's a sspush x1 - cputstring("Store fault on sspush, new pte is: "); - new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_W; - copy_page = 0; /* shadow stack page don't need a copy */ - printhex(new_pte); - cputstring("\n"); - } - write_csr(sstatus, prev_sstatus); + if (pf_filter(addr, &filter_encodings, ©_page)) { + cputstring("pf_filter returned true\n"); + new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | filter_encodings; } user_llpt[addr/PGSIZE] = new_pte | PTE_A | PTE_D; @@ -215,13 +210,12 @@ void handle_trap(trapframe_t* tf) else if (tf->cause == CAUSE_ILLEGAL_INSTRUCTION) { assert(tf->epc % 4 == 0); - + int faulting_opcode = read_csr(stval); int* fssr; asm ("jal %0, 1f; fssr x0; 1:" : "=r"(fssr)); - - if (*(int*)tf->epc == *fssr) + if (faulting_opcode == *fssr) terminate(1); // FP test on non-FP hardware. "succeed." - else + else assert(!"illegal instruction"); tf->epc += 4; } @@ -253,6 +247,8 @@ void vm_boot(uintptr_t test_addr) { cputstring ("Entered vm_boot \n"); uint64_t random = ENTROPY; + unsigned int m_status = 0; + if (read_csr(mhartid) > 0) coherence_torture(); @@ -304,9 +300,13 @@ void vm_boot(uintptr_t test_addr) (1 << CAUSE_USER_ECALL) | (1 << CAUSE_FETCH_PAGE_FAULT) | (1 << CAUSE_LOAD_PAGE_FAULT) | - (1 << CAUSE_STORE_PAGE_FAULT)); + (1 << CAUSE_STORE_PAGE_FAULT) | + (1 << CAUSE_ILLEGAL_INSTRUCTION)); + + m_status = read_csr(mstatus); // FPU on; accelerator on; vector unit on - write_csr(mstatus, MSTATUS_FS | MSTATUS_XS | MSTATUS_VS); + m_status |= (MSTATUS_FS | MSTATUS_XS | MSTATUS_VS); + write_csr(mstatus, m_status); write_csr(mie, 0); random = 1 + (random % MAX_TEST_PAGES); From 29403a47c1c442d702b862f27cb1db244cf57567 Mon Sep 17 00:00:00 2001 From: Deepak Gupta Date: Tue, 6 Dec 2022 17:19:18 -0800 Subject: [PATCH 3/6] trap filter: adding trap filter support for tests handle_trap will call trap_filter. Tests can implement trap_filter to take necessary actions. Signed-off-by: Deepak Gupta --- v/vm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/v/vm.c b/v/vm.c index e532eb6..8f56c8e 100644 --- a/v/vm.c +++ b/v/vm.c @@ -139,6 +139,7 @@ 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, trapframe_t* tf) { @@ -198,6 +199,11 @@ void handle_fault(uintptr_t addr, uintptr_t cause, trapframe_t* tf) void handle_trap(trapframe_t* tf) { + if (trap_filter(tf)) { + cputstring("trap_filter returned true\n"); + pop_tf(tf); + } + if (tf->cause == CAUSE_USER_ECALL) { int n = tf->gpr[10]; From 8c0d4caf602acfd0408c321d149c5ecab8f029a1 Mon Sep 17 00:00:00 2001 From: Deepak Gupta Date: Thu, 8 Dec 2022 06:33:32 -0800 Subject: [PATCH 4/6] Exception delegation: illegal, access fault deleg to S Some of the tests require exception delegated to S mode to be handled. Delegating instruction, access (load/store) exceptions. This patch also adds support for printing which test case failed. Signed-off-by: Deepak Gupta --- v/vm.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/v/vm.c b/v/vm.c index 8f56c8e..2cc7658 100644 --- a/v/vm.c +++ b/v/vm.c @@ -200,7 +200,20 @@ void handle_fault(uintptr_t addr, uintptr_t cause, trapframe_t* tf) void handle_trap(trapframe_t* tf) { if (trap_filter(tf)) { - cputstring("trap_filter returned true\n"); + cputstring("trap_filter returned true, trap cause \n"); + printhex(tf->cause); + /* + * trap_filter returning true and + * cause being ecall means, one of the test went wrong + */ + if (tf->cause == CAUSE_USER_ECALL) { + cputstring("\nTest failed test # "); + printhex(tf->gpr[3]); /* x3 holds testnum */ + cputstring("\nEPC # "); + printhex(tf->epc); + cputstring("\nt1/x6 val "); + terminate(0xbaddeed); + } pop_tf(tf); } @@ -307,6 +320,8 @@ void vm_boot(uintptr_t test_addr) (1 << CAUSE_FETCH_PAGE_FAULT) | (1 << CAUSE_LOAD_PAGE_FAULT) | (1 << CAUSE_STORE_PAGE_FAULT) | + (1 << CAUSE_STORE_ACCESS) | + (1 << CAUSE_LOAD_ACCESS) | (1 << CAUSE_ILLEGAL_INSTRUCTION)); m_status = read_csr(mstatus); From f17ba7b0d0d9a98d1f913405a28e545fd24d46a9 Mon Sep 17 00:00:00 2001 From: Deepak Gupta Date: Wed, 1 Feb 2023 13:15:41 -0800 Subject: [PATCH 5/6] v: adding additional logs for trap filtering adding additional logs for trap filtering mechanism so that failing tests can be debugged. Signed-off-by: Deepak Gupta --- v/vm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/v/vm.c b/v/vm.c index 2cc7658..ac431a7 100644 --- a/v/vm.c +++ b/v/vm.c @@ -200,8 +200,11 @@ void handle_fault(uintptr_t addr, uintptr_t cause, trapframe_t* tf) void handle_trap(trapframe_t* tf) { if (trap_filter(tf)) { - cputstring("trap_filter returned true, trap cause \n"); + cputstring("trap_filter returned true, trap cause "); printhex(tf->cause); + cputstring("\n epc "); + printhex(tf->epc); + cputstring("\n"); /* * trap_filter returning true and * cause being ecall means, one of the test went wrong @@ -215,6 +218,13 @@ void handle_trap(trapframe_t* tf) terminate(0xbaddeed); } pop_tf(tf); + } else { + cputstring("! trap_filter returned false, trap cause "); + printhex(tf->cause); + cputstring("\n epc "); + printhex(tf->epc); + cputstring("\n"); + } if (tf->cause == CAUSE_USER_ECALL) From 3b2df448726a45f81f1e75f2d6661e912376537f Mon Sep 17 00:00:00 2001 From: Deepak Gupta Date: Mon, 26 Jun 2023 17:55:06 -0700 Subject: [PATCH 6/6] mstatus: updating status encoding bits in mstatus for cfi No separate enable/disable bits for back cfi in M/S mode. Software compiled for backward cfi will have anyways back cfi support compiled in. And if it wants to be disabled, it can anyways be disabled via menvcfg and henvcfg. Signed-off-by: Deepak Gupta --- encoding.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/encoding.h b/encoding.h index 9eac035..b0bdbf6 100644 --- a/encoding.h +++ b/encoding.h @@ -23,12 +23,9 @@ #define MSTATUS_TW 0x00200000 #define MSTATUS_TSR 0x00400000 #define MSTATUS_UFCFIEN 0x00800000 /* Zisslpcfi-.01 */ -#define MSTATUS_SFCFIEN 0x01000000 /* Zisslpcfi-.01 */ -#define MSTATUS_MFCFIEN 0x02000000 /* Zisslpcfi-.01 */ -#define MSTATUS_UBCFIEN 0x04000000 /* Zisslpcfi-.01 */ -#define MSTATUS_SBCFIEN 0x08000000 /* Zisslpcfi-.01 */ -#define MSTATUS_SPELP 0x10000000 /* Zisslpcfi-.01 */ -#define MSTATUS_MPELP 0x20000000 /* Zisslpcfi-.01 */ +#define MSTATUS_UBCFIEN 0x01000000 /* Zisslpcfi-.01 */ +#define MSTATUS_SPELP 0x02000000 /* Zisslpcfi-.01 */ +#define MSTATUS_MPELP 0x04000000 /* Zisslpcfi-.01 */ #define MSTATUS32_SD 0x80000000 #define MSTATUS_UXL 0x0000000300000000 #define MSTATUS_SXL 0x0000000C00000000