aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 99165a961f08..b5e9932e0f62 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -69,6 +69,8 @@ static u64 __read_mostly efer_reserved_bits = 0xfffffffffffffffeULL;
69 69
70static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, 70static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
71 struct kvm_cpuid_entry2 __user *entries); 71 struct kvm_cpuid_entry2 __user *entries);
72struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
73 u32 function, u32 index);
72 74
73struct kvm_x86_ops *kvm_x86_ops; 75struct kvm_x86_ops *kvm_x86_ops;
74EXPORT_SYMBOL_GPL(kvm_x86_ops); 76EXPORT_SYMBOL_GPL(kvm_x86_ops);
@@ -173,6 +175,7 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr,
173 u32 error_code) 175 u32 error_code)
174{ 176{
175 ++vcpu->stat.pf_guest; 177 ++vcpu->stat.pf_guest;
178
176 if (vcpu->arch.exception.pending) { 179 if (vcpu->arch.exception.pending) {
177 if (vcpu->arch.exception.nr == PF_VECTOR) { 180 if (vcpu->arch.exception.nr == PF_VECTOR) {
178 printk(KERN_DEBUG "kvm: inject_page_fault:" 181 printk(KERN_DEBUG "kvm: inject_page_fault:"
@@ -442,6 +445,11 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
442} 445}
443EXPORT_SYMBOL_GPL(kvm_get_cr8); 446EXPORT_SYMBOL_GPL(kvm_get_cr8);
444 447
448static inline u32 bit(int bitno)
449{
450 return 1 << (bitno & 31);
451}
452
445/* 453/*
446 * List of msr numbers which we expose to userspace through KVM_GET_MSRS 454 * List of msr numbers which we expose to userspace through KVM_GET_MSRS
447 * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST. 455 * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST.
@@ -481,6 +489,17 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
481 return; 489 return;
482 } 490 }
483 491
492 if (efer & EFER_SVME) {
493 struct kvm_cpuid_entry2 *feat;
494
495 feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
496 if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) {
497 printk(KERN_DEBUG "set_efer: #GP, enable SVM w/o SVM\n");
498 kvm_inject_gp(vcpu, 0);
499 return;
500 }
501 }
502
484 kvm_x86_ops->set_efer(vcpu, efer); 503 kvm_x86_ops->set_efer(vcpu, efer);
485 504
486 efer &= ~EFER_LMA; 505 efer &= ~EFER_LMA;
@@ -1181,11 +1200,6 @@ out:
1181 return r; 1200 return r;
1182} 1201}
1183 1202
1184static inline u32 bit(int bitno)
1185{
1186 return 1 << (bitno & 31);
1187}
1188
1189static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function, 1203static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function,
1190 u32 index) 1204 u32 index)
1191{ 1205{
@@ -1228,7 +1242,8 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
1228 const u32 kvm_supported_word3_x86_features = 1242 const u32 kvm_supported_word3_x86_features =
1229 bit(X86_FEATURE_XMM3) | bit(X86_FEATURE_CX16); 1243 bit(X86_FEATURE_XMM3) | bit(X86_FEATURE_CX16);
1230 const u32 kvm_supported_word6_x86_features = 1244 const u32 kvm_supported_word6_x86_features =
1231 bit(X86_FEATURE_LAHF_LM) | bit(X86_FEATURE_CMP_LEGACY); 1245 bit(X86_FEATURE_LAHF_LM) | bit(X86_FEATURE_CMP_LEGACY) |
1246 bit(X86_FEATURE_SVM);
1232 1247
1233 /* all func 2 cpuid_count() should be called on the same cpu */ 1248 /* all func 2 cpuid_count() should be called on the same cpu */
1234 get_cpu(); 1249 get_cpu();
@@ -2832,20 +2847,15 @@ static int is_matching_cpuid_entry(struct kvm_cpuid_entry2 *e,
2832 return 1; 2847 return 1;
2833} 2848}
2834 2849
2835void kvm_emulate_cpuid(struct kvm_vcpu *vcpu) 2850struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
2851 u32 function, u32 index)
2836{ 2852{
2837 int i; 2853 int i;
2838 u32 function, index; 2854 struct kvm_cpuid_entry2 *best = NULL;
2839 struct kvm_cpuid_entry2 *e, *best;
2840 2855
2841 function = kvm_register_read(vcpu, VCPU_REGS_RAX);
2842 index = kvm_register_read(vcpu, VCPU_REGS_RCX);
2843 kvm_register_write(vcpu, VCPU_REGS_RAX, 0);
2844 kvm_register_write(vcpu, VCPU_REGS_RBX, 0);
2845 kvm_register_write(vcpu, VCPU_REGS_RCX, 0);
2846 kvm_register_write(vcpu, VCPU_REGS_RDX, 0);
2847 best = NULL;
2848 for (i = 0; i < vcpu->arch.cpuid_nent; ++i) { 2856 for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
2857 struct kvm_cpuid_entry2 *e;
2858
2849 e = &vcpu->arch.cpuid_entries[i]; 2859 e = &vcpu->arch.cpuid_entries[i];
2850 if (is_matching_cpuid_entry(e, function, index)) { 2860 if (is_matching_cpuid_entry(e, function, index)) {
2851 if (e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC) 2861 if (e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC)
@@ -2860,6 +2870,22 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
2860 if (!best || e->function > best->function) 2870 if (!best || e->function > best->function)
2861 best = e; 2871 best = e;
2862 } 2872 }
2873
2874 return best;
2875}
2876
2877void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
2878{
2879 u32 function, index;
2880 struct kvm_cpuid_entry2 *best;
2881
2882 function = kvm_register_read(vcpu, VCPU_REGS_RAX);
2883 index = kvm_register_read(vcpu, VCPU_REGS_RCX);
2884 kvm_register_write(vcpu, VCPU_REGS_RAX, 0);
2885 kvm_register_write(vcpu, VCPU_REGS_RBX, 0);
2886 kvm_register_write(vcpu, VCPU_REGS_RCX, 0);
2887 kvm_register_write(vcpu, VCPU_REGS_RDX, 0);
2888 best = kvm_find_cpuid_entry(vcpu, function, index);
2863 if (best) { 2889 if (best) {
2864 kvm_register_write(vcpu, VCPU_REGS_RAX, best->eax); 2890 kvm_register_write(vcpu, VCPU_REGS_RAX, best->eax);
2865 kvm_register_write(vcpu, VCPU_REGS_RBX, best->ebx); 2891 kvm_register_write(vcpu, VCPU_REGS_RBX, best->ebx);