arm64: KVM: Free perf event of PMU when destroying vcpu
authorShannon Zhao <shannon.zhao@linaro.org>
Fri, 11 Sep 2015 07:18:05 +0000 (15:18 +0800)
committerMarc Zyngier <marc.zyngier@arm.com>
Mon, 29 Feb 2016 18:34:21 +0000 (18:34 +0000)
When KVM frees VCPU, it needs to free the perf_event of PMU.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
arch/arm/kvm/arm.c
include/kvm/arm_pmu.h
virt/kvm/arm/pmu.c

index c5e959187abd59ec482cb30a0eefe8a5eceb5bfa..9d133df2da5316862c3629276e12cd519da962ff 100644 (file)
@@ -266,6 +266,7 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
        kvm_mmu_free_memory_caches(vcpu);
        kvm_timer_vcpu_terminate(vcpu);
        kvm_vgic_vcpu_destroy(vcpu);
+       kvm_pmu_vcpu_destroy(vcpu);
        kmem_cache_free(kvm_vcpu_cache, vcpu);
 }
 
index b4993eb76aa100d352a3dc3e5e75f21942a49393..9f87d717ef84234ea22f3e725a4c5b4b161d725d 100644 (file)
@@ -43,6 +43,7 @@ u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx);
 void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, u64 select_idx, u64 val);
 u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu);
 void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu);
+void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu);
 void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, u64 val);
 void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, u64 val);
 void kvm_pmu_overflow_set(struct kvm_vcpu *vcpu, u64 val);
@@ -69,6 +70,7 @@ static inline u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu)
        return 0;
 }
 static inline void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) {}
+static inline void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu) {}
 static inline void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, u64 val) {}
 static inline void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, u64 val) {}
 static inline void kvm_pmu_overflow_set(struct kvm_vcpu *vcpu, u64 val) {}
index 1dbbc2c515591622b9f31e6713b492b5aadabf73..9b83857da195e11107b3939f1e3d0b4c0012fb9e 100644 (file)
@@ -101,6 +101,27 @@ void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu)
        }
 }
 
+/**
+ * kvm_pmu_vcpu_destroy - free perf event of PMU for cpu
+ * @vcpu: The vcpu pointer
+ *
+ */
+void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu)
+{
+       int i;
+       struct kvm_pmu *pmu = &vcpu->arch.pmu;
+
+       for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) {
+               struct kvm_pmc *pmc = &pmu->pmc[i];
+
+               if (pmc->perf_event) {
+                       perf_event_disable(pmc->perf_event);
+                       perf_event_release_kernel(pmc->perf_event);
+                       pmc->perf_event = NULL;
+               }
+       }
+}
+
 u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu)
 {
        u64 val = vcpu_sys_reg(vcpu, PMCR_EL0) >> ARMV8_PMU_PMCR_N_SHIFT;