diff options
author | James Hogan <james.hogan@imgtec.com> | 2014-03-14 09:06:07 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-03-19 12:01:34 -0400 |
commit | 15505679362270d02c449626385cb74af8905514 (patch) | |
tree | 85c633a8f1894cf0ad5d46f102c0837050c71202 | |
parent | 22027945482303573b3600c0e3d7445020c2f29b (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.c | 7 |
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 | } |