All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: David Dunn <daviddunn@google.com>
Cc: pbonzini@redhat.com, jmattson@google.com,
	like.xu.linux@gmail.com, kvm@vger.kernel.org
Subject: Re: [PATCH v7 1/3] KVM: x86: Provide per VM capability for disabling PMU virtualization
Date: Thu, 17 Feb 2022 16:22:28 +0000	[thread overview]
Message-ID: <Yg52RP+hzIVaNAas@google.com> (raw)
In-Reply-To: <20220215014806.4102669-2-daviddunn@google.com>

On Tue, Feb 15, 2022, David Dunn wrote:
> Add a new capability, KVM_CAP_PMU_CAPABILITY, that takes a bitmask of
> settings/features to allow userspace to configure PMU virtualization on
> a per-VM basis.  For now, support a single flag, KVM_CAP_PMU_DISABLE,
> to allow disabling PMU virtualization for a VM even when KVM is configured
> with enable_pmu=true a module level.
> 
> To keep KVM simple, disallow changing VM's PMU configuration after vCPUs
> have been created.
> 
> Signed-off-by: David Dunn <daviddunn@google.com>
> ---

A few nits, otherwise

Reviewed-by: Sean Christopherson <seanjc@google.com>

Somewhat off-topic, looking at this got me looking at vmx_get_perf_capabilities().
We really should cache the result of its RDMSR.

And I believe emulation of WRMSR from the guest to MSR_IA32_PERF_CAPABILITIES is
missing a guest_cpuid_has() check.

>  Documentation/virt/kvm/api.rst  | 22 ++++++++++++++++++++++
>  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              | 17 +++++++++++++++++
>  include/uapi/linux/kvm.h        |  3 +++
>  tools/include/uapi/linux/kvm.h  |  3 +++
>  7 files changed, 48 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> index a4267104db50..df836965b347 100644
> --- a/Documentation/virt/kvm/api.rst
> +++ b/Documentation/virt/kvm/api.rst
> @@ -7561,3 +7561,25 @@ The argument to KVM_ENABLE_CAP is also a bitmask, and must be a subset
>  of the result of KVM_CHECK_EXTENSION.  KVM will forward to userspace
>  the hypercalls whose corresponding bit is in the argument, and return
>  ENOSYS for the others.
> +
> +8.35 KVM_CAP_PMU_CAPABILITY
> +---------------------------
> +
> +:Capability KVM_CAP_PMU_CAPABILITY
> +:Architectures: x86
> +:Type: vm
> +:Parameters: arg[0] is bitmask of PMU virtualization capabilities.

Referring to "DISABLE" as a capabilitiy is rather odd, but I don't have a better
suggestion.

> +:Returns 0 on success, -EINVAL when arg[0] contains invalid bits
> +
> +This capability alters PMU virtualization in KVM.
> +
> +Calling KVM_CHECK_EXTENSION for this capability returns a bitmask of
> +PMU virtualization capabilities that can be adjusted on a VM.
> +
> +The argument to KVM_ENABLE_CAP is also a bitmask and selects specific
> +PMU virtualization capabilities to be applied to the VM.  This can
> +only be invoked on a VM prior to the creation of VCPUs.
> +
> +At this time, KVM_CAP_PMU_DISABLE is the only capability.  Setting
> +this capability will disable PMU virtualization for that VM.  Usermode
> +should adjust CPUID leaf 0xA to reflect that the PMU is disabled.
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 10815b672a26..61e9050a3488 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -1233,6 +1233,7 @@ struct kvm_arch {
>  	hpa_t	hv_root_tdp;
>  	spinlock_t hv_root_tdp_lock;
>  #endif
> +	bool enable_pmu;

Doesn''t really matter, but I'd prefer we put this up among the many other bools, e.g.

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 4bb0d3be2055..b57d40419ddd 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1150,6 +1150,7 @@ struct kvm_arch {
        bool guest_can_read_msr_platform_info;
        bool exception_payload_enabled;
 
+       bool enable_pmu;
        bool bus_lock_detection_enabled;
        /*
         * If exit_on_emulation_error is set, and the in-kernel instruction
@@ -1233,7 +1234,6 @@ struct kvm_arch {
        hpa_t   hv_root_tdp;
        spinlock_t hv_root_tdp_lock;
 #endif
-       bool enable_pmu;
 };
 
 struct kvm_vm_stat {

>  };
>  
>  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)
>  		return NULL;
>  
>  	switch (msr) {
> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
> index 03fab48b149c..4e5b1eeeb77c 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 eaa3b5b89c5e..0803a1388bbf 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -110,6 +110,8 @@ static u64 __read_mostly cr4_reserved_bits = CR4_RESERVED_BITS;
>  
>  #define KVM_EXIT_HYPERCALL_VALID_MASK (1 << KVM_HC_MAP_GPA_RANGE)
>  
> +#define KVM_CAP_PMU_VALID_MASK KVM_CAP_PMU_DISABLE
> +
>  #define KVM_X2APIC_API_VALID_FLAGS (KVM_X2APIC_API_USE_32BIT_IDS | \
>                                      KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK)
>  
> @@ -4331,6 +4333,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_CAPABILITY:
> +		r = enable_pmu ? KVM_CAP_PMU_VALID_MASK : 0;
> +		break;
>  	}
>  	default:
>  		break;
> @@ -6005,6 +6010,17 @@ 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_CAPABILITY:
> +		r = -EINVAL;
> +		if (!enable_pmu || (cap->args[0] & ~KVM_CAP_PMU_VALID_MASK))
> +			break;

I'd prefer another newline here, the other case statements are just bad influences :-)

> +		mutex_lock(&kvm->lock);
> +		if (!kvm->created_vcpus) {
> +			kvm->arch.enable_pmu = !(cap->args[0] & KVM_CAP_PMU_DISABLE);
> +			r = 0;
> +		}
> +		mutex_unlock(&kvm->lock);
> +		break;
>  	default:
>  		r = -EINVAL;
>  		break;

  reply	other threads:[~2022-02-17 16:22 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-15  1:48 [PATCH v7 0/3] KVM: x86: Provide per VM capability for disabling PMU virtualization David Dunn
2022-02-15  1:48 ` [PATCH v7 1/3] " David Dunn
2022-02-17 16:22   ` Sean Christopherson [this message]
2022-02-15  1:48 ` [PATCH v7 2/3] KVM: selftests: Carve out helper to create "default" VM without vCPUs David Dunn
2022-02-17 15:46   ` Sean Christopherson
2022-02-15  1:48 ` [PATCH v7 3/3] KVM: selftests: Verify disabling PMU virtualization via KVM_CAP_CONFIG_PMU David Dunn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Yg52RP+hzIVaNAas@google.com \
    --to=seanjc@google.com \
    --cc=daviddunn@google.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=like.xu.linux@gmail.com \
    --cc=pbonzini@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.