diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-04-14 16:44:42 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-04-14 16:44:42 +0200 |
commit | 740c699a8d316c8bf8593f19e2ca47795e690622 (patch) | |
tree | a78886955770a477945c5d84e06b2e7678733b54 /arch/mips/kvm/kvm_mips_emul.c | |
parent | e69af4657e7764d03ad555f0b583d9c4217bcefa (diff) | |
parent | c9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff) |
Merge tag 'v3.15-rc1' into perf/urgent
Pick up the latest fixes.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/mips/kvm/kvm_mips_emul.c')
-rw-r--r-- | arch/mips/kvm/kvm_mips_emul.c | 40 |
1 files changed, 18 insertions, 22 deletions
diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c index 4b6274b47f3..e3fec99941a 100644 --- a/arch/mips/kvm/kvm_mips_emul.c +++ b/arch/mips/kvm/kvm_mips_emul.c @@ -436,13 +436,6 @@ kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, uint32_t cause, sel = inst & 0x7; co_bit = (inst >> 25) & 1; - /* Verify that the register is valid */ - if (rd > MIPS_CP0_DESAVE) { - printk("Invalid rd: %d\n", rd); - er = EMULATE_FAIL; - goto done; - } - if (co_bit) { op = (inst) & 0xff; @@ -1542,8 +1535,15 @@ kvm_mips_handle_ri(unsigned long cause, uint32_t *opc, } if ((inst & OPCODE) == SPEC3 && (inst & FUNC) == RDHWR) { + int usermode = !KVM_GUEST_KERNEL_MODE(vcpu); int rd = (inst & RD) >> 11; int rt = (inst & RT) >> 16; + /* If usermode, check RDHWR rd is allowed by guest HWREna */ + if (usermode && !(kvm_read_c0_guest_hwrena(cop0) & BIT(rd))) { + kvm_debug("RDHWR %#x disallowed by HWREna @ %p\n", + rd, opc); + goto emulate_ri; + } switch (rd) { case 0: /* CPU number */ arch->gprs[rt] = 0; @@ -1567,31 +1567,27 @@ kvm_mips_handle_ri(unsigned long cause, uint32_t *opc, } break; case 29: -#if 1 arch->gprs[rt] = kvm_read_c0_guest_userlocal(cop0); -#else - /* UserLocal not implemented */ - er = kvm_mips_emulate_ri_exc(cause, opc, run, vcpu); -#endif break; default: - printk("RDHWR not supported\n"); - er = EMULATE_FAIL; - break; + kvm_debug("RDHWR %#x not supported @ %p\n", rd, opc); + goto emulate_ri; } } else { - printk("Emulate RI not supported @ %p: %#x\n", opc, inst); - er = EMULATE_FAIL; + kvm_debug("Emulate RI not supported @ %p: %#x\n", opc, inst); + goto emulate_ri; } + return EMULATE_DONE; + +emulate_ri: /* - * Rollback PC only if emulation was unsuccessful + * Rollback PC (if in branch delay slot then the PC already points to + * branch target), and pass the RI exception to the guest OS. */ - if (er == EMULATE_FAIL) { - vcpu->arch.pc = curr_pc; - } - return er; + vcpu->arch.pc = curr_pc; + return kvm_mips_emulate_ri_exc(cause, opc, run, vcpu); } enum emulation_result |