int kvm_run(CPUState *env) { int r; kvm_context_t kvm = &env->kvm_state->kvm_context; struct kvm_run *run = env->kvm_run; int fd = env->kvm_fd; again: if (env->kvm_vcpu_dirty) { kvm_arch_load_regs(env, KVM_PUT_RUNTIME_STATE); env->kvm_vcpu_dirty = 0; } push_nmi(kvm); #if !defined(__s390__) if (!kvm->irqchip_in_kernel) { run->request_interrupt_window = kvm_arch_try_push_interrupts(env); } #endif r = pre_kvm_run(kvm, env); if (r) { return r; } if (env->exit_request) { env->exit_request = 0; pthread_kill(env->kvm_cpu_state.thread, SIG_IPI); } r = ioctl(fd, KVM_RUN, 0); if (r == -1 && errno != EINTR && errno != EAGAIN) { r = -errno; post_kvm_run(kvm, env); fprintf(stderr, "kvm_run: %s\n", strerror(-r)); return r; } post_kvm_run(kvm, env); kvm_flush_coalesced_mmio_buffer(); #if !defined(__s390__) if (r == -1) { r = handle_io_window(kvm); goto more; } #endif if (1) { switch (run->exit_reason) { case KVM_EXIT_UNKNOWN: r = handle_unhandled(run->hw.hardware_exit_reason); break; case KVM_EXIT_FAIL_ENTRY: r = handle_failed_vmentry(run->fail_entry.hardware_entry_failure_reason); break; case KVM_EXIT_EXCEPTION: fprintf(stderr, "exception %d (%x)\n", run->ex.exception, run->ex.error_code); kvm_show_regs(env); kvm_show_code(env); abort(); break; case KVM_EXIT_IO: r = kvm_handle_io(run->io.port, (uint8_t *)run + run->io.data_offset, run->io.direction, run->io.size, run->io.count); r = 0; break; case KVM_EXIT_DEBUG: r = handle_debug(env); break; case KVM_EXIT_MMIO: r = handle_mmio(env); break; case KVM_EXIT_HLT: r = kvm_arch_halt(env); break; case KVM_EXIT_IRQ_WINDOW_OPEN: break; case KVM_EXIT_SHUTDOWN: r = handle_shutdown(kvm, env); break; #if defined(__s390__) case KVM_EXIT_S390_SIEIC: r = kvm_s390_handle_intercept(kvm, env, run); break; case KVM_EXIT_S390_RESET: r = kvm_s390_handle_reset(kvm, env, run); break; #endif case KVM_EXIT_INTERNAL_ERROR: kvm_handle_internal_error(env, run); r = 1; break; default: if (kvm_arch_run(env)) { fprintf(stderr, "unhandled vm exit: 0x%x\n", run->exit_reason); kvm_show_regs(env); abort(); } break; } } more: if (!r) { goto again; } return r; }
int kvm_run(kvm_context_t kvm, int vcpu) { int r; int fd = kvm->vcpu_fd[vcpu]; struct kvm_run *run = kvm->run[vcpu]; /*if (kvm_abi == 10) return kvm_run_abi10(kvm, vcpu);*/ again: // if (!kvm->irqchip_in_kernel) // run->request_interrupt_window = try_push_interrupts(kvm); //r = pre_kvm_run(kvm, vcpu); //if (r) // return r; r = ioctl(fd, KVM_RUN, 0); printf("here\n"); //post_kvm_run(kvm, vcpu); if (r == -1 && errno != EINTR && errno != EAGAIN) { r = -errno; printf("kvm_run: %m\n"); return r; } if (r == -1) { r = handle_io_window(kvm); goto more; } if (1) { switch (run->exit_reason) { case KVM_EXIT_UNKNOWN: fprintf(stderr, "unhandled vm exit: 0x%x\n", (unsigned)run->hw.hardware_exit_reason); kvm_show_regs(kvm, vcpu); abort(); break; case KVM_EXIT_FAIL_ENTRY: fprintf(stderr, "kvm_run: failed entry, reason %u\n", (unsigned)run->fail_entry.hardware_entry_failure_reason & 0xffff); return -ENOEXEC; break; case KVM_EXIT_EXCEPTION: fprintf(stderr, "exception %d (%x)\n", run->ex.exception, run->ex.error_code); kvm_show_regs(kvm, vcpu); kvm_show_code(kvm, vcpu); abort(); break; case KVM_EXIT_IO: r = handle_io(kvm, run, vcpu); break; case KVM_EXIT_DEBUG: r = handle_debug(kvm, vcpu); break; case KVM_EXIT_MMIO: r = handle_mmio(kvm, run); break; case KVM_EXIT_HLT: r = handle_halt(kvm, vcpu); break; case KVM_EXIT_IRQ_WINDOW_OPEN: break; case KVM_EXIT_SHUTDOWN: r = handle_shutdown(kvm, vcpu); break; case KVM_EXIT_SET_TPR: break; default: fprintf(stderr, "unhandled vm exit: 0x%x\n", run->exit_reason); kvm_show_regs(kvm, vcpu); abort(); break; } } more: if (!r) goto again; return r; }
int __cdecl kvm_run(kvm_context_t kvm, int vcpu) { int r = 0; int fd = kvm->vcpu_fd[vcpu]; struct kvm_run kvm_run; int retlen; BOOL ret = FALSE; kvm_run.emulated = 0; kvm_run.mmio_completed = 0; kvm_run.vcpu_fd = fd; again: kvm_run.request_interrupt_window = try_push_interrupts(kvm); pre_kvm_run(kvm, &kvm_run); /* r = ioctl(fd, KVM_RUN, &kvm_run); */ ret = DeviceIoControl( kvm->hnd, KVM_RUN, &kvm_run, sizeof(kvm_run), &kvm_run, sizeof(kvm_run), &retlen, NULL); if (retlen != sizeof(kvm_run)) { fprintf(stderr, "kvm_run: invalid return value\n"); return r; } post_kvm_run(kvm, &kvm_run); kvm_run.emulated = 0; kvm_run.mmio_completed = 0; if (!ret) { fprintf(stderr, "kvm_run: failed\n"); return -1; } if (kvm_run.ioctl_r == -1 && kvm_run._errno != EINTR) { r = -(kvm_run._errno); fprintf(stderr, "kvm_run: %d\n", kvm_run._errno); return r; } if (kvm_run.ioctl_r == -1) { r = handle_io_window(kvm, &kvm_run); goto more; } /* if (kvm_run.ioctl_r == -EINTR) { r = handle_io_window(kvm, &kvm_run); r = 1; goto more; } */ switch (kvm_run.exit_type) { case KVM_EXIT_TYPE_FAIL_ENTRY: fprintf(stderr, "kvm_run: failed entry, reason %u\n", kvm_run.exit_reason & 0xffff); return -ENOEXEC; break; case KVM_EXIT_TYPE_VM_EXIT: switch (kvm_run.exit_reason) { case KVM_EXIT_UNKNOWN: fprintf(stderr, "unhandled vm exit: 0x%x\n", kvm_run.hw.hardware_exit_reason); kvm_show_regs(kvm, vcpu); abort(); break; case KVM_EXIT_EXCEPTION: fprintf(stderr, "exception %d (%x)\n", kvm_run.ex.exception, kvm_run.ex.error_code); kvm_show_regs(kvm, vcpu); abort(); break; case KVM_EXIT_IO: r = handle_io(kvm, &kvm_run, vcpu); break; case KVM_EXIT_CPUID: r = handle_cpuid(kvm, &kvm_run, vcpu); break; case KVM_EXIT_DEBUG: r = handle_debug(kvm, &kvm_run, vcpu); break; case KVM_EXIT_MMIO: r = handle_mmio(kvm, &kvm_run); break; case KVM_EXIT_HLT: r = handle_halt(kvm, &kvm_run, vcpu); break; case KVM_EXIT_IRQ_WINDOW_OPEN: break; case KVM_EXIT_SHUTDOWN: r = handle_shutdown(kvm, &kvm_run, vcpu); break; default: fprintf(stderr, "unhandled vm exit: 0x%x\n", kvm_run.exit_reason); kvm_show_regs(kvm, vcpu); abort(); break; } } more: if (!r) goto again; return r; }