Merge branch 'kvm-lapic-fix-and-cleanup' into HEAD
[linux-block.git] / arch / x86 / kvm / x86.c
index 5becce5bd45a40d7f622692069a2afbc49c600ee..508074e47bc0ebd4535de4bc548f57abdffe863d 100644 (file)
@@ -15,6 +15,7 @@
  *   Amit Shah    <amit.shah@qumranet.com>
  *   Ben-Ami Yassour <benami@il.ibm.com>
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kvm_host.h>
 #include "irq.h"
@@ -128,6 +129,7 @@ static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu);
 static int __set_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2);
 static void __get_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2);
 
+static DEFINE_MUTEX(vendor_module_lock);
 struct kvm_x86_ops kvm_x86_ops __read_mostly;
 
 #define KVM_X86_OP(func)                                            \
@@ -1557,7 +1559,7 @@ static const u32 msr_based_features_all[] = {
        MSR_IA32_VMX_EPT_VPID_CAP,
        MSR_IA32_VMX_VMFUNC,
 
-       MSR_F10H_DECFG,
+       MSR_AMD64_DE_CFG,
        MSR_IA32_UCODE_REV,
        MSR_IA32_ARCH_CAPABILITIES,
        MSR_IA32_PERF_CAPABILITIES,
@@ -2086,7 +2088,7 @@ static int kvm_emulate_monitor_mwait(struct kvm_vcpu *vcpu, const char *insn)
            !guest_cpuid_has(vcpu, X86_FEATURE_MWAIT))
                return kvm_handle_invalid_op(vcpu);
 
-       pr_warn_once("kvm: %s instruction emulated as NOP!\n", insn);
+       pr_warn_once("%s instruction emulated as NOP!\n", insn);
        return kvm_emulate_as_nop(vcpu);
 }
 int kvm_emulate_mwait(struct kvm_vcpu *vcpu)
@@ -2433,7 +2435,8 @@ static int kvm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
        thresh_lo = adjust_tsc_khz(tsc_khz, -tsc_tolerance_ppm);
        thresh_hi = adjust_tsc_khz(tsc_khz, tsc_tolerance_ppm);
        if (user_tsc_khz < thresh_lo || user_tsc_khz > thresh_hi) {
-               pr_debug("kvm: requested TSC rate %u falls outside tolerance [%u,%u]\n", user_tsc_khz, thresh_lo, thresh_hi);
+               pr_debug("requested TSC rate %u falls outside tolerance [%u,%u]\n",
+                        user_tsc_khz, thresh_lo, thresh_hi);
                use_scaling = 1;
        }
        return set_tsc_khz(vcpu, user_tsc_khz, use_scaling);
@@ -7701,7 +7704,7 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
        return X86EMUL_CONTINUE;
 
 emul_write:
-       printk_once(KERN_WARNING "kvm: emulating exchange as write\n");
+       pr_warn_once("emulating exchange as write\n");
 
        return emulator_write_emulated(ctxt, addr, new, bytes, exception);
 }
@@ -8262,7 +8265,7 @@ static struct x86_emulate_ctxt *alloc_emulate_ctxt(struct kvm_vcpu *vcpu)
 
        ctxt = kmem_cache_zalloc(x86_emulator_cache, GFP_KERNEL_ACCOUNT);
        if (!ctxt) {
-               pr_err("kvm: failed to allocate vcpu's emulator\n");
+               pr_err("failed to allocate vcpu's emulator\n");
                return NULL;
        }
 
@@ -9273,35 +9276,66 @@ static struct notifier_block pvclock_gtod_notifier = {
 };
 #endif
 
