|
@@ -1528,13 +1528,25 @@ enum emulation_result kvm_mips_emulate_load(union mips_instruction inst,
|
|
|
struct kvm_vcpu *vcpu)
|
|
|
{
|
|
|
enum emulation_result er = EMULATE_DO_MMIO;
|
|
|
+ unsigned long curr_pc;
|
|
|
u32 op, rt;
|
|
|
u32 bytes;
|
|
|
|
|
|
rt = inst.i_format.rt;
|
|
|
op = inst.i_format.opcode;
|
|
|
|
|
|
- vcpu->arch.pending_load_cause = cause;
|
|
|
+ /*
|
|
|
+ * Find the resume PC now while we have safe and easy access to the
|
|
|
+ * prior branch instruction, and save it for
|
|
|
+ * kvm_mips_complete_mmio_load() to restore later.
|
|
|
+ */
|
|
|
+ curr_pc = vcpu->arch.pc;
|
|
|
+ er = update_pc(vcpu, cause);
|
|
|
+ if (er == EMULATE_FAIL)
|
|
|
+ return er;
|
|
|
+ vcpu->arch.io_pc = vcpu->arch.pc;
|
|
|
+ vcpu->arch.pc = curr_pc;
|
|
|
+
|
|
|
vcpu->arch.io_gpr = rt;
|
|
|
|
|
|
switch (op) {
|
|
@@ -2494,9 +2506,8 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
- er = update_pc(vcpu, vcpu->arch.pending_load_cause);
|
|
|
- if (er == EMULATE_FAIL)
|
|
|
- return er;
|
|
|
+ /* Restore saved resume PC */
|
|
|
+ vcpu->arch.pc = vcpu->arch.io_pc;
|
|
|
|
|
|
switch (run->mmio.len) {
|
|
|
case 4:
|
|
@@ -2518,11 +2529,6 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if (vcpu->arch.pending_load_cause & CAUSEF_BD)
|
|
|
- kvm_debug("[%#lx] Completing %d byte BD Load to gpr %d (0x%08lx) type %d\n",
|
|
|
- vcpu->arch.pc, run->mmio.len, vcpu->arch.io_gpr, *gpr,
|
|
|
- vcpu->mmio_needed);
|
|
|
-
|
|
|
done:
|
|
|
return er;
|
|
|
}
|