lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1515167000-51323-1-git-send-email-pbonzini@redhat.com>
Date:   Fri,  5 Jan 2018 16:43:20 +0100
From:   Paolo Bonzini <pbonzini@...hat.com>
To:     linux-kernel@...r.kernel.org, kvm@...r.kernel.org
Cc:     Luwei Kang <luwei.kang@...el.com>
Subject: [PATCH] KVM: VMX: use same MSR bitmaps for 32-/64-bit modes, fix MSR bitmaps for processor tracing

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.

Remove the long-mode bitmaps set, and touch all the three remaining
bitmaps in vmx_disable_intercept_for_msr and vmx_enable_intercept_for_msr.

Fixes: 3bd1f85e893daec4f3982d1d45b6bfc0683442c4
Cc: Luwei Kang <luwei.kang@...el.com>
Signed-off-by: Paolo Bonzini <pbonzini@...hat.com>
---
 arch/x86/kvm/vmx.c | 126 ++++++++++++++++++++---------------------------------
 1 file changed, 48 insertions(+), 78 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 11321cc4129a..ea5b52dc2d78 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -935,12 +935,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_NOX2APIC,
+	VMX_MSR_BITMAP_X2APIC_APICV,
+	VMX_MSR_BITMAP_X2APIC,
 	VMX_VMREAD_BITMAP,
 	VMX_VMWRITE_BITMAP,
 	VMX_BITMAP_NR
@@ -948,12 +945,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_nox2apic              (vmx_bitmap[VMX_MSR_BITMAP_NOX2APIC])
+#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])
 
@@ -2203,8 +2197,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);
@@ -2222,8 +2215,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);
@@ -2635,21 +2627,12 @@ static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu)
 		 (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;
+			msr_bitmap = vmx_msr_bitmap_x2apic_apicv;
 		} else {
-			if (is_long_mode(vcpu))
-				msr_bitmap = vmx_msr_bitmap_longmode_x2apic;
-			else
-				msr_bitmap = vmx_msr_bitmap_legacy_x2apic;
+			msr_bitmap = vmx_msr_bitmap_x2apic;
 		}
 	} else {
-		if (is_long_mode(vcpu))
-			msr_bitmap = vmx_msr_bitmap_longmode;
-		else
-			msr_bitmap = vmx_msr_bitmap_legacy;
+		msr_bitmap = vmx_msr_bitmap_nox2apic;
 	}
 
 	vmcs_write64(MSR_BITMAP, __pa(msr_bitmap));
@@ -5211,22 +5194,24 @@ 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,
-						msr, MSR_TYPE_R | MSR_TYPE_W);
+	__vmx_disable_intercept_for_msr(vmx_msr_bitmap_nox2apic,
+					msr, MSR_TYPE_R | MSR_TYPE_W);
+	__vmx_disable_intercept_for_msr(vmx_msr_bitmap_x2apic,
+					msr, MSR_TYPE_R | MSR_TYPE_W);
+	__vmx_disable_intercept_for_msr(vmx_msr_bitmap_x2apic_apicv,
+					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,
-						msr, MSR_TYPE_R | MSR_TYPE_W);
+	__vmx_enable_intercept_for_msr(vmx_msr_bitmap_nox2apic,
+				       msr, MSR_TYPE_R | MSR_TYPE_W);
+	__vmx_enable_intercept_for_msr(vmx_msr_bitmap_x2apic,
+				       msr, MSR_TYPE_R | MSR_TYPE_W);
+	__vmx_enable_intercept_for_msr(vmx_msr_bitmap_x2apic_apicv,
+				       msr, MSR_TYPE_R | MSR_TYPE_W);
 }
 
 static void pt_disable_intercept_for_msr(bool flag)
@@ -5235,36 +5220,29 @@ static void pt_disable_intercept_for_msr(bool flag)
 	unsigned int addr_num = kvm_get_pt_addr_cnt();
 
 	if (flag) {
-		vmx_disable_intercept_for_msr(MSR_IA32_RTIT_STATUS, false);
-		vmx_disable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_BASE, false);
-		vmx_disable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_MASK, false);
-		vmx_disable_intercept_for_msr(MSR_IA32_RTIT_CR3_MATCH, false);
+		vmx_disable_intercept_for_msr(MSR_IA32_RTIT_STATUS);
+		vmx_disable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_BASE);
+		vmx_disable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_MASK);
+		vmx_disable_intercept_for_msr(MSR_IA32_RTIT_CR3_MATCH);
 		for (i = 0; i < addr_num; i++)
-			vmx_disable_intercept_for_msr(MSR_IA32_RTIT_ADDR0_A + i,
-									false);
+			vmx_disable_intercept_for_msr(MSR_IA32_RTIT_ADDR0_A + i);
 	} else {
-		vmx_enable_intercept_for_msr(MSR_IA32_RTIT_STATUS, false);
-		vmx_enable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_BASE, false);
-		vmx_enable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_MASK, false);
-		vmx_enable_intercept_for_msr(MSR_IA32_RTIT_CR3_MATCH, false);
+		vmx_enable_intercept_for_msr(MSR_IA32_RTIT_STATUS);
+		vmx_enable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_BASE);
+		vmx_enable_intercept_for_msr(MSR_IA32_RTIT_OUTPUT_MASK);
+		vmx_enable_intercept_for_msr(MSR_IA32_RTIT_CR3_MATCH);
 		for (i = 0; i < addr_num; i++)
-			vmx_enable_intercept_for_msr(MSR_IA32_RTIT_ADDR0_A + i,
-									false);
+			vmx_enable_intercept_for_msr(MSR_IA32_RTIT_ADDR0_A + i);
 	}
 }
 
 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,
+	__vmx_disable_intercept_for_msr(vmx_msr_bitmap_x2apic_apicv,
 					msr, type);
-	__vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_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,
+	if (!apicv_only)
+		__vmx_disable_intercept_for_msr(vmx_msr_bitmap_x2apic,
 				msr, type);
-	}
 }
 
 static bool vmx_get_enable_apicv(struct kvm_vcpu *vcpu)
@@ -5733,7 +5711,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_nox2apic));
 
 	vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */
 
@@ -7047,8 +7025,9 @@ 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_nox2apic, 0xff, PAGE_SIZE);
+	memset(vmx_msr_bitmap_x2apic, 0xff, PAGE_SIZE);
+	memset(vmx_msr_bitmap_x2apic_apicv, 0xff, PAGE_SIZE);
 
 	if (setup_vmcs_config(&vmcs_config) < 0) {
 		r = -EIO;
@@ -7113,21 +7092,12 @@ 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);
-
-	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);
+	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);
 
 	set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */
 
-- 
1.8.3.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