Skip to content

Commit 27131b1

Browse files
rananta468oupton
authored andcommitted
KVM: arm64: Sanitize PM{C,I}NTEN{SET,CLR}, PMOVS{SET,CLR} before first run
For unimplemented counters, the registers PM{C,I}NTEN{SET,CLR} and PMOVS{SET,CLR} are expected to have the corresponding bits RAZ. Hence to ensure correct KVM's PMU emulation, mask out the RES0 bits. Defer this work to the point that userspace can no longer change the number of advertised PMCs. Signed-off-by: Raghavendra Rao Ananta <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent a45f41d commit 27131b1

File tree

3 files changed

+14
-2
lines changed

3 files changed

+14
-2
lines changed

arch/arm64/kvm/arm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)
801801
}
802802

803803
if (kvm_check_request(KVM_REQ_RELOAD_PMU, vcpu))
804-
kvm_pmu_handle_pmcr(vcpu, kvm_vcpu_read_pmcr(vcpu));
804+
kvm_vcpu_reload_pmu(vcpu);
805805

806806
if (kvm_check_request(KVM_REQ_RESYNC_PMU_EL0, vcpu))
807807
kvm_vcpu_pmu_restore_guest(vcpu);

arch/arm64/kvm/pmu-emul.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,17 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
785785
return val & mask;
786786
}
787787

788+
void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu)
789+
{
790+
u64 mask = kvm_pmu_valid_counter_mask(vcpu);
791+
792+
kvm_pmu_handle_pmcr(vcpu, kvm_vcpu_read_pmcr(vcpu));
793+
794+
__vcpu_sys_reg(vcpu, PMOVSSET_EL0) &= mask;
795+
__vcpu_sys_reg(vcpu, PMINTENSET_EL1) &= mask;
796+
__vcpu_sys_reg(vcpu, PMCNTENSET_EL0) &= mask;
797+
}
798+
788799
int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu)
789800
{
790801
if (!kvm_vcpu_has_pmu(vcpu))

include/kvm/arm_pmu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#define ARMV8_PMU_CYCLE_IDX (ARMV8_PMU_MAX_COUNTERS - 1)
1414

1515
#if IS_ENABLED(CONFIG_HW_PERF_EVENTS) && IS_ENABLED(CONFIG_KVM)
16-
1716
struct kvm_pmc {
1817
u8 idx; /* index into the pmu->pmc array */
1918
struct perf_event *perf_event;
@@ -63,6 +62,7 @@ void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val);
6362
void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val);
6463
void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
6564
u64 select_idx);
65+
void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu);
6666
int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu,
6767
struct kvm_device_attr *attr);
6868
int kvm_arm_pmu_v3_get_attr(struct kvm_vcpu *vcpu,
@@ -171,6 +171,7 @@ static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
171171
static inline void kvm_pmu_update_vcpu_events(struct kvm_vcpu *vcpu) {}
172172
static inline void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) {}
173173
static inline void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) {}
174+
static inline void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu) {}
174175
static inline u8 kvm_arm_pmu_get_pmuver_limit(void)
175176
{
176177
return 0;

0 commit comments

Comments
 (0)