aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWanpeng Li <wanpeng.li@linux.intel.com>2014-12-02 06:21:30 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2014-12-05 07:57:16 -0500
commit55412b2eda2b783ef37316eb06ba91fa63ae049d (patch)
tree8eff0de0c34eacb8f9dbb989c4d64e8a5c3cf2c5
parent5c404cabd1b5c125653ac573cb9284bdf42b658a (diff)
kvm: x86: Add kvm_x86_ops hook that enables XSAVES for guest
Expose the XSAVES feature to the guest if the kvm_x86_ops say it is available. Signed-off-by: Wanpeng Li <wanpeng.li@linux.intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/include/asm/vmx.h1
-rw-r--r--arch/x86/kvm/cpuid.c3
-rw-r--r--arch/x86/kvm/svm.c6
-rw-r--r--arch/x86/kvm/vmx.c7
5 files changed, 17 insertions, 1 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 2896dbc18987..0271f6bcf123 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -771,6 +771,7 @@ struct kvm_x86_ops {
771 enum x86_intercept_stage stage); 771 enum x86_intercept_stage stage);
772 void (*handle_external_intr)(struct kvm_vcpu *vcpu); 772 void (*handle_external_intr)(struct kvm_vcpu *vcpu);
773 bool (*mpx_supported)(void); 773 bool (*mpx_supported)(void);
774 bool (*xsaves_supported)(void);
774 775
775 int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr); 776 int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr);
776 777
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index bcbfade26d8d..08dc770bd340 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -69,6 +69,7 @@
69#define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 69#define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400
70#define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 70#define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000
71#define SECONDARY_EXEC_SHADOW_VMCS 0x00004000 71#define SECONDARY_EXEC_SHADOW_VMCS 0x00004000
72#define SECONDARY_EXEC_XSAVES 0x00100000
72 73
73 74
74#define PIN_BASED_EXT_INTR_MASK 0x00000001 75#define PIN_BASED_EXT_INTR_MASK 0x00000001
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 11f09a2b31a0..e24df01ab118 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -267,6 +267,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
267 unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0; 267 unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
268 unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0; 268 unsigned f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0;
269 unsigned f_mpx = kvm_x86_ops->mpx_supported() ? F(MPX) : 0; 269 unsigned f_mpx = kvm_x86_ops->mpx_supported() ? F(MPX) : 0;
270 unsigned f_xsaves = kvm_x86_ops->xsaves_supported() ? F(XSAVES) : 0;
270 271
271 /* cpuid 1.edx */ 272 /* cpuid 1.edx */
272 const u32 kvm_supported_word0_x86_features = 273 const u32 kvm_supported_word0_x86_features =
@@ -322,7 +323,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
322 323
323 /* cpuid 0xD.1.eax */ 324 /* cpuid 0xD.1.eax */
324 const u32 kvm_supported_word10_x86_features = 325 const u32 kvm_supported_word10_x86_features =
325 F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1); 326 F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | f_xsaves;
326 327
327 /* all calls to cpuid_count() should be made on the same cpu */ 328 /* all calls to cpuid_count() should be made on the same cpu */
328 get_cpu(); 329 get_cpu();
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 6b411add23b8..41dd0387cccb 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -4127,6 +4127,11 @@ static bool svm_mpx_supported(void)
4127 return false; 4127 return false;
4128} 4128}
4129 4129
4130static bool svm_xsaves_supported(void)
4131{
4132 return false;
4133}
4134
4130static bool svm_has_wbinvd_exit(void) 4135static bool svm_has_wbinvd_exit(void)
4131{ 4136{
4132 return true; 4137 return true;
@@ -4414,6 +4419,7 @@ static struct kvm_x86_ops svm_x86_ops = {
4414 .rdtscp_supported = svm_rdtscp_supported, 4419 .rdtscp_supported = svm_rdtscp_supported,
4415 .invpcid_supported = svm_invpcid_supported, 4420 .invpcid_supported = svm_invpcid_supported,
4416 .mpx_supported = svm_mpx_supported, 4421 .mpx_supported = svm_mpx_supported,
4422 .xsaves_supported = svm_xsaves_supported,
4417 4423
4418 .set_supported_cpuid = svm_set_supported_cpuid, 4424 .set_supported_cpuid = svm_set_supported_cpuid,
4419 4425
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 6a951d823c82..dd4fa461454a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -7553,6 +7553,12 @@ static bool vmx_mpx_supported(void)
7553 (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS); 7553 (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS);
7554} 7554}
7555 7555
7556static bool vmx_xsaves_supported(void)
7557{
7558 return vmcs_config.cpu_based_2nd_exec_ctrl &
7559 SECONDARY_EXEC_XSAVES;
7560}
7561
7556static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) 7562static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
7557{ 7563{
7558 u32 exit_intr_info; 7564 u32 exit_intr_info;
@@ -9329,6 +9335,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
9329 .check_intercept = vmx_check_intercept, 9335 .check_intercept = vmx_check_intercept,
9330 .handle_external_intr = vmx_handle_external_intr, 9336 .handle_external_intr = vmx_handle_external_intr,
9331 .mpx_supported = vmx_mpx_supported, 9337 .mpx_supported = vmx_mpx_supported,
9338 .xsaves_supported = vmx_xsaves_supported,
9332 9339
9333 .check_nested_events = vmx_check_nested_events, 9340 .check_nested_events = vmx_check_nested_events,
9334 9341