diff options
-rw-r--r-- | arch/x86/include/asm/vmx.h | 3 | ||||
-rw-r--r-- | arch/x86/include/uapi/asm/vmx.h | 5 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 17 |
3 files changed, 20 insertions, 5 deletions
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 056bda586a45..fc1c3134473b 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h | |||
@@ -70,6 +70,7 @@ | |||
70 | #define PIN_BASED_EXT_INTR_MASK 0x00000001 | 70 | #define PIN_BASED_EXT_INTR_MASK 0x00000001 |
71 | #define PIN_BASED_NMI_EXITING 0x00000008 | 71 | #define PIN_BASED_NMI_EXITING 0x00000008 |
72 | #define PIN_BASED_VIRTUAL_NMIS 0x00000020 | 72 | #define PIN_BASED_VIRTUAL_NMIS 0x00000020 |
73 | #define PIN_BASED_VMX_PREEMPTION_TIMER 0x00000040 | ||
73 | 74 | ||
74 | #define PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR 0x00000016 | 75 | #define PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR 0x00000016 |
75 | 76 | ||
@@ -95,6 +96,7 @@ | |||
95 | 96 | ||
96 | #define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR 0x000011ff | 97 | #define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR 0x000011ff |
97 | 98 | ||
99 | #define VMX_MISC_PREEMPTION_TIMER_RATE_MASK 0x0000001f | ||
98 | #define VMX_MISC_SAVE_EFER_LMA 0x00000020 | 100 | #define VMX_MISC_SAVE_EFER_LMA 0x00000020 |
99 | 101 | ||
100 | /* VMCS Encodings */ | 102 | /* VMCS Encodings */ |
@@ -217,6 +219,7 @@ enum vmcs_field { | |||
217 | GUEST_INTERRUPTIBILITY_INFO = 0x00004824, | 219 | GUEST_INTERRUPTIBILITY_INFO = 0x00004824, |
218 | GUEST_ACTIVITY_STATE = 0X00004826, | 220 | GUEST_ACTIVITY_STATE = 0X00004826, |
219 | GUEST_SYSENTER_CS = 0x0000482A, | 221 | GUEST_SYSENTER_CS = 0x0000482A, |
222 | VMX_PREEMPTION_TIMER_VALUE = 0x0000482E, | ||
220 | HOST_IA32_SYSENTER_CS = 0x00004c00, | 223 | HOST_IA32_SYSENTER_CS = 0x00004c00, |
221 | CR0_GUEST_HOST_MASK = 0x00006000, | 224 | CR0_GUEST_HOST_MASK = 0x00006000, |
222 | CR4_GUEST_HOST_MASK = 0x00006002, | 225 | CR4_GUEST_HOST_MASK = 0x00006002, |
diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h index 2871fccfee68..d651082c7cf7 100644 --- a/arch/x86/include/uapi/asm/vmx.h +++ b/arch/x86/include/uapi/asm/vmx.h | |||
@@ -65,6 +65,7 @@ | |||
65 | #define EXIT_REASON_EOI_INDUCED 45 | 65 | #define EXIT_REASON_EOI_INDUCED 45 |
66 | #define EXIT_REASON_EPT_VIOLATION 48 | 66 | #define EXIT_REASON_EPT_VIOLATION 48 |
67 | #define EXIT_REASON_EPT_MISCONFIG 49 | 67 | #define EXIT_REASON_EPT_MISCONFIG 49 |
68 | #define EXIT_REASON_PREEMPTION_TIMER 52 | ||
68 | #define EXIT_REASON_WBINVD 54 | 69 | #define EXIT_REASON_WBINVD 54 |
69 | #define EXIT_REASON_XSETBV 55 | 70 | #define EXIT_REASON_XSETBV 55 |
70 | #define EXIT_REASON_APIC_WRITE 56 | 71 | #define EXIT_REASON_APIC_WRITE 56 |
@@ -110,7 +111,7 @@ | |||
110 | { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, \ | 111 | { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, \ |
111 | { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \ | 112 | { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \ |
112 | { EXIT_REASON_INVD, "INVD" }, \ | 113 | { EXIT_REASON_INVD, "INVD" }, \ |
113 | { EXIT_REASON_INVPCID, "INVPCID" } | 114 | { EXIT_REASON_INVPCID, "INVPCID" }, \ |
114 | 115 | { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" } | |
115 | 116 | ||
116 | #endif /* _UAPIVMX_H */ | 117 | #endif /* _UAPIVMX_H */ |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 02f8c32b9b08..17a693868458 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -298,7 +298,8 @@ struct __packed vmcs12 { | |||
298 | u32 guest_activity_state; | 298 | u32 guest_activity_state; |
299 | u32 guest_sysenter_cs; | 299 | u32 guest_sysenter_cs; |
300 | u32 host_ia32_sysenter_cs; | 300 | u32 host_ia32_sysenter_cs; |
301 | u32 padding32[8]; /* room for future expansion */ | 301 | u32 vmx_preemption_timer_value; |
302 | u32 padding32[7]; /* room for future expansion */ | ||
302 | u16 virtual_processor_id; | 303 | u16 virtual_processor_id; |
303 | u16 guest_es_selector; | 304 | u16 guest_es_selector; |
304 | u16 guest_cs_selector; | 305 | u16 guest_cs_selector; |
@@ -537,6 +538,7 @@ static const unsigned short vmcs_field_to_offset_table[] = { | |||
537 | FIELD(GUEST_ACTIVITY_STATE, guest_activity_state), | 538 | FIELD(GUEST_ACTIVITY_STATE, guest_activity_state), |
538 | FIELD(GUEST_SYSENTER_CS, guest_sysenter_cs), | 539 | FIELD(GUEST_SYSENTER_CS, guest_sysenter_cs), |
539 | FIELD(HOST_IA32_SYSENTER_CS, host_ia32_sysenter_cs), | 540 | FIELD(HOST_IA32_SYSENTER_CS, host_ia32_sysenter_cs), |
541 | FIELD(VMX_PREEMPTION_TIMER_VALUE, vmx_preemption_timer_value), | ||
540 | FIELD(CR0_GUEST_HOST_MASK, cr0_guest_host_mask), | 542 | FIELD(CR0_GUEST_HOST_MASK, cr0_guest_host_mask), |
541 | FIELD(CR4_GUEST_HOST_MASK, cr4_guest_host_mask), | 543 | FIELD(CR4_GUEST_HOST_MASK, cr4_guest_host_mask), |
542 | FIELD(CR0_READ_SHADOW, cr0_read_shadow), | 544 | FIELD(CR0_READ_SHADOW, cr0_read_shadow), |
@@ -2049,7 +2051,8 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
2049 | */ | 2051 | */ |
2050 | nested_vmx_pinbased_ctls_low |= PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR; | 2052 | nested_vmx_pinbased_ctls_low |= PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR; |
2051 | nested_vmx_pinbased_ctls_high &= PIN_BASED_EXT_INTR_MASK | | 2053 | nested_vmx_pinbased_ctls_high &= PIN_BASED_EXT_INTR_MASK | |
2052 | PIN_BASED_NMI_EXITING | PIN_BASED_VIRTUAL_NMIS; | 2054 | PIN_BASED_NMI_EXITING | PIN_BASED_VIRTUAL_NMIS | |
2055 | PIN_BASED_VMX_PREEMPTION_TIMER; | ||
2053 | nested_vmx_pinbased_ctls_high |= PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR; | 2056 | nested_vmx_pinbased_ctls_high |= PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR; |
2054 | 2057 | ||
2055 | /* | 2058 | /* |
@@ -2110,7 +2113,8 @@ static __init void nested_vmx_setup_ctls_msrs(void) | |||
2110 | 2113 | ||
2111 | /* miscellaneous data */ | 2114 | /* miscellaneous data */ |
2112 | rdmsr(MSR_IA32_VMX_MISC, nested_vmx_misc_low, nested_vmx_misc_high); | 2115 | rdmsr(MSR_IA32_VMX_MISC, nested_vmx_misc_low, nested_vmx_misc_high); |
2113 | nested_vmx_misc_low &= VMX_MISC_SAVE_EFER_LMA; | 2116 | nested_vmx_misc_low &= VMX_MISC_PREEMPTION_TIMER_RATE_MASK | |
2117 | VMX_MISC_SAVE_EFER_LMA; | ||
2114 | nested_vmx_misc_high = 0; | 2118 | nested_vmx_misc_high = 0; |
2115 | } | 2119 | } |
2116 | 2120 | ||
@@ -6190,6 +6194,9 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) | |||
6190 | case EXIT_REASON_EPT_VIOLATION: | 6194 | case EXIT_REASON_EPT_VIOLATION: |
6191 | case EXIT_REASON_EPT_MISCONFIG: | 6195 | case EXIT_REASON_EPT_MISCONFIG: |
6192 | return 0; | 6196 | return 0; |
6197 | case EXIT_REASON_PREEMPTION_TIMER: | ||
6198 | return vmcs12->pin_based_vm_exec_control & | ||
6199 | PIN_BASED_VMX_PREEMPTION_TIMER; | ||
6193 | case EXIT_REASON_WBINVD: | 6200 | case EXIT_REASON_WBINVD: |
6194 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_WBINVD_EXITING); | 6201 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_WBINVD_EXITING); |
6195 | case EXIT_REASON_XSETBV: | 6202 | case EXIT_REASON_XSETBV: |
@@ -7011,6 +7018,10 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) | |||
7011 | (vmcs_config.pin_based_exec_ctrl | | 7018 | (vmcs_config.pin_based_exec_ctrl | |
7012 | vmcs12->pin_based_vm_exec_control)); | 7019 | vmcs12->pin_based_vm_exec_control)); |
7013 | 7020 | ||
7021 | if (vmcs12->pin_based_vm_exec_control & PIN_BASED_VMX_PREEMPTION_TIMER) | ||
7022 | vmcs_write32(VMX_PREEMPTION_TIMER_VALUE, | ||
7023 | vmcs12->vmx_preemption_timer_value); | ||
7024 | |||
7014 | /* | 7025 | /* |
7015 | * Whether page-faults are trapped is determined by a combination of | 7026 | * Whether page-faults are trapped is determined by a combination of |
7016 | * 3 settings: PFEC_MASK, PFEC_MATCH and EXCEPTION_BITMAP.PF. | 7027 | * 3 settings: PFEC_MASK, PFEC_MATCH and EXCEPTION_BITMAP.PF. |