RISCV: Illegal instruction delegated to VS mode sets the wrong vscause value Description of problem: When delegating an illegal instruction exception caused in VS-mode to VS-mode, the vscause value for an illegal instruction is set incorrectly. Steps to reproduce: 1. Delegate 2(,6,10) in medeleg and hedeleg. 2. Enter VS-mode 3. Cause an illegal instruction fault, cause 6 can't happen in QEMU since there is misaligned support and 10 can't be delegated to VS mode. 4. The (v)scause CSR is then set to 1, i.e. instruction access fault which isn't correct. I have located the issue in the code @ cpu_helper.c:1703 ``` if ((cause == IRQ_VS_TIMER || cause == IRQ_VS_SOFT || cause == IRQ_VS_EXT)) { cause = cause - 1; } ``` The if statement should include a check for the async otherwise the cause shouldn't be altered. The patch I propose is simply to **and** the current statement with async. ``` if (async & (cause == IRQ_VS_TIMER || cause == IRQ_VS_SOFT || cause == IRQ_VS_EXT)) { cause = cause - 1; } ``` Additional information: Log where the incorrect cause is set. Note this line: `DEBUG: [src/trap_handling.c: 105] Instruction access fault exception: SEPC = 0x80008850, STVAL = 0x0` ``` TRACE: [src/hart_ctrl.c:35] STARTING CPU 0 TRACE: [src/page_tables.c:343] Setting up page tables between 0x80000000 -> 0x81c00000 TRACE: [src/page_tables.c:359] Setting up page tables between 0x81c01000 -> 0x81c02000 TRACE: [src/page_tables.c:374] Setting up page tables for UART 0x10000000 TRACE: [src/page_tables.c:386] Setting up page tables for CLINT 0x2000000 DEBUG: [src/page_tables.c: 406] Mapping IMISIC 0x24000000 DEBUG: [src/page_tables.c: 406] Mapping IMISIC 0x28000000 DEBUG: [src/page_tables.c: 406] Mapping IMISIC 0x28001000 TRACE: [src/main.c:32] STARTING HYPERVISOR TESTS DEBUG: [src/util_fn.c:1175] pmpcfg0 = 0x00000000000f000f DEBUG: [src/util_fn.c:1176] pmpcfg2 = 0x0000000000000000 PMP Entry : 0 Low Address : 0x0 High Address : 0x81c00000 Address Range : 0x0 - 0x81c00000 Mode : TOR Executable : Yes Writable : Yes Readable : Yes Locked : No -------------------------------------- PMP Entry : 2 Low Address : 0x82000000 High Address : 0xfffffffffffffffc Address Range : 0x82000000 - 0xfffffffffffffffc Mode : TOR Executable : Yes Writable : Yes Readable : Yes Locked : No -------------------------------------- DEBUG: [src/trap_trigger.c: 85] Switching mode to VS riscv_cpu_do_interrupt: hart:0, async:0, cause:0000000000000002, epc:0x00000000800062a4, tval:0x0000000000000000, desc=illegal_instruction DEBUG: [src/trap_handling.c: 102] Illegal instruction exception: MEPC = 0x800062a4, MTVAL = 0x0 TRACE: [src/util_fn.c:374] Done switching mode riscv_cpu_do_interrupt: hart:0, async:0, cause:0000000000000002, epc:0x0000000080008850, tval:0x0000000000000000, desc=illegal_instruction DEBUG: [src/trap_handling.c: 105] Instruction access fault exception: SEPC = 0x80008850, STVAL = 0x0 ERROR: [src/trap_handling.c:158] The following assert failed: mask_cause == cause2check mask_cause = 0x1