Hi Marc, On 2015/12/9 0:30, Marc Zyngier wrote: > On 08/12/15 12:47, Shannon Zhao wrote: >> > From: Shannon Zhao <shannon.z...@linaro.org> >> > >> > Since the reset value of PMEVCNTRn or PMCCNTR is UNKNOWN, use >> > reset_unknown for its reset handler. Add access handler which emulates >> > writing and reading PMEVCNTRn or PMCCNTR register. When reading >> > PMEVCNTRn or PMCCNTR, call perf_event_read_value to get the count value >> > of the perf event. >> > >> > Signed-off-by: Shannon Zhao <shannon.z...@linaro.org> >> > --- >> > arch/arm64/kvm/sys_regs.c | 107 >> > +++++++++++++++++++++++++++++++++++++++++++++- >> > 1 file changed, 105 insertions(+), 2 deletions(-) >> > >> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c >> > index c116a1b..f7a73b5 100644 >> > --- a/arch/arm64/kvm/sys_regs.c >> > +++ b/arch/arm64/kvm/sys_regs.c >> > @@ -525,6 +525,12 @@ static bool access_pmu_regs(struct kvm_vcpu *vcpu, >> > >> > if (p->is_write) { >> > switch (r->reg) { >> > + case PMEVCNTR0_EL0 ... PMCCNTR_EL0: { > Same problem as previously mentioned. > >> > + val = kvm_pmu_get_counter_value(vcpu, >> > + r->reg - PMEVCNTR0_EL0); >> > + vcpu_sys_reg(vcpu, r->reg) += (s64)p->regval - val; >> > + break; >> > + }
If I use a handler to handle these accesses to PMEVCNTRn and PMCCNTR like below. It converts the register offset c14_PMEVCNTRn and c9_PMCCNTR to PMEVCNTRn_EL0 and PMCCNTR_EL0, uniformly uses vcpu_sys_reg and doesn't need to take care the big endian. What do you think about this? static bool access_pmu_evcntr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { u64 idx, reg, val; if (p->is_aarch32) reg = r->reg / 2; else reg = r->reg; switch (reg) { case PMEVCNTR0_EL0 ... PMEVCNTR30_EL0: { idx = reg - PMEVCNTR0_EL0; break; } case PMCCNTR_EL0: { idx = ARMV8_CYCLE_IDX; break; } default: idx = vcpu_sys_reg(vcpu, PMSELR_EL0) & ARMV8_COUNTER_MASK; if (!pmu_counter_idx_valid(vcpu, idx)) return true; reg = (idx == ARMV8_CYCLE_IDX) ? PMCCNTR_EL0 : PMEVCNTR0_EL0 + idx; break; } val = kvm_pmu_get_counter_value(vcpu, idx); if (p->is_write) vcpu_sys_reg(vcpu, reg) = (s64)p->regval - val; else p->regval = val; return true; } Thanks, -- Shannon -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html