Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[platform/kernel/linux-starfive.git] / arch / x86 / kvm / x86.c
index bbc4e04..6d3955a 100644 (file)
@@ -3072,6 +3072,19 @@ static void kvm_vcpu_flush_tlb_all(struct kvm_vcpu *vcpu)
 static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu)
 {
        ++vcpu->stat.tlb_flush;
+
+       if (!tdp_enabled) {
+               /*
+                * A TLB flush on behalf of the guest is equivalent to
+                * INVPCID(all), toggling CR4.PGE, etc., which requires
+                * a forced sync of the shadow page tables.  Unload the
+                * entire MMU here and the subsequent load will sync the
+                * shadow page tables, and also flush the TLB.
+                */
+               kvm_mmu_unload(vcpu);
+               return;
+       }
+
        static_call(kvm_x86_tlb_flush_guest)(vcpu);
 }
 
@@ -3101,10 +3114,14 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
         * expensive IPIs.
         */
        if (guest_pv_has(vcpu, KVM_FEATURE_PV_TLB_FLUSH)) {
+               u8 st_preempted = xchg(&st->preempted, 0);
+
                trace_kvm_pv_tlb_flush(vcpu->vcpu_id,
-                                      st->preempted & KVM_VCPU_FLUSH_TLB);
-               if (xchg(&st->preempted, 0) & KVM_VCPU_FLUSH_TLB)
+                                      st_preempted & KVM_VCPU_FLUSH_TLB);
+               if (st_preempted & KVM_VCPU_FLUSH_TLB)
                        kvm_vcpu_flush_tlb_guest(vcpu);
+       } else {
+               st->preempted = 0;
        }
 
        vcpu->arch.st.preempted = 0;
@@ -7226,6 +7243,11 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
        BUILD_BUG_ON(HF_SMM_MASK != X86EMUL_SMM_MASK);
        BUILD_BUG_ON(HF_SMM_INSIDE_NMI_MASK != X86EMUL_SMM_INSIDE_NMI_MASK);
 
+       ctxt->interruptibility = 0;
+       ctxt->have_exception = false;
+       ctxt->exception.vector = -1;
+       ctxt->perm_ok = false;
+
        init_decode_cache(ctxt);
        vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
 }
@@ -7561,14 +7583,7 @@ int x86_decode_emulated_instruction(struct kvm_vcpu *vcpu, int emulation_type,
            kvm_vcpu_check_breakpoint(vcpu, &r))
                return r;
 
-       ctxt->interruptibility = 0;
-       ctxt->have_exception = false;
-       ctxt->exception.vector = -1;
-       ctxt->perm_ok = false;
-
-       ctxt->ud = emulation_type & EMULTYPE_TRAP_UD;
-
-       r = x86_decode_insn(ctxt, insn, insn_len);
+       r = x86_decode_insn(ctxt, insn, insn_len, emulation_type);
 
        trace_kvm_emulate_insn_start(vcpu);
        ++vcpu->stat.insn_emulation;
@@ -8360,6 +8375,9 @@ static void kvm_sched_yield(struct kvm_vcpu *vcpu, unsigned long dest_id)
 
        vcpu->stat.directed_yield_attempted++;
 
+       if (single_task_running())
+               goto no_yield;
+
        rcu_read_lock();
        map = rcu_dereference(vcpu->kvm->arch.apic_map);
 
@@ -9496,7 +9514,7 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
                if (r <= 0)
                        break;
 
-               kvm_clear_request(KVM_REQ_PENDING_TIMER, vcpu);
+               kvm_clear_request(KVM_REQ_UNBLOCK, vcpu);
                if (kvm_cpu_has_pending_timer(vcpu))
                        kvm_inject_pending_timer_irqs(vcpu);
 
@@ -10115,8 +10133,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
        kvm_update_dr7(vcpu);
 
        if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
-               vcpu->arch.singlestep_rip = kvm_rip_read(vcpu) +
-                       get_segment_base(vcpu, VCPU_SREG_CS);
+               vcpu->arch.singlestep_rip = kvm_get_linear_rip(vcpu);
 
        /*
         * Trigger an rflags update that will inject or remove the trace
@@ -11499,7 +11516,8 @@ bool kvm_arch_can_dequeue_async_page_present(struct kvm_vcpu *vcpu)
 
 void kvm_arch_start_assignment(struct kvm *kvm)
 {
-       atomic_inc(&kvm->arch.assigned_device_count);
+       if (atomic_inc_return(&kvm->arch.assigned_device_count) == 1)
+               static_call_cond(kvm_x86_start_assignment)(kvm);
 }
 EXPORT_SYMBOL_GPL(kvm_arch_start_assignment);