#define KVM_PRIVATE_MEM_SLOTS          0
 
 #define KVM_HALT_POLL_NS_DEFAULT       500000
+#define KVM_REQ_TLB_FLUSH_GPA          KVM_ARCH_REQ(0)
 
 #define KVM_GUESTDBG_SW_BP_MASK                \
        (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
 
        /* vcpu's vpid */
        u64 vpid;
+       gpa_t flush_gpa;
 
        /* Frequency of stable timer in Hz */
        u64 timer_mhz;
 
                kvm_update_vpid(vcpu, cpu);
                trace_kvm_vpid_change(vcpu, vcpu->arch.vpid);
                vcpu->cpu = cpu;
+               kvm_clear_request(KVM_REQ_TLB_FLUSH_GPA, vcpu);
        }
 
        /* Restore GSTAT(0x50).vpid */
 
                return ret;
 
        /* Invalidate this entry in the TLB */
-       kvm_flush_tlb_gpa(vcpu, gpa);
+       vcpu->arch.flush_gpa = gpa;
+       kvm_make_request(KVM_REQ_TLB_FLUSH_GPA, vcpu);
 
        return 0;
 }
 
 
 void kvm_flush_tlb_gpa(struct kvm_vcpu *vcpu, unsigned long gpa)
 {
-       unsigned long flags;
-
-       local_irq_save(flags);
+       lockdep_assert_irqs_disabled();
        gpa &= (PAGE_MASK << 1);
        invtlb(INVTLB_GID_ADDR, read_csr_gstat() & CSR_GSTAT_GID, gpa);
-       local_irq_restore(flags);
 }
 
        return RESUME_GUEST;
 }
 
+static void kvm_late_check_requests(struct kvm_vcpu *vcpu)
+{
+       lockdep_assert_irqs_disabled();
+       if (kvm_check_request(KVM_REQ_TLB_FLUSH_GPA, vcpu))
+               if (vcpu->arch.flush_gpa != INVALID_GPA) {
+                       kvm_flush_tlb_gpa(vcpu, vcpu->arch.flush_gpa);
+                       vcpu->arch.flush_gpa = INVALID_GPA;
+               }
+}
+
 /*
  * Check and handle pending signal and vCPU requests etc
  * Run with irq enabled and preempt enabled
                /* Make sure the vcpu mode has been written */
                smp_store_mb(vcpu->mode, IN_GUEST_MODE);
                kvm_check_vpid(vcpu);
+
+               /*
+                * Called after function kvm_check_vpid()
+                * Since it updates CSR.GSTAT used by kvm_flush_tlb_gpa(),
+                * and it may also clear KVM_REQ_TLB_FLUSH_GPA pending bit
+                */
+               kvm_late_check_requests(vcpu);
                vcpu->arch.host_eentry = csr_read64(LOONGARCH_CSR_EENTRY);
                /* Clear KVM_LARCH_SWCSR_LATEST as CSR will change when enter guest */
                vcpu->arch.aux_inuse &= ~KVM_LARCH_SWCSR_LATEST;
        struct loongarch_csrs *csr;
 
        vcpu->arch.vpid = 0;
+       vcpu->arch.flush_gpa = INVALID_GPA;
 
        hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED);
        vcpu->arch.swtimer.function = kvm_swtimer_wakeup;