Re: [PATCH 1/6] LoongArch: KVM: Add vmid support for stage2 MMU
Bibo Mao <[email protected]> Wed, 5 Aug 2026 10:19:54 +0800
| Newsgroups | org.kernel.vger.kvm,dev.linux.lists.loongarch,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 2026/8/5 上午9:27, Bibo Mao wrote: > > > On 2026/8/5 上午9:21, Bibo Mao wrote: >> >> >> On 2026/8/4 下午10:14, Huacai Chen wrote: >>> On Mon, Aug 3, 2026 at 9:21 AM Bibo Mao <[email protected]> wrote: >>>> >>>> >>>> >>>> On 2026/8/2 下午10:11, Huacai Chen wrote: >>>>> Hi, Bibo, >>>>> >>>>> On Mon, Jul 27, 2026 at 3:29 PM Bibo Mao <[email protected]> wrote: >>>>>> >>>>>> LoongArch KVM hypervisor supports two-level MMU, vpid index is used >>>>>> for stage1 MMU and vmid index is used for stage2 MMU. >>>>>> >>>>>> On 3A5000, vmid must be the same with vpid. On 3A6000 platform vmid >>>>>> may separate from vpid. If vcpu migrate to different physical CPUs, >>>>>> vpid need change however vmid can keep the same with old value. Also >>>>>> vmid index of the while VM machine on physical CPU the same, all >>>>>> vCPUs >>>>>> on the VM can share the same vmid index on one physical CPU. >>>>>> >>>>>> Here vmid index is added and it keeps the same with vpid still. >>>>>> >>>>>> Signed-off-by: Bibo Mao <[email protected]> >>>>>> --- >>>>>> arch/loongarch/include/asm/kvm_host.h | 3 +++ >>>>>> arch/loongarch/kernel/asm-offsets.c | 1 + >>>>>> arch/loongarch/kvm/main.c | 1 + >>>>>> arch/loongarch/kvm/switch.S | 5 ++--- >>>>>> arch/loongarch/kvm/tlb.c | 5 ++++- >>>>>> 5 files changed, 11 insertions(+), 4 deletions(-) >>>>>> >>>>>> diff --git a/arch/loongarch/include/asm/kvm_host.h >>>>>> b/arch/loongarch/include/asm/kvm_host.h >>>>>> index 23cfbecebbd7..ec7b0c402385 100644 >>>>>> --- a/arch/loongarch/include/asm/kvm_host.h >>>>>> +++ b/arch/loongarch/include/asm/kvm_host.h >>>>>> @@ -189,6 +189,9 @@ struct kvm_vcpu_arch { >>>>>> unsigned long host_tp; >>>>>> unsigned long host_pgd; >>>>>> >>>>>> + /* vmid info for guest VM */ >>>>>> + unsigned long vmid; >>>>> Put it near vpid? >>>> yes, it it better to near vpid. will do this. >>>>> >>>>>> + >>>>>> /* Host CSRs are used when handling exits from guest */ >>>>>> unsigned long badi; >>>>>> unsigned long badv; >>>>>> diff --git a/arch/loongarch/kernel/asm-offsets.c >>>>>> b/arch/loongarch/kernel/asm-offsets.c >>>>>> index 1b861cbc5e10..32ef6adfc8dd 100644 >>>>>> --- a/arch/loongarch/kernel/asm-offsets.c >>>>>> +++ b/arch/loongarch/kernel/asm-offsets.c >>>>>> @@ -300,6 +300,7 @@ static void __used output_kvm_defines(void) >>>>>> OFFSET(KVM_ARCH_HSP, kvm_vcpu_arch, host_sp); >>>>>> OFFSET(KVM_ARCH_HTP, kvm_vcpu_arch, host_tp); >>>>>> OFFSET(KVM_ARCH_HPGD, kvm_vcpu_arch, host_pgd); >>>>>> + OFFSET(KVM_ARCH_VMID, kvm_vcpu_arch, vmid); >>>>>> OFFSET(KVM_ARCH_KVMPGD, kvm_vcpu_arch, kvm_pgd); >>>>>> OFFSET(KVM_ARCH_HANDLE_EXIT, kvm_vcpu_arch, handle_exit); >>>>>> OFFSET(KVM_ARCH_HEENTRY, kvm_vcpu_arch, host_eentry); >>>>>> diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c >>>>>> index 3e1005526f4b..6e3e8efa1dc2 100644 >>>>>> --- a/arch/loongarch/kvm/main.c >>>>>> +++ b/arch/loongarch/kvm/main.c >>>>>> @@ -223,6 +223,7 @@ static void kvm_update_vpid(struct kvm_vcpu >>>>>> *vcpu, int cpu) >>>>>> >>>>>> context->vpid_cache = vpid; >>>>>> vcpu->arch.vpid = vpid; >>>>>> + vcpu->arch.vmid = vcpu->arch.vpid & vpid_mask; >>>>> >>>>> I think both vpid and vmid need "& vpid_mask". >>>> vpid used in function kvm_check_vcpuid() includes version information >>>> also. vmid here is hardware id directly used by LOONGARCH_CSR_GTLBC in >>>> arch/loongarch/kvm/switch.S. >>> I'm not sure, but it seems both vpid and vmid have a sw version and a >>> hw version? The hw version will be written into register so its width >>> is limited, while the sw version is 64bit. If I'm right, I think the >> yes, it is. >> >>> "& vpid_mask" is only used when writing registers, in other places >>> they are full 64bit (in other words, they need the same treatment). >> If vmid includes version, it requires one extra shift operation when >> writing to real HW in file arch/loongarch/kvm/switch.S. >> - /* Mix GID and RID */ >> - csrrd t1, LOONGARCH_CSR_GSTAT >> - bstrpick.w t1, t1, CSR_GSTAT_GID_SHIFT_END, >> CSR_GSTAT_GID_SHIFT >> + /* Set VMID for gpa --> hpa mapping */ >> + ld.d t1, a2, KVM_ARCH_VMID >> csrrd t0, LOONGARCH_CSR_GTLBC >> bstrins.w t0, t1, CSR_GTLBC_TGID_SHIFT_END, >> >> vpid is per-vcpu and it is represented with *vcpu->arch.vpid*, vmid is >> per-vm,it is shared by vCPUs and represented with >> *vcpu->kvm->arch.vmid[cpu]*. Instead arch.vmid is special for HW >> register writing with LOONGARCH_CSR_GTLBC, if there is misleading, how >> about renaming it with hw_vmid? > hw_vmid is strange, I am ok with vmid with version information, so that > the name is clear, one shift assemble code is not too much. Will change > in the next version. Sorry to response too hurry. If vmid represents software version, it is hard to write with assemble language such as: + /* Set VMID for gpa --> hpa mapping */ + ld.d t1, a2, KVM_ARCH_VMID + ld.d t0, vpid_mask module variable vpid_mask need export and put in structure kvm_vcpu_arch. + add t1, t1, t0 csrrd t0, LOONGARCH_CSR_GTLBC Regards Bibo Mao > > Regards > Bibo Mao >> >> Regards >> >> >>> >>> Huacai >>> >>>> >>>> Regards >>>> Bibo Mao >>>>> >>>>> >>>>> Huacai >>>>> >>>>>> } >>>>>> >>>>>> void kvm_check_vpid(struct kvm_vcpu *vcpu) >>>>>> diff --git a/arch/loongarch/kvm/switch.S >>>>>> b/arch/loongarch/kvm/switch.S >>>>>> index 936e4ae3e408..af972394fd55 100644 >>>>>> --- a/arch/loongarch/kvm/switch.S >>>>>> +++ b/arch/loongarch/kvm/switch.S >>>>>> @@ -66,9 +66,8 @@ >>>>>> ld.d t0, a2, KVM_ARCH_KVMPGD >>>>>> csrwr t0, LOONGARCH_CSR_PGDL >>>>>> >>>>>> - /* Mix GID and RID */ >>>>>> - csrrd t1, LOONGARCH_CSR_GSTAT >>>>>> - bstrpick.w t1, t1, CSR_GSTAT_GID_SHIFT_END, >>>>>> CSR_GSTAT_GID_SHIFT >>>>>> + /* Set VMID for gpa --> hpa mapping */ >>>>>> + ld.d t1, a2, KVM_ARCH_VMID >>>>>> csrrd t0, LOONGARCH_CSR_GTLBC >>>>>> bstrins.w t0, t1, CSR_GTLBC_TGID_SHIFT_END, >>>>>> CSR_GTLBC_TGID_SHIFT >>>>>> csrwr t0, LOONGARCH_CSR_GTLBC >>>>>> diff --git a/arch/loongarch/kvm/tlb.c b/arch/loongarch/kvm/tlb.c >>>>>> index ebdbe9264e9c..38daf936021d 100644 >>>>>> --- a/arch/loongarch/kvm/tlb.c >>>>>> +++ b/arch/loongarch/kvm/tlb.c >>>>>> @@ -23,7 +23,10 @@ void kvm_flush_tlb_all(void) >>>>>> >>>>>> void kvm_flush_tlb_gpa(struct kvm_vcpu *vcpu, unsigned long gpa) >>>>>> { >>>>>> + unsigned int vmid; >>>>>> + >>>>>> lockdep_assert_irqs_disabled(); >>>>>> gpa &= (PAGE_MASK << 1); >>>>>> - invtlb(INVTLB_GID_ADDR, read_csr_gstat() & CSR_GSTAT_GID, >>>>>> gpa); >>>>>> + vmid = (vcpu->arch.vmid << CSR_GSTAT_GID_SHIFT) & >>>>>> CSR_GSTAT_GID; >>>>>> + invtlb(INVTLB_GID_ADDR, vmid, gpa); >>>>>> } >>>>>> -- >>>>>> 2.39.3 >>>>>> >>>>