[1/2] KVM: x86: Advertise CPUID.(EAX=7,ECX=2):EDX[5:0] to userspace

Message ID 20231024001636.890236-1-jmattson@google.com
State New
Headers
Series [1/2] KVM: x86: Advertise CPUID.(EAX=7,ECX=2):EDX[5:0] to userspace |

Commit Message

Jim Mattson Oct. 24, 2023, 12:16 a.m. UTC
  The low five bits {INTEL_PSFD, IPRED_CTRL, RRSBA_CTRL, DDPD_U, BHI_CTRL}
advertise the availability of specific bits in IA32_SPEC_CTRL. Since KVM
dynamically determines the legal IA32_SPEC_CTRL bits for the underlying
hardware, the hard work has already been done. Just let userspace know
that a guest can use these IA32_SPEC_CTRL bits.

The sixth bit (MCDT_NO) states that the processor does not exhibit MXCSR
Configuration Dependent Timing (MCDT) behavior. This is an inherent
property of the physical processor that is inherited by the virtual
CPU. Pass that information on to userspace.

Signed-off-by: Jim Mattson <jmattson@google.com>
---
 arch/x86/kvm/cpuid.c         | 21 ++++++++++++++++++---
 arch/x86/kvm/reverse_cpuid.h | 12 ++++++++++++
 2 files changed, 30 insertions(+), 3 deletions(-)
  

Comments

Chao Gao Oct. 25, 2023, 7:06 a.m. UTC | #1
On Mon, Oct 23, 2023 at 05:16:35PM -0700, Jim Mattson wrote:
>The low five bits {INTEL_PSFD, IPRED_CTRL, RRSBA_CTRL, DDPD_U, BHI_CTRL}
>advertise the availability of specific bits in IA32_SPEC_CTRL. Since KVM
>dynamically determines the legal IA32_SPEC_CTRL bits for the underlying
>hardware, the hard work has already been done. Just let userspace know
>that a guest can use these IA32_SPEC_CTRL bits.
>
>The sixth bit (MCDT_NO) states that the processor does not exhibit MXCSR
>Configuration Dependent Timing (MCDT) behavior. This is an inherent
>property of the physical processor that is inherited by the virtual
>CPU. Pass that information on to userspace.
>
>Signed-off-by: Jim Mattson <jmattson@google.com>

Reviewed-by: Chao Gao <chao.gao@intel.com>
  
Sean Christopherson Dec. 1, 2023, 1:52 a.m. UTC | #2
On Mon, 23 Oct 2023 17:16:35 -0700, Jim Mattson wrote:
> The low five bits {INTEL_PSFD, IPRED_CTRL, RRSBA_CTRL, DDPD_U, BHI_CTRL}
> advertise the availability of specific bits in IA32_SPEC_CTRL. Since KVM
> dynamically determines the legal IA32_SPEC_CTRL bits for the underlying
> hardware, the hard work has already been done. Just let userspace know
> that a guest can use these IA32_SPEC_CTRL bits.
> 
> The sixth bit (MCDT_NO) states that the processor does not exhibit MXCSR
> Configuration Dependent Timing (MCDT) behavior. This is an inherent
> property of the physical processor that is inherited by the virtual
> CPU. Pass that information on to userspace.
> 
> [...]

Applied to kvm-x86 misc, with macros to make Jim queasy (but they really do
guard against copy+paste errors).

[1/2] KVM: x86: Advertise CPUID.(EAX=7,ECX=2):EDX[5:0] to userspace
      https://github.com/kvm-x86/linux/commit/eefe5e668209
[2/2] KVM: x86: Use a switch statement and macros in __feature_translate()
      https://github.com/kvm-x86/linux/commit/80c883db87d9

--
https://github.com/kvm-x86/linux/tree/next
  
Jim Mattson Dec. 1, 2023, 4:18 a.m. UTC | #3
On Thu, Nov 30, 2023 at 5:54 PM Sean Christopherson <seanjc@google.com> wrote:
>
> On Mon, 23 Oct 2023 17:16:35 -0700, Jim Mattson wrote:
> > The low five bits {INTEL_PSFD, IPRED_CTRL, RRSBA_CTRL, DDPD_U, BHI_CTRL}
> > advertise the availability of specific bits in IA32_SPEC_CTRL. Since KVM
> > dynamically determines the legal IA32_SPEC_CTRL bits for the underlying
> > hardware, the hard work has already been done. Just let userspace know
> > that a guest can use these IA32_SPEC_CTRL bits.
> >
> > The sixth bit (MCDT_NO) states that the processor does not exhibit MXCSR
> > Configuration Dependent Timing (MCDT) behavior. This is an inherent
> > property of the physical processor that is inherited by the virtual
> > CPU. Pass that information on to userspace.
> >
> > [...]
>
> Applied to kvm-x86 misc, with macros to make Jim queasy (but they really do
> guard against copy+paste errors).

They are also quite effective at guarding against code search. :)

> [1/2] KVM: x86: Advertise CPUID.(EAX=7,ECX=2):EDX[5:0] to userspace
>       https://github.com/kvm-x86/linux/commit/eefe5e668209
> [2/2] KVM: x86: Use a switch statement and macros in __feature_translate()
>       https://github.com/kvm-x86/linux/commit/80c883db87d9
>
> --
> https://github.com/kvm-x86/linux/tree/next
  

