]> git.ipfire.org Git - thirdparty/kernel/stable.git/blobdiff - arch/x86/kvm/x86.c
Merge tag 'kvm-x86-lam-6.8' of https://github.com/kvm-x86/linux into HEAD
[thirdparty/kernel/stable.git] / arch / x86 / kvm / x86.c
index ecfe97aa35c2a6c4a414542cabd19f06068628a2..0366eca119d70f1089ff27e4bbf00a23aa04f090 100644 (file)
@@ -1504,6 +1504,8 @@ static unsigned num_msrs_to_save;
 static const u32 emulated_msrs_all[] = {
        MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
        MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW,
+
+#ifdef CONFIG_KVM_HYPERV
        HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
        HV_X64_MSR_TIME_REF_COUNT, HV_X64_MSR_REFERENCE_TSC,
        HV_X64_MSR_TSC_FREQUENCY, HV_X64_MSR_APIC_FREQUENCY,
@@ -1521,6 +1523,7 @@ static const u32 emulated_msrs_all[] = {
        HV_X64_MSR_SYNDBG_CONTROL, HV_X64_MSR_SYNDBG_STATUS,
        HV_X64_MSR_SYNDBG_SEND_BUFFER, HV_X64_MSR_SYNDBG_RECV_BUFFER,
        HV_X64_MSR_SYNDBG_PENDING_BUFFER,
+#endif
 
        MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME,
        MSR_KVM_PV_EOI_EN, MSR_KVM_ASYNC_PF_INT, MSR_KVM_ASYNC_PF_ACK,
@@ -2510,26 +2513,29 @@ static inline int gtod_is_based_on_tsc(int mode)
 }
 #endif
 
-static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
+static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu, bool new_generation)
 {
 #ifdef CONFIG_X86_64
-       bool vcpus_matched;
        struct kvm_arch *ka = &vcpu->kvm->arch;
        struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
 
-       vcpus_matched = (ka->nr_vcpus_matched_tsc + 1 ==
-                        atomic_read(&vcpu->kvm->online_vcpus));
+       /*
+        * To use the masterclock, the host clocksource must be based on TSC
+        * and all vCPUs must have matching TSCs.  Note, the count for matching
+        * vCPUs doesn't include the reference vCPU, hence "+1".
+        */
+       bool use_master_clock = (ka->nr_vcpus_matched_tsc + 1 ==
+                                atomic_read(&vcpu->kvm->online_vcpus)) &&
+                               gtod_is_based_on_tsc(gtod->clock.vclock_mode);
 
        /*
-        * Once the masterclock is enabled, always perform request in
-        * order to update it.
-        *
-        * In order to enable masterclock, the host clocksource must be TSC
-        * and the vcpus need to have matched TSCs.  When that happens,
-        * perform request to enable masterclock.
+        * Request a masterclock update if the masterclock needs to be toggled
+        * on/off, or when starting a new generation and the masterclock is
+        * enabled (compute_guest_tsc() requires the masterclock snapshot to be
+        * taken _after_ the new generation is created).
         */
-       if (ka->use_master_clock ||
-           (gtod_is_based_on_tsc(gtod->clock.vclock_mode) && vcpus_matched))
+       if ((ka->use_master_clock && new_generation) ||
+           (ka->use_master_clock != use_master_clock))
                kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu);
 
        trace_kvm_track_tsc(vcpu->vcpu_id, ka->nr_vcpus_matched_tsc,
@@ -2706,7 +2712,7 @@ static void __kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 offset, u64 tsc,
        vcpu->arch.this_tsc_nsec = kvm->arch.cur_tsc_nsec;
        vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
 
-       kvm_track_tsc_matching(vcpu);
+       kvm_track_tsc_matching(vcpu, !matched);
 }
 
 static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 *user_value)
@@ -4020,6 +4026,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                 * the need to ignore the workaround.
                 */
                break;
+#ifdef CONFIG_KVM_HYPERV
        case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
        case HV_X64_MSR_SYNDBG_CONTROL ... HV_X64_MSR_SYNDBG_PENDING_BUFFER:
        case HV_X64_MSR_SYNDBG_OPTIONS:
@@ -4032,6 +4039,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case HV_X64_MSR_TSC_INVARIANT_CONTROL:
                return kvm_hv_set_msr_common(vcpu, msr, data,
                                             msr_info->host_initiated);
+#endif
        case MSR_IA32_BBL_CR_CTL3:
                /* Drop writes to this legacy MSR -- see rdmsr
                 * counterpart for further detail.
@@ -4377,6 +4385,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                 */
                msr_info->data = 0x20000000;
                break;
+#ifdef CONFIG_KVM_HYPERV
        case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
        case HV_X64_MSR_SYNDBG_CONTROL ... HV_X64_MSR_SYNDBG_PENDING_BUFFER:
        case HV_X64_MSR_SYNDBG_OPTIONS:
@@ -4390,6 +4399,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                return kvm_hv_get_msr_common(vcpu,
                                             msr_info->index, &msr_info->data,
                                             msr_info->host_initiated);
+#endif
        case MSR_IA32_BBL_CR_CTL3:
                /* This legacy MSR exists but isn't fully documented in current
                 * silicon.  It is however accessed by winxp in very narrow
@@ -4527,6 +4537,7 @@ static inline bool kvm_can_mwait_in_guest(void)
                boot_cpu_has(X86_FEATURE_ARAT);
 }
 
+#ifdef CONFIG_KVM_HYPERV
 static int kvm_ioctl_get_supported_hv_cpuid(struct kvm_vcpu *vcpu,
                                            struct kvm_cpuid2 __user *cpuid_arg)
 {
@@ -4547,6 +4558,7 @@ static int kvm_ioctl_get_supported_hv_cpuid(struct kvm_vcpu *vcpu,
 
        return 0;
 }
+#endif
 
 static bool kvm_is_vm_type_supported(unsigned long type)
 {
@@ -4580,9 +4592,11 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_PIT_STATE2:
        case KVM_CAP_SET_IDENTITY_MAP_ADDR:
        case KVM_CAP_VCPU_EVENTS:
+#ifdef CONFIG_KVM_HYPERV
        case KVM_CAP_HYPERV:
        case KVM_CAP_HYPERV_VAPIC:
        case KVM_CAP_HYPERV_SPIN:
+       case KVM_CAP_HYPERV_TIME:
        case KVM_CAP_HYPERV_SYNIC:
        case KVM_CAP_HYPERV_SYNIC2:
        case KVM_CAP_HYPERV_VP_INDEX:
@@ -4592,6 +4606,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_HYPERV_CPUID:
        case KVM_CAP_HYPERV_ENFORCE_CPUID:
        case KVM_CAP_SYS_HYPERV_CPUID:
+#endif
        case KVM_CAP_PCI_SEGMENT:
        case KVM_CAP_DEBUGREGS:
        case KVM_CAP_X86_ROBUST_SINGLESTEP:
@@ -4601,7 +4616,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_GET_TSC_KHZ:
        case KVM_CAP_KVMCLOCK_CTRL:
        case KVM_CAP_READONLY_MEM:
-       case KVM_CAP_HYPERV_TIME:
        case KVM_CAP_IOAPIC_POLARITY_IGNORED:
        case KVM_CAP_TSC_DEADLINE_TIMER:
        case KVM_CAP_DISABLE_QUIRKS:
@@ -4712,12 +4726,14 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                r = kvm_x86_ops.nested_ops->get_state ?
                        kvm_x86_ops.nested_ops->get_state(NULL, NULL, 0) : 0;
                break;
+#ifdef CONFIG_KVM_HYPERV
        case KVM_CAP_HYPERV_DIRECT_TLBFLUSH:
                r = kvm_x86_ops.enable_l2_tlb_flush != NULL;
                break;
        case KVM_CAP_HYPERV_ENLIGHTENED_VMCS:
                r = kvm_x86_ops.nested_ops->enable_evmcs != NULL;
                break;
+#endif
        case KVM_CAP_SMALLER_MAXPHYADDR:
                r = (int) allow_smaller_maxphyaddr;
                break;
@@ -4884,9 +4900,11 @@ long kvm_arch_dev_ioctl(struct file *filp,
        case KVM_GET_MSRS:
                r = msr_io(NULL, argp, do_get_msr_feature, 1);
                break;
+#ifdef CONFIG_KVM_HYPERV
        case KVM_GET_SUPPORTED_HV_CPUID:
                r = kvm_ioctl_get_supported_hv_cpuid(NULL, argp);
                break;
+#endif
        case KVM_GET_DEVICE_ATTR: {
                struct kvm_device_attr attr;
                r = -EFAULT;
@@ -5531,8 +5549,8 @@ static void kvm_vcpu_ioctl_x86_get_xsave2(struct kvm_vcpu *vcpu,
 static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
                                         struct kvm_xsave *guest_xsave)
 {
-       return kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region,
-                                            sizeof(guest_xsave->region));
+       kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region,
+                                     sizeof(guest_xsave->region));
 }
 
 static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
@@ -5712,14 +5730,11 @@ static int kvm_vcpu_ioctl_device_attr(struct kvm_vcpu *vcpu,
 static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
                                     struct kvm_enable_cap *cap)
 {
-       int r;
-       uint16_t vmcs_version;
-       void __user *user_ptr;
-
        if (cap->flags)
                return -EINVAL;
 
        switch (cap->cap) {
+#ifdef CONFIG_KVM_HYPERV
        case KVM_CAP_HYPERV_SYNIC2:
                if (cap->args[0])
                        return -EINVAL;
@@ -5731,16 +5746,22 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
                return kvm_hv_activate_synic(vcpu, cap->cap ==
                                             KVM_CAP_HYPERV_SYNIC2);
        case KVM_CAP_HYPERV_ENLIGHTENED_VMCS:
-               if (!kvm_x86_ops.nested_ops->enable_evmcs)
-                       return -ENOTTY;
-               r = kvm_x86_ops.nested_ops->enable_evmcs(vcpu, &vmcs_version);
-               if (!r) {
-                       user_ptr = (void __user *)(uintptr_t)cap->args[0];
-                       if (copy_to_user(user_ptr, &vmcs_version,
-                                        sizeof(vmcs_version)))
-                               r = -EFAULT;
+               {
+                       int r;
+                       uint16_t vmcs_version;
+                       void __user *user_ptr;
+
+                       if (!kvm_x86_ops.nested_ops->enable_evmcs)
+                               return -ENOTTY;
+                       r = kvm_x86_ops.nested_ops->enable_evmcs(vcpu, &vmcs_version);
+                       if (!r) {
+                               user_ptr = (void __user *)(uintptr_t)cap->args[0];
+                               if (copy_to_user(user_ptr, &vmcs_version,
+                                                sizeof(vmcs_version)))
+                                       r = -EFAULT;
+                       }
+                       return r;
                }
-               return r;
        case KVM_CAP_HYPERV_DIRECT_TLBFLUSH:
                if (!kvm_x86_ops.enable_l2_tlb_flush)
                        return -ENOTTY;
@@ -5749,6 +5770,7 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
 
        case KVM_CAP_HYPERV_ENFORCE_CPUID:
                return kvm_hv_set_enforce_cpuid(vcpu, cap->args[0]);
+#endif
 
        case KVM_CAP_ENFORCE_PV_FEATURE_CPUID:
                vcpu->arch.pv_cpuid.enforce = cap->args[0];
@@ -6141,9 +6163,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                srcu_read_unlock(&vcpu->kvm->srcu, idx);
                break;
        }
+#ifdef CONFIG_KVM_HYPERV
        case KVM_GET_SUPPORTED_HV_CPUID:
                r = kvm_ioctl_get_supported_hv_cpuid(vcpu, argp);
                break;
+#endif
 #ifdef CONFIG_KVM_XEN
        case KVM_XEN_VCPU_GET_ATTR: {
                struct kvm_xen_vcpu_attr xva;
@@ -7201,6 +7225,7 @@ set_pit2_out:
                r = static_call(kvm_x86_mem_enc_unregister_region)(kvm, &region);
                break;
        }
+#ifdef CONFIG_KVM_HYPERV
        case KVM_HYPERV_EVENTFD: {
                struct kvm_hyperv_eventfd hvevfd;
 
@@ -7210,6 +7235,7 @@ set_pit2_out:
                r = kvm_vm_ioctl_hv_eventfd(kvm, &hvevfd);
                break;
        }
+#endif
        case KVM_SET_PMU_EVENT_FILTER:
                r = kvm_vm_ioctl_set_pmu_event_filter(kvm, argp);
                break;
@@ -10598,19 +10624,20 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
 
 static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
 {
-       u64 eoi_exit_bitmap[4];
-
        if (!kvm_apic_hw_enabled(vcpu->arch.apic))
                return;
 
+#ifdef CONFIG_KVM_HYPERV
        if (to_hv_vcpu(vcpu)) {
+               u64 eoi_exit_bitmap[4];
+
                bitmap_or((ulong *)eoi_exit_bitmap,
                          vcpu->arch.ioapic_handled_vectors,
                          to_hv_synic(vcpu)->vec_bitmap, 256);
                static_call_cond(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
                return;
        }
-
+#endif
        static_call_cond(kvm_x86_load_eoi_exitmap)(
                vcpu, (u64 *)vcpu->arch.ioapic_handled_vectors);
 }
@@ -10701,9 +10728,11 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                 * the flushes are considered "remote" and not "local" because
                 * the requests can be initiated from other vCPUs.
                 */
