Signed-off-by: Alistair Francis <alistair.fran...@wdc.com> Reviewed-by: Palmer Dabbelt <pal...@sifive.com> --- target/riscv/cpu_helper.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 12a10e8679..bb4557df16 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -39,12 +39,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 vsstatus_sie = get_field(env->mstatus_novirt, MSTATUS_SIE); + target_ulong pending = 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 hspending = 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.23.0