All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fabiano Rosas <farosas@linux.ibm.com>
To: Matheus Ferst <matheus.ferst@eldorado.org.br>,
	qemu-devel@nongnu.org, qemu-ppc@nongnu.org
Cc: clg@kaod.org, danielhb413@gmail.com, david@gibson.dropbear.id.au,
	groug@kaod.org, fbarrat@linux.ibm.com, alex.bennee@linaro.org,
	Matheus Ferst <matheus.ferst@eldorado.org.br>
Subject: Re: [RFC PATCH 05/13] target/ppc: create an interrupt masking method for POWER9/POWER10
Date: Mon, 15 Aug 2022 19:39:07 -0300	[thread overview]
Message-ID: <87y1vp5dys.fsf@linux.ibm.com> (raw)
In-Reply-To: <20220815162020.2420093-6-matheus.ferst@eldorado.org.br>

Matheus Ferst <matheus.ferst@eldorado.org.br> writes:

> Create an interrupt masking method for the POWER9 and POWER10
> processors. The new method is based on cpu_has_work_POWER{9,10} and
> ppc_pending_interrupt_legacy.
>
> Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
> ---
>  target/ppc/excp_helper.c | 160 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 160 insertions(+)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 59981efd16..2ca6a917b2 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -1678,6 +1678,163 @@ void ppc_cpu_do_interrupt(CPUState *cs)
>      powerpc_excp(cpu, cs->exception_index);
>  }
>  
> +static int ppc_pending_interrupt_p9(CPUPPCState *env)
> +{
> +    CPUState *cs = env_cpu(env);
> +    bool async_deliver = false;

I would suggest this to disentangle the PM stuff from MSR_EE:

  if (cs->halted) {
     if (env->spr[SPR_PSSCR] & PSSCR_EC) {
         return p9_interrupt_powersave();
     } else {
         /*
          * If EC is clear, any system-caused exception exits
          * power-saving mode.
          */
          ignore_msr_ee = true;
     }
  }
  
  RESET    (keep it duplicated)
  MCHECK
  
  if (!MSR_EE && !ignore_msr_ee) {
     return 0;
  }
  
  MSR_EE interrupts
---

> +
> +    /* External reset */
> +    if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
> +        return PPC_INTERRUPT_RESET;
> +    }
> +
> +    if (cs->halted) {
> +        uint64_t psscr = env->spr[SPR_PSSCR];
> +
> +        if (!(psscr & PSSCR_EC)) {
> +            /* If EC is clear, return any system-caused interrupt */
> +            async_deliver = true;

This doesn't look correct, look at what the ISA says:

  EC=0
  
  Hardware will exit power-saving mode when the exception corresponding
  to any system-caused interrupt occurs. Power-saving mode is exited
  either at the instruction following the stop (if MSR_EE=0) or in the
  corresponding interrupt handler (if MSR_EE=1).

So with MSR_EE=0 we should *not* deliver any interrupts, but return to NIP+4.

> +        } else {
> +            /* External Exception */
> +            if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
> +                (env->spr[SPR_LPCR] & LPCR_EEE)) {
> +                bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
> +                if (!heic || !FIELD_EX64_HV(env->msr) ||
> +                    FIELD_EX64(env->msr, MSR, PR)) {
> +                    return PPC_INTERRUPT_EXT;
> +                }
> +            }
> +            /* Decrementer Exception */
> +            if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
> +                (env->spr[SPR_LPCR] & LPCR_DEE)) {
> +                return PPC_INTERRUPT_DECR;
> +            }
> +            /* Machine Check or Hypervisor Maintenance Exception */
> +            if (env->spr[SPR_LPCR] & LPCR_OEE) {
> +                if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
> +                    return PPC_INTERRUPT_MCK;
> +                }
> +                if (env->pending_interrupts & PPC_INTERRUPT_HMI) {
> +                    return PPC_INTERRUPT_HMI;
> +                }
> +            }
> +            /* Privileged Doorbell Exception */
> +            if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
> +                (env->spr[SPR_LPCR] & LPCR_PDEE)) {
> +                return PPC_INTERRUPT_DOORBELL;
> +            }
> +            /* Hypervisor Doorbell Exception */
> +            if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
> +                (env->spr[SPR_LPCR] & LPCR_HDEE)) {
> +                return PPC_INTERRUPT_HDOORBELL;
> +            }
> +            /* Hypervisor virtualization exception */
> +            if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) &&
> +                (env->spr[SPR_LPCR] & LPCR_HVEE)) {
> +                return PPC_INTERRUPT_HVIRT;
> +            }
> +            return 0;
> +        }
> +    }
> +
> +    /* Machine check exception */
> +    if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
> +        return PPC_INTERRUPT_MCK;
> +    }
> +
> +    /*
> +     * For interrupts that gate on MSR:EE, we need to do something a
> +     * bit more subtle, as we need to let them through even when EE is
> +     * clear when coming out of some power management states (in order
> +     * for them to become a 0x100).
> +     */
> +    async_deliver |= FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset;
> +
> +    /* Hypervisor decrementer exception */
> +    if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
> +        /* LPCR will be clear when not supported so this will work */
> +        bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
> +        if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) {
> +            /* HDEC clears on delivery */
> +            return PPC_INTERRUPT_HDECR;
> +        }
> +    }
> +
> +    /* Hypervisor virtualization interrupt */
> +    if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) {
> +        /* LPCR will be clear when not supported so this will work */
> +        bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE);
> +        if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) {
> +            return PPC_INTERRUPT_HVIRT;
> +        }
> +    }
> +
> +    /* External interrupt can ignore MSR:EE under some circumstances */
> +    if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
> +        bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
> +        bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
> +        /* HEIC blocks delivery to the hypervisor */
> +        if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) &&
> +            !FIELD_EX64(env->msr, MSR, PR))) ||
> +            (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) {
> +            return PPC_INTERRUPT_EXT;
> +        }
> +    }
> +    if (FIELD_EX64(env->msr, MSR, CE)) {
> +        /* External critical interrupt */
> +        if (env->pending_interrupts & PPC_INTERRUPT_CEXT) {
> +            return PPC_INTERRUPT_CEXT;
> +        }
> +    }
> +    if (async_deliver != 0) {
> +        /* Watchdog timer on embedded PowerPC */
> +        if (env->pending_interrupts & PPC_INTERRUPT_WDT) {
> +            return PPC_INTERRUPT_WDT;
> +        }
> +        if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) {
> +            return PPC_INTERRUPT_CDOORBELL;
> +        }
> +        /* Fixed interval timer on embedded PowerPC */
> +        if (env->pending_interrupts & PPC_INTERRUPT_FIT) {
> +            return PPC_INTERRUPT_FIT;
> +        }
> +        /* Programmable interval timer on embedded PowerPC */
> +        if (env->pending_interrupts & PPC_INTERRUPT_PIT) {
> +            return PPC_INTERRUPT_PIT;
> +        }
> +        /* Decrementer exception */
> +        if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
> +            return PPC_INTERRUPT_DECR;
> +        }
> +        if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
> +            return PPC_INTERRUPT_DOORBELL;
> +        }
> +        if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
> +            return PPC_INTERRUPT_HDOORBELL;
> +        }
> +        if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
> +            return PPC_INTERRUPT_PERFM;
> +        }
> +        /* Thermal interrupt */
> +        if (env->pending_interrupts & PPC_INTERRUPT_THERM) {
> +            return PPC_INTERRUPT_THERM;
> +        }
> +        /* EBB exception */
> +        if (env->pending_interrupts & PPC_INTERRUPT_EBB) {
> +            /*
> +             * EBB exception must be taken in problem state and
> +             * with BESCR_GE set.
> +             */
> +            if (FIELD_EX64(env->msr, MSR, PR) &&
> +                (env->spr[SPR_BESCR] & BESCR_GE)) {
> +                return PPC_INTERRUPT_EBB;
> +            }
> +        }
> +    }
> +
> +    return 0;
> +}
> +
>  static int ppc_pending_interrupt_legacy(CPUPPCState *env)
>  {
>      bool async_deliver;
> @@ -1793,6 +1950,9 @@ static int ppc_pending_interrupt_legacy(CPUPPCState *env)
>  static int ppc_pending_interrupt(CPUPPCState *env)
>  {
>      switch (env->excp_model) {
> +    case POWERPC_EXCP_POWER9:
> +    case POWERPC_EXCP_POWER10:
> +        return ppc_pending_interrupt_p9(env);
>      default:
>          return ppc_pending_interrupt_legacy(env);
>      }


  reply	other threads:[~2022-08-15 22:40 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-15 16:20 [RFC PATCH 00/13] PowerPC interrupt rework Matheus Ferst
2022-08-15 16:20 ` [RFC PATCH 01/13] target/ppc: define PPC_INTERRUPT_* values directly Matheus Ferst
2022-08-18  2:18   ` David Gibson
2022-08-15 16:20 ` [RFC PATCH 02/13] target/ppc: always use ppc_set_irq to set env->pending_interrupts Matheus Ferst
2022-08-15 16:20 ` [RFC PATCH 03/13] target/ppc: move interrupt masking out of ppc_hw_interrupt Matheus Ferst
2022-08-15 20:09   ` Fabiano Rosas
2022-08-17 13:42     ` Matheus K. Ferst
2022-08-19 14:18       ` Fabiano Rosas
2022-08-15 16:20 ` [RFC PATCH 04/13] target/ppc: prepare to split ppc_interrupt_pending by excp_model Matheus Ferst
2022-08-15 20:25   ` Fabiano Rosas
2022-08-17 13:42     ` Matheus K. Ferst
2022-08-15 16:20 ` [RFC PATCH 05/13] target/ppc: create an interrupt masking method for POWER9/POWER10 Matheus Ferst
2022-08-15 22:39   ` Fabiano Rosas [this message]
2022-08-17 13:43     ` Matheus K. Ferst
2022-08-15 16:20 ` [RFC PATCH 06/13] target/ppc: remove embedded interrupts from ppc_pending_interrupt_p9 Matheus Ferst
2022-08-15 21:23   ` Fabiano Rosas
2022-08-17 13:44     ` Matheus K. Ferst
2022-08-19 16:04       ` Fabiano Rosas
2022-08-15 16:20 ` [RFC PATCH 07/13] target/ppc: create an interrupt masking method for POWER8 Matheus Ferst
2022-08-15 16:20 ` [RFC PATCH 08/13] target/ppc: remove unused interrupts from ppc_pending_interrupt_p8 Matheus Ferst
2022-08-15 16:20 ` [RFC PATCH 09/13] target/ppc: create an interrupt masking method for POWER7 Matheus Ferst
2022-08-15 16:20 ` [RFC PATCH 10/13] target/ppc: remove unused interrupts from ppc_pending_interrupt_p7 Matheus Ferst
2022-08-15 16:20 ` [RFC PATCH 11/13] target/ppc: remove ppc_store_lpcr from CONFIG_USER_ONLY builds Matheus Ferst
2022-08-15 16:20 ` [RFC PATCH 12/13] target/ppc: introduce ppc_maybe_interrupt Matheus Ferst
2022-08-15 16:20 ` [RFC PATCH 13/13] target/ppc: unify cpu->has_work based on cs->interrupt_request Matheus Ferst
2022-08-15 20:02 ` [RFC PATCH 00/13] PowerPC interrupt rework Cédric Le Goater
2022-08-17 13:42   ` Matheus K. Ferst

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y1vp5dys.fsf@linux.ibm.com \
    --to=farosas@linux.ibm.com \
    --cc=alex.bennee@linaro.org \
    --cc=clg@kaod.org \
    --cc=danielhb413@gmail.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=fbarrat@linux.ibm.com \
    --cc=groug@kaod.org \
    --cc=matheus.ferst@eldorado.org.br \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.