+#ifdef CONFIG_KVM_HYPERV
                if (kvm_check_request(KVM_REQ_HV_TLB_FLUSH, vcpu) &&
                    kvm_hv_vcpu_flush_tlb(vcpu))
                        kvm_vcpu_flush_tlb_guest(vcpu);
+#endif
 
                if (kvm_check_request(KVM_REQ_REPORT_TPR_ACCESS, vcpu)) {
                        vcpu->run->exit_reason = KVM_EXIT_TPR_ACCESS;
@@ -10756,6 +10785,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                        vcpu_load_eoi_exitmap(vcpu);
                if (kvm_check_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu))
                        kvm_vcpu_reload_apic_access_page(vcpu);
+#ifdef CONFIG_KVM_HYPERV
                if (kvm_check_request(KVM_REQ_HV_CRASH, vcpu)) {
                        vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
                        vcpu->run->system_event.type = KVM_SYSTEM_EVENT_CRASH;
@@ -10786,6 +10816,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                 */
                if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
                        kvm_hv_process_stimers(vcpu);
+#endif
                if (kvm_check_request(KVM_REQ_APICV_UPDATE, vcpu))
                        kvm_vcpu_update_apicv(vcpu);
                if (kvm_check_request(KVM_REQ_APF_READY, vcpu))
@@ -12231,7 +12262,6 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
        }
 
        if (!init_event) {
-               kvm_pmu_reset(vcpu);
                vcpu->arch.smbase = 0x30000;
 
                vcpu->arch.msr_misc_features_enables = 0;
@@ -12448,7 +12478,9 @@ void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu)
 
 void kvm_arch_free_vm(struct kvm *kvm)
 {
-       kfree(to_kvm_hv(kvm)->hv_pa_pg);
+#if IS_ENABLED(CONFIG_HYPERV)
+       kfree(kvm->arch.hv_pa_pg);
+#endif
        __kvm_arch_free_vm(kvm);
 }
 
@@ -13061,7 +13093,10 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
        if (vcpu->arch.guest_state_protected)
                return true;
 
-       return vcpu->arch.preempted_in_kernel;
+       if (vcpu != kvm_get_running_vcpu())
+               return vcpu->arch.preempted_in_kernel;
+
+       return static_call(kvm_x86_get_cpl)(vcpu) == 0;
 }
 
 unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)