summaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorPrashanth Mundkur2018-04-26 17:36:22 -0700
committerPrashanth Mundkur2018-04-26 17:42:20 -0700
commit5c09a560c7d8b1824e7898e5335a57960c6fc879 (patch)
tree19d13d20e38c26cd1fc0f97b5cb3f68e46ec4683 /riscv
parent1fabc6c20acc57844e088cea5a074d8703411fde (diff)
Ensure riscv interrupt delegation does not reduce current privilege.
Diffstat (limited to 'riscv')
-rw-r--r--riscv/riscv_sys.sail7
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()