From: Fabiano Rosas <farosas@linux.ibm.com>
To: Daniel Henrique Barboza <danielhb413@gmail.com>, qemu-devel@nongnu.org
Cc: Daniel Henrique Barboza <danielhb413@gmail.com>,
qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au
Subject: Re: [PATCH v10 3/3] target/ppc: EBB exception implementation
Date: Tue, 08 Feb 2022 20:20:14 -0300 [thread overview]
Message-ID: <87zgn1j68h.fsf@linux.ibm.com> (raw)
In-Reply-To: <20220208194838.169257-4-danielhb413@gmail.com>
Daniel Henrique Barboza <danielhb413@gmail.com> writes:
> This patch adds the EBB exception support that are triggered by
> Performance Monitor alerts. This happens when a Performance Monitor
> alert occurs and MMCR0_EBE, BESCR_PME and BESCR_GE are set.
>
> A 'ebb_excp_enabled' helper is called at the end of fire_PMC_interrupt()
> to fire the EBB exception, checking for FSCR and HFSCR support
> beforehand.
>
> In ppc_hw_interrupt() the generated EBB exception will be taken only if
> running in problem state and with BESCR_GE set. The check for BESCR_GE
> bit in this step is needed to avoid race conditions where we take an
> EBB, while the previous EBB is still inflight (BESCR_GE cleared), and
> SPR_EBBHR is not set yet. In this case we'll branch to env->nip = 0 and the
> guest will crash. The Linux kernel selftest 'lost_exception_test' is an
> example where this racing will occur.
>
> The code in powerpc_excp_books() is the default EBB handling described
> in the PowerISA v3.1: clear BESCR_GE, set BESCR_PMEO, save env->nip in
> SPR_EBBRR and redirect the execution to the address pointed by
> SPR_EBBHR. The already implemented 'rbebb' instruction is then able to
> return from the EBB by retrieving the NIP in SPR_EBBRR.
>
> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Now that BookS code is separate from the other CPUs, let me leave this
here:
Why do we have "interrupts" before "exceptions"? As in ppc_hw_interrupt
calling powerpc_excp.
If anyone has a consistent mental model on how this that they could
share I'd appreciate it.
Now onto the patch:
> ---
> target/ppc/excp_helper.c | 51 +++++++++++++++++++++++++++++++++++++---
> target/ppc/helper.h | 1 +
> target/ppc/power8-pmu.c | 12 ++++++++--
> 3 files changed, 59 insertions(+), 5 deletions(-)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 8a49a4ab90..2a95cec39e 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -19,6 +19,7 @@
> #include "qemu/osdep.h"
> #include "qemu/main-loop.h"
> #include "cpu.h"
> +#include "hw/ppc/ppc.h"
> #include "exec/exec-all.h"
> #include "internal.h"
> #include "helper_regs.h"
> @@ -990,8 +991,22 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
> new_msr |= (target_ulong)MSR_HVB;
> new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> break;
> - case POWERPC_EXCP_THERM: /* Thermal interrupt */
> case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
We would need some way to tell apart EBB from other Performance Monitor
interrupts here. Unless you want to leave that to the next person that
looks at Performance Monitor interrupts.
> + env->spr[SPR_BESCR] &= ~BESCR_GE;
> + env->spr[SPR_BESCR] |= BESCR_PMEO;
> +
> + /*
> + * Save NIP for rfebb insn in SPR_EBBRR. Next nip is
> + * stored in the EBB Handler SPR_EBBHR.
> + */
> + env->spr[SPR_EBBRR] = env->nip;
> + powerpc_set_excp_state(cpu, env->spr[SPR_EBBHR], env->msr);
> +
> + /*
> + * This exception is handled in userspace. No need to proceed.
> + */
> + return;
> + case POWERPC_EXCP_THERM: /* Thermal interrupt */
> case POWERPC_EXCP_VPUA: /* Vector assist exception */
> case POWERPC_EXCP_MAINT: /* Maintenance exception */
> case POWERPC_EXCP_SDOOR: /* Doorbell interrupt */
> @@ -1671,8 +1686,14 @@ static void ppc_hw_interrupt(CPUPPCState *env)
> return;
> }
> if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
> - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
> - powerpc_excp(cpu, POWERPC_EXCP_PERFM);
> + /*
> + * PERFM EBB must be taken in problem state and
> + * with BESCR_GE set.
> + */
> + if (msr_pr == 1 && env->spr[SPR_BESCR] & BESCR_GE) {
> + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
> + powerpc_excp(cpu, POWERPC_EXCP_PERFM);
> + }
This is masking other Performance Interrupts (for all CPUs). Can we move
these checks into the helper?
> return;
> }
> /* Thermal interrupt */
> @@ -1915,6 +1936,30 @@ void helper_rfebb(CPUPPCState *env, target_ulong s)
> env->spr[SPR_BESCR] &= ~BESCR_GE;
> }
> }
> +
> +void helper_ebb_perfm_int(CPUPPCState *env)
> +{
> + PowerPCCPU *cpu = env_archcpu(env);
> +
> + /*
> + * FSCR_EBB and FSCR_IC_EBB are the same bits used with
> + * HFSCR.
> + */
> + helper_fscr_facility_check(env, FSCR_EBB, 0, FSCR_IC_EBB);
> + helper_hfscr_facility_check(env, FSCR_EBB, "EBB", FSCR_IC_EBB);
> +
> + /*
> + * Setting "env->pending_interrupts |= 1 << PPC_INTERRUPT_PERFM"
> + * instead of calling "ppc_set_irq()"" works in most cases, but under
> + * certain race conditions (e.g. lost_exception_test EBB kernel
> + * selftest) this hits an assert when dealing with the BQL:
> + *
> + * tcg_handle_interrupt: assertion failed: (qemu_mutex_iothread_locked())
> + *
> + * We ended up using ppc_set_irq() because it handles the BQL.
> + */
> + ppc_set_irq(cpu, PPC_INTERRUPT_PERFM, 1);
> +}
> #endif
>
> /*****************************************************************************/
> diff --git a/target/ppc/helper.h b/target/ppc/helper.h
> index f2e5060910..bb26da6176 100644
> --- a/target/ppc/helper.h
> +++ b/target/ppc/helper.h
> @@ -19,6 +19,7 @@ DEF_HELPER_1(rfid, void, env)
> DEF_HELPER_1(rfscv, void, env)
> DEF_HELPER_1(hrfid, void, env)
> DEF_HELPER_2(rfebb, void, env, tl)
> +DEF_HELPER_1(ebb_perfm_int, void, env)
> DEF_HELPER_2(store_lpcr, void, env, tl)
> DEF_HELPER_2(store_pcr, void, env, tl)
> DEF_HELPER_2(store_mmcr0, void, env, tl)
> diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
> index d245663158..41409e609f 100644
> --- a/target/ppc/power8-pmu.c
> +++ b/target/ppc/power8-pmu.c
> @@ -281,6 +281,13 @@ void helper_store_pmc(CPUPPCState *env, uint32_t sprn, uint64_t value)
> pmc_update_overflow_timer(env, sprn);
> }
>
> +static bool ebb_excp_enabled(CPUPPCState *env)
> +{
> + return env->spr[SPR_POWER_MMCR0] & MMCR0_EBE &&
> + env->spr[SPR_BESCR] & BESCR_PME &&
> + env->spr[SPR_BESCR] & BESCR_GE;
> +}
> +
> static void fire_PMC_interrupt(PowerPCCPU *cpu)
> {
> CPUPPCState *env = &cpu->env;
> @@ -307,8 +314,9 @@ static void fire_PMC_interrupt(PowerPCCPU *cpu)
> env->spr[SPR_POWER_MMCR0] |= MMCR0_PMAO;
> }
>
> - /* PMC interrupt not implemented yet */
> - return;
> + if (ebb_excp_enabled(env)) {
> + helper_ebb_perfm_int(env);
> + }
> }
>
> /* This helper assumes that the PMC is running. */
next prev parent reply other threads:[~2022-02-08 23:23 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-08 19:48 [PATCH v10 0/3] PMU-EBB support for PPC64 TCG Daniel Henrique Barboza
2022-02-08 19:48 ` [PATCH v10 1/3] target/ppc: fix indent of function parameters Daniel Henrique Barboza
2022-02-10 2:20 ` David Gibson
2022-02-08 19:48 ` [PATCH v10 2/3] target/ppc: finalize pre-EBB PMU logic Daniel Henrique Barboza
2022-02-08 19:48 ` [PATCH v10 3/3] target/ppc: EBB exception implementation Daniel Henrique Barboza
2022-02-08 23:20 ` Fabiano Rosas [this message]
2022-02-09 12:40 ` Daniel Henrique Barboza
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=87zgn1j68h.fsf@linux.ibm.com \
--to=farosas@linux.ibm.com \
--cc=clg@kaod.org \
--cc=danielhb413@gmail.com \
--cc=david@gibson.dropbear.id.au \
--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.