]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
KVM: arm64: nv: Reload PMU events upon MDCR_EL2.HPME change
authorOliver Upton <oliver.upton@linux.dev>
Tue, 17 Dec 2024 17:55:50 +0000 (09:55 -0800)
committerOliver Upton <oliver.upton@linux.dev>
Wed, 18 Dec 2024 21:22:25 +0000 (13:22 -0800)
MDCR_EL2.HPME is the 'global' enable bit for event counters reserved for
EL2. Give the PMU a kick when it's changed to ensure events are
reprogrammed before returning to the guest.

Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20241217175550.3658212-1-oliver.upton@linux.dev
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/kvm/sys_regs.c

index 6ef8641d9833cc65d64b74287b8eb5ba41b845e9..634ff18a59a17cdcbf6ace8d390dfcaab5118b27 100644 (file)
@@ -2448,6 +2448,26 @@ static unsigned int s1pie_el2_visibility(const struct kvm_vcpu *vcpu,
        return __el2_visibility(vcpu, rd, s1pie_visibility);
 }
 
+static bool access_mdcr(struct kvm_vcpu *vcpu,
+                       struct sys_reg_params *p,
+                       const struct sys_reg_desc *r)
+{
+       u64 old = __vcpu_sys_reg(vcpu, MDCR_EL2);
+
+       if (!access_rw(vcpu, p, r))
+               return false;
+
+       /*
+        * Request a reload of the PMU to enable/disable the counters affected
+        * by HPME.
+        */
+       if ((old ^ __vcpu_sys_reg(vcpu, MDCR_EL2)) & MDCR_EL2_HPME)
+               kvm_make_request(KVM_REQ_RELOAD_PMU, vcpu);
+
+       return true;
+}
+
+
 /*
  * Architected system registers.
  * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -2981,7 +3001,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        EL2_REG(SCTLR_EL2, access_rw, reset_val, SCTLR_EL2_RES1),
        EL2_REG(ACTLR_EL2, access_rw, reset_val, 0),
        EL2_REG_VNCR(HCR_EL2, reset_hcr, 0),
-       EL2_REG(MDCR_EL2, access_rw, reset_val, 0),
+       EL2_REG(MDCR_EL2, access_mdcr, reset_val, 0),
        EL2_REG(CPTR_EL2, access_rw, reset_val, CPTR_NVHE_EL2_RES1),
        EL2_REG_VNCR(HSTR_EL2, reset_val, 0),
        EL2_REG_VNCR(HFGRTR_EL2, reset_val, 0),