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