}
}
-int hvf_arch_vcpu_exec(CPUState *cpu)
+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;
+ CPUARMState *env = cpu_env(cpu);
+ ARMCPU *arm_cpu = env_archcpu(env);
+ 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: {
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");
}
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) {
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);
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,