]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
LoongArch: KVM: Clear LLBCTL if secondary mmu mapping is changed
authorBibo Mao <maobibo@loongson.cn>
Mon, 13 Jan 2025 13:37:17 +0000 (21:37 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Mon, 13 Jan 2025 13:37:17 +0000 (21:37 +0800)
LLBCTL is a separated guest CSR register from host, host exception ERET
instruction will clear the host LLBCTL CSR register, and guest exception
will clear the guest LLBCTL CSR register.

VCPU0 atomic64_fetch_add_unless     VCPU1 atomic64_fetch_add_unless
     ll.d    %[p],  %[c]
     beq     %[p],  %[u], 1f

Here secondary mmu mapping is changed, host hpa page is replaced with a
new page. And VCPU1 will execute atomic instruction on the new page.

                                       ll.d    %[p],  %[c]
                                       beq     %[p],  %[u], 1f
                                       add.d   %[rc], %[p], %[a]
                                       sc.d    %[rc], %[c]
     add.d   %[rc], %[p], %[a]
     sc.d    %[rc], %[c]

LLBCTL is set on VCPU0 and it represents the memory is not modified by
other VCPUs, sc.d will modify the memory directly.

So clear WCLLB of the guest LLBCTL register when mapping is the changed.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/kvm/main.c

index 396fed2665a5174060112056b2406117f071d1b5..bf9268bf26d5b8f46435685c9869dec38a8800ad 100644 (file)
@@ -245,6 +245,24 @@ void kvm_check_vpid(struct kvm_vcpu *vcpu)
                trace_kvm_vpid_change(vcpu, vcpu->arch.vpid);
                vcpu->cpu = cpu;
                kvm_clear_request(KVM_REQ_TLB_FLUSH_GPA, vcpu);
+
+               /*
+                * LLBCTL is a separated guest CSR register from host, a general
+                * exception ERET instruction clears the host LLBCTL register in
+                * host mode, and clears the guest LLBCTL register in guest mode.
+                * ERET in tlb refill exception does not clear LLBCTL register.
+                *
+                * When secondary mmu mapping is changed, guest OS does not know
+                * even if the content is changed after mapping is changed.
+                *
+                * Here clear WCLLB of the guest LLBCTL register when mapping is
+                * changed. Otherwise, if mmu mapping is changed while guest is
+                * executing LL/SC pair, LL loads with the old address and set
+                * the LLBCTL flag, SC checks the LLBCTL flag and will store the
+                * new address successfully since LLBCTL_WCLLB is on, even if
+                * memory with new address is changed on other VCPUs.
+                */
+               set_gcsr_llbctl(CSR_LLBCTL_WCLLB);
        }
 
        /* Restore GSTAT(0x50).vpid */