Re: [PATCH v2 1/3] Provide VM capability to disable PMU virtualization for individual VMs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi David,

Please modify the subject of this patch to follow the convention.

On 21/1/2022 8:29 am, David Dunn wrote:
KVM_PMU_CONFIG_DISABLE can be used to disable PMU virtualization on

How about using:

case KVM_CAP_PMU_CAPABILITY
#define KVM_CAP_PMU_DISABLE	(1 << 0)
#define KVM_CAP_PMU_MASK (KVM_CAP_PMU_DISABLE)

individual x86 VMs.  PMU configuration must be done prior to creating
VCPUs.

To enable future extension, KVM_CAP_PMU_CONFIG reports available
settings when queried via check_extension.

Please help update the document in the Documentation/virt/kvm/api.rst


Since KVM_GET_SUPPORTED_CPUID reports the maximal CPUID information
based on module parameters, usermode will need to adjust CPUID when
disabling PMU virtualization on individual VMs.

For an irrational user space (set both pmu cpuid bits and KVM_CAP_PMU_DISABLE),
how about we remove the relevant PMU cpuid bits in kvm_pmu_refresh() silently?


Signed-off-by: David Dunn <daviddunn@xxxxxxxxxx>
---
  arch/x86/include/asm/kvm_host.h |  1 +
  arch/x86/kvm/svm/pmu.c          |  2 +-
  arch/x86/kvm/vmx/pmu_intel.c    |  2 +-
  arch/x86/kvm/x86.c              | 12 ++++++++++++
  include/uapi/linux/kvm.h        |  4 ++++
  tools/include/uapi/linux/kvm.h  |  4 ++++
  6 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 682ad02a4e58..5cdcd4a7671b 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1232,6 +1232,7 @@ struct kvm_arch {
  	hpa_t	hv_root_tdp;
  	spinlock_t hv_root_tdp_lock;
  #endif
+	bool enable_pmu;
  };
struct kvm_vm_stat {
diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c
index 5aa45f13b16d..d4de52409335 100644
--- a/arch/x86/kvm/svm/pmu.c
+++ b/arch/x86/kvm/svm/pmu.c
@@ -101,7 +101,7 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr,
  {
  	struct kvm_vcpu *vcpu = pmu_to_vcpu(pmu);
- if (!enable_pmu)
+	if (!vcpu->kvm->arch.enable_pmu)

Compared to diff in the v1:

-	if (!enable_pmu)
+	if (!enable_pmu || !vcpu->kvm->arch.enable_pmu)

Now I have come to appreciate the ingenious name.

  		return NULL;
switch (msr) {
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 466d18fc0c5d..2c5868d77268 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -487,7 +487,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
  	pmu->reserved_bits = 0xffffffff00200000ull;
entry = kvm_find_cpuid_entry(vcpu, 0xa, 0);
-	if (!entry || !enable_pmu)
+	if (!entry || !vcpu->kvm->arch.enable_pmu)
  		return;
  	eax.full = entry->eax;
  	edx.full = entry->edx;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 55518b7d3b96..42a98635bea5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4326,6 +4326,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
  		if (r < sizeof(struct kvm_xsave))
  			r = sizeof(struct kvm_xsave);
  		break;
+	case KVM_CAP_PMU_CONFIG:
+		r = enable_pmu ? KVM_PMU_CONFIG_VALID : 0;
+		break;

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 42a98635bea5..94481f92355d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4326,10 +4326,10 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		if (r < sizeof(struct kvm_xsave))
 			r = sizeof(struct kvm_xsave);
 		break;
+	}
 	case KVM_CAP_PMU_CONFIG:
 		r = enable_pmu ? KVM_CAP_PMU_MASK : 0;
 		break;
-	}
 	default:
 		break;
 	}

  	}
  	default:
  		break;
@@ -5937,6 +5940,14 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
  		kvm->arch.exit_on_emulation_error = cap->args[0];
  		r = 0;
  		break;
+	case KVM_CAP_PMU_CONFIG:
+		r = -EINVAL;
+		if (!enable_pmu || kvm->created_vcpus > 0 ||
+		    cap->args[0] & ~KVM_PMU_CONFIG_VALID)
+			break;
+		kvm->arch.enable_pmu = !(cap->args[0] & KVM_PMU_CONFIG_DISABLE);
+		r = 0;
+		break;
  	default:
  		r = -EINVAL;
  		break;
@@ -11562,6 +11573,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
  	raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
kvm->arch.guest_can_read_msr_platform_info = true;
+	kvm->arch.enable_pmu = enable_pmu;
#if IS_ENABLED(CONFIG_HYPERV)
  	spin_lock_init(&kvm->arch.hv_root_tdp_lock);
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 9563d294f181..57a1280fa43b 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1133,6 +1133,7 @@ struct kvm_ppc_resize_hpt {
  #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
  #define KVM_CAP_VM_GPA_BITS 207
  #define KVM_CAP_XSAVE2 208
+#define KVM_CAP_PMU_CONFIG 209
#ifdef KVM_CAP_IRQ_ROUTING @@ -1972,6 +1973,9 @@ struct kvm_dirty_gfn {
  #define KVM_BUS_LOCK_DETECTION_OFF             (1 << 0)
  #define KVM_BUS_LOCK_DETECTION_EXIT            (1 << 1)
+#define KVM_PMU_CONFIG_DISABLE (1 << 0)
+#define KVM_PMU_CONFIG_VALID                   (KVM_PMU_CONFIG_DISABLE)
+
  /**
   * struct kvm_stats_header - Header of per vm/vcpu binary statistics data.
   * @flags: Some extra information for header, always 0 for now.
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h
index 9563d294f181..57a1280fa43b 100644
--- a/tools/include/uapi/linux/kvm.h
+++ b/tools/include/uapi/linux/kvm.h
@@ -1133,6 +1133,7 @@ struct kvm_ppc_resize_hpt {
  #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
  #define KVM_CAP_VM_GPA_BITS 207
  #define KVM_CAP_XSAVE2 208
+#define KVM_CAP_PMU_CONFIG 209
#ifdef KVM_CAP_IRQ_ROUTING @@ -1972,6 +1973,9 @@ struct kvm_dirty_gfn {
  #define KVM_BUS_LOCK_DETECTION_OFF             (1 << 0)
  #define KVM_BUS_LOCK_DETECTION_EXIT            (1 << 1)
+#define KVM_PMU_CONFIG_DISABLE (1 << 0)
+#define KVM_PMU_CONFIG_VALID                   (KVM_PMU_CONFIG_DISABLE)
+
  /**
   * struct kvm_stats_header - Header of per vm/vcpu binary statistics data.
   * @flags: Some extra information for header, always 0 for now.



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux