diff mbox series

[19/19] target/ppc: Add support for LPCR:HEIC on POWER9

Message ID 20190128094625.4428-20-clg@kaod.org (mailing list archive)
State New, archived
Headers show
Series ppc: support for the baremetal XIVE interrupt controller (POWER9) | expand

Commit Message

Cédric Le Goater Jan. 28, 2019, 9:46 a.m. UTC
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This controls whether the External Interrupt (0x500) can be
delivered to the hypervisor or not.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target/ppc/excp_helper.c        | 5 ++++-
 target/ppc/translate_init.inc.c | 5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

Comments

David Gibson Feb. 13, 2019, 5:18 a.m. UTC | #1
On Mon, Jan 28, 2019 at 10:46:25AM +0100, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> This controls whether the External Interrupt (0x500) can be
> delivered to the hypervisor or not.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  target/ppc/excp_helper.c        | 5 ++++-
>  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 d171a5eb6236..39bedbb11db0 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 7f25215f0192..63ded33ea7ea 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)) &&
diff mbox series

Patch

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index d171a5eb6236..39bedbb11db0 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 7f25215f0192..63ded33ea7ea 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)) &&