X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=cpus.c;h=d9c332fcb8b4744a1ca3b5fa220ba43e29b63b1a;hb=9a77a0f58923443913e1071ffb47b74c54566e70;hp=4a10775cb6150ab92ad09e97964a9fed90e44859;hpb=8e564b4ebf472095b7ca5692302c8a3883d99d91;p=qemu.git diff --git a/cpus.c b/cpus.c index 4a10775cb..d9c332fcb 100644 --- a/cpus.c +++ b/cpus.c @@ -34,7 +34,9 @@ #include "qemu-thread.h" #include "cpus.h" +#include "qtest.h" #include "main-loop.h" +#include "bitmap.h" #ifndef _WIN32 #include "compatfd.h" @@ -58,7 +60,36 @@ #endif /* CONFIG_LINUX */ -static CPUState *next_cpu; +static CPUArchState *next_cpu; + +static bool cpu_thread_is_idle(CPUArchState *env) +{ + CPUState *cpu = ENV_GET_CPU(env); + + if (cpu->stop || cpu->queued_work_first) { + return false; + } + if (cpu->stopped || !runstate_is_running()) { + return true; + } + if (!env->halted || qemu_cpu_has_work(cpu) || + kvm_async_interrupts_enabled()) { + return false; + } + return true; +} + +static bool all_cpu_threads_idle(void) +{ + CPUArchState *env; + + for (env = first_cpu; env != NULL; env = env->next_cpu) { + if (!cpu_thread_is_idle(env)) { + return false; + } + } + return true; +} /***********************************************************/ /* guest cycle counter */ @@ -89,7 +120,7 @@ TimersState timers_state; int64_t cpu_get_icount(void) { int64_t icount; - CPUState *env = cpu_single_env; + CPUArchState *env = cpu_single_env; icount = qemu_icount; if (env) { @@ -238,6 +269,20 @@ static void icount_warp_rt(void *opaque) vm_clock_warp_start = -1; } +void qtest_clock_warp(int64_t dest) +{ + int64_t clock = qemu_get_clock_ns(vm_clock); + assert(qtest_enabled()); + while (clock < dest) { + int64_t deadline = qemu_clock_deadline(vm_clock); + int64_t warp = MIN(dest - clock, deadline); + qemu_icount_bias += warp; + qemu_run_timers(vm_clock); + clock = qemu_get_clock_ns(vm_clock); + } + qemu_notify_event(); +} + void qemu_clock_warp(QEMUClock *clock) { int64_t deadline; @@ -264,6 +309,11 @@ void qemu_clock_warp(QEMUClock *clock) return; } + if (qtest_enabled()) { + /* When testing, qtest commands advance icount. */ + return; + } + vm_clock_warp_start = qemu_get_clock_ns(rt_clock); deadline = qemu_clock_deadline(vm_clock); if (deadline > 0) { @@ -339,7 +389,7 @@ void configure_icount(const char *option) void hw_error(const char *fmt, ...) { va_list ap; - CPUState *env; + CPUArchState *env; va_start(ap, fmt); fprintf(stderr, "qemu: hardware error: "); @@ -347,11 +397,7 @@ void hw_error(const char *fmt, ...) fprintf(stderr, "\n"); for(env = first_cpu; env != NULL; env = env->next_cpu) { fprintf(stderr, "CPU #%d:\n", env->cpu_index); -#ifdef TARGET_I386 - cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU); -#else - cpu_dump_state(env, stderr, fprintf, 0); -#endif + cpu_dump_state(env, stderr, fprintf, CPU_DUMP_FPU); } va_end(ap); abort(); @@ -359,7 +405,7 @@ void hw_error(const char *fmt, ...) void cpu_synchronize_all_states(void) { - CPUState *cpu; + CPUArchState *cpu; for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) { cpu_synchronize_state(cpu); @@ -368,7 +414,7 @@ void cpu_synchronize_all_states(void) void cpu_synchronize_all_post_reset(void) { - CPUState *cpu; + CPUArchState *cpu; for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) { cpu_synchronize_post_reset(cpu); @@ -377,16 +423,16 @@ void cpu_synchronize_all_post_reset(void) void cpu_synchronize_all_post_init(void) { - CPUState *cpu; + CPUArchState *cpu; for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) { cpu_synchronize_post_init(cpu); } } -int cpu_is_stopped(CPUState *env) +bool cpu_is_stopped(CPUState *cpu) { - return !runstate_is_running() || env->stopped; + return !runstate_is_running() || cpu->stopped; } static void do_vm_stop(RunState state) @@ -402,49 +448,24 @@ static void do_vm_stop(RunState state) } } -static int cpu_can_run(CPUState *env) -{ - if (env->stop) { - return 0; - } - if (env->stopped || !runstate_is_running()) { - return 0; - } - return 1; -} - -static bool cpu_thread_is_idle(CPUState *env) +static bool cpu_can_run(CPUState *cpu) { - if (env->stop || env->queued_work_first) { + if (cpu->stop) { return false; } - if (env->stopped || !runstate_is_running()) { - return true; - } - if (!env->halted || qemu_cpu_has_work(env) || - (kvm_enabled() && kvm_irqchip_in_kernel())) { + if (cpu->stopped || !runstate_is_running()) { return false; } return true; } -bool all_cpu_threads_idle(void) +static void cpu_handle_guest_debug(CPUArchState *env) { - CPUState *env; + CPUState *cpu = ENV_GET_CPU(env); - for (env = first_cpu; env != NULL; env = env->next_cpu) { - if (!cpu_thread_is_idle(env)) { - return false; - } - } - return true; -} - -static void cpu_handle_guest_debug(CPUState *env) -{ gdb_set_stop_cpu(env); qemu_system_debug_request(); - env->stopped = 1; + cpu->stopped = true; } static void cpu_signal(int sig) @@ -494,7 +515,7 @@ static void qemu_init_sigbus(void) prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0); } -static void qemu_kvm_eat_signals(CPUState *env) +static void qemu_kvm_eat_signals(CPUArchState *env) { struct timespec ts = { 0, 0 }; siginfo_t siginfo; @@ -537,7 +558,7 @@ static void qemu_init_sigbus(void) { } -static void qemu_kvm_eat_signals(CPUState *env) +static void qemu_kvm_eat_signals(CPUArchState *env) { } #endif /* !CONFIG_LINUX */ @@ -547,7 +568,7 @@ static void dummy_signal(int sig) { } -static void qemu_kvm_init_cpu_signals(CPUState *env) +static void qemu_kvm_init_cpu_signals(CPUArchState *env) { int r; sigset_t set; @@ -582,7 +603,7 @@ static void qemu_tcg_init_cpu_signals(void) } #else /* _WIN32 */ -static void qemu_kvm_init_cpu_signals(CPUState *env) +static void qemu_kvm_init_cpu_signals(CPUArchState *env) { abort(); } @@ -592,7 +613,7 @@ static void qemu_tcg_init_cpu_signals(void) } #endif /* _WIN32 */ -QemuMutex qemu_global_mutex; +static QemuMutex qemu_global_mutex; static QemuCond qemu_io_proceeded_cond; static bool iothread_requesting_mutex; @@ -619,66 +640,66 @@ void qemu_init_cpu_loop(void) qemu_thread_get_self(&io_thread); } -void run_on_cpu(CPUState *env, void (*func)(void *data), void *data) +void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data) { struct qemu_work_item wi; - if (qemu_cpu_is_self(env)) { + if (qemu_cpu_is_self(cpu)) { func(data); return; } wi.func = func; wi.data = data; - if (!env->queued_work_first) { - env->queued_work_first = &wi; + if (cpu->queued_work_first == NULL) { + cpu->queued_work_first = &wi; } else { - env->queued_work_last->next = &wi; + cpu->queued_work_last->next = &wi; } - env->queued_work_last = &wi; + cpu->queued_work_last = &wi; wi.next = NULL; wi.done = false; - qemu_cpu_kick(env); + qemu_cpu_kick(cpu); while (!wi.done) { - CPUState *self_env = cpu_single_env; + CPUArchState *self_env = cpu_single_env; qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex); cpu_single_env = self_env; } } -static void flush_queued_work(CPUState *env) +static void flush_queued_work(CPUState *cpu) { struct qemu_work_item *wi; - if (!env->queued_work_first) { + if (cpu->queued_work_first == NULL) { return; } - while ((wi = env->queued_work_first)) { - env->queued_work_first = wi->next; + while ((wi = cpu->queued_work_first)) { + cpu->queued_work_first = wi->next; wi->func(wi->data); wi->done = true; } - env->queued_work_last = NULL; + cpu->queued_work_last = NULL; qemu_cond_broadcast(&qemu_work_cond); } -static void qemu_wait_io_event_common(CPUState *env) +static void qemu_wait_io_event_common(CPUState *cpu) { - if (env->stop) { - env->stop = 0; - env->stopped = 1; + if (cpu->stop) { + cpu->stop = false; + cpu->stopped = true; qemu_cond_signal(&qemu_pause_cond); } - flush_queued_work(env); - env->thread_kicked = false; + flush_queued_work(cpu); + cpu->thread_kicked = false; } static void qemu_tcg_wait_io_event(void) { - CPUState *env; + CPUArchState *env; while (all_cpu_threads_idle()) { /* Start accounting real time to the virtual clock if the CPUs @@ -692,28 +713,31 @@ static void qemu_tcg_wait_io_event(void) } for (env = first_cpu; env != NULL; env = env->next_cpu) { - qemu_wait_io_event_common(env); + qemu_wait_io_event_common(ENV_GET_CPU(env)); } } -static void qemu_kvm_wait_io_event(CPUState *env) +static void qemu_kvm_wait_io_event(CPUArchState *env) { + CPUState *cpu = ENV_GET_CPU(env); + while (cpu_thread_is_idle(env)) { - qemu_cond_wait(env->halt_cond, &qemu_global_mutex); + qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); } qemu_kvm_eat_signals(env); - qemu_wait_io_event_common(env); + qemu_wait_io_event_common(cpu); } static void *qemu_kvm_cpu_thread_fn(void *arg) { - CPUState *env = arg; + CPUArchState *env = arg; + CPUState *cpu = ENV_GET_CPU(env); int r; qemu_mutex_lock(&qemu_global_mutex); - qemu_thread_get_self(env->thread); - env->thread_id = qemu_get_thread_id(); + qemu_thread_get_self(cpu->thread); + cpu->thread_id = qemu_get_thread_id(); cpu_single_env = env; r = kvm_init_vcpu(env); @@ -725,11 +749,11 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) qemu_kvm_init_cpu_signals(env); /* signal CPU creation */ - env->created = 1; + cpu->created = true; qemu_cond_signal(&qemu_cpu_cond); while (1) { - if (cpu_can_run(env)) { + if (cpu_can_run(cpu)) { r = kvm_cpu_exec(env); if (r == EXCP_DEBUG) { cpu_handle_guest_debug(env); @@ -741,30 +765,75 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) return NULL; } +static void *qemu_dummy_cpu_thread_fn(void *arg) +{ +#ifdef _WIN32 + fprintf(stderr, "qtest is not supported under Windows\n"); + exit(1); +#else + CPUArchState *env = arg; + CPUState *cpu = ENV_GET_CPU(env); + sigset_t waitset; + int r; + + qemu_mutex_lock_iothread(); + qemu_thread_get_self(cpu->thread); + cpu->thread_id = qemu_get_thread_id(); + + sigemptyset(&waitset); + sigaddset(&waitset, SIG_IPI); + + /* signal CPU creation */ + cpu->created = true; + qemu_cond_signal(&qemu_cpu_cond); + + cpu_single_env = env; + while (1) { + cpu_single_env = NULL; + qemu_mutex_unlock_iothread(); + do { + int sig; + r = sigwait(&waitset, &sig); + } while (r == -1 && (errno == EAGAIN || errno == EINTR)); + if (r == -1) { + perror("sigwait"); + exit(1); + } + qemu_mutex_lock_iothread(); + cpu_single_env = env; + qemu_wait_io_event_common(cpu); + } + + return NULL; +#endif +} + static void tcg_exec_all(void); static void *qemu_tcg_cpu_thread_fn(void *arg) { - CPUState *env = arg; + CPUState *cpu = arg; + CPUArchState *env; qemu_tcg_init_cpu_signals(); - qemu_thread_get_self(env->thread); + qemu_thread_get_self(cpu->thread); /* signal CPU creation */ qemu_mutex_lock(&qemu_global_mutex); for (env = first_cpu; env != NULL; env = env->next_cpu) { - env->thread_id = qemu_get_thread_id(); - env->created = 1; + cpu = ENV_GET_CPU(env); + cpu->thread_id = qemu_get_thread_id(); + cpu->created = true; } qemu_cond_signal(&qemu_cpu_cond); /* wait for initial kick-off after machine start */ - while (first_cpu->stopped) { + while (ENV_GET_CPU(first_cpu)->stopped) { qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); /* process any pending work */ for (env = first_cpu; env != NULL; env = env->next_cpu) { - qemu_wait_io_event_common(env); + qemu_wait_io_event_common(ENV_GET_CPU(env)); } } @@ -779,33 +848,31 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) return NULL; } -static void qemu_cpu_kick_thread(CPUState *env) +static void qemu_cpu_kick_thread(CPUState *cpu) { #ifndef _WIN32 int err; - err = pthread_kill(env->thread->thread, SIG_IPI); + err = pthread_kill(cpu->thread->thread, SIG_IPI); if (err) { fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); exit(1); } #else /* _WIN32 */ - if (!qemu_cpu_is_self(env)) { - SuspendThread(env->hThread); + if (!qemu_cpu_is_self(cpu)) { + SuspendThread(cpu->hThread); cpu_signal(0); - ResumeThread(env->hThread); + ResumeThread(cpu->hThread); } #endif } -void qemu_cpu_kick(void *_env) +void qemu_cpu_kick(CPUState *cpu) { - CPUState *env = _env; - - qemu_cond_broadcast(env->halt_cond); - if (kvm_enabled() && !env->thread_kicked) { - qemu_cpu_kick_thread(env); - env->thread_kicked = true; + qemu_cond_broadcast(cpu->halt_cond); + if (!tcg_enabled() && !cpu->thread_kicked) { + qemu_cpu_kick_thread(cpu); + cpu->thread_kicked = true; } } @@ -813,31 +880,35 @@ void qemu_cpu_kick_self(void) { #ifndef _WIN32 assert(cpu_single_env); + CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env); - if (!cpu_single_env->thread_kicked) { - qemu_cpu_kick_thread(cpu_single_env); - cpu_single_env->thread_kicked = true; + if (!cpu_single_cpu->thread_kicked) { + qemu_cpu_kick_thread(cpu_single_cpu); + cpu_single_cpu->thread_kicked = true; } #else abort(); #endif } -int qemu_cpu_is_self(void *_env) +bool qemu_cpu_is_self(CPUState *cpu) { - CPUState *env = _env; + return qemu_thread_is_self(cpu->thread); +} - return qemu_thread_is_self(env->thread); +static bool qemu_in_vcpu_thread(void) +{ + return cpu_single_env && qemu_cpu_is_self(ENV_GET_CPU(cpu_single_env)); } void qemu_mutex_lock_iothread(void) { - if (kvm_enabled()) { + if (!tcg_enabled()) { qemu_mutex_lock(&qemu_global_mutex); } else { iothread_requesting_mutex = true; if (qemu_mutex_trylock(&qemu_global_mutex)) { - qemu_cpu_kick_thread(first_cpu); + qemu_cpu_kick_thread(ENV_GET_CPU(first_cpu)); qemu_mutex_lock(&qemu_global_mutex); } iothread_requesting_mutex = false; @@ -852,10 +923,11 @@ void qemu_mutex_unlock_iothread(void) static int all_vcpus_paused(void) { - CPUState *penv = first_cpu; + CPUArchState *penv = first_cpu; while (penv) { - if (!penv->stopped) { + CPUState *pcpu = ENV_GET_CPU(penv); + if (!pcpu->stopped) { return 0; } penv = penv->next_cpu; @@ -866,20 +938,34 @@ static int all_vcpus_paused(void) void pause_all_vcpus(void) { - CPUState *penv = first_cpu; + CPUArchState *penv = first_cpu; qemu_clock_enable(vm_clock, false); while (penv) { - penv->stop = 1; - qemu_cpu_kick(penv); + CPUState *pcpu = ENV_GET_CPU(penv); + pcpu->stop = true; + qemu_cpu_kick(pcpu); penv = penv->next_cpu; } + if (qemu_in_vcpu_thread()) { + cpu_stop_current(); + if (!kvm_enabled()) { + while (penv) { + CPUState *pcpu = ENV_GET_CPU(penv); + pcpu->stop = 0; + pcpu->stopped = true; + penv = penv->next_cpu; + } + return; + } + } + while (!all_vcpus_paused()) { qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex); penv = first_cpu; while (penv) { - qemu_cpu_kick(penv); + qemu_cpu_kick(ENV_GET_CPU(penv)); penv = penv->next_cpu; } } @@ -887,73 +973,92 @@ void pause_all_vcpus(void) void resume_all_vcpus(void) { - CPUState *penv = first_cpu; + CPUArchState *penv = first_cpu; qemu_clock_enable(vm_clock, true); while (penv) { - penv->stop = 0; - penv->stopped = 0; - qemu_cpu_kick(penv); + CPUState *pcpu = ENV_GET_CPU(penv); + pcpu->stop = false; + pcpu->stopped = false; + qemu_cpu_kick(pcpu); penv = penv->next_cpu; } } -static void qemu_tcg_init_vcpu(void *_env) +static void qemu_tcg_init_vcpu(CPUState *cpu) { - CPUState *env = _env; - /* share a single thread for all cpus with TCG */ if (!tcg_cpu_thread) { - env->thread = g_malloc0(sizeof(QemuThread)); - env->halt_cond = g_malloc0(sizeof(QemuCond)); - qemu_cond_init(env->halt_cond); - tcg_halt_cond = env->halt_cond; - qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env, + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + tcg_halt_cond = cpu->halt_cond; + qemu_thread_create(cpu->thread, qemu_tcg_cpu_thread_fn, cpu, QEMU_THREAD_JOINABLE); #ifdef _WIN32 - env->hThread = qemu_thread_get_handle(env->thread); + cpu->hThread = qemu_thread_get_handle(cpu->thread); #endif - while (env->created == 0) { + while (!cpu->created) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); } - tcg_cpu_thread = env->thread; + tcg_cpu_thread = cpu->thread; } else { - env->thread = tcg_cpu_thread; - env->halt_cond = tcg_halt_cond; + cpu->thread = tcg_cpu_thread; + cpu->halt_cond = tcg_halt_cond; } } -static void qemu_kvm_start_vcpu(CPUState *env) +static void qemu_kvm_start_vcpu(CPUArchState *env) { - env->thread = g_malloc0(sizeof(QemuThread)); - env->halt_cond = g_malloc0(sizeof(QemuCond)); - qemu_cond_init(env->halt_cond); - qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env, + CPUState *cpu = ENV_GET_CPU(env); + + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + qemu_thread_create(cpu->thread, qemu_kvm_cpu_thread_fn, env, QEMU_THREAD_JOINABLE); - while (env->created == 0) { + while (!cpu->created) { + qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); + } +} + +static void qemu_dummy_start_vcpu(CPUArchState *env) +{ + CPUState *cpu = ENV_GET_CPU(env); + + cpu->thread = g_malloc0(sizeof(QemuThread)); + cpu->halt_cond = g_malloc0(sizeof(QemuCond)); + qemu_cond_init(cpu->halt_cond); + qemu_thread_create(cpu->thread, qemu_dummy_cpu_thread_fn, env, + QEMU_THREAD_JOINABLE); + while (!cpu->created) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); } } void qemu_init_vcpu(void *_env) { - CPUState *env = _env; + CPUArchState *env = _env; + CPUState *cpu = ENV_GET_CPU(env); env->nr_cores = smp_cores; env->nr_threads = smp_threads; - env->stopped = 1; + cpu->stopped = true; if (kvm_enabled()) { qemu_kvm_start_vcpu(env); + } else if (tcg_enabled()) { + qemu_tcg_init_vcpu(cpu); } else { - qemu_tcg_init_vcpu(env); + qemu_dummy_start_vcpu(env); } } void cpu_stop_current(void) { if (cpu_single_env) { - cpu_single_env->stop = 0; - cpu_single_env->stopped = 1; + CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env); + cpu_single_cpu->stop = false; + cpu_single_cpu->stopped = true; cpu_exit(cpu_single_env); qemu_cond_signal(&qemu_pause_cond); } @@ -961,7 +1066,7 @@ void cpu_stop_current(void) void vm_stop(RunState state) { - if (!qemu_thread_is_self(&io_thread)) { + if (qemu_in_vcpu_thread()) { qemu_system_vmstop_request(state); /* * FIXME: should not return to device code in case @@ -984,7 +1089,7 @@ void vm_stop_force_state(RunState state) } } -static int tcg_cpu_exec(CPUState *env) +static int tcg_cpu_exec(CPUArchState *env) { int ret; #ifdef CONFIG_PROFILER @@ -1033,18 +1138,19 @@ static void tcg_exec_all(void) next_cpu = first_cpu; } for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) { - CPUState *env = next_cpu; + CPUArchState *env = next_cpu; + CPUState *cpu = ENV_GET_CPU(env); qemu_clock_enable(vm_clock, (env->singlestep_enabled & SSTEP_NOTIMER) == 0); - if (cpu_can_run(env)) { + if (cpu_can_run(cpu)) { r = tcg_cpu_exec(env); if (r == EXCP_DEBUG) { cpu_handle_guest_debug(env); break; } - } else if (env->stop || env->stopped) { + } else if (cpu->stop || cpu->stopped) { break; } } @@ -1053,12 +1159,12 @@ static void tcg_exec_all(void) void set_numa_modes(void) { - CPUState *env; + CPUArchState *env; int i; for (env = first_cpu; env != NULL; env = env->next_cpu) { for (i = 0; i < nb_numa_nodes; i++) { - if (node_cpumask[i] & (1 << env->cpu_index)) { + if (test_bit(env->cpu_index, node_cpumask[i])) { env->numa_node = i; } } @@ -1089,19 +1195,18 @@ void set_cpu_log_filename(const char *optarg) void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg) { /* XXX: implement xxx_cpu_list for targets that still miss it */ -#if defined(cpu_list_id) - cpu_list_id(f, cpu_fprintf, optarg); -#elif defined(cpu_list) - cpu_list(f, cpu_fprintf); /* deprecated */ +#if defined(cpu_list) + cpu_list(f, cpu_fprintf); #endif } CpuInfoList *qmp_query_cpus(Error **errp) { CpuInfoList *head = NULL, *cur_item = NULL; - CPUState *env; + CPUArchState *env; - for(env = first_cpu; env != NULL; env = env->next_cpu) { + for (env = first_cpu; env != NULL; env = env->next_cpu) { + CPUState *cpu = ENV_GET_CPU(env); CpuInfoList *info; cpu_synchronize_state(env); @@ -1111,7 +1216,7 @@ CpuInfoList *qmp_query_cpus(Error **errp) info->value->CPU = env->cpu_index; info->value->current = (env == first_cpu); info->value->halted = env->halted; - info->value->thread_id = env->thread_id; + info->value->thread_id = cpu->thread_id; #if defined(TARGET_I386) info->value->has_pc = true; info->value->pc = env->eip + env->segs[R_CS].base; @@ -1145,7 +1250,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename, { FILE *f; uint32_t l; - CPUState *env; + CPUArchState *env; uint8_t buf[1024]; if (!has_cpu) { @@ -1220,7 +1325,7 @@ exit: void qmp_inject_nmi(Error **errp) { #if defined(TARGET_I386) - CPUState *env; + CPUArchState *env; for (env = first_cpu; env != NULL; env = env->next_cpu) { if (!env->apic_state) {