aboutsummaryrefslogtreecommitdiff
path: root/target-arm/kvm64.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-arm/kvm64.c')
-rw-r--r--target-arm/kvm64.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c
index 771ecdbafe..bb9531f33c 100644
--- a/target-arm/kvm64.c
+++ b/target-arm/kvm64.c
@@ -871,6 +871,7 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
{
int hsr_ec = debug_exit->hsr >> ARM_EL_EC_SHIFT;
ARMCPU *cpu = ARM_CPU(cs);
+ CPUClass *cc = CPU_GET_CLASS(cs);
CPUARMState *env = &cpu->env;
/* Ensure PC is synchronised */
@@ -881,7 +882,14 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
if (cs->singlestep_enabled) {
return true;
} else {
- error_report("Came out of SINGLE STEP when not enabled");
+ /*
+ * The kernel should have suppressed the guest's ability to
+ * single step at this point so something has gone wrong.
+ */
+ error_report("%s: guest single-step while debugging unsupported"
+ " (%"PRIx64", %"PRIx32")\n",
+ __func__, env->pc, debug_exit->hsr);
+ return false;
}
break;
case EC_AA64_BKPT:
@@ -908,12 +916,14 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
__func__, debug_exit->hsr, env->pc);
}
- /* If we don't handle this it could be it really is for the
- guest to handle */
- qemu_log_mask(LOG_UNIMP,
- "%s: re-injecting exception not yet implemented"
- " (0x%"PRIx32", %"PRIx64")\n",
- __func__, hsr_ec, env->pc);
+ /* If we are not handling the debug exception it must belong to
+ * the guest. Let's re-use the existing TCG interrupt code to set
+ * everything up properly.
+ */
+ cs->exception_index = EXCP_BKPT;
+ env->exception.syndrome = debug_exit->hsr;
+ env->exception.vaddress = debug_exit->far;
+ cc->do_interrupt(cs);
return false;
}