static void *kvm_cpu_thread(void *arg) { char name[16]; current_kvm_cpu = arg; sprintf(name, "kvm-vcpu-%lu", current_kvm_cpu->cpu_id); kvm__set_thread_name(name); if (kvm_cpu__start(current_kvm_cpu)) goto panic_kvm; return (void *) (intptr_t) 0; panic_kvm: fprintf(stderr, "KVM exit reason: %u (\"%s\")\n", current_kvm_cpu->kvm_run->exit_reason, kvm_exit_reasons[current_kvm_cpu->kvm_run->exit_reason]); if (current_kvm_cpu->kvm_run->exit_reason == KVM_EXIT_UNKNOWN) fprintf(stderr, "KVM exit code: 0x%llu\n", (unsigned long long)current_kvm_cpu->kvm_run->hw.hardware_exit_reason); kvm_cpu__set_debug_fd(STDOUT_FILENO); kvm_cpu__show_registers(current_kvm_cpu); kvm_cpu__show_code(current_kvm_cpu); kvm_cpu__show_page_tables(current_kvm_cpu); return (void *) (intptr_t) 1; }
static void *kvm_cpu_thread(void *arg) { current_kvm_cpu = arg; if (kvm_cpu__start(current_kvm_cpu)) goto panic_kvm; kvm_cpu__delete(current_kvm_cpu); return (void *) (intptr_t) 0; panic_kvm: fprintf(stderr, "KVM exit reason: %u (\"%s\")\n", current_kvm_cpu->kvm_run->exit_reason, kvm_exit_reasons[current_kvm_cpu->kvm_run->exit_reason]); if (current_kvm_cpu->kvm_run->exit_reason == KVM_EXIT_UNKNOWN) fprintf(stderr, "KVM exit code: 0x%Lu\n", current_kvm_cpu->kvm_run->hw.hardware_exit_reason); kvm_cpu__show_registers(current_kvm_cpu); kvm_cpu__show_code(current_kvm_cpu); kvm_cpu__show_page_tables(current_kvm_cpu); kvm_cpu__delete(current_kvm_cpu); return (void *) (intptr_t) 1; }
static void handle_sigusr1(int sig) { struct kvm_cpu *cpu = current_kvm_cpu; if (!cpu) return; printf("\n #\n # vCPU #%ld's dump:\n #\n", cpu->cpu_id); kvm_cpu__show_registers(cpu); kvm_cpu__show_code(cpu); kvm_cpu__show_page_tables(cpu); fflush(stdout); printout_done = 1; mb(); }
int kvm_cpu__start(struct kvm_cpu *cpu) { sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); pthread_sigmask(SIG_BLOCK, &sigset, NULL); signal(SIGKVMEXIT, kvm_cpu_signal_handler); signal(SIGKVMPAUSE, kvm_cpu_signal_handler); kvm_cpu__reset_vcpu(cpu); if (cpu->kvm->cfg.single_step) kvm_cpu__enable_singlestep(cpu); while (cpu->is_running) { if (cpu->paused) { kvm__notify_paused(); cpu->paused = 0; } if (cpu->needs_nmi) { kvm_cpu__arch_nmi(cpu); cpu->needs_nmi = 0; } kvm_cpu__run(cpu); switch (cpu->kvm_run->exit_reason) { case KVM_EXIT_UNKNOWN: break; case KVM_EXIT_DEBUG: kvm_cpu__show_registers(cpu); kvm_cpu__show_code(cpu); break; case KVM_EXIT_IO: { bool ret; ret = kvm_cpu__emulate_io(cpu, cpu->kvm_run->io.port, (u8 *)cpu->kvm_run + cpu->kvm_run->io.data_offset, cpu->kvm_run->io.direction, cpu->kvm_run->io.size, cpu->kvm_run->io.count); if (!ret) goto panic_kvm; break; } case KVM_EXIT_MMIO: { bool ret; /* * If we had MMIO exit, coalesced ring should be processed * *before* processing the exit itself */ kvm_cpu__handle_coalesced_mmio(cpu); ret = kvm_cpu__emulate_mmio(cpu, cpu->kvm_run->mmio.phys_addr, cpu->kvm_run->mmio.data, cpu->kvm_run->mmio.len, cpu->kvm_run->mmio.is_write); if (!ret) goto panic_kvm; break; } case KVM_EXIT_INTR: if (cpu->is_running) break; goto exit_kvm; case KVM_EXIT_SHUTDOWN: goto exit_kvm; case KVM_EXIT_SYSTEM_EVENT: /* * Print the type of system event and * treat all system events as shutdown request. */ switch (cpu->kvm_run->system_event.type) { case KVM_SYSTEM_EVENT_RESET: /* Fall through for now */ case KVM_SYSTEM_EVENT_SHUTDOWN: goto exit_kvm; default: pr_warning("unknown system event type %d", cpu->kvm_run->system_event.type); goto exit_kvm; }; break; default: { bool ret; ret = kvm_cpu__handle_exit(cpu); if (!ret) goto panic_kvm; break; } } kvm_cpu__handle_coalesced_mmio(cpu); } exit_kvm: return 0; panic_kvm: return 1; }