Patch

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index c134c181ba80..e5fc888b2715 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -677,6 +677,11 @@  void kvm_set_cpu_caps(void)
 		F(AMX_COMPLEX)
 	);
 
+	kvm_cpu_cap_init_kvm_defined(CPUID_7_2_EDX,
+		F(INTEL_PSFD) | F(IPRED_CTRL) | F(RRSBA_CTRL) | F(DDPD_U) |
+		F(BHI_CTRL) | F(MCDT_NO)
+	);
+
 	kvm_cpu_cap_mask(CPUID_D_1_EAX,
 		F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | F(XSAVES) | f_xfd
 	);
@@ -957,13 +962,13 @@  static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
 		break;
 	/* function 7 has additional index. */
 	case 7:
-		entry->eax = min(entry->eax, 1u);
+		max_idx = entry->eax = min(entry->eax, 2u);
 		cpuid_entry_override(entry, CPUID_7_0_EBX);
 		cpuid_entry_override(entry, CPUID_7_ECX);
 		cpuid_entry_override(entry, CPUID_7_EDX);
 
-		/* KVM only supports 0x7.0 and 0x7.1, capped above via min(). */
-		if (entry->eax == 1) {
+		/* KVM only supports up to 0x7.2, capped above via min(). */
+		if (max_idx >= 1) {
 			entry = do_host_cpuid(array, function, 1);
 			if (!entry)
 				goto out;
@@ -973,6 +978,16 @@  static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
 			entry->ebx = 0;
 			entry->ecx = 0;
 		}
+		if (max_idx >= 2) {
+			entry = do_host_cpuid(array, function, 2);
+			if (!entry)
+				goto out;
+
+			cpuid_entry_override(entry, CPUID_7_2_EDX);
+			entry->ecx = 0;
+			entry->ebx = 0;
+			entry->eax = 0;
+		}
 		break;
 	case 0xa: { /* Architectural Performance Monitoring */
 		union cpuid10_eax eax;
diff --git a/arch/x86/kvm/reverse_cpuid.h b/arch/x86/kvm/reverse_cpuid.h
index b81650678375..17007016d8b5 100644
--- a/arch/x86/kvm/reverse_cpuid.h
+++ b/arch/x86/kvm/reverse_cpuid.h
@@ -16,6 +16,7 @@  enum kvm_only_cpuid_leafs {
 	CPUID_7_1_EDX,
 	CPUID_8000_0007_EDX,
 	CPUID_8000_0022_EAX,
+	CPUID_7_2_EDX,
 	NR_KVM_CPU_CAPS,
 
 	NKVMCAPINTS = NR_KVM_CPU_CAPS - NCAPINTS,
@@ -46,6 +47,14 @@  enum kvm_only_cpuid_leafs {
 #define X86_FEATURE_AMX_COMPLEX         KVM_X86_FEATURE(CPUID_7_1_EDX, 8)
 #define X86_FEATURE_PREFETCHITI         KVM_X86_FEATURE(CPUID_7_1_EDX, 14)
 
+/* Intel-defined sub-features, CPUID level 0x00000007:2 (EDX) */
+#define X86_FEATURE_INTEL_PSFD		KVM_X86_FEATURE(CPUID_7_2_EDX, 0)
+#define X86_FEATURE_IPRED_CTRL		KVM_X86_FEATURE(CPUID_7_2_EDX, 1)
+#define KVM_X86_FEATURE_RRSBA_CTRL	KVM_X86_FEATURE(CPUID_7_2_EDX, 2)
+#define X86_FEATURE_DDPD_U		KVM_X86_FEATURE(CPUID_7_2_EDX, 3)
+#define X86_FEATURE_BHI_CTRL		KVM_X86_FEATURE(CPUID_7_2_EDX, 4)
+#define X86_FEATURE_MCDT_NO		KVM_X86_FEATURE(CPUID_7_2_EDX, 5)
+
 /* CPUID level 0x80000007 (EDX). */
 #define KVM_X86_FEATURE_CONSTANT_TSC	KVM_X86_FEATURE(CPUID_8000_0007_EDX, 8)
 
@@ -80,6 +89,7 @@  static const struct cpuid_reg reverse_cpuid[] = {
 	[CPUID_8000_0007_EDX] = {0x80000007, 0, CPUID_EDX},
 	[CPUID_8000_0021_EAX] = {0x80000021, 0, CPUID_EAX},
 	[CPUID_8000_0022_EAX] = {0x80000022, 0, CPUID_EAX},
+	[CPUID_7_2_EDX]       = {         7, 2, CPUID_EDX},
 };
 
 /*
@@ -116,6 +126,8 @@  static __always_inline u32 __feature_translate(int x86_feature)
 		return KVM_X86_FEATURE_CONSTANT_TSC;
 	else if (x86_feature == X86_FEATURE_PERFMON_V2)
 		return KVM_X86_FEATURE_PERFMON_V2;
+	else if (x86_feature == X86_FEATURE_RRSBA_CTRL)
+		return KVM_X86_FEATURE_RRSBA_CTRL;
 
 	return x86_feature;
 }