diff mbox series

[v2,14/25] KVM: VMX: Disable FRED if FRED consistency checks fail

Message ID 20240207172646.3981-15-xin3.li@intel.com
State New
Headers show
Series Enable FRED with KVM VMX | expand

Commit Message

Li, Xin3 Feb. 7, 2024, 5:26 p.m. UTC
Refuse to virtualize FRED if FRED consistency checks fail.

Suggested-by: Chao Gao <chao.gao@intel.com>
Signed-off-by: Xin Li <xin3.li@intel.com>
---
 arch/x86/kvm/vmx/capabilities.h | 10 ++++++++++
 arch/x86/kvm/vmx/vmx.c          |  2 ++
 2 files changed, 12 insertions(+)

Comments

Chao Gao April 30, 2024, 8:21 a.m. UTC | #1
On Thu, Feb 08, 2024 at 01:26:34AM +0800, Xin Li wrote:
>Refuse to virtualize FRED if FRED consistency checks fail.

After reading this, I realize some consistency checks are missing in
setup_vmcs_config(). Actually Sean requested some infrastructure for
vmcs_entry_exit_pairs to deal with secondary_vmexit_ctrl.

https://lore.kernel.org/kvm/ZU5F58_KRIHzxrMp@google.com/
Sean Christopherson June 13, 2024, 6 p.m. UTC | #2
On Tue, Apr 30, 2024, Chao Gao wrote:
> On Thu, Feb 08, 2024 at 01:26:34AM +0800, Xin Li wrote:
> >Refuse to virtualize FRED if FRED consistency checks fail.
> 
> After reading this, I realize some consistency checks are missing in
> setup_vmcs_config(). Actually Sean requested some infrastructure for
> vmcs_entry_exit_pairs to deal with secondary_vmexit_ctrl.

Yeah, this belongs in setup_vmcs_config(), e.g. to guarantee that discrepancies
between CPUs are detected.  I would also strongly prefer this be squashed with
the patch(es) that introduce recognition of the FRED fields, if only so that we
can avoid "consistency checks" in the shortlog (I thought this patch was going
to disable FRED if a VM-Enter consistency check failed, which would be... interesting).
diff mbox series

Patch

diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
index e8f3ad0f79ee..73bf6618c425 100644
--- a/arch/x86/kvm/vmx/capabilities.h
+++ b/arch/x86/kvm/vmx/capabilities.h
@@ -400,6 +400,16 @@  static inline bool vmx_pebs_supported(void)
 	return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept;
 }
 
+static inline bool cpu_has_vmx_fred(void)
+{
+	return boot_cpu_has(X86_FEATURE_FRED) &&
+		(vmcs_config.basic & VMX_BASIC_NESTED_EXCEPTION) &&
+		(vmcs_config.vmexit_ctrl & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) &&
+		(vmcs_config.secondary_vmexit_ctrl & SECONDARY_VM_EXIT_SAVE_IA32_FRED) &&
+		(vmcs_config.secondary_vmexit_ctrl & SECONDARY_VM_EXIT_LOAD_IA32_FRED) &&
+		(vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_FRED);
+}
+
 static inline bool cpu_has_notify_vmexit(void)
 {
 	return vmcs_config.cpu_based_2nd_exec_ctrl &
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 1f265d526daf..a484b9ac2400 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -8113,6 +8113,8 @@  static __init void vmx_set_cpu_caps(void)
 		kvm_cpu_cap_check_and_set(X86_FEATURE_DS);
 		kvm_cpu_cap_check_and_set(X86_FEATURE_DTES64);
 	}
+	if (!cpu_has_vmx_fred())
+		kvm_cpu_cap_clear(X86_FEATURE_FRED);
 
 	if (!enable_pmu)
 		kvm_cpu_cap_clear(X86_FEATURE_PDCM);