[PATCH v2 13/36] KVM: nVMX: Update intercept on TSC deadline MSR

isaku.yamahata@intel.com posted 36 patches 3 weeks, 6 days ago
[PATCH v2 13/36] KVM: nVMX: Update intercept on TSC deadline MSR
Posted by isaku.yamahata@intel.com 3 weeks, 6 days ago
From: Isaku Yamahata <isaku.yamahata@intel.com>

When APIC timer virtualization is enabled, the hardware handles the access
to the guest TSC deadline MSR, not by the VMM.  Disable/enable MSR
intercept on TSC DEADLINE MSR based on the APIC timer virtualization bit of
tertiary processor-based execution control.

Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
---
 arch/x86/kvm/vmx/nested.c | 22 ++++++++++++++++++++++
 arch/x86/kvm/vmx/nested.h |  5 +++++
 2 files changed, 27 insertions(+)

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 1bd5e164e285..8bb8734cc690 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -598,6 +598,26 @@ static inline void enable_x2apic_msr_intercepts(unsigned long *msr_bitmap)
 	}
 }
 
+static inline void prepare_tsc_deadline_msr_intercepts(struct vmcs12 *vmcs12,
+						       unsigned long *msr_bitmap_l1,
+						       unsigned long *msr_bitmap_l0)
+{
+	if (nested_cpu_has_guest_apic_timer(vmcs12)) {
+		if (vmx_test_msr_bitmap_read(msr_bitmap_l1, MSR_IA32_TSC_DEADLINE))
+			vmx_set_msr_bitmap_read(msr_bitmap_l0, MSR_IA32_TSC_DEADLINE);
+		else
+			vmx_clear_msr_bitmap_read(msr_bitmap_l0, MSR_IA32_TSC_DEADLINE);
+
+		if (vmx_test_msr_bitmap_write(msr_bitmap_l1, MSR_IA32_TSC_DEADLINE))
+			vmx_set_msr_bitmap_write(msr_bitmap_l0, MSR_IA32_TSC_DEADLINE);
+		else
+			vmx_clear_msr_bitmap_write(msr_bitmap_l0, MSR_IA32_TSC_DEADLINE);
+	} else {
+		vmx_set_msr_bitmap_read(msr_bitmap_l0, MSR_IA32_TSC_DEADLINE);
+		vmx_set_msr_bitmap_write(msr_bitmap_l0, MSR_IA32_TSC_DEADLINE);
+	}
+}
+
 #define BUILD_NVMX_MSR_INTERCEPT_HELPER(rw)					\
 static inline									\
 void nested_vmx_set_msr_##rw##_intercept(struct vcpu_vmx *vmx,			\
@@ -745,6 +765,8 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
 		}
 	}
 
+	prepare_tsc_deadline_msr_intercepts(vmcs12, msr_bitmap_l1, msr_bitmap_l0);
+
 	/*
 	 * Always check vmcs01's bitmap to honor userspace MSR filters and any
 	 * other runtime changes to vmcs01's bitmap, e.g. dynamic pass-through.
diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h
index 52bf035bcc03..6df2cfb20d87 100644
--- a/arch/x86/kvm/vmx/nested.h
+++ b/arch/x86/kvm/vmx/nested.h
@@ -286,6 +286,11 @@ static inline bool nested_cpu_has_encls_exit(struct vmcs12 *vmcs12)
 	return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENCLS_EXITING);
 }
 
+static inline bool nested_cpu_has_guest_apic_timer(struct vmcs12 *vmcs12)
+{
+	return nested_cpu_has3(vmcs12, TERTIARY_EXEC_GUEST_APIC_TIMER);
+}
+
 /*
  * if fixed0[i] == 1: val[i] must be 1
  * if fixed1[i] == 0: val[i] must be 0
-- 
2.45.2