From: Daniel Henrique Barboza <danielhb413@gmail.com>
To: qemu-devel@nongnu.org
Cc: richard.henderson@linaro.org,
Daniel Henrique Barboza <danielhb413@gmail.com>,
qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au
Subject: [PATCH v2 4/5] target/ppc/power8-pmu-insn-cnt: add pmu_check_overflow()
Date: Thu, 23 Dec 2021 17:18:11 -0300 [thread overview]
Message-ID: <20211223201812.846495-5-danielhb413@gmail.com> (raw)
In-Reply-To: <20211223201812.846495-1-danielhb413@gmail.com>
pmu_check_overflow() will verify for overflow in the PMC1-5 counters,
firing a performance monitor alert if an overflow happened with the
proper MMCR0 bits set.
The alert is fired by using helper_pmu_overflow().
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
target/ppc/helper.h | 1 +
target/ppc/power8-pmu-insn-cnt.c.inc | 76 ++++++++++++++++++++++++++++
target/ppc/power8-pmu.c | 8 +++
3 files changed, 85 insertions(+)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index fb6cac38b4..4d8193caab 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -26,6 +26,7 @@ DEF_HELPER_2(store_mmcr1, void, env, tl)
DEF_HELPER_3(store_pmc, void, env, i32, i64)
DEF_HELPER_2(read_pmc, tl, env, i32)
DEF_HELPER_2(insns_inc, void, env, i32)
+DEF_HELPER_1(pmu_overflow, void, env)
#endif
DEF_HELPER_1(check_tlb_flush_local, void, env)
DEF_HELPER_1(check_tlb_flush_global, void, env)
diff --git a/target/ppc/power8-pmu-insn-cnt.c.inc b/target/ppc/power8-pmu-insn-cnt.c.inc
index a5a0d42e71..6e0e4e1270 100644
--- a/target/ppc/power8-pmu-insn-cnt.c.inc
+++ b/target/ppc/power8-pmu-insn-cnt.c.inc
@@ -18,6 +18,8 @@
#define MMCR1_PMC4_INS_CNT 0x00000002
#define MMCR1_PMC4_INS_LATCH_CNT 0x000000FA
+#define PMC_COUNTER_NEGATIVE_VAL 0x80000000UL
+
/*
* This function increments a SPR 'spr' by 'inc_val' if a given
* register 'reg' has a bitmask 'mask' set (cond = TCG_COND_EQ) or
@@ -47,6 +49,78 @@ static void inc_spr_if_cond(int reg, uint64_t mask, TCGCond cond,
tcg_temp_free(t0);
tcg_temp_free(t1);
}
+
+/*
+ * Check for overflow of PMC1-PMC5 counters and call the overflow
+ * helper in case any counter has overflown.
+ */
+static void pmu_check_overflow(DisasContext *ctx)
+{
+ TCGv t0, t1, t_pmc1, t_pmc;
+ TCGLabel *l_pmc_overflow;
+ TCGLabel *l_skip_pmc1_overflow;
+ TCGLabel *l_skip_overflow;
+ int i;
+
+ /*
+ * Check if we have overflow bits set and fire an overflow
+ * event if necessary. Skip directly to 'l_pmc_overflow'
+ * right after finding the first overflow.
+ */
+ l_pmc_overflow = gen_new_label();
+ l_skip_pmc1_overflow = gen_new_label();
+
+ t0 = tcg_temp_new();
+ gen_load_spr(t0, SPR_POWER_MMCR0);
+ tcg_gen_andi_tl(t0, t0, MMCR0_PMC1CE);
+ tcg_gen_brcondi_tl(TCG_COND_NE, t0, MMCR0_PMC1CE, l_skip_pmc1_overflow);
+
+ t_pmc1 = tcg_temp_new();
+ gen_load_spr(t_pmc1, SPR_POWER_PMC1);
+ tcg_gen_brcondi_tl(TCG_COND_GE, t_pmc1, PMC_COUNTER_NEGATIVE_VAL,
+ l_pmc_overflow);
+
+ gen_set_label(l_skip_pmc1_overflow);
+
+ l_skip_overflow = gen_new_label();
+
+ /*
+ * At this point we're sure PMC1 didn't overflow. If MMCR0_PMCjCE
+ * isn't set we can skip everything since PMC2-5 overflow is
+ * disabled.
+ */
+ t1 = tcg_temp_new();
+ gen_load_spr(t1, SPR_POWER_MMCR0);
+ tcg_gen_andi_tl(t1, t1, MMCR0_PMCjCE);
+ tcg_gen_brcondi_tl(TCG_COND_NE, t1, MMCR0_PMCjCE, l_skip_overflow);
+
+ for (i = SPR_POWER_PMC2; i < SPR_POWER_PMC6; i++) {
+ t_pmc = tcg_temp_new();
+ gen_load_spr(t_pmc, i);
+ tcg_gen_brcondi_tl(TCG_COND_GE, t_pmc, PMC_COUNTER_NEGATIVE_VAL,
+ l_pmc_overflow);
+ tcg_temp_free(t_pmc);
+ }
+
+ tcg_gen_br(l_skip_overflow);
+
+ gen_set_label(l_pmc_overflow);
+
+ /*
+ * The PMU overflow helper manipulates the internal PMU timer.
+ * In that case, if the guest is running with icount and we do not
+ * handle it beforehand, the helper can trigger a 'bad icount
+ * read'.
+ */
+ gen_icount_io_start(ctx);
+ gen_helper_pmu_overflow(cpu_env);
+
+ gen_set_label(l_skip_overflow);
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ tcg_temp_free(t_pmc1);
+}
#endif /* #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
#if defined(TARGET_PPC64)
@@ -115,6 +189,8 @@ static void pmu_count_insns(DisasContext *ctx)
gen_set_label(l_skip_pmc14);
+ pmu_check_overflow(ctx);
+
tcg_temp_free(t_mmcr0);
tcg_temp_free(t_mmcr1);
tcg_temp_free(t_ctrl);
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index 08d1902cd5..6696c9b3ae 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -323,6 +323,14 @@ void helper_insns_inc(CPUPPCState *env, uint32_t num_insns)
}
}
+/* Helper to fire a PMC interrupt from TCG code */
+void helper_pmu_overflow(CPUPPCState *env)
+{
+ PowerPCCPU *cpu = env_archcpu(env);
+
+ fire_PMC_interrupt(cpu);
+}
+
static void cpu_ppc_pmu_timer_cb(void *opaque)
{
PowerPCCPU *cpu = opaque;
--
2.33.1
next prev parent reply other threads:[~2021-12-23 20:23 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-23 20:18 [PATCH v2 0/5] Re-write PPC64 PMU instruction count using TCG Ops Daniel Henrique Barboza
2021-12-23 20:18 ` [PATCH v2 1/5] target/ppc: introduce power8-pmu-insn-cnt.c.inc Daniel Henrique Barboza
2021-12-23 20:18 ` [PATCH v2 2/5] target/ppc/power8-pmu-insn-cnt: introduce inc_spr_if_cond() Daniel Henrique Barboza
2021-12-23 21:14 ` Richard Henderson
2021-12-23 20:18 ` [PATCH v2 3/5] target/ppc/power8-pmu-insn-cnt: add PMCs1-4 insn count Daniel Henrique Barboza
2021-12-23 20:18 ` Daniel Henrique Barboza [this message]
2021-12-23 20:18 ` [PATCH v2 5/5] target/ppc/power8-pmu.c: remove helper_insns_inc() Daniel Henrique Barboza
2022-01-03 6:46 ` [PATCH v2 0/5] Re-write PPC64 PMU instruction count using TCG Ops Cédric Le Goater
2022-01-03 18:14 ` 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=20211223201812.846495-5-danielhb413@gmail.com \
--to=danielhb413@gmail.com \
--cc=clg@kaod.org \
--cc=david@gibson.dropbear.id.au \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=richard.henderson@linaro.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).