@@ -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 */
@@ -48,7 +48,12 @@ 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, kernel address space is
+ * not included. 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;
Physical address space is 48 bit on 3A5000 physical machine, however it is 47 bit for VM on 3A5000 system. Size of physical address space of VM is the same with size of virtual user space of physical machine. Variable cpu_vabits represents user address space, kernel address space is not include. Here cpu_vabits is to represent size of physical address space, rather than cpu_vabits - 1. Also there is strict checking about page fault GPA address, inject error if it is larger than maximum GPA address of VM. Signed-off-by: Bibo Mao <maobibo@loongson.cn> --- arch/loongarch/kvm/exit.c | 6 ++++++ arch/loongarch/kvm/vm.c | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-)