-int kvm_arch_init(void *opaque)
+static inline void kvm_ops_update(struct kvm_x86_init_ops *ops)
+{
+       memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
+
+#define __KVM_X86_OP(func) \
+       static_call_update(kvm_x86_##func, kvm_x86_ops.func);
+#define KVM_X86_OP(func) \
+       WARN_ON(!kvm_x86_ops.func); __KVM_X86_OP(func)
+#define KVM_X86_OP_OPTIONAL __KVM_X86_OP
+#define KVM_X86_OP_OPTIONAL_RET0(func) \
+       static_call_update(kvm_x86_##func, (void *)kvm_x86_ops.func ? : \
+                                          (void *)__static_call_return0);
+#include <asm/kvm-x86-ops.h>
+#undef __KVM_X86_OP
+
+       kvm_pmu_ops_update(ops->pmu_ops);
+}
+
+static int kvm_x86_check_processor_compatibility(void)
+{
+       int cpu = smp_processor_id();
+       struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+       /*
+        * Compatibility checks are done when loading KVM and when enabling
+        * hardware, e.g. during CPU hotplug, to ensure all online CPUs are
+        * compatible, i.e. KVM should never perform a compatibility check on
+        * an offline CPU.
+        */
+       WARN_ON(!cpu_online(cpu));
+
+       if (__cr4_reserved_bits(cpu_has, c) !=
+           __cr4_reserved_bits(cpu_has, &boot_cpu_data))
+               return -EIO;
+
+       return static_call(kvm_x86_check_processor_compatibility)();
+}
+
+static void kvm_x86_check_cpu_compat(void *ret)
+{
+       *(int *)ret = kvm_x86_check_processor_compatibility();
+}
+
+static int __kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
 {
-       struct kvm_x86_init_ops *ops = opaque;
        u64 host_pat;
-       int r;
+       int r, cpu;
 
        if (kvm_x86_ops.hardware_enable) {
-               pr_err("kvm: already loaded vendor module '%s'\n", kvm_x86_ops.name);
+               pr_err("already loaded vendor module '%s'\n", kvm_x86_ops.name);
                return -EEXIST;
        }
 
-       if (!ops->cpu_has_kvm_support()) {
-               pr_err_ratelimited("kvm: no hardware support for '%s'\n",
-                                  ops->runtime_ops->name);
-               return -EOPNOTSUPP;
-       }
-       if (ops->disabled_by_bios()) {
-               pr_err_ratelimited("kvm: support for '%s' disabled by bios\n",
-                                  ops->runtime_ops->name);
-               return -EOPNOTSUPP;
-       }
-
        /*
         * KVM explicitly assumes that the guest has an FPU and
         * FXSAVE/FXRSTOR. For example, the KVM_GET_FPU explicitly casts the
         * vCPU's FPU state as a fxregs_state struct.
         */
        if (!boot_cpu_has(X86_FEATURE_FPU) || !boot_cpu_has(X86_FEATURE_FXSR)) {
-               printk(KERN_ERR "kvm: inadequate fpu\n");
+               pr_err("inadequate fpu\n");
                return -EOPNOTSUPP;
        }
 
@@ -9319,19 +9353,19 @@ int kvm_arch_init(void *opaque)
         */
        if (rdmsrl_safe(MSR_IA32_CR_PAT, &host_pat) ||
            (host_pat & GENMASK(2, 0)) != 6) {
-               pr_err("kvm: host PAT[0] is not WB\n");
+               pr_err("host PAT[0] is not WB\n");
                return -EIO;
        }
 
        x86_emulator_cache = kvm_alloc_emulator_cache();
        if (!x86_emulator_cache) {
-               pr_err("kvm: failed to allocate cache for x86 emulator\n");
+               pr_err("failed to allocate cache for x86 emulator\n");
                return -ENOMEM;
        }
 
        user_return_msrs = alloc_percpu(struct kvm_user_return_msrs);
        if (!user_return_msrs) {
-               printk(KERN_ERR "kvm: failed to allocate percpu kvm_user_return_msrs\n");
+               pr_err("failed to allocate percpu kvm_user_return_msrs\n");
                r = -ENOMEM;
                goto out_free_x86_emulator_cache;
        }
@@ -9341,13 +9375,37 @@ int kvm_arch_init(void *opaque)
        if (r)
                goto out_free_percpu;
 
-       kvm_timer_init();
-
        if (boot_cpu_has(X86_FEATURE_XSAVE)) {
                host_xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
                kvm_caps.supported_xcr0 = host_xcr0 & KVM_SUPPORTED_XCR0;
        }
 
+       rdmsrl_safe(MSR_EFER, &host_efer);
+
+       if (boot_cpu_has(X86_FEATURE_XSAVES))
+               rdmsrl(MSR_IA32_XSS, host_xss);
+
+       kvm_init_pmu_capability();
+
+       r = ops->hardware_setup();
+       if (r != 0)
+               goto out_mmu_exit;
+
+       kvm_ops_update(ops);
+
+       for_each_online_cpu(cpu) {
+               smp_call_function_single(cpu, kvm_x86_check_cpu_compat, &r, 1);
+               if (r < 0)
+                       goto out_unwind_ops;
+       }
+
+       /*
+        * Point of no return!  DO NOT add error paths below this point unless
+        * absolutely necessary, as most operations from this point forward
+        * require unwinding.
+        */
+       kvm_timer_init();
+
        if (pi_inject_timer == -1)
                pi_inject_timer = housekeeping_enabled(HK_TYPE_TIMER);
 #ifdef CONFIG_X86_64
@@ -9357,8 +9415,35 @@ int kvm_arch_init(void *opaque)
                set_hv_tscchange_cb(kvm_hyperv_tsc_notifier);
 #endif
 
+       kvm_register_perf_callbacks(ops->handle_intel_pt_intr);
+
+       if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
+               kvm_caps.supported_xss = 0;
+
+#define __kvm_cpu_cap_has(UNUSED_, f) kvm_cpu_cap_has(f)
+       cr4_reserved_bits = __cr4_reserved_bits(__kvm_cpu_cap_has, UNUSED_);
+#undef __kvm_cpu_cap_has
+
+       if (kvm_caps.has_tsc_control) {
+               /*
+                * Make sure the user can only configure tsc_khz values that
+                * fit into a signed integer.
+                * A min value is not calculated because it will always
+                * be 1 on all machines.
+                */
+               u64 max = min(0x7fffffffULL,
+                             __scale_tsc(kvm_caps.max_tsc_scaling_ratio, tsc_khz));
+               kvm_caps.max_guest_tsc_khz = max;
+       }
+       kvm_caps.default_tsc_scaling_ratio = 1ULL << kvm_caps.tsc_scaling_ratio_frac_bits;
+       kvm_init_msr_list();
        return 0;
 
+out_unwind_ops:
+       kvm_x86_ops.hardware_enable = NULL;
+       static_call(kvm_x86_hardware_unsetup)();
+out_mmu_exit:
+       kvm_mmu_vendor_module_exit();
 out_free_percpu:
        free_percpu(user_return_msrs);
 out_free_x86_emulator_cache:
@@ -9366,8 +9451,22 @@ out_free_x86_emulator_cache:
        return r;
 }
 
-void kvm_arch_exit(void)
+int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
+{
+       int r;
+
+       mutex_lock(&vendor_module_lock);
+       r = __kvm_x86_vendor_init(ops);
+       mutex_unlock(&vendor_module_lock);
+
+       return r;
+}
+EXPORT_SYMBOL_GPL(kvm_x86_vendor_init);
+
+void kvm_x86_vendor_exit(void)
 {
+       kvm_unregister_perf_callbacks();
+
 #ifdef CONFIG_X86_64
        if (hypervisor_is_type(X86_HYPER_MS_HYPERV))
                clear_hv_tscchange_cb();
@@ -9384,7 +9483,7 @@ void kvm_arch_exit(void)
        irq_work_sync(&pvclock_irq_work);
        cancel_work_sync(&pvclock_gtod_work);
 #endif
-       kvm_x86_ops.hardware_enable = NULL;
+       static_call(kvm_x86_hardware_unsetup)();
        kvm_mmu_vendor_module_exit();
        free_percpu(user_return_msrs);
        kmem_cache_destroy(x86_emulator_cache);
@@ -9392,7 +9491,11 @@ void kvm_arch_exit(void)
        static_key_deferred_flush(&kvm_xen_enabled);
        WARN_ON(static_branch_unlikely(&kvm_xen_enabled.key));
 #endif
+       mutex_lock(&vendor_module_lock);
+       kvm_x86_ops.hardware_enable = NULL;
+       mutex_unlock(&vendor_module_lock);
 }
+EXPORT_SYMBOL_GPL(kvm_x86_vendor_exit);
 
 static int __kvm_emulate_halt(struct kvm_vcpu *vcpu, int state, int reason)
 {
@@ -11556,7 +11659,7 @@ static int sync_regs(struct kvm_vcpu *vcpu)
 int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
 {
        if (kvm_check_tsc_unstable() && kvm->created_vcpus)
-               pr_warn_once("kvm: SMP vm created on host with unstable TSC; "
+               pr_warn_once("SMP vm created on host with unstable TSC; "
                             "guest TSC will not be reliable\n");
 
        if (!kvm->arch.max_vcpu_ids)
@@ -11633,7 +11736,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
                goto free_wbinvd_dirty_mask;
 
        if (!fpu_alloc_guest_fpstate(&vcpu->arch.guest_fpu)) {
-               pr_err("kvm: failed to allocate vcpu's fpu\n");
+               pr_err("failed to allocate vcpu's fpu\n");
                goto free_emulate_ctxt;
        }
 
@@ -11907,6 +12010,11 @@ int kvm_arch_hardware_enable(void)
        bool stable, backwards_tsc = false;
 
        kvm_user_return_msr_cpu_online();
+
+       ret = kvm_x86_check_processor_compatibility();
+       if (ret)
+               return ret;
+
        ret = static_call(kvm_x86_hardware_enable)();
        if (ret != 0)
                return ret;
@@ -11993,88 +12101,6 @@ void kvm_arch_hardware_disable(void)
        drop_user_return_notifiers();
 }
 
-static inline void kvm_ops_update(struct kvm_x86_init_ops *ops)
-{
-       memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
-
-#define __KVM_X86_OP(func) \
-       static_call_update(kvm_x86_##func, kvm_x86_ops.func);
-#define KVM_X86_OP(func) \
-       WARN_ON(!kvm_x86_ops.func); __KVM_X86_OP(func)
-#define KVM_X86_OP_OPTIONAL __KVM_X86_OP
-#define KVM_X86_OP_OPTIONAL_RET0(func) \
-       static_call_update(kvm_x86_##func, (void *)kvm_x86_ops.func ? : \
-                                          (void *)__static_call_return0);
-#include <asm/kvm-x86-ops.h>
-#undef __KVM_X86_OP
-
-       kvm_pmu_ops_update(ops->pmu_ops);
-}
-
-int kvm_arch_hardware_setup(void *opaque)
-{
-       struct kvm_x86_init_ops *ops = opaque;
-       int r;
-
-       rdmsrl_safe(MSR_EFER, &host_efer);
-
-       if (boot_cpu_has(X86_FEATURE_XSAVES))
-               rdmsrl(MSR_IA32_XSS, host_xss);
-
-       kvm_init_pmu_capability();
-
-       r = ops->hardware_setup();
-       if (r != 0)
-               return r;
-
-       kvm_ops_update(ops);
-
-       kvm_register_perf_callbacks(ops->handle_intel_pt_intr);
-
-       if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
-               kvm_caps.supported_xss = 0;
-
-#define __kvm_cpu_cap_has(UNUSED_, f) kvm_cpu_cap_has(f)
-       cr4_reserved_bits = __cr4_reserved_bits(__kvm_cpu_cap_has, UNUSED_);
-#undef __kvm_cpu_cap_has
-
-       if (kvm_caps.has_tsc_control) {
-               /*
-                * Make sure the user can only configure tsc_khz values that
-                * fit into a signed integer.
-                * A min value is not calculated because it will always
-                * be 1 on all machines.
-                */
-               u64 max = min(0x7fffffffULL,
-                             __scale_tsc(kvm_caps.max_tsc_scaling_ratio, tsc_khz));
-               kvm_caps.max_guest_tsc_khz = max;
-       }
-       kvm_caps.default_tsc_scaling_ratio = 1ULL << kvm_caps.tsc_scaling_ratio_frac_bits;
-       kvm_init_msr_list();
-       return 0;
-}
-
-void kvm_arch_hardware_unsetup(void)
-{
-       kvm_unregister_perf_callbacks();
-
-       static_call(kvm_x86_hardware_unsetup)();
-}
-
-int kvm_arch_check_processor_compat(void *opaque)
-{
-       struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
-       struct kvm_x86_init_ops *ops = opaque;
-
-       WARN_ON(!irqs_disabled());
-
-       if (__cr4_reserved_bits(cpu_has, c) !=
-           __cr4_reserved_bits(cpu_has, &boot_cpu_data))
-               return -EIO;
-
-       return ops->check_processor_compatibility();
-}
-
 bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu)
 {
        return vcpu->kvm->arch.bsp_vcpu_id == vcpu->vcpu_id;