Re: [PATCH 1/6] LoongArch: KVM: Add vmid support for stage2 MMU
Bibo Mao <[email protected]> Wed, 5 Aug 2026 09:27:31 +0800
| Newsgroups | org.kernel.vger.kvm,dev.linux.lists.loongarch,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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. 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 >>>>> >>>