Re: [PATCH v2 1/6] LoongArch: KVM: Delay secondary mmu tlb flush until guest entry

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi, Bibo,

On Wed, Jun 19, 2024 at 4:09 PM Bibo Mao <maobibo@xxxxxxxxxxx> wrote:
>
> If there is page fault for secondary mmu, there needs tlb flush
What does "secondary mmu" in this context mean? Maybe "guest mmu"?

Huacai

> operation indexed with fault gpa address and VMID. VMID is stored
> at register CSR_GSTAT and will be reload or recalculated during
> guest entry.
>
> Currently CSR_GSTAT is not saved and restored during vcpu context
> switch, it is recalculated during guest entry. So CSR_GSTAT is in
> effect only when vcpu runs in guest mode, however it may be not in
> effected if vcpu exits to host mode, since register CSR_GSTAT may
> be stale, it maybe records VMID of last scheduled vcpu, rather than
> current vcpu.
>
> Function kvm_flush_tlb_gpa() should be called with its real VMID,
> here move it to guest entrance. Also arch specific request id
> KVM_REQ_TLB_FLUSH_GPA is added to flush tlb, and it can be optimized
> if VMID is updated, since all guest tlb entries will be invalid if
> VMID is updated.
>
> Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx>
> ---
>  arch/loongarch/include/asm/kvm_host.h |  2 ++
>  arch/loongarch/kvm/main.c             |  1 +
>  arch/loongarch/kvm/mmu.c              |  4 ++--
>  arch/loongarch/kvm/tlb.c              |  5 +----
>  arch/loongarch/kvm/vcpu.c             | 18 ++++++++++++++++++
>  5 files changed, 24 insertions(+), 6 deletions(-)
>
> diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
> index c87b6ea0ec47..32c4948f534f 100644
> --- a/arch/loongarch/include/asm/kvm_host.h
> +++ b/arch/loongarch/include/asm/kvm_host.h
> @@ -30,6 +30,7 @@
>  #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)
> @@ -190,6 +191,7 @@ struct kvm_vcpu_arch {
>
>         /* vcpu's vpid */
>         u64 vpid;
> +       gpa_t flush_gpa;
>
>         /* Frequency of stable timer in Hz */
>         u64 timer_mhz;
> diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c
> index 86a2f2d0cb27..844736b99d38 100644
> --- a/arch/loongarch/kvm/main.c
> +++ b/arch/loongarch/kvm/main.c
> @@ -242,6 +242,7 @@ void kvm_check_vpid(struct kvm_vcpu *vcpu)
>                 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 */
> diff --git a/arch/loongarch/kvm/mmu.c b/arch/loongarch/kvm/mmu.c
> index 98883aa23ab8..9e39d28fec35 100644
> --- a/arch/loongarch/kvm/mmu.c
> +++ b/arch/loongarch/kvm/mmu.c
> @@ -908,8 +908,8 @@ int kvm_handle_mm_fault(struct kvm_vcpu *vcpu, unsigned long gpa, bool write)
>                 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;
>  }
>
> diff --git a/arch/loongarch/kvm/tlb.c b/arch/loongarch/kvm/tlb.c
> index 02535df6b51f..ebdbe9264e9c 100644
> --- a/arch/loongarch/kvm/tlb.c
> +++ b/arch/loongarch/kvm/tlb.c
> @@ -23,10 +23,7 @@ void kvm_flush_tlb_all(void)
>
>  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);
>  }
> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> index 9e8030d45129..b747bd8bc037 100644
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -51,6 +51,16 @@ static int kvm_check_requests(struct kvm_vcpu *vcpu)
>         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
> @@ -101,6 +111,13 @@ static int kvm_pre_enter_guest(struct kvm_vcpu *vcpu)
>                 /* 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(),
> +                * also it may 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;
> @@ -994,6 +1011,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
>         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;
> --
> 2.39.3
>





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux