[PATCH 2/4] KVM: arm64: PMU: Set the default PMU for the guest on vCPU reset
Reiji Watanabe
reijiw at google.com
Fri May 26 21:02:34 PDT 2023
Set the default PMU for the guest on the first vCPU reset,
not when userspace initially uses KVM_ARM_VCPU_PMU_V3_CTRL.
The following patches will use the PMUVer of the PMU as the
default value of the ID_AA64DFR0_EL1.PMUVer for vCPUs with
PMU configured.
Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
arch/arm64/kvm/pmu-emul.c | 10 +---------
arch/arm64/kvm/reset.c | 20 +++++++++++++-------
include/kvm/arm_pmu.h | 6 ++++++
3 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index d50c8f7a2410..0194a94c4bae 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -869,7 +869,7 @@ static bool pmu_irq_is_valid(struct kvm *kvm, int irq)
return true;
}
-static int kvm_arm_set_vm_pmu(struct kvm *kvm, struct arm_pmu *arm_pmu)
+int kvm_arm_set_vm_pmu(struct kvm *kvm, struct arm_pmu *arm_pmu)
{
lockdep_assert_held(&kvm->arch.config_lock);
@@ -926,14 +926,6 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
if (vcpu->arch.pmu.created)
return -EBUSY;
- if (!kvm->arch.arm_pmu) {
- /* No PMU set, get the default one */
- int ret = kvm_arm_set_vm_pmu(kvm, NULL);
-
- if (ret)
- return ret;
- }
-
switch (attr->attr) {
case KVM_ARM_VCPU_PMU_V3_IRQ: {
int __user *uaddr = (int __user *)(long)attr->addr;
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index b5dee8e57e77..f5e24492926c 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -258,13 +258,24 @@ static int kvm_set_vm_width(struct kvm_vcpu *vcpu)
int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
{
struct vcpu_reset_state reset_state;
+ struct kvm *kvm = vcpu->kvm;
int ret;
bool loaded;
u32 pstate;
- mutex_lock(&vcpu->kvm->arch.config_lock);
+ mutex_lock(&kvm->arch.config_lock);
ret = kvm_set_vm_width(vcpu);
- mutex_unlock(&vcpu->kvm->arch.config_lock);
+ if (!ret && kvm_vcpu_has_pmu(vcpu)) {
+ if (!kvm_arm_support_pmu_v3())
+ ret = -EINVAL;
+ else if (unlikely(!kvm->arch.arm_pmu))
+ /*
+ * As no PMU is set for the guest yet,
+ * set the default one.
+ */
+ ret = kvm_arm_set_vm_pmu(kvm, NULL);
+ }
+ mutex_unlock(&kvm->arch.config_lock);
if (ret)
return ret;
@@ -315,11 +326,6 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
} else {
pstate = VCPU_RESET_PSTATE_EL1;
}
-
- if (kvm_vcpu_has_pmu(vcpu) && !kvm_arm_support_pmu_v3()) {
- ret = -EINVAL;
- goto out;
- }
break;
}
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 1a6a695ca67a..5ece2a3c1858 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -96,6 +96,7 @@ void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu);
(vcpu->kvm->arch.dfr0_pmuver.imp >= ID_AA64DFR0_EL1_PMUVer_V3P5)
u8 kvm_arm_pmu_get_pmuver_limit(void);
+int kvm_arm_set_vm_pmu(struct kvm *kvm, struct arm_pmu *arm_pmu);
#else
struct kvm_pmu {
@@ -168,6 +169,11 @@ static inline u8 kvm_arm_pmu_get_pmuver_limit(void)
return 0;
}
+static inline int kvm_arm_set_vm_pmu(struct kvm *kvm, struct arm_pmu *arm_pmu)
+{
+ return 0;
+}
+
#endif
#endif
--
2.41.0.rc0.172.g3f132b7071-goog
More information about the linux-arm-kernel
mailing list