+++ /dev/null
-From 9fbc81f2e30dcfa51e1e617ccf2f17ccf0cfceac Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 12 Mar 2023 20:32:08 -0700
-Subject: KVM: arm64: PMU: Fix GET_ONE_REG for vPMC regs to return the current
- value
-
-From: Reiji Watanabe <reijiw@google.com>
-
-[ Upstream commit 9228b26194d1cc00449f12f306f53ef2e234a55b ]
-
-Have KVM_GET_ONE_REG for vPMU counter (vPMC) registers (PMCCNTR_EL0
-and PMEVCNTR<n>_EL0) return the sum of the register value in the sysreg
-file and the current perf event counter value.
-
-Values of vPMC registers are saved in sysreg files on certain occasions.
-These saved values don't represent the current values of the vPMC
-registers if the perf events for the vPMCs count events after the save.
-The current values of those registers are the sum of the sysreg file
-value and the current perf event counter value. But, when userspace
-reads those registers (using KVM_GET_ONE_REG), KVM returns the sysreg
-file value to userspace (not the sum value).
-
-Fix this to return the sum value for KVM_GET_ONE_REG.
-
-Fixes: 051ff581ce70 ("arm64: KVM: Add access handler for event counter register")
-Cc: stable@vger.kernel.org
-Reviewed-by: Marc Zyngier <maz@kernel.org>
-Signed-off-by: Reiji Watanabe <reijiw@google.com>
-Link: https://lore.kernel.org/r/20230313033208.1475499-1-reijiw@google.com
-Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/arm64/kvm/sys_regs.c | 21 +++++++++++++++++++--
- 1 file changed, 19 insertions(+), 2 deletions(-)
-
-diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
-index c11612db4a371..c211f719c2474 100644
---- a/arch/arm64/kvm/sys_regs.c
-+++ b/arch/arm64/kvm/sys_regs.c
-@@ -764,6 +764,22 @@ static bool pmu_counter_idx_valid(struct kvm_vcpu *vcpu, u64 idx)
- return true;
- }
-
-+static int get_pmu_evcntr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
-+ u64 *val)
-+{
-+ u64 idx;
-+
-+ if (r->CRn == 9 && r->CRm == 13 && r->Op2 == 0)
-+ /* PMCCNTR_EL0 */
-+ idx = ARMV8_PMU_CYCLE_IDX;
-+ else
-+ /* PMEVCNTRn_EL0 */
-+ idx = ((r->CRm & 3) << 3) | (r->Op2 & 7);
-+
-+ *val = kvm_pmu_get_counter_value(vcpu, idx);
-+ return 0;
-+}
-+
- static bool access_pmu_evcntr(struct kvm_vcpu *vcpu,
- struct sys_reg_params *p,
- const struct sys_reg_desc *r)
-@@ -980,7 +996,7 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
- /* Macro to expand the PMEVCNTRn_EL0 register */
- #define PMU_PMEVCNTR_EL0(n) \
- { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \
-- .reset = reset_pmevcntr, \
-+ .reset = reset_pmevcntr, .get_user = get_pmu_evcntr, \
- .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), }
-
- /* Macro to expand the PMEVTYPERn_EL0 register */
-@@ -1651,7 +1667,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
- { PMU_SYS_REG(SYS_PMCEID1_EL0),
- .access = access_pmceid, .reset = NULL },
- { PMU_SYS_REG(SYS_PMCCNTR_EL0),
-- .access = access_pmu_evcntr, .reset = reset_unknown, .reg = PMCCNTR_EL0 },
-+ .access = access_pmu_evcntr, .reset = reset_unknown,
-+ .reg = PMCCNTR_EL0, .get_user = get_pmu_evcntr},
- { PMU_SYS_REG(SYS_PMXEVTYPER_EL0),
- .access = access_pmu_evtyper, .reset = NULL },
- { PMU_SYS_REG(SYS_PMXEVCNTR_EL0),
---
-2.39.2
-