|
@@ -138,6 +138,7 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
|
|
|
unsigned long entryhi = 0, entrylo0 = 0, entrylo1 = 0;
|
|
|
struct kvm *kvm = vcpu->kvm;
|
|
|
kvm_pfn_t pfn0, pfn1;
|
|
|
+ gfn_t gfn0, gfn1;
|
|
|
long tlb_lo[2];
|
|
|
int ret;
|
|
|
|
|
@@ -152,18 +153,24 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
|
|
|
VPN2_MASK & (PAGE_MASK << 1)))
|
|
|
tlb_lo[(KVM_GUEST_COMMPAGE_ADDR >> PAGE_SHIFT) & 1] = 0;
|
|
|
|
|
|
- if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb_lo[0])
|
|
|
- >> PAGE_SHIFT) < 0)
|
|
|
+ gfn0 = mips3_tlbpfn_to_paddr(tlb_lo[0]) >> PAGE_SHIFT;
|
|
|
+ gfn1 = mips3_tlbpfn_to_paddr(tlb_lo[1]) >> PAGE_SHIFT;
|
|
|
+ if (gfn0 >= kvm->arch.guest_pmap_npages ||
|
|
|
+ gfn1 >= kvm->arch.guest_pmap_npages) {
|
|
|
+ kvm_err("%s: Invalid gfn: [%#llx, %#llx], EHi: %#lx\n",
|
|
|
+ __func__, gfn0, gfn1, tlb->tlb_hi);
|
|
|
+ kvm_mips_dump_guest_tlbs(vcpu);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (kvm_mips_map_page(kvm, gfn0) < 0)
|
|
|
return -1;
|
|
|
|
|
|
- if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb_lo[1])
|
|
|
- >> PAGE_SHIFT) < 0)
|
|
|
+ if (kvm_mips_map_page(kvm, gfn1) < 0)
|
|
|
return -1;
|
|
|
|
|
|
- pfn0 = kvm->arch.guest_pmap[
|
|
|
- mips3_tlbpfn_to_paddr(tlb_lo[0]) >> PAGE_SHIFT];
|
|
|
- pfn1 = kvm->arch.guest_pmap[
|
|
|
- mips3_tlbpfn_to_paddr(tlb_lo[1]) >> PAGE_SHIFT];
|
|
|
+ pfn0 = kvm->arch.guest_pmap[gfn0];
|
|
|
+ pfn1 = kvm->arch.guest_pmap[gfn1];
|
|
|
|
|
|
/* Get attributes from the Guest TLB */
|
|
|
entrylo0 = mips3_paddr_to_tlbpfn(pfn0 << PAGE_SHIFT) |
|