Merge branch 'kvm-lapic-fix-and-cleanup' into HEAD
[linux-block.git] / arch / x86 / kvm / svm / svm.c
index f2453df77727e9b704ea1c88edf54d56525fd9af..d13cf53e739067485f64b303b2f945b93117ae67 100644 (file)
@@ -1,4 +1,4 @@
-#define pr_fmt(fmt) "SVM: " fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kvm_host.h>
 
@@ -519,21 +519,37 @@ static void svm_init_osvw(struct kvm_vcpu *vcpu)
                vcpu->arch.osvw.status |= 1;
 }
 
-static int has_svm(void)
+static bool kvm_is_svm_supported(void)
 {
+       int cpu = raw_smp_processor_id();
        const char *msg;
+       u64 vm_cr;
 
        if (!cpu_has_svm(&msg)) {
-               printk(KERN_INFO "has_svm: %s\n", msg);
-               return 0;
+               pr_err("SVM not supported by CPU %d, %s\n", cpu, msg);
+               return false;
        }
 
        if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) {
                pr_info("KVM is unsupported when running as an SEV guest\n");
-               return 0;
+               return false;
        }
 
-       return 1;
+       rdmsrl(MSR_VM_CR, vm_cr);
+       if (vm_cr & (1 << SVM_VM_CR_SVM_DISABLE)) {
+               pr_err("SVM disabled (by BIOS) in MSR_VM_CR on CPU %d\n", cpu);
+               return false;
+       }
+
+       return true;
+}
+
+static int svm_check_processor_compat(void)
+{
+       if (!kvm_is_svm_supported())
+               return -EIO;
+
+       return 0;
 }
 
 void __svm_write_tsc_multiplier(u64 multiplier)
@@ -572,10 +588,6 @@ static int svm_hardware_enable(void)
        if (efer & EFER_SVME)
                return -EBUSY;
 
-       if (!has_svm()) {
-               pr_err("%s: err EOPNOTSUPP on %d\n", __func__, me);
-               return -EINVAL;
-       }
        sd = per_cpu_ptr(&svm_data, me);
        sd->asid_generation = 1;
        sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
@@ -2076,7 +2088,7 @@ static void svm_handle_mce(struct kvm_vcpu *vcpu)
                 * Erratum 383 triggered. Guest state is corrupt so kill the
                 * guest.
                 */
-               pr_err("KVM: Guest triggered AMD Erratum 383\n");
+               pr_err("Guest triggered AMD Erratum 383\n");
 
                kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
 
@@ -2705,9 +2717,9 @@ static int svm_get_msr_feature(struct kvm_msr_entry *msr)
        msr->data = 0;
 
        switch (msr->index) {
-       case MSR_F10H_DECFG:
-               if (boot_cpu_has(X86_FEATURE_LFENCE_RDTSC))
-                       msr->data |= MSR_F10H_DECFG_LFENCE_SERIALIZE;
+       case MSR_AMD64_DE_CFG:
+               if (cpu_feature_enabled(X86_FEATURE_LFENCE_RDTSC))
+                       msr->data |= MSR_AMD64_DE_CFG_LFENCE_SERIALIZE;
                break;
        default:
                return KVM_MSR_RET_INVALID;
@@ -2806,7 +2818,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        msr_info->data = 0x1E;
                }
                break;
-       case MSR_F10H_DECFG:
+       case MSR_AMD64_DE_CFG:
                msr_info->data = svm->msr_decfg;
                break;
        default:
@@ -3035,7 +3047,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
        case MSR_VM_IGNNE:
                vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
                break;
