From: "Alex Bennée" <alex.bennee@linaro.org>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-devel@nongnu.org,
Richard Henderson <richard.henderson@linaro.org>,
qemu-arm@nongnu.org
Subject: Re: [PATCH v2 03/10] target/arm: Don't mishandle count when enabling or disabling PMU counters
Date: Mon, 03 Oct 2022 09:54:30 +0100 [thread overview]
Message-ID: <87sfk5nv5n.fsf@linaro.org> (raw)
In-Reply-To: <20220822132358.3524971-4-peter.maydell@linaro.org>
Peter Maydell <peter.maydell@linaro.org> writes:
> The PMU cycle and event counter infrastructure design requires that
> operations on the PMU register fields are wrapped in pmu_op_start()
> and pmu_op_finish() calls (or their more specific pmmcntr and
> pmevcntr equivalents). This includes any changes to registers which
> affect whether the counter should be enabled or disabled, but we
> forgot to do this.
>
> The effect of this bug is that in sequences like:
> * disable the cycle counter (PMCCNTR) using the PMCNTEN register
> * write a value such as 0xfffff000 to the PMCCNTR
> * restart the counter by writing to PMCNTEN
> the value written to the cycle counter is corrupted, and it starts
> counting from the wrong place. (Essentially, we fail to record that
> the QEMU_CLOCK_VIRTUAL timestamp when the counter should be considered
> to have started counting is the point when PMCNTEN is written to enable
> the counter.)
>
> Add the necessary bracketing calls, so that updates to the various
> registers which affect whether the PMU is counting are handled
> correctly.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
I'm not sure why but this commit seems to be breaking a bunch of avocado
tests for me, including the TCG plugin ones:
➜ ./tests/venv/bin/avocado run tests/avocado/tcg_plugins.py:test_aarch64_virt_insn_icount
JOB ID : 0f5647d95f678e73fc01730cf9f8d7f80118443e
JOB LOG : /home/alex/avocado/job-results/job-2022-10-02T20.19-0f5647d/job.log
(1/1) tests/avocado/tcg_plugins.py:PluginKernelNormal.test_aarch64_virt_insn_icount: INTERRUPTED: Test interrupted by SIGTERM\nRunner error occurred: Timeout reached\nOrigi
nal status: ERROR\n{'name': '1-tests/avocado/tcg_plugins.py:PluginKernelNormal.test_aarch64_virt_insn_icount', 'logdir': '/home/alex/avocado/job-results/job-2022-10-02T20.19
-0f5647d/te... (120.43 s)
RESULTS : PASS 0 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 1 | CANCEL 0
JOB TIME : 120.72 s
> ---
> v1->v2: fixed comment typo
> ---
> target/arm/helper.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 45 insertions(+)
>
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 87c89748954..59e1280a9cd 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -1079,6 +1079,14 @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
> return pmreg_access(env, ri, isread);
> }
>
> +/*
> + * Bits in MDCR_EL2 and MDCR_EL3 which pmu_counter_enabled() looks at.
> + * We use these to decide whether we need to wrap a write to MDCR_EL2
> + * or MDCR_EL3 in pmu_op_start()/pmu_op_finish() calls.
> + */
> +#define MDCR_EL2_PMU_ENABLE_BITS (MDCR_HPME | MDCR_HPMD | MDCR_HPMN)
> +#define MDCR_EL3_PMU_ENABLE_BITS (MDCR_SPME)
> +
> /* Returns true if the counter (pass 31 for PMCCNTR) should count events using
> * the current EL, security state, and register configuration.
> */
> @@ -1432,15 +1440,19 @@ static uint64_t pmccfiltr_read_a32(CPUARMState *env, const ARMCPRegInfo *ri)
> static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
> uint64_t value)
> {
> + pmu_op_start(env);
> value &= pmu_counter_mask(env);
> env->cp15.c9_pmcnten |= value;
> + pmu_op_finish(env);
> }
>
> static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> uint64_t value)
> {
> + pmu_op_start(env);
> value &= pmu_counter_mask(env);
> env->cp15.c9_pmcnten &= ~value;
> + pmu_op_finish(env);
> }
>
> static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> @@ -4681,7 +4693,39 @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> static void sdcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
> uint64_t value)
> {
> + /*
> + * Some MDCR_EL3 bits affect whether PMU counters are running:
> + * if we are trying to change any of those then we must
> + * bracket this update with PMU start/finish calls.
> + */
> + bool pmu_op = (env->cp15.mdcr_el3 ^ value) & MDCR_EL3_PMU_ENABLE_BITS;
> +
> + if (pmu_op) {
> + pmu_op_start(env);
> + }
> env->cp15.mdcr_el3 = value & SDCR_VALID_MASK;
> + if (pmu_op) {
> + pmu_op_finish(env);
> + }
> +}
> +
> +static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
> + uint64_t value)
> +{
> + /*
> + * Some MDCR_EL2 bits affect whether PMU counters are running:
> + * if we are trying to change any of those then we must
> + * bracket this update with PMU start/finish calls.
> + */
> + bool pmu_op = (env->cp15.mdcr_el2 ^ value) & MDCR_EL2_PMU_ENABLE_BITS;
> +
> + if (pmu_op) {
> + pmu_op_start(env);
> + }
> + env->cp15.mdcr_el2 = value;
> + if (pmu_op) {
> + pmu_op_finish(env);
> + }
> }
>
> static const ARMCPRegInfo v8_cp_reginfo[] = {
> @@ -7669,6 +7713,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
> ARMCPRegInfo mdcr_el2 = {
> .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
> .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
> + .writefn = mdcr_el2_write,
> .access = PL2_RW, .resetvalue = pmu_num_counters(env),
> .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2),
> };
--
Alex Bennée
next prev parent reply other threads:[~2022-10-03 9:03 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-22 13:23 [PATCH v2 00/10] target/arm: Implement FEAT_PMUv3p5 Peter Maydell
2022-08-22 13:23 ` [PATCH v2 01/10] target/arm: Don't corrupt high half of PMOVSR when cycle counter overflows Peter Maydell
2022-08-22 13:23 ` [PATCH v2 02/10] target/arm: Correct value returned by pmu_counter_mask() Peter Maydell
2022-08-22 13:23 ` [PATCH v2 03/10] target/arm: Don't mishandle count when enabling or disabling PMU counters Peter Maydell
2022-10-03 8:54 ` Alex Bennée [this message]
2022-10-03 9:32 ` Peter Maydell
2022-08-22 13:23 ` [PATCH v2 04/10] target/arm: Ignore PMCR.D when PMCR.LC is set Peter Maydell
2022-08-22 13:23 ` [PATCH v2 05/10] target/arm: Honour MDCR_EL2.HPMD in Secure EL2 Peter Maydell
2022-08-22 13:23 ` [PATCH v2 06/10] target/arm: Detect overflow when calculating next PMU interrupt Peter Maydell
2022-08-22 13:23 ` [PATCH v2 07/10] target/arm: Rename pmu_8_n feature test functions Peter Maydell
2022-08-22 13:23 ` [PATCH v2 08/10] target/arm: Implement FEAT_PMUv3p5 cycle counter disable bits Peter Maydell
2022-08-22 16:15 ` Richard Henderson
2022-08-22 13:23 ` [PATCH v2 09/10] target/arm: Support 64-bit event counters for FEAT_PMUv3p5 Peter Maydell
2022-08-22 13:23 ` [PATCH v2 10/10] target/arm: Report FEAT_PMUv3p5 for TCG '-cpu max' Peter Maydell
2022-08-23 21:53 ` [PATCH v2 00/10] target/arm: Implement FEAT_PMUv3p5 Richard Henderson
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=87sfk5nv5n.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@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).