diff options
-rw-r--r-- | arch/x86/kvm/vmx.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ad1153a725a2..9bcc871f0635 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -216,6 +216,7 @@ struct __packed vmcs12 { | |||
216 | u64 virtual_apic_page_addr; | 216 | u64 virtual_apic_page_addr; |
217 | u64 apic_access_addr; | 217 | u64 apic_access_addr; |
218 | u64 ept_pointer; | 218 | u64 ept_pointer; |
219 | u64 xss_exit_bitmap; | ||
219 | u64 guest_physical_address; | 220 | u64 guest_physical_address; |
220 | u64 vmcs_link_pointer; | 221 | u64 vmcs_link_pointer; |
221 | u64 guest_ia32_debugctl; | 222 | u64 guest_ia32_debugctl; |
@@ -618,6 +619,7 @@ static const unsigned short vmcs_field_to_offset_table[] = { | |||
618 | FIELD64(VIRTUAL_APIC_PAGE_ADDR, virtual_apic_page_addr), | 619 | FIELD64(VIRTUAL_APIC_PAGE_ADDR, virtual_apic_page_addr), |
619 | FIELD64(APIC_ACCESS_ADDR, apic_access_addr), | 620 | FIELD64(APIC_ACCESS_ADDR, apic_access_addr), |
620 | FIELD64(EPT_POINTER, ept_pointer), | 621 | FIELD64(EPT_POINTER, ept_pointer), |
622 | FIELD64(XSS_EXIT_BITMAP, xss_exit_bitmap), | ||
621 | FIELD64(GUEST_PHYSICAL_ADDRESS, guest_physical_address), | 623 | FIELD64(GUEST_PHYSICAL_ADDRESS, guest_physical_address), |
622 | FIELD64(VMCS_LINK_POINTER, vmcs_link_pointer), | 624 | FIELD64(VMCS_LINK_POINTER, vmcs_link_pointer), |
623 | FIELD64(GUEST_IA32_DEBUGCTL, guest_ia32_debugctl), | 625 | FIELD64(GUEST_IA32_DEBUGCTL, guest_ia32_debugctl), |
@@ -1104,6 +1106,12 @@ static inline int nested_cpu_has_ept(struct vmcs12 *vmcs12) | |||
1104 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_EPT); | 1106 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_EPT); |
1105 | } | 1107 | } |
1106 | 1108 | ||
1109 | static inline bool nested_cpu_has_xsaves(struct vmcs12 *vmcs12) | ||
1110 | { | ||
1111 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES) && | ||
1112 | vmx_xsaves_supported(); | ||
1113 | } | ||
1114 | |||
1107 | static inline bool is_exception(u32 intr_info) | 1115 | static inline bool is_exception(u32 intr_info) |
1108 | { | 1116 | { |
1109 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) | 1117 | return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) |
@@ -2392,7 +2400,8 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
2392 | nested_vmx_secondary_ctls_high &= | 2400 | nested_vmx_secondary_ctls_high &= |
2393 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | | 2401 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | |
2394 | SECONDARY_EXEC_UNRESTRICTED_GUEST | | 2402 | SECONDARY_EXEC_UNRESTRICTED_GUEST | |
2395 | SECONDARY_EXEC_WBINVD_EXITING; | 2403 | SECONDARY_EXEC_WBINVD_EXITING | |
2404 | SECONDARY_EXEC_XSAVES; | ||
2396 | 2405 | ||
2397 | if (enable_ept) { | 2406 | if (enable_ept) { |
2398 | /* nested EPT: emulate EPT also to L1 */ | 2407 | /* nested EPT: emulate EPT also to L1 */ |
@@ -7286,6 +7295,14 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
7286 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_WBINVD_EXITING); | 7295 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_WBINVD_EXITING); |
7287 | case EXIT_REASON_XSETBV: | 7296 | case EXIT_REASON_XSETBV: |
7288 | return 1; | 7297 | return 1; |
7298 | case EXIT_REASON_XSAVES: case EXIT_REASON_XRSTORS: | ||
7299 | /* | ||
7300 | * This should never happen, since it is not possible to | ||
7301 | * set XSS to a non-zero value---neither in L1 nor in L2. | ||
7302 | * If if it were, XSS would have to be checked against | ||
7303 | * the XSS exit bitmap in vmcs12. | ||
7304 | */ | ||
7305 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES); | ||
7289 | default: | 7306 | default: |
7290 | return 1; | 7307 | return 1; |
7291 | } | 7308 | } |
@@ -8342,6 +8359,8 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
8342 | vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->guest_sysenter_esp); | 8359 | vmcs_writel(GUEST_SYSENTER_ESP, vmcs12->guest_sysenter_esp); |
8343 | vmcs_writel(GUEST_SYSENTER_EIP, vmcs12->guest_sysenter_eip); | 8360 | vmcs_writel(GUEST_SYSENTER_EIP, vmcs12->guest_sysenter_eip); |
8344 | 8361 | ||
8362 | if (nested_cpu_has_xsaves(vmcs12)) | ||
8363 | vmcs_write64(XSS_EXIT_BITMAP, vmcs12->xss_exit_bitmap); | ||
8345 | vmcs_write64(VMCS_LINK_POINTER, -1ull); | 8364 | vmcs_write64(VMCS_LINK_POINTER, -1ull); |
8346 | 8365 | ||
8347 | exec_control = vmcs12->pin_based_vm_exec_control; | 8366 | exec_control = vmcs12->pin_based_vm_exec_control; |
@@ -8982,6 +9001,8 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, | |||
8982 | vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP); | 9001 | vmcs12->guest_sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP); |
8983 | if (vmx_mpx_supported()) | 9002 | if (vmx_mpx_supported()) |
8984 | vmcs12->guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS); | 9003 | vmcs12->guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS); |
9004 | if (nested_cpu_has_xsaves(vmcs12)) | ||
9005 | vmcs12->xss_exit_bitmap = vmcs_read64(XSS_EXIT_BITMAP); | ||
8985 | 9006 | ||
8986 | /* update exit information fields: */ | 9007 | /* update exit information fields: */ |
8987 | 9008 | ||