diff options
| author | Prashanth Mundkur | 2018-04-26 17:36:22 -0700 |
|---|---|---|
| committer | Prashanth Mundkur | 2018-04-26 17:42:20 -0700 |
| commit | 5c09a560c7d8b1824e7898e5335a57960c6fc879 (patch) | |
| tree | 19d13d20e38c26cd1fc0f97b5cb3f68e46ec4683 /riscv | |
| parent | 1fabc6c20acc57844e088cea5a074d8703411fde (diff) | |
Ensure riscv interrupt delegation does not reduce current privilege.
Diffstat (limited to 'riscv')
| -rw-r--r-- | riscv/riscv_sys.sail | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/riscv/riscv_sys.sail b/riscv/riscv_sys.sail index ab15604b..e9428448 100644 --- a/riscv/riscv_sys.sail +++ b/riscv/riscv_sys.sail @@ -564,7 +564,11 @@ function findPendingInterrupt(ip : xlenbits) -> option(InterruptType) = { } /* Examines current M-mode interrupt state and returns an interrupt to be - * handled, and the privilege it should be handled at. + * handled, and the privilege it should be handled at. Interrupts are + * dispatched in order of decreasing privilege, while ensuring that the + * resulting privilege level is not reduced; i.e. delegated interrupts to + * lower privileges are effectively masked until control returns to them. + * * For now, it assumes 'S' and no 'N' extension, which is the common case. */ function curInterrupt(pend : Minterrupts, enbl : Minterrupts, delg : Minterrupts) @@ -580,6 +584,7 @@ function curInterrupt(pend : Minterrupts, enbl : Minterrupts, delg : Minterrupts None() => None() } else if (mstatus.SIE() == true) & (eff_sip != EXTZ(0b0)) + & (cur_privilege == Supervisor | cur_privilege == User) then match findPendingInterrupt(eff_sip) { Some(i) => let r = (i, Supervisor) in Some(r), None() => None() |
