Factor hvf_handle_exception() out of hvf_vcpu_exec().
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
target/arm/hvf/hvf.c | 120 +++++++++++++++++++++++--------------------
1 file changed, 64 insertions(+), 56 deletions(-)
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index fd209d23c1e..3db0a8e288c 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1928,61 +1928,16 @@ static void hvf_sync_vtimer(CPUState *cpu)
}
}
-int hvf_arch_vcpu_exec(CPUState *cpu)
+/* Must be called by the owning thread */
+static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp)
{
ARMCPU *arm_cpu = ARM_CPU(cpu);
CPUARMState *env = &arm_cpu->env;
- int ret;
- hv_vcpu_exit_t *hvf_exit = cpu->accel->exit;
- hv_return_t r;
- bool advance_pc = false;
-
- if (!(cpu->singlestep_enabled & SSTEP_NOIRQ) &&
- hvf_inject_interrupts(cpu)) {
- return EXCP_INTERRUPT;
- }
-
- if (cpu->halted) {
- return EXCP_HLT;
- }
-
- flush_cpu_state(cpu);
-
- bql_unlock();
- r = hv_vcpu_run(cpu->accel->fd);
- bql_lock();
- switch (r) {
- case HV_SUCCESS:
- break;
- case HV_ILLEGAL_GUEST_STATE:
- trace_hvf_illegal_guest_state();
- /* fall through */
- default:
- g_assert_not_reached();
- }
-
- /* handle VMEXIT */
- uint64_t exit_reason = hvf_exit->reason;
- uint64_t syndrome = hvf_exit->exception.syndrome;
+ uint64_t syndrome = excp->syndrome;
uint32_t ec = syn_get_ec(syndrome);
-
- ret = 0;
- switch (exit_reason) {
- case HV_EXIT_REASON_EXCEPTION:
- /* This is the main one, handle below. */
- break;
- case HV_EXIT_REASON_VTIMER_ACTIVATED:
- qemu_set_irq(arm_cpu->gt_timer_outputs[GTIMER_VIRT], 1);
- cpu->accel->vtimer_masked = true;
- return 0;
- case HV_EXIT_REASON_CANCELED:
- /* we got kicked, no exit to process */
- return 0;
- default:
- g_assert_not_reached();
- }
-
- hvf_sync_vtimer(cpu);
+ bool advance_pc = false;
+ hv_return_t r;
+ int ret = 0;
switch (ec) {
case EC_SOFTWARESTEP: {
@@ -2021,7 +1976,7 @@ int hvf_arch_vcpu_exec(CPUState *cpu)
cpu_synchronize_state(cpu);
CPUWatchpoint *wp =
- find_hw_watchpoint(cpu, hvf_exit->exception.virtual_address);
+ find_hw_watchpoint(cpu, excp->virtual_address);
if (!wp) {
error_report("EXCP_DEBUG but unknown hw watchpoint");
}
@@ -2039,8 +1994,8 @@ int hvf_arch_vcpu_exec(CPUState *cpu)
uint32_t cm = (syndrome >> 8) & 0x1;
uint64_t val = 0;
- trace_hvf_data_abort(hvf_exit->exception.virtual_address,
- hvf_exit->exception.physical_address, isv,
+ trace_hvf_data_abort(excp->virtual_address,
+ excp->physical_address, isv,
iswrite, s1ptw, len, srt);
if (cm) {
@@ -2054,11 +2009,11 @@ int hvf_arch_vcpu_exec(CPUState *cpu)
if (iswrite) {
val = hvf_get_reg(cpu, srt);
address_space_write(&address_space_memory,
- hvf_exit->exception.physical_address,
+ excp->physical_address,
MEMTXATTRS_UNSPECIFIED, &val, len);
} else {
address_space_read(&address_space_memory,
- hvf_exit->exception.physical_address,
+ excp->physical_address,
MEMTXATTRS_UNSPECIFIED, &val, len);
if (sse) {
val = sextract64(val, 0, len * 8);
@@ -2156,6 +2111,59 @@ int hvf_arch_vcpu_exec(CPUState *cpu)
return ret;
}
+int hvf_arch_vcpu_exec(CPUState *cpu)
+{
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
+ hv_vcpu_exit_t *hvf_exit = cpu->accel->exit;
+ hv_return_t r;
+
+ if (!(cpu->singlestep_enabled & SSTEP_NOIRQ) &&
+ hvf_inject_interrupts(cpu)) {
+ return EXCP_INTERRUPT;
+ }
+
+ if (cpu->halted) {
+ return EXCP_HLT;
+ }
+
+ flush_cpu_state(cpu);
+
+ bql_unlock();
+ r = hv_vcpu_run(cpu->accel->fd);
+ bql_lock();
+ switch (r) {
+ case HV_SUCCESS:
+ break;
+ case HV_ILLEGAL_GUEST_STATE:
+ trace_hvf_illegal_guest_state();
+ /* fall through */
+ default:
+ g_assert_not_reached();
+ }
+
+ /* handle VMEXIT */
+ uint64_t exit_reason = hvf_exit->reason;
+
+ switch (exit_reason) {
+ case HV_EXIT_REASON_EXCEPTION:
+ /* This is the main one, handle below. */
+ break;
+ case HV_EXIT_REASON_VTIMER_ACTIVATED:
+ qemu_set_irq(arm_cpu->gt_timer_outputs[GTIMER_VIRT], 1);
+ cpu->accel->vtimer_masked = true;
+ return 0;
+ case HV_EXIT_REASON_CANCELED:
+ /* we got kicked, no exit to process */
+ return 0;
+ default:
+ g_assert_not_reached();
+ }
+
+ hvf_sync_vtimer(cpu);
+
+ return hvf_handle_exception(cpu, &hvf_exit->exception);
+}
+
static const VMStateDescription vmstate_hvf_vtimer = {
.name = "hvf-vtimer",
.version_id = 1,
--
2.51.0