Skip to content

Commit

Permalink
priv: fix wrong behavior of sinval.vma (OpenXiangShan#300)
Browse files Browse the repository at this point in the history
There is two bugs in this code:
* If `!srnctl->svinval`, sinval.vma would throw a Virtual Instruction exception.
  It should throw an Illegal Instruction exception instead.
* If exec sinval.vma in U-mode, it would not throw an exception.
  It should throw a Illegal Instruction exception instead.
  • Loading branch information
cebarobot committed Apr 9, 2024
1 parent 41c3d6e commit 3dd30c6
Showing 1 changed file with 15 additions and 9 deletions.
24 changes: 15 additions & 9 deletions src/isa/riscv64/system/priv.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,17 +780,23 @@ static word_t priv_instr(uint32_t op, const rtlreg_t *src) {
#ifdef CONFIG_RV_SVINVAL
case 0x0b: // sinval.vma
#ifdef CONFIG_RVH
if(cpu.v && cpu.mode == MODE_U) longjmp_exception(EX_VI);
if((cpu.v && cpu.mode == MODE_S && hstatus->vtvm == 1) ||
!srnctl->svinval){
if (!srnctl->svinval) { // srnctl contrl extension enable or not
longjmp_exception(EX_II);
} else if (cpu.v == 0 && cpu.mode == MODE_U) {
longjmp_exception(EX_II);
} else if (cpu.v == 0 && cpu.mode == MODE_S && mstatus->tvm == 1){
longjmp_exception(EX_II);
} else if (cpu.v == 1 && cpu.mode == MODE_U) {
longjmp_exception(EX_VI);
}else if ((cpu.v == 0 && cpu.mode == MODE_S && mstatus->tvm == 1) ||
!srnctl->svinval){
longjmp_exception(EX_II);
}
} else if (cpu.v == 1 && cpu.mode == MODE_S && hstatus->vtvm == 1) {
longjmp_exception(EX_VI);
}
#else
if ((cpu.mode == MODE_S && mstatus->tvm == 1) ||
!srnctl->svinval) { // srnctl contrl extension enable or not
if (!srnctl->svinval) { // srnctl contrl extension enable or not
longjmp_exception(EX_II);
} else if (cpu.mode == MODE_U) {
longjmp_exception(EX_II);
} else if (cpu.mode == MODE_S && mstatus->tvm == 1) {
longjmp_exception(EX_II);
}
#endif // CONFIG_RVH
Expand Down

0 comments on commit 3dd30c6

Please sign in to comment.