kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Sean Christopherson <seanjc@google.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	Zeng Guang <guang.zeng@intel.com>, Yuan Yao <yuan.yao@intel.com>
Subject: [PATCH v3 01/15] KVM: x86: Add a framework for enabling KVM-governed x86 features
Date: Tue, 15 Aug 2023 13:36:39 -0700	[thread overview]
Message-ID: <20230815203653.519297-2-seanjc@google.com> (raw)
In-Reply-To: <20230815203653.519297-1-seanjc@google.com>

Introduce yet another X86_FEATURE flag framework to manage and cache KVM
governed features (for lack of a better name).  "Governed" in this case
means that KVM has some level of involvement and/or vested interest in
whether or not an X86_FEATURE can be used by the guest.  The intent of the
framework is twofold: to simplify caching of guest CPUID flags that KVM
needs to frequently query, and to add clarity to such caching, e.g. it
isn't immediately obvious that SVM's bundle of flags for "optional nested
SVM features" track whether or not a flag is exposed to L1.

Begrudgingly define KVM_MAX_NR_GOVERNED_FEATURES for the size of the
bitmap to avoid exposing governed_features.h in arch/x86/include/asm/, but
add a FIXME to call out that it can and should be cleaned up once
"struct kvm_vcpu_arch" is no longer expose to the kernel at large.

Cc: Zeng Guang <guang.zeng@intel.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/include/asm/kvm_host.h  | 19 +++++++++++++
 arch/x86/kvm/cpuid.c             |  4 +++
 arch/x86/kvm/cpuid.h             | 46 ++++++++++++++++++++++++++++++++
 arch/x86/kvm/governed_features.h |  9 +++++++
 4 files changed, 78 insertions(+)
 create mode 100644 arch/x86/kvm/governed_features.h

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 19d64f019240..60d430b4650f 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -831,6 +831,25 @@ struct kvm_vcpu_arch {
 	struct kvm_cpuid_entry2 *cpuid_entries;
 	struct kvm_hypervisor_cpuid kvm_cpuid;
 
+	/*
+	 * FIXME: Drop this macro and use KVM_NR_GOVERNED_FEATURES directly
+	 * when "struct kvm_vcpu_arch" is no longer defined in an
+	 * arch/x86/include/asm header.  The max is mostly arbitrary, i.e.
+	 * can be increased as necessary.
+	 */
+#define KVM_MAX_NR_GOVERNED_FEATURES BITS_PER_LONG
+
+	/*
+	 * Track whether or not the guest is allowed to use features that are
+	 * governed by KVM, where "governed" means KVM needs to manage state
+	 * and/or explicitly enable the feature in hardware.  Typically, but
+	 * not always, governed features can be used by the guest if and only
+	 * if both KVM and userspace want to expose the feature to the guest.
+	 */
+	struct {
+		DECLARE_BITMAP(enabled, KVM_MAX_NR_GOVERNED_FEATURES);
+	} governed_features;
+
 	u64 reserved_gpa_bits;
 	int maxphyaddr;
 
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 5a88affb2e1a..4ba43ae008cb 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -313,6 +313,10 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 	struct kvm_lapic *apic = vcpu->arch.apic;
 	struct kvm_cpuid_entry2 *best;
 
+	BUILD_BUG_ON(KVM_NR_GOVERNED_FEATURES > KVM_MAX_NR_GOVERNED_FEATURES);
+	bitmap_zero(vcpu->arch.governed_features.enabled,
+		    KVM_MAX_NR_GOVERNED_FEATURES);
+
 	best = kvm_find_cpuid_entry(vcpu, 1);
 	if (best && apic) {
 		if (cpuid_entry_has(best, X86_FEATURE_TSC_DEADLINE_TIMER))
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index b1658c0de847..284fa4704553 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -232,4 +232,50 @@ static __always_inline bool guest_pv_has(struct kvm_vcpu *vcpu,
 	return vcpu->arch.pv_cpuid.features & (1u << kvm_feature);
 }
 
+enum kvm_governed_features {
+#define KVM_GOVERNED_FEATURE(x) KVM_GOVERNED_##x,
+#include "governed_features.h"
+	KVM_NR_GOVERNED_FEATURES
+};
+
+static __always_inline int kvm_governed_feature_index(unsigned int x86_feature)
+{
+	switch (x86_feature) {
+#define KVM_GOVERNED_FEATURE(x) case x: return KVM_GOVERNED_##x;
+#include "governed_features.h"
+	default:
+		return -1;
+	}
+}
+
+static __always_inline bool kvm_is_governed_feature(unsigned int x86_feature)
+{
+	return kvm_governed_feature_index(x86_feature) >= 0;
+}
+
+static __always_inline void kvm_governed_feature_set(struct kvm_vcpu *vcpu,
+						     unsigned int x86_feature)
+{
+	BUILD_BUG_ON(!kvm_is_governed_feature(x86_feature));
+
+	__set_bit(kvm_governed_feature_index(x86_feature),
+		  vcpu->arch.governed_features.enabled);
+}
+
+static __always_inline void kvm_governed_feature_check_and_set(struct kvm_vcpu *vcpu,
+							       unsigned int x86_feature)
+{
+	if (kvm_cpu_cap_has(x86_feature) && guest_cpuid_has(vcpu, x86_feature))
+		kvm_governed_feature_set(vcpu, x86_feature);
+}
+
+static __always_inline bool guest_can_use(struct kvm_vcpu *vcpu,
+					  unsigned int x86_feature)
+{
+	BUILD_BUG_ON(!kvm_is_governed_feature(x86_feature));
+
+	return test_bit(kvm_governed_feature_index(x86_feature),
+			vcpu->arch.governed_features.enabled);
+}
+
 #endif
diff --git a/arch/x86/kvm/governed_features.h b/arch/x86/kvm/governed_features.h
new file mode 100644
index 000000000000..40ce8e6608cd
--- /dev/null
+++ b/arch/x86/kvm/governed_features.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#if !defined(KVM_GOVERNED_FEATURE) || defined(KVM_GOVERNED_X86_FEATURE)
+BUILD_BUG()
+#endif
+
+#define KVM_GOVERNED_X86_FEATURE(x) KVM_GOVERNED_FEATURE(X86_FEATURE_##x)
+
+#undef KVM_GOVERNED_X86_FEATURE
+#undef KVM_GOVERNED_FEATURE
-- 
2.41.0.694.ge786442a9b-goog


  reply	other threads:[~2023-08-15 20:38 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-15 20:36 [PATCH v3 00/15] KVM: x86: Add "governed" X86_FEATURE framework Sean Christopherson
2023-08-15 20:36 ` Sean Christopherson [this message]
2023-08-16  1:36   ` [PATCH v3 01/15] KVM: x86: Add a framework for enabling KVM-governed x86 features Huang, Kai
2023-08-16 14:20     ` Sean Christopherson
2023-08-16 22:46       ` Huang, Kai
2023-08-16 23:01   ` Yuan Yao
2023-08-17  2:11   ` Binbin Wu
2023-08-15 20:36 ` [PATCH v3 02/15] KVM: x86/mmu: Use KVM-governed feature framework to track "GBPAGES enabled" Sean Christopherson
2023-08-16  2:10   ` Yuan Yao
2023-08-15 20:36 ` [PATCH v3 03/15] KVM: VMX: Recompute "XSAVES enabled" only after CPUID update Sean Christopherson
2023-08-16  2:26   ` Yuan Yao
2023-08-15 20:36 ` [PATCH v3 04/15] KVM: VMX: Check KVM CPU caps, not just VMX MSR support, for XSAVE enabling Sean Christopherson
2023-08-16  8:07   ` Yuan Yao
2023-08-15 20:36 ` [PATCH v3 05/15] KVM: VMX: Rename XSAVES control to follow KVM's preferred "ENABLE_XYZ" Sean Christopherson
2023-08-16  7:50   ` Vitaly Kuznetsov
2023-08-16 14:15     ` Sean Christopherson
2023-08-15 20:36 ` [PATCH v3 06/15] KVM: x86: Use KVM-governed feature framework to track "XSAVES enabled" Sean Christopherson
2023-08-16  2:58   ` Yuan Yao
2023-08-16  3:21     ` Yuan Yao
2023-08-15 20:36 ` [PATCH v3 07/15] KVM: nVMX: Use KVM-governed feature framework to track "nested VMX enabled" Sean Christopherson
2023-08-16  2:25   ` Huang, Kai
2023-08-16  2:45   ` Huang, Kai
2023-08-16 14:42     ` Sean Christopherson
2023-08-15 20:36 ` [PATCH v3 08/15] KVM: nSVM: Use KVM-governed feature framework to track "NRIPS enabled" Sean Christopherson
2023-08-16  6:18   ` Yuan Yao
2023-08-15 20:36 ` [PATCH v3 09/15] KVM: nSVM: Use KVM-governed feature framework to track "TSC scaling enabled" Sean Christopherson
2023-08-16  6:35   ` Yuan Yao
2023-08-16 13:44     ` Sean Christopherson
2023-08-16 23:03       ` Yuan Yao
2023-08-15 20:36 ` [PATCH v3 10/15] KVM: nSVM: Use KVM-governed feature framework to track "vVM{SAVE,LOAD} enabled" Sean Christopherson
2023-08-15 20:36 ` [PATCH v3 11/15] KVM: nSVM: Use KVM-governed feature framework to track "LBRv enabled" Sean Christopherson
2023-08-15 20:36 ` [PATCH v3 12/15] KVM: nSVM: Use KVM-governed feature framework to track "Pause Filter enabled" Sean Christopherson
2023-08-16  7:24   ` Yuan Yao
2023-08-15 20:36 ` [PATCH v3 13/15] KVM: nSVM: Use KVM-governed feature framework to track "vGIF enabled" Sean Christopherson
2023-08-16  7:27   ` Yuan Yao
2023-08-15 20:36 ` [PATCH v3 14/15] KVM: nSVM: Use KVM-governed feature framework to track "vNMI enabled" Sean Christopherson
2023-08-15 20:36 ` [PATCH v3 15/15] KVM: x86: Disallow guest CPUID lookups when IRQs are disabled Sean Christopherson
2023-08-18  0:09 ` [PATCH v3 00/15] KVM: x86: Add "governed" X86_FEATURE framework Sean Christopherson

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=20230815203653.519297-2-seanjc@google.com \
    --to=seanjc@google.com \
    --cc=guang.zeng@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=vkuznets@redhat.com \
    --cc=yuan.yao@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).