All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] target/arm/helper: Propagate MDCR_EL2.HPMN into PMCR_EL0.N
@ 2023-12-15 14:46 Jean-Philippe Brucker
  2023-12-18 15:05 ` Peter Maydell
  0 siblings, 1 reply; 2+ messages in thread
From: Jean-Philippe Brucker @ 2023-12-15 14:46 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-arm, qemu-devel, Jean-Philippe Brucker

MDCR_EL2.HPMN allows an hypervisor to limit the number of PMU counters
available to EL1 and EL0 (to keep the others to itself). QEMU already
implements this split correctly, except for PMCR_EL0.N reads: the number
of counters read by EL1 or EL0 should be the one configured in
MDCR_EL2.HPMN.

Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
 target/arm/helper.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index ff1970981e..bec293bc93 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1475,6 +1475,22 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
     pmu_op_finish(env);
 }
 
+static uint64_t pmcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    uint64_t pmcr = env->cp15.c9_pmcr;
+
+    /*
+     * If EL2 is implemented and enabled for the current security state, reads
+     * of PMCR.N from EL1 or EL0 return the value of MDCR_EL2.HPMN or HDCR.HPMN.
+     */
+    if (arm_current_el(env) <= 1 && arm_is_el2_enabled(env)) {
+        pmcr &= ~PMCRN_MASK;
+        pmcr |= (env->cp15.mdcr_el2 & MDCR_HPMN) << PMCRN_SHIFT;
+    }
+
+    return pmcr;
+}
+
 static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
                           uint64_t value)
 {
@@ -7137,8 +7153,9 @@ static void define_pmu_regs(ARMCPU *cpu)
         .fgt = FGT_PMCR_EL0,
         .type = ARM_CP_IO | ARM_CP_ALIAS,
         .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
-        .accessfn = pmreg_access, .writefn = pmcr_write,
-        .raw_writefn = raw_write,
+        .accessfn = pmreg_access,
+        .readfn = pmcr_read, .raw_readfn = raw_read,
+        .writefn = pmcr_write, .raw_writefn = raw_write,
     };
     ARMCPRegInfo pmcr64 = {
         .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
@@ -7148,6 +7165,7 @@ static void define_pmu_regs(ARMCPU *cpu)
         .type = ARM_CP_IO,
         .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
         .resetvalue = cpu->isar.reset_pmcr_el0,
+        .readfn = pmcr_read, .raw_readfn = raw_read,
         .writefn = pmcr_write, .raw_writefn = raw_write,
     };
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] target/arm/helper: Propagate MDCR_EL2.HPMN into PMCR_EL0.N
  2023-12-15 14:46 [PATCH] target/arm/helper: Propagate MDCR_EL2.HPMN into PMCR_EL0.N Jean-Philippe Brucker
@ 2023-12-18 15:05 ` Peter Maydell
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Maydell @ 2023-12-18 15:05 UTC (permalink / raw)
  To: Jean-Philippe Brucker; +Cc: qemu-arm, qemu-devel

On Fri, 15 Dec 2023 at 15:16, Jean-Philippe Brucker
<jean-philippe@linaro.org> wrote:
>
> MDCR_EL2.HPMN allows an hypervisor to limit the number of PMU counters
> available to EL1 and EL0 (to keep the others to itself). QEMU already
> implements this split correctly, except for PMCR_EL0.N reads: the number
> of counters read by EL1 or EL0 should be the one configured in
> MDCR_EL2.HPMN.
>
> Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>

Applied to target-arm.next for 9.0, thanks. I've added a
Cc: qemu-stable@nongnu.org because it seems a fix worth
backporting.

-- PMM


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-12-18 15:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-15 14:46 [PATCH] target/arm/helper: Propagate MDCR_EL2.HPMN into PMCR_EL0.N Jean-Philippe Brucker
2023-12-18 15:05 ` Peter Maydell

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.