[PATCH v5 08/21] KVM: ARM64: Add reset and access handlers for PMXEVTYPER register
Marc Zyngier
marc.zyngier at arm.com
Mon Dec 7 05:38:02 PST 2015
On 03/12/15 06:11, Shannon Zhao wrote:
> From: Shannon Zhao <shannon.zhao at linaro.org>
>
> 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 <shannon.zhao at linaro.org>
> ---
> 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...
More information about the linux-arm-kernel
mailing list