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>
Alistair Francis committed
Apr 16, 2026 at 09:37 UTC
175afdb0d155a7429e2ac0c568c1c807953444a4
1 file changed
+8
target/riscv/csr.c
+8
@@ -3728,6 +3728,14 @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
3728
uint64_t old_mip, mask = wr_mask & delegable_ints;
3729
uint32_t gin;
3730
3731
+ /*
3732
+ * When mvien[9]=1, mip.SEIP is read-only and reflects only
3733
+ * the external interrupt signal from the interrupt controller.
3734
+ */
3735
+ if (env->mvien & MIP_SEIP) {
3736
+ mask &= ~MIP_SEIP;
3737
+ }
3738
+
3739
if (mask & MIP_SEIP) {
3740
env->software_seip = new_val & MIP_SEIP;
3741
new_val |= env->external_seip * MIP_SEIP;