Thread (38 messages) 38 messages, 3 authors, 2015-12-08
STALE3840d

[PATCH v5 08/21] KVM: ARM64: Add reset and access handlers for PMXEVTYPER register

From: Marc Zyngier <hidden>
Date: 2015-12-07 13:38:02
Also in: kvm, kvmarm

On 03/12/15 06:11, Shannon Zhao wrote:
quoted hunk ↗ jump to hunk
From: Shannon Zhao <redacted>

Since the reset value of PMXEVTYPER is UNKNOWN, use reset_unknown or
reset_unknown_cp15 for its reset handler. Add access handler which
emulates writing and reading PMXEVTYPER register. When writing to
PMXEVTYPER, call kvm_pmu_set_counter_event_type to create a perf_event
for the selected event type.

Signed-off-by: Shannon Zhao <redacted>
---
 arch/arm64/kvm/sys_regs.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index b0a8d88..6967a49 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -473,6 +473,17 @@ static void reset_pmceid(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 	vcpu_sys_reg(vcpu, r->reg) = pmceid;
 }
 
+static bool pmu_counter_idx_valid(u64 pmcr, u64 idx)
+{
+	u64 val;
+
+	val = (pmcr >> ARMV8_PMCR_N_SHIFT) & ARMV8_PMCR_N_MASK;
+	if (idx >= val && idx != ARMV8_COUNTER_MASK)
+		return false;
+
+	return true;
+}
+
 /* PMU registers accessor. */
 static bool access_pmu_regs(struct kvm_vcpu *vcpu,
 			    const struct sys_reg_params *p,
@@ -482,6 +493,20 @@ static bool access_pmu_regs(struct kvm_vcpu *vcpu,
 
 	if (p->is_write) {
 		switch (r->reg) {
+		case PMXEVTYPER_EL0: {
+			u64 idx = vcpu_sys_reg(vcpu, PMSELR_EL0)
+				  & ARMV8_COUNTER_MASK;
+
+			if (!pmu_counter_idx_valid(vcpu_sys_reg(vcpu, PMCR_EL0),
+						   idx))
+				break;
+
+			val = *vcpu_reg(vcpu, p->Rt);
+			kvm_pmu_set_counter_event_type(vcpu, val, idx);
+			vcpu_sys_reg(vcpu, PMXEVTYPER_EL0) = val;
+			vcpu_sys_reg(vcpu, PMEVTYPER0_EL0 + idx) = val;
I'm really confused by this. PMXEVTYPER is not really a register, but
level of indirection between PMEVTYPERn_EL0 and PMCCFILTER_EL0
(depending on PMSELR_EL0.SEL). On its own, it doesn't exist.

Here, you are making PMXEVTYPER_EL0 an actual register, storing the same
value twice (and not handling PMCCFILTER_EL0). It definitely feels
wrong. You should be able to trap it and propagate the access to the
right register, without duplicating the state.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help