diff options
Diffstat (limited to 'target/ppc')
-rw-r--r-- | target/ppc/excp_helper.c | 5 | ||||
-rw-r--r-- | target/ppc/translate_init.inc.c | 5 |
2 files changed, 8 insertions, 2 deletions
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index d171a5eb62..39bedbb11d 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -827,7 +827,10 @@ static void ppc_hw_interrupt(CPUPPCState *env) /* External interrupt can ignore MSR:EE under some circumstances */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); - if (async_deliver || (env->has_hv_mode && msr_hv == 0 && !lpes0)) { + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + /* HEIC blocks delivery to the hypervisor */ + if ((async_deliver && !(heic && msr_hv && !msr_pr)) || + (env->has_hv_mode && msr_hv == 0 && !lpes0)) { powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL); return; } diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 9d84164915..965c5273a6 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -8823,7 +8823,10 @@ static bool cpu_has_work_POWER9(CPUState *cs) /* External Exception */ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && (env->spr[SPR_LPCR] & LPCR_EEE)) { - return true; + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + if (heic == 0 || !msr_hv || msr_pr) { + return true; + } } /* Decrementer Exception */ if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && |