MIPS: KVM: Propagate kseg0/mapped tlb fault errors
commit 9b731bcfdec4c159ad2e4312e25d69221709b96a upstream. Propagate errors from kvm_mips_handle_kseg0_tlb_fault() and kvm_mips_handle_mapped_seg_tlb_fault(), usually triggering an internal error since they normally indicate the guest accessed bad physical memory or the commpage in an unexpected way. Fixes:858dd5d457("KVM/MIPS32: MMU/TLB operations for the Guest.") Fixes:e685c689f3("KVM/MIPS32: Privileged instruction/target branch emulation.") Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: "Radim KrÄmáÅ" <rkrcmar@redhat.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org Signed-off-by: Radim KrÄmáŠ<rkrcmar@redhat.com> [james.hogan@imgtec.com: Backport to v3.10.y - v3.15.y] Signed-off-by: James Hogan <james.hogan@imgtec.com> Signed-off-by: Willy Tarreau <w@1wt.eu>
This commit is contained in:
committed by
Willy Tarreau
parent
8cee00e93c
commit
5928125348
@@ -972,8 +972,13 @@ kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, uint32_t cause,
|
||||
preempt_disable();
|
||||
if (KVM_GUEST_KSEGX(va) == KVM_GUEST_KSEG0) {
|
||||
|
||||
if (kvm_mips_host_tlb_lookup(vcpu, va) < 0) {
|
||||
kvm_mips_handle_kseg0_tlb_fault(va, vcpu);
|
||||
if (kvm_mips_host_tlb_lookup(vcpu, va) < 0 &&
|
||||
kvm_mips_handle_kseg0_tlb_fault(va, vcpu)) {
|
||||
kvm_err("%s: handling mapped kseg0 tlb fault for %lx, vcpu: %p, ASID: %#lx\n",
|
||||
__func__, va, vcpu, read_c0_entryhi());
|
||||
er = EMULATE_FAIL;
|
||||
preempt_enable();
|
||||
goto done;
|
||||
}
|
||||
} else if ((KVM_GUEST_KSEGX(va) < KVM_GUEST_KSEG0) ||
|
||||
KVM_GUEST_KSEGX(va) == KVM_GUEST_KSEG23) {
|
||||
@@ -1006,11 +1011,16 @@ kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, uint32_t cause,
|
||||
run, vcpu);
|
||||
preempt_enable();
|
||||
goto dont_update_pc;
|
||||
} else {
|
||||
/* We fault an entry from the guest tlb to the shadow host TLB */
|
||||
kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
/* We fault an entry from the guest tlb to the shadow host TLB */
|
||||
if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb,
|
||||
NULL, NULL)) {
|
||||
kvm_err("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n",
|
||||
__func__, va, index, vcpu,
|
||||
read_c0_entryhi());
|
||||
er = EMULATE_FAIL;
|
||||
preempt_enable();
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1821,8 +1831,13 @@ kvm_mips_handle_tlbmiss(unsigned long cause, uint32_t *opc,
|
||||
tlb->tlb_hi, tlb->tlb_lo0, tlb->tlb_lo1);
|
||||
#endif
|
||||
/* OK we have a Guest TLB entry, now inject it into the shadow host TLB */
|
||||
kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb, NULL,
|
||||
NULL);
|
||||
if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb,
|
||||
NULL, NULL)) {
|
||||
kvm_err("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n",
|
||||
__func__, va, index, vcpu,
|
||||
read_c0_entryhi());
|
||||
er = EMULATE_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-4
@@ -926,10 +926,16 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
|
||||
local_irq_restore(flags);
|
||||
return KVM_INVALID_INST;
|
||||
}
|
||||
kvm_mips_handle_mapped_seg_tlb_fault(vcpu,
|
||||
&vcpu->arch.
|
||||
guest_tlb[index],
|
||||
NULL, NULL);
|
||||
if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu,
|
||||
&vcpu->arch.guest_tlb[index],
|
||||
NULL, NULL)) {
|
||||
kvm_err("%s: handling mapped seg tlb fault failed for %p, index: %u, vcpu: %p, ASID: %#lx\n",
|
||||
__func__, opc, index, vcpu,
|
||||
read_c0_entryhi());
|
||||
kvm_mips_dump_guest_tlbs(vcpu);
|
||||
local_irq_restore(flags);
|
||||
return KVM_INVALID_INST;
|
||||
}
|
||||
inst = *(opc);
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
|
||||
Reference in New Issue
Block a user