-       case MSR_F10H_DECFG: {
+       case MSR_AMD64_DE_CFG: {
                struct kvm_msr_entry msr_entry;
 
                msr_entry.index = msr->index;
@@ -4076,17 +4088,6 @@ static void svm_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa,
        vmcb_mark_dirty(svm->vmcb, VMCB_CR);
 }
 
-static int is_disabled(void)
-{
-       u64 vm_cr;
-
-       rdmsrl(MSR_VM_CR, vm_cr);
-       if (vm_cr & (1 << SVM_VM_CR_SVM_DISABLE))
-               return 1;
-
-       return 0;
-}
-
 static void
 svm_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
 {
@@ -4098,11 +4099,6 @@ svm_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
        hypercall[2] = 0xd9;
 }
 
-static int __init svm_check_processor_compat(void)
-{
-       return 0;
-}
-
 /*
  * The kvm parameter can be NULL (module initialization, or invocation before
  * VM creation). Be sure to check the kvm parameter before using it.
@@ -4629,7 +4625,7 @@ static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type,
        smap = cr4 & X86_CR4_SMAP;
        is_user = svm_get_cpl(vcpu) == 3;
        if (smap && (!smep || is_user)) {
-               pr_err_ratelimited("KVM: SEV Guest triggered AMD Erratum 1096\n");
+               pr_err_ratelimited("SEV Guest triggered AMD Erratum 1096\n");
 
                /*
                 * If the fault occurred in userspace, arbitrarily inject #GP
@@ -4701,7 +4697,9 @@ static int svm_vm_init(struct kvm *kvm)
 }
 
 static struct kvm_x86_ops svm_x86_ops __initdata = {
-       .name = "kvm_amd",
+       .name = KBUILD_MODNAME,
+
+       .check_processor_compatibility = svm_check_processor_compat,
 
        .hardware_unsetup = svm_hardware_unsetup,
        .hardware_enable = svm_hardware_enable,
@@ -4978,7 +4976,7 @@ static __init int svm_hardware_setup(void)
        }
 
        if (nested) {
-               printk(KERN_INFO "kvm: Nested Virtualization enabled\n");
+               pr_info("Nested Virtualization enabled\n");
                kvm_enable_efer_bits(EFER_SVME | EFER_LMSLE);
        }
 
@@ -4996,7 +4994,7 @@ static __init int svm_hardware_setup(void)
        /* Force VM NPT level equal to the host's paging level */
        kvm_configure_mmu(npt_enabled, get_npt_level(),
                          get_npt_level(), PG_LEVEL_1G);
-       pr_info("kvm: Nested Paging %sabled\n", npt_enabled ? "en" : "dis");
+       pr_info("Nested Paging %sabled\n", npt_enabled ? "en" : "dis");
 
        /* Setup shadow_me_value and shadow_me_mask */
        kvm_mmu_set_me_spte_mask(sme_me_mask, sme_me_mask);
@@ -5088,10 +5086,7 @@ err:
 
 
 static struct kvm_x86_init_ops svm_init_ops __initdata = {
-       .cpu_has_kvm_support = has_svm,
-       .disabled_by_bios = is_disabled,
        .hardware_setup = svm_hardware_setup,
-       .check_processor_compatibility = svm_check_processor_compat,
 
        .runtime_ops = &svm_x86_ops,
        .pmu_ops = &amd_pmu_ops,
@@ -5099,15 +5094,37 @@ static struct kvm_x86_init_ops svm_init_ops __initdata = {
 
 static int __init svm_init(void)
 {
+       int r;
+
        __unused_size_checks();
 
-       return kvm_init(&svm_init_ops, sizeof(struct vcpu_svm),
-                       __alignof__(struct vcpu_svm), THIS_MODULE);
+       if (!kvm_is_svm_supported())
+               return -EOPNOTSUPP;
+
+       r = kvm_x86_vendor_init(&svm_init_ops);
+       if (r)
+               return r;
+
+       /*
+        * Common KVM initialization _must_ come last, after this, /dev/kvm is
+        * exposed to userspace!
+        */
+       r = kvm_init(sizeof(struct vcpu_svm), __alignof__(struct vcpu_svm),
+                    THIS_MODULE);
+       if (r)
+               goto err_kvm_init;
+
+       return 0;
+
+err_kvm_init:
+       kvm_x86_vendor_exit();
+       return r;
 }
 
 static void __exit svm_exit(void)
 {
        kvm_exit();
+       kvm_x86_vendor_exit();
 }
 
 module_init(svm_init)