[PATCH 2/3] KVM: VMX: use same MSR bitmaps for 32-/64-bit modes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



KVM has a small optimization where it doesn't save/restore
MSR_KERNEL_GS_BASE if the guest is in 32-bit mode.  However, this
complicates the code noticeably by doubling the number of possible MSR
bitmaps.  In addition, pt_disable_intercept_for_msr was only updating the
"basic" MSR bitmap, because x2apic and x2apic_apicv are memcpy'd just
once in hardware_setup.

In order to simplify the upcoming introduction of per-VCPU bitmaps,
remove the long-mode bitmaps set.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 arch/x86/kvm/vmx.c | 95 +++++++++++++++++-------------------------------------
 1 file changed, 29 insertions(+), 66 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index d81fd4a87f2b..d8057fac336a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -913,12 +913,9 @@ static bool nested_vmx_is_page_fault_vmexit(struct vmcs12 *vmcs12,
 static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock);
 
 enum {
-	VMX_MSR_BITMAP_LEGACY,
-	VMX_MSR_BITMAP_LONGMODE,
-	VMX_MSR_BITMAP_LEGACY_X2APIC_APICV,
-	VMX_MSR_BITMAP_LONGMODE_X2APIC_APICV,
-	VMX_MSR_BITMAP_LEGACY_X2APIC,
-	VMX_MSR_BITMAP_LONGMODE_X2APIC,
+	VMX_MSR_BITMAP,
+	VMX_MSR_BITMAP_X2APIC_APICV,
+	VMX_MSR_BITMAP_X2APIC,
 	VMX_VMREAD_BITMAP,
 	VMX_VMWRITE_BITMAP,
 	VMX_BITMAP_NR
@@ -926,12 +923,9 @@ enum {
 
 static unsigned long *vmx_bitmap[VMX_BITMAP_NR];
 
-#define vmx_msr_bitmap_legacy                (vmx_bitmap[VMX_MSR_BITMAP_LEGACY])
-#define vmx_msr_bitmap_longmode              (vmx_bitmap[VMX_MSR_BITMAP_LONGMODE])
-#define vmx_msr_bitmap_legacy_x2apic_apicv   (vmx_bitmap[VMX_MSR_BITMAP_LEGACY_X2APIC_APICV])
-#define vmx_msr_bitmap_longmode_x2apic_apicv (vmx_bitmap[VMX_MSR_BITMAP_LONGMODE_X2APIC_APICV])
-#define vmx_msr_bitmap_legacy_x2apic         (vmx_bitmap[VMX_MSR_BITMAP_LEGACY_X2APIC])
-#define vmx_msr_bitmap_longmode_x2apic       (vmx_bitmap[VMX_MSR_BITMAP_LONGMODE_X2APIC])
+#define vmx_msr_bitmap                       (vmx_bitmap[VMX_MSR_BITMAP])
+#define vmx_msr_bitmap_x2apic_apicv          (vmx_bitmap[VMX_MSR_BITMAP_X2APIC_APICV])
+#define vmx_msr_bitmap_x2apic                (vmx_bitmap[VMX_MSR_BITMAP_X2APIC])
 #define vmx_vmread_bitmap                    (vmx_bitmap[VMX_VMREAD_BITMAP])
 #define vmx_vmwrite_bitmap                   (vmx_bitmap[VMX_VMWRITE_BITMAP])
 
@@ -2119,8 +2113,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
 
 #ifdef CONFIG_X86_64
 	rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
-	if (is_long_mode(&vmx->vcpu))
-		wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
+	wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
 #endif
 	if (boot_cpu_has(X86_FEATURE_MPX))
 		rdmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs);
@@ -2138,8 +2131,7 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 	++vmx->vcpu.stat.host_state_reload;
 	vmx->host_state.loaded = 0;
 #ifdef CONFIG_X86_64
-	if (is_long_mode(&vmx->vcpu))
-		rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
+	rdmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base);
 #endif
 	if (vmx->host_state.gs_ldt_reload_needed) {
 		kvm_load_ldt(vmx->host_state.ldt_sel);
@@ -2541,22 +2533,12 @@ static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu)
 	else if (cpu_has_secondary_exec_ctrls() &&
 		 (vmcs_read32(SECONDARY_VM_EXEC_CONTROL) &
 		  SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE)) {
-		if (enable_apicv && kvm_vcpu_apicv_active(vcpu)) {
-			if (is_long_mode(vcpu))
-				msr_bitmap = vmx_msr_bitmap_longmode_x2apic_apicv;
-			else
-				msr_bitmap = vmx_msr_bitmap_legacy_x2apic_apicv;
-		} else {
-			if (is_long_mode(vcpu))
-				msr_bitmap = vmx_msr_bitmap_longmode_x2apic;
-			else
-				msr_bitmap = vmx_msr_bitmap_legacy_x2apic;
-		}
-	} else {
-		if (is_long_mode(vcpu))
-			msr_bitmap = vmx_msr_bitmap_longmode;
+		if (enable_apicv && kvm_vcpu_apicv_active(vcpu))
+			msr_bitmap = vmx_msr_bitmap_x2apic_apicv;
 		else
-			msr_bitmap = vmx_msr_bitmap_legacy;
+			msr_bitmap = vmx_msr_bitmap_x2apic;
+	} else {
+		msr_bitmap = vmx_msr_bitmap;
 	}
 
 	vmcs_write64(MSR_BITMAP, __pa(msr_bitmap));
@@ -5014,21 +4996,15 @@ static void nested_vmx_disable_intercept_for_msr(unsigned long *msr_bitmap_l1,
 	}
 }
 
-static void vmx_disable_intercept_for_msr(u32 msr, bool longmode_only)
+static void vmx_disable_intercept_for_msr(u32 msr)
 {
-	if (!longmode_only)
-		__vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy,
-						msr, MSR_TYPE_R | MSR_TYPE_W);
-	__vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode,
+	__vmx_disable_intercept_for_msr(vmx_msr_bitmap,
 						msr, MSR_TYPE_R | MSR_TYPE_W);
 }
 
-static void vmx_enable_intercept_for_msr(u32 msr, bool longmode_only)
+static void vmx_enable_intercept_for_msr(u32 msr)
 {
-	if (!longmode_only)
-		__vmx_enable_intercept_for_msr(vmx_msr_bitmap_legacy,
-						msr, MSR_TYPE_R | MSR_TYPE_W);
-	__vmx_enable_intercept_for_msr(vmx_msr_bitmap_longmode,
+	__vmx_enable_intercept_for_msr(vmx_msr_bitmap,
 						msr, MSR_TYPE_R | MSR_TYPE_W);
 }
 
@@ -5036,15 +5012,9 @@ static void vmx_enable_intercept_for_msr(u32 msr, bool longmode_only)
 
 static void vmx_disable_intercept_msr_x2apic(u32 msr, int type, bool apicv_only)
 {
-	__vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic_apicv,
-					msr, type);
-	__vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic_apicv,
-					msr, type);
+	__vmx_disable_intercept_for_msr(vmx_msr_bitmap_x2apic_apicv, msr, type);
 	if (!apicv_only) {
-		__vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic,
-				msr, type);
-		__vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic,
-				msr, type);
+		__vmx_disable_intercept_for_msr(vmx_msr_bitmap_x2apic, msr, type);
 	}
 }
 
@@ -5488,7 +5458,7 @@ static void vmx_vcpu_setup(struct vcpu_vmx *vmx)
 		vmcs_write64(VMWRITE_BITMAP, __pa(vmx_vmwrite_bitmap));
 	}
 	if (cpu_has_vmx_msr_bitmap())
-		vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap_legacy));
+		vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap));
 
 	vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */
 
@@ -6794,8 +6764,7 @@ static __init int hardware_setup(void)
 	memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
 	memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
 
-	memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
-	memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
+	memset(vmx_msr_bitmap, 0xff, PAGE_SIZE);
 
 	if (setup_vmcs_config(&vmcs_config) < 0) {
 		r = -EIO;
@@ -6860,21 +6829,15 @@ static __init int hardware_setup(void)
 		kvm_tsc_scaling_ratio_frac_bits = 48;
 	}
 
-	vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
-	vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
-	vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
-	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
-	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
-	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
+	vmx_disable_intercept_for_msr(MSR_FS_BASE);
+	vmx_disable_intercept_for_msr(MSR_GS_BASE);
+	vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE);
+	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS);
+	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP);
+	vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP);
 
-	memcpy(vmx_msr_bitmap_legacy_x2apic_apicv,
-			vmx_msr_bitmap_legacy, PAGE_SIZE);
-	memcpy(vmx_msr_bitmap_longmode_x2apic_apicv,
-			vmx_msr_bitmap_longmode, PAGE_SIZE);
-	memcpy(vmx_msr_bitmap_legacy_x2apic,
-			vmx_msr_bitmap_legacy, PAGE_SIZE);
-	memcpy(vmx_msr_bitmap_longmode_x2apic,
-			vmx_msr_bitmap_longmode, PAGE_SIZE);
+	memcpy(vmx_msr_bitmap_x2apic_apicv, vmx_msr_bitmap, PAGE_SIZE);
+	memcpy(vmx_msr_bitmap_x2apic, vmx_msr_bitmap, PAGE_SIZE);
 
 	set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */
 
-- 
1.8.3.1





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux