Signed-off-by: Alistair Francis <alistair.fran...@wdc.com> --- target/riscv/cpu_helper.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 41d4368128..afb3e8579e 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -38,12 +38,27 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env) { target_ulong mstatus_mie = get_field(*env->mstatus, MSTATUS_MIE); target_ulong mstatus_sie = get_field(*env->mstatus, MSTATUS_SIE); - target_ulong pending = atomic_read(env->mip) & *env->mie; - target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && mstatus_mie); - target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && mstatus_sie); + target_ulong vsstatus_sie = get_field(env->mstatus_novirt, MSTATUS_SIE); + + target_ulong pending = atomic_read(&env->mip) & *env->mie; + target_ulong hspending = atomic_read(&env->mip_novirt) & env->mie_novirt; + + target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && mstatus_mie); + target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && mstatus_sie); + target_ulong vsie = env->priv < PRV_S || (env->priv == PRV_S && vsstatus_sie); + target_ulong irqs = (pending & ~env->mideleg & -mie) | (pending & env->mideleg & -sie); + if (riscv_cpu_virt_enabled(env)) { + target_ulong pending_hs_irq = hspending & -vsie; + + if (pending_hs_irq) { + riscv_cpu_set_force_hs_excep(env, FORCE_HS_EXCEP); + return ctz64(pending_hs_irq); + } + } + if (irqs) { return ctz64(irqs); /* since non-zero */ } else { -- 2.22.0