@@ -166,6 +166,9 @@ struct kvm_vcpu_arch {
unsigned long host_tp;
unsigned long host_pgd;
+ /* vmid info for guest VM */
+ unsigned long vmid;
+
/* Host CSRs are used when handling exits from guest */
unsigned long badi;
unsigned long badv;
@@ -307,6 +307,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_HANDLE_EXIT, kvm_vcpu_arch, handle_exit);
OFFSET(KVM_ARCH_HEENTRY, kvm_vcpu_arch, host_eentry);
OFFSET(KVM_ARCH_GEENTRY, kvm_vcpu_arch, guest_eentry);
@@ -212,6 +212,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;
}
void kvm_check_vpid(struct kvm_vcpu *vcpu)
@@ -72,9 +72,8 @@
ldx.d t0, t1, t0
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
@@ -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);
}
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@loongson.cn> --- 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(-)