aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2014-03-14 09:06:07 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-03-19 12:01:34 -0400
commit15505679362270d02c449626385cb74af8905514 (patch)
tree85c633a8f1894cf0ad5d46f102c0837050c71202
parent22027945482303573b3600c0e3d7445020c2f29b (diff)
MIPS: KVM: Pass reserved instruction exceptions to guest
Previously a reserved instruction exception while in guest code would cause a KVM internal error if kvm_mips_handle_ri() didn't recognise the instruction (including a RDHWR from an unrecognised hardware register). However the guest OS should really have the opportunity to catch the exception so that it can take the appropriate actions such as sending a SIGILL to the guest user process or emulating the instruction itself. Therefore in these cases emulate a guest RI exception and only return EMULATE_FAIL if that fails, being careful to revert the PC first in case the exception occurred in a branch delay slot in which case the PC will already point to the branch target. Also turn the printk messages relating to these cases into kvm_debug messages so that they aren't usually visible. This allows crashme to run in the guest without killing the entire VM. Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Gleb Natapov <gleb@kernel.org> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Sanjay Lal <sanjayl@kymasys.com> Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/mips/kvm/kvm_mips_emul.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c
index 4b6274b47f33..e75ef8219caf 100644
--- a/arch/mips/kvm/kvm_mips_emul.c
+++ b/arch/mips/kvm/kvm_mips_emul.c
@@ -1571,17 +1571,17 @@ kvm_mips_handle_ri(unsigned long cause, uint32_t *opc,
1571 arch->gprs[rt] = kvm_read_c0_guest_userlocal(cop0); 1571 arch->gprs[rt] = kvm_read_c0_guest_userlocal(cop0);
1572#else 1572#else
1573 /* UserLocal not implemented */ 1573 /* UserLocal not implemented */
1574 er = kvm_mips_emulate_ri_exc(cause, opc, run, vcpu); 1574 er = EMULATE_FAIL;
1575#endif 1575#endif
1576 break; 1576 break;
1577 1577
1578 default: 1578 default:
1579 printk("RDHWR not supported\n"); 1579 kvm_debug("RDHWR %#x not supported @ %p\n", rd, opc);
1580 er = EMULATE_FAIL; 1580 er = EMULATE_FAIL;
1581 break; 1581 break;
1582 } 1582 }
1583 } else { 1583 } else {
1584 printk("Emulate RI not supported @ %p: %#x\n", opc, inst); 1584 kvm_debug("Emulate RI not supported @ %p: %#x\n", opc, inst);
1585 er = EMULATE_FAIL; 1585 er = EMULATE_FAIL;
1586 } 1586 }
1587 1587
@@ -1590,6 +1590,7 @@ kvm_mips_handle_ri(unsigned long cause, uint32_t *opc,
1590 */ 1590 */
1591 if (er == EMULATE_FAIL) { 1591 if (er == EMULATE_FAIL) {
1592 vcpu->arch.pc = curr_pc; 1592 vcpu->arch.pc = curr_pc;
1593 er = kvm_mips_emulate_ri_exc(cause, opc, run, vcpu);
1593 } 1594 }
1594 return er; 1595 return er;
1595} 1596}