]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
LoongArch: KVM: Fix GPA size issue about VM
authorBibo Mao <maobibo@loongson.cn>
Sat, 8 Mar 2025 05:52:04 +0000 (13:52 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Sat, 8 Mar 2025 05:52:04 +0000 (13:52 +0800)
Physical address space is 48 bit on Loongson-3A5000 physical machine,
however it is 47 bit for VM on Loongson-3A5000 system. Size of physical
address space of VM is the same with the size of virtual user space (a
half) of physical machine.

Variable cpu_vabits represents user address space, kernel address space
is not included (user space and kernel space are both a half of total).
Here cpu_vabits, rather than cpu_vabits - 1, is to represent the size of
guest physical address space.

Also there is strict checking about page fault GPA address, inject error
if it is larger than maximum GPA address of VM.

Cc: stable@vger.kernel.org
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/kvm/exit.c
arch/loongarch/kvm/vm.c

index c1e8ec5b941b22cc32c0ed63e63d4fb6963c9559..ea321403644adc67e4dc4d2e9b0d52894ba7db6a 100644 (file)
@@ -669,6 +669,12 @@ static int kvm_handle_rdwr_fault(struct kvm_vcpu *vcpu, bool write)
        struct kvm_run *run = vcpu->run;
        unsigned long badv = vcpu->arch.badv;
 
+       /* Inject ADE exception if exceed max GPA size */
+       if (unlikely(badv >= vcpu->kvm->arch.gpa_size)) {
+               kvm_queue_exception(vcpu, EXCCODE_ADE, EXSUBCODE_ADEM);
+               return RESUME_GUEST;
+       }
+
        ret = kvm_handle_mm_fault(vcpu, badv, write);
        if (ret) {
                /* Treat as MMIO */
index b8b3e1972d6eaa889f84c81e57e562b549f35ba7..edccfc8c9cd804906c53f905cb005a4e98ca3e14 100644 (file)
@@ -48,7 +48,11 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
        if (kvm_pvtime_supported())
                kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME);
 
-       kvm->arch.gpa_size = BIT(cpu_vabits - 1);
+       /*
+        * cpu_vabits means user address space only (a half of total).
+        * GPA size of VM is the same with the size of user address space.
+        */
+       kvm->arch.gpa_size = BIT(cpu_vabits);
        kvm->arch.root_level = CONFIG_PGTABLE_LEVELS - 1;
        kvm->arch.invalid_ptes[0] = 0;
        kvm->arch.invalid_ptes[1] = (unsigned long)invalid_pte_table;