Commit 175afdb0d1 for qemu.org
commit 175afdb0d155a7429e2ac0c568c1c807953444a4
Author: Alistair Francis <alistair.francis@wdc.com>
Date: Thu Apr 16 09:37:39 2026 +1000
target/riscv: Don't OR mip.SEIP when mvien is one
The RISC-V spec states that
"""
But when bit 9 of mvien is one, bit SEIP in mip is read-only and does
not include the value of bit 9 of mvip. Rather, the value of mip.SEIP
is simply the supervisor external interrupt signal from the hart’s
external interrupt controller (APLIC or IMSIC).
"""
As such let's mark the mip.SEIP in rmw_mip64().
Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/2828
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Message-ID: <20260415233740.3027321-4-alistair.francis@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 80727aa81e..da366cf562 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3728,6 +3728,14 @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
uint64_t old_mip, mask = wr_mask & delegable_ints;
uint32_t gin;
+ /*
+ * When mvien[9]=1, mip.SEIP is read-only and reflects only
+ * the external interrupt signal from the interrupt controller.
+ */
+ if (env->mvien & MIP_SEIP) {
+ mask &= ~MIP_SEIP;
+ }
+
if (mask & MIP_SEIP) {
env->software_seip = new_val & MIP_SEIP;
new_val |= env->external_seip * MIP_SEIP;