LoongArch: KVM: Fix GPA size issue about VM

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>

authored by Bibo Mao and committed by Huacai Chen 6bdbb73d 78d7bc5a

+11 -1
+6
arch/loongarch/kvm/exit.c
··· 669 struct kvm_run *run = vcpu->run; 670 unsigned long badv = vcpu->arch.badv; 671 672 ret = kvm_handle_mm_fault(vcpu, badv, write); 673 if (ret) { 674 /* Treat as MMIO */
··· 669 struct kvm_run *run = vcpu->run; 670 unsigned long badv = vcpu->arch.badv; 671 672 + /* Inject ADE exception if exceed max GPA size */ 673 + if (unlikely(badv >= vcpu->kvm->arch.gpa_size)) { 674 + kvm_queue_exception(vcpu, EXCCODE_ADE, EXSUBCODE_ADEM); 675 + return RESUME_GUEST; 676 + } 677 + 678 ret = kvm_handle_mm_fault(vcpu, badv, write); 679 if (ret) { 680 /* Treat as MMIO */
+5 -1
arch/loongarch/kvm/vm.c
··· 48 if (kvm_pvtime_supported()) 49 kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME); 50 51 - kvm->arch.gpa_size = BIT(cpu_vabits - 1); 52 kvm->arch.root_level = CONFIG_PGTABLE_LEVELS - 1; 53 kvm->arch.invalid_ptes[0] = 0; 54 kvm->arch.invalid_ptes[1] = (unsigned long)invalid_pte_table;
··· 48 if (kvm_pvtime_supported()) 49 kvm->arch.pv_features |= BIT(KVM_FEATURE_STEAL_TIME); 50 51 + /* 52 + * cpu_vabits means user address space only (a half of total). 53 + * GPA size of VM is the same with the size of user address space. 54 + */ 55 + kvm->arch.gpa_size = BIT(cpu_vabits); 56 kvm->arch.root_level = CONFIG_PGTABLE_LEVELS - 1; 57 kvm->arch.invalid_ptes[0] = 0; 58 kvm->arch.invalid_ptes[1] = (unsigned long)invalid_pte_table;