diff options
author | Liu, Jinsong <jinsong.liu@intel.com> | 2014-02-24 05:55:46 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-02-24 06:14:00 -0500 |
commit | da8999d31818fdc8508d527ba3aac2e128005af4 (patch) | |
tree | ca2f32a5f2aeaf957803e189ad7a264be63ef225 /arch/x86/kvm | |
parent | 56c103ec040b1944c8866f79aa768265c0dd2986 (diff) |
KVM: x86: Intel MPX vmx and msr handle
From caddc009a6d2019034af8f2346b2fd37a81608d0 Mon Sep 17 00:00:00 2001
From: Liu Jinsong <jinsong.liu@intel.com>
Date: Mon, 24 Feb 2014 18:11:11 +0800
Subject: [PATCH v5 1/3] KVM: x86: Intel MPX vmx and msr handle
This patch handle vmx and msr of Intel MPX feature.
Signed-off-by: Xudong Hao <xudong.hao@intel.com>
Signed-off-by: Liu Jinsong <jinsong.liu@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/vmx.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a06f101ef64b..e4e4b50f57e6 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -441,6 +441,7 @@ struct vcpu_vmx { | |||
441 | #endif | 441 | #endif |
442 | int gs_ldt_reload_needed; | 442 | int gs_ldt_reload_needed; |
443 | int fs_reload_needed; | 443 | int fs_reload_needed; |
444 | u64 msr_host_bndcfgs; | ||
444 | } host_state; | 445 | } host_state; |
445 | struct { | 446 | struct { |
446 | int vm86_active; | 447 | int vm86_active; |
@@ -1710,6 +1711,8 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) | |||
1710 | if (is_long_mode(&vmx->vcpu)) | 1711 | if (is_long_mode(&vmx->vcpu)) |
1711 | wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); | 1712 | wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_guest_kernel_gs_base); |
1712 | #endif | 1713 | #endif |
1714 | if (boot_cpu_has(X86_FEATURE_MPX)) | ||
1715 | rdmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs); | ||
1713 | for (i = 0; i < vmx->save_nmsrs; ++i) | 1716 | for (i = 0; i < vmx->save_nmsrs; ++i) |
1714 | kvm_set_shared_msr(vmx->guest_msrs[i].index, | 1717 | kvm_set_shared_msr(vmx->guest_msrs[i].index, |
1715 | vmx->guest_msrs[i].data, | 1718 | vmx->guest_msrs[i].data, |
@@ -1747,6 +1750,8 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx) | |||
1747 | #ifdef CONFIG_X86_64 | 1750 | #ifdef CONFIG_X86_64 |
1748 | wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); | 1751 | wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); |
1749 | #endif | 1752 | #endif |
1753 | if (vmx->host_state.msr_host_bndcfgs) | ||
1754 | wrmsrl(MSR_IA32_BNDCFGS, vmx->host_state.msr_host_bndcfgs); | ||
1750 | /* | 1755 | /* |
1751 | * If the FPU is not active (through the host task or | 1756 | * If the FPU is not active (through the host task or |
1752 | * the guest vcpu), then restore the cr0.TS bit. | 1757 | * the guest vcpu), then restore the cr0.TS bit. |
@@ -2837,7 +2842,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
2837 | min |= VM_EXIT_HOST_ADDR_SPACE_SIZE; | 2842 | min |= VM_EXIT_HOST_ADDR_SPACE_SIZE; |
2838 | #endif | 2843 | #endif |
2839 | opt = VM_EXIT_SAVE_IA32_PAT | VM_EXIT_LOAD_IA32_PAT | | 2844 | opt = VM_EXIT_SAVE_IA32_PAT | VM_EXIT_LOAD_IA32_PAT | |
2840 | VM_EXIT_ACK_INTR_ON_EXIT; | 2845 | VM_EXIT_ACK_INTR_ON_EXIT | VM_EXIT_CLEAR_BNDCFGS; |
2841 | if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_EXIT_CTLS, | 2846 | if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_EXIT_CTLS, |
2842 | &_vmexit_control) < 0) | 2847 | &_vmexit_control) < 0) |
2843 | return -EIO; | 2848 | return -EIO; |
@@ -2854,7 +2859,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
2854 | _pin_based_exec_control &= ~PIN_BASED_POSTED_INTR; | 2859 | _pin_based_exec_control &= ~PIN_BASED_POSTED_INTR; |
2855 | 2860 | ||
2856 | min = 0; | 2861 | min = 0; |
2857 | opt = VM_ENTRY_LOAD_IA32_PAT; | 2862 | opt = VM_ENTRY_LOAD_IA32_PAT | VM_ENTRY_LOAD_BNDCFGS; |
2858 | if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_ENTRY_CTLS, | 2863 | if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_ENTRY_CTLS, |
2859 | &_vmentry_control) < 0) | 2864 | &_vmentry_control) < 0) |
2860 | return -EIO; | 2865 | return -EIO; |
@@ -7052,6 +7057,12 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) | |||
7052 | local_irq_enable(); | 7057 | local_irq_enable(); |
7053 | } | 7058 | } |
7054 | 7059 | ||
7060 | static bool vmx_mpx_supported(void) | ||
7061 | { | ||
7062 | return (vmcs_config.vmexit_ctrl & VM_EXIT_CLEAR_BNDCFGS) && | ||
7063 | (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS); | ||
7064 | } | ||
7065 | |||
7055 | static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) | 7066 | static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) |
7056 | { | 7067 | { |
7057 | u32 exit_intr_info; | 7068 | u32 exit_intr_info; |
@@ -8634,6 +8645,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
8634 | 8645 | ||
8635 | .check_intercept = vmx_check_intercept, | 8646 | .check_intercept = vmx_check_intercept, |
8636 | .handle_external_intr = vmx_handle_external_intr, | 8647 | .handle_external_intr = vmx_handle_external_intr, |
8648 | .mpx_supported = vmx_mpx_supported, | ||
8637 | }; | 8649 | }; |
8638 | 8650 | ||
8639 | static int __init vmx_init(void) | 8651 | static int __init vmx_init(void) |
@@ -8721,6 +8733,8 @@ static int __init vmx_init(void) | |||
8721 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); | 8733 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); |
8722 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); | 8734 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); |
8723 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); | 8735 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); |
8736 | vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true); | ||
8737 | |||
8724 | memcpy(vmx_msr_bitmap_legacy_x2apic, | 8738 | memcpy(vmx_msr_bitmap_legacy_x2apic, |
8725 | vmx_msr_bitmap_legacy, PAGE_SIZE); | 8739 | vmx_msr_bitmap_legacy, PAGE_SIZE); |
8726 | memcpy(vmx_msr_bitmap_longmode_x2apic, | 8740 | memcpy(vmx_msr_bitmap_longmode_x2apic, |