]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
LoongArch: KVM: Remove PGD saving during VM context switch
authorBibo Mao <maobibo@loongson.cn>
Tue, 18 Mar 2025 08:48:08 +0000 (16:48 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Tue, 18 Mar 2025 08:48:08 +0000 (16:48 +0800)
PGD table for primary mmu keeps unchanged once VM is created, it is not
necessary to save PGD table pointer during VM context switch. And it can
be acquired when VM is created.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/include/asm/kvm_host.h
arch/loongarch/kernel/asm-offsets.c
arch/loongarch/kvm/switch.S
arch/loongarch/kvm/vcpu.c

index 590982cd986ec8186ade85df96e252570d2ec444..d8b543b3fa259bc755470ab800ed4a1d7e7e036b 100644 (file)
@@ -176,6 +176,9 @@ struct kvm_vcpu_arch {
        /* Pointers stored here for easy accessing from assembly code */
        int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu);
 
+       /* GPA (=HVA) of PGD for secondary mmu */
+       unsigned long kvm_pgd;
+
        /* Host registers preserved across guest mode execution */
        unsigned long host_sp;
        unsigned long host_tp;
index 8be1c38ad8eb26cc3d901c4a0c0b71bde715057a..c19f446ad0db9e11964d133a257ae3fcf7cf7543 100644 (file)
@@ -296,6 +296,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_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);
        OFFSET(KVM_ARCH_GEENTRY, kvm_vcpu_arch, guest_eentry);
index 1be185e948072394902cfa0c3dae3a55c1bb3a90..f1768b7a619497323bd7f96cddf8280938ca594b 100644 (file)
        ld.d    t0, a2, KVM_ARCH_GPC
        csrwr   t0, LOONGARCH_CSR_ERA
 
-       /* Save host PGDL */
-       csrrd   t0, LOONGARCH_CSR_PGDL
-       st.d    t0, a2, KVM_ARCH_HPGD
-
-       /* Switch to kvm */
-       ld.d    t1, a2, KVM_VCPU_KVM - KVM_VCPU_ARCH
-
-       /* Load guest PGDL */
-       li.w    t0, KVM_GPGD
-       ldx.d   t0, t1, t0
+       /* Load PGD for KVM hypervisor */
+       ld.d    t0, a2, KVM_ARCH_KVMPGD
        csrwr   t0, LOONGARCH_CSR_PGDL
 
        /* Mix GID and RID */
index 9e1a9b4aa4c6a99c3aa06b860e32314a4f3d0307..a147290a11e43f34ce206b3cbd99c0595d5815b9 100644 (file)
@@ -1462,6 +1462,15 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
        hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD);
        vcpu->arch.swtimer.function = kvm_swtimer_wakeup;
 
+       /* Get GPA (=HVA) of PGD for kvm hypervisor */
+       vcpu->arch.kvm_pgd = __pa(vcpu->kvm->arch.pgd);
+
+       /*
+        * Get PGD for primary mmu, virtual address is used since there is
+        * memory access after loading from CSR_PGD in tlb exception fast path.
+        */
+       vcpu->arch.host_pgd = (unsigned long)vcpu->kvm->mm->pgd;
+
        vcpu->arch.handle_exit = kvm_handle_exit;
        vcpu->arch.guest_eentry = (unsigned long)kvm_loongarch_ops->exc_entry;
        vcpu->arch.csr = kzalloc(sizeof(struct loongarch_csrs), GFP_KERNEL);