Re: [PATCH 1/6] LoongArch: KVM: Add vmid support for stage2 MMU
From: Bibo Mao
Date: Tue Aug 04 2026 - 22:20:43 EST
On 2026/8/5 上午9:27, Bibo Mao wrote:
Sorry to response too hurry. If vmid represents software version, it is hard to write with assemble language such as:
On 2026/8/5 上午9:21, Bibo Mao wrote:
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.
On 2026/8/4 下午10:14, Huacai Chen wrote:
On Mon, Aug 3, 2026 at 9:21 AM Bibo Mao <maobibo@xxxxxxxxxxx> wrote:yes, it is.
I'm not sure, but it seems both vpid and vmid have a sw version and a
On 2026/8/2 下午10:11, Huacai Chen wrote:
Hi, Bibo,yes, it it better to near vpid. will do this.
On Mon, Jul 27, 2026 at 3:29 PM Bibo Mao <maobibo@xxxxxxxxxxx> wrote:
Put it near vpid?
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 <maobibo@xxxxxxxxxxx>
---
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;
vpid used in function kvm_check_vcpuid() includes version information
+
/* 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".
also. vmid here is hardware id directly used by LOONGARCH_CSR_GTLBC in
arch/loongarch/kvm/switch.S.
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
"& vpid_mask" is only used when writing registers, in other placesIf vmid includes version, it requires one extra shift operation when writing to real HW in file arch/loongarch/kvm/switch.S.
they are full 64bit (in other words, they need the same treatment).
- /* 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?
+ /* 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