diff options
Diffstat (limited to 'target-arm')
-rw-r--r-- | target-arm/helper-a64.c | 12 | ||||
-rw-r--r-- | target-arm/kvm64.c | 24 |
2 files changed, 27 insertions, 9 deletions
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c index deb8dbe489..fc3ccdf2a7 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -25,6 +25,7 @@ #include "qemu/bitops.h" #include "internals.h" #include "qemu/crc32c.h" +#include "sysemu/kvm.h" #include <zlib.h> /* For crc32 */ /* C2.4.7 Multiply and divide */ @@ -469,7 +470,8 @@ void aarch64_cpu_do_interrupt(CPUState *cs) new_el); if (qemu_loglevel_mask(CPU_LOG_INT) && !excp_is_internal(cs->exception_index)) { - qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%" PRIx32 "\n", + qemu_log_mask(CPU_LOG_INT, "...with ESR %x/0x%" PRIx32 "\n", + env->exception.syndrome >> ARM_EL_EC_SHIFT, env->exception.syndrome); } @@ -535,6 +537,12 @@ void aarch64_cpu_do_interrupt(CPUState *cs) aarch64_restore_sp(env, new_el); env->pc = addr; - cs->interrupt_request |= CPU_INTERRUPT_EXITTB; + + qemu_log_mask(CPU_LOG_INT, "...to EL%d PC 0x%" PRIx64 " PSTATE 0x%x\n", + new_el, env->pc, pstate_read(env)); + + if (!kvm_enabled()) { + cs->interrupt_request |= CPU_INTERRUPT_EXITTB; + } } #endif 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; } |