aboutsummaryrefslogtreecommitdiff
path: root/cpus.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpus.c')
-rw-r--r--cpus.c214
1 files changed, 108 insertions, 106 deletions
diff --git a/cpus.c b/cpus.c
index e476a3c..d9c332f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -64,13 +64,15 @@ static CPUArchState *next_cpu;
static bool cpu_thread_is_idle(CPUArchState *env)
{
- if (env->stop || env->queued_work_first) {
+ CPUState *cpu = ENV_GET_CPU(env);
+
+ if (cpu->stop || cpu->queued_work_first) {
return false;
}
- if (env->stopped || !runstate_is_running()) {
+ if (cpu->stopped || !runstate_is_running()) {
return true;
}
- if (!env->halted || qemu_cpu_has_work(env) ||
+ if (!env->halted || qemu_cpu_has_work(cpu) ||
kvm_async_interrupts_enabled()) {
return false;
}
@@ -395,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();
@@ -432,9 +430,9 @@ void cpu_synchronize_all_post_init(void)
}
}
-int cpu_is_stopped(CPUArchState *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)
@@ -450,22 +448,24 @@ static void do_vm_stop(RunState state)
}
}
-static int cpu_can_run(CPUArchState *env)
+static bool cpu_can_run(CPUState *cpu)
{
- if (env->stop) {
- return 0;
+ if (cpu->stop) {
+ return false;
}
- if (env->stopped || !runstate_is_running()) {
- return 0;
+ if (cpu->stopped || !runstate_is_running()) {
+ return false;
}
- return 1;
+ return true;
}
static void cpu_handle_guest_debug(CPUArchState *env)
{
+ CPUState *cpu = ENV_GET_CPU(env);
+
gdb_set_stop_cpu(env);
qemu_system_debug_request();
- env->stopped = 1;
+ cpu->stopped = true;
}
static void cpu_signal(int sig)
@@ -613,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;
@@ -640,27 +640,27 @@ void qemu_init_cpu_loop(void)
qemu_thread_get_self(&io_thread);
}
-void run_on_cpu(CPUArchState *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) {
CPUArchState *self_env = cpu_single_env;
@@ -669,33 +669,31 @@ void run_on_cpu(CPUArchState *env, void (*func)(void *data), void *data)
}
}
-static void flush_queued_work(CPUArchState *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(CPUArchState *env)
+static void qemu_wait_io_event_common(CPUState *cpu)
{
- CPUState *cpu = ENV_GET_CPU(env);
-
- 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);
+ flush_queued_work(cpu);
cpu->thread_kicked = false;
}
@@ -715,18 +713,20 @@ 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(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)
@@ -737,7 +737,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
qemu_mutex_lock(&qemu_global_mutex);
qemu_thread_get_self(cpu->thread);
- env->thread_id = qemu_get_thread_id();
+ cpu->thread_id = qemu_get_thread_id();
cpu_single_env = env;
r = kvm_init_vcpu(env);
@@ -749,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);
@@ -778,13 +778,13 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
- env->thread_id = qemu_get_thread_id();
+ cpu->thread_id = qemu_get_thread_id();
sigemptyset(&waitset);
sigaddset(&waitset, SIG_IPI);
/* signal CPU creation */
- env->created = 1;
+ cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
cpu_single_env = env;
@@ -801,7 +801,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
}
qemu_mutex_lock_iothread();
cpu_single_env = env;
- qemu_wait_io_event_common(env);
+ qemu_wait_io_event_common(cpu);
}
return NULL;
@@ -812,8 +812,8 @@ static void tcg_exec_all(void);
static void *qemu_tcg_cpu_thread_fn(void *arg)
{
- CPUArchState *env = arg;
- CPUState *cpu = ENV_GET_CPU(env);
+ CPUState *cpu = arg;
+ CPUArchState *env;
qemu_tcg_init_cpu_signals();
qemu_thread_get_self(cpu->thread);
@@ -821,18 +821,19 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
/* 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));
}
}
@@ -847,9 +848,8 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
return NULL;
}
-static void qemu_cpu_kick_thread(CPUArchState *env)
+static void qemu_cpu_kick_thread(CPUState *cpu)
{
- CPUState *cpu = ENV_GET_CPU(env);
#ifndef _WIN32
int err;
@@ -859,7 +859,7 @@ static void qemu_cpu_kick_thread(CPUArchState *env)
exit(1);
}
#else /* _WIN32 */
- if (!qemu_cpu_is_self(env)) {
+ if (!qemu_cpu_is_self(cpu)) {
SuspendThread(cpu->hThread);
cpu_signal(0);
ResumeThread(cpu->hThread);
@@ -867,14 +867,11 @@ static void qemu_cpu_kick_thread(CPUArchState *env)
#endif
}
-void qemu_cpu_kick(void *_env)
+void qemu_cpu_kick(CPUState *cpu)
{
- CPUArchState *env = _env;
- CPUState *cpu = ENV_GET_CPU(env);
-
- qemu_cond_broadcast(env->halt_cond);
+ qemu_cond_broadcast(cpu->halt_cond);
if (!tcg_enabled() && !cpu->thread_kicked) {
- qemu_cpu_kick_thread(env);
+ qemu_cpu_kick_thread(cpu);
cpu->thread_kicked = true;
}
}
@@ -886,7 +883,7 @@ void qemu_cpu_kick_self(void)
CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
if (!cpu_single_cpu->thread_kicked) {
- qemu_cpu_kick_thread(cpu_single_env);
+ qemu_cpu_kick_thread(cpu_single_cpu);
cpu_single_cpu->thread_kicked = true;
}
#else
@@ -894,14 +891,16 @@ void qemu_cpu_kick_self(void)
#endif
}
-int qemu_cpu_is_self(void *_env)
+bool qemu_cpu_is_self(CPUState *cpu)
{
- CPUArchState *env = _env;
- CPUState *cpu = ENV_GET_CPU(env);
-
return qemu_thread_is_self(cpu->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 (!tcg_enabled()) {
@@ -909,7 +908,7 @@ void qemu_mutex_lock_iothread(void)
} 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;
@@ -927,7 +926,8 @@ static int all_vcpus_paused(void)
CPUArchState *penv = first_cpu;
while (penv) {
- if (!penv->stopped) {
+ CPUState *pcpu = ENV_GET_CPU(penv);
+ if (!pcpu->stopped) {
return 0;
}
penv = penv->next_cpu;
@@ -942,17 +942,19 @@ void pause_all_vcpus(void)
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_thread_is_self(&io_thread)) {
+ if (qemu_in_vcpu_thread()) {
cpu_stop_current();
if (!kvm_enabled()) {
while (penv) {
- penv->stop = 0;
- penv->stopped = 1;
+ CPUState *pcpu = ENV_GET_CPU(penv);
+ pcpu->stop = 0;
+ pcpu->stopped = true;
penv = penv->next_cpu;
}
return;
@@ -963,7 +965,7 @@ void pause_all_vcpus(void)
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;
}
}
@@ -975,36 +977,34 @@ void resume_all_vcpus(void)
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)
{
- CPUArchState *env = _env;
- CPUState *cpu = ENV_GET_CPU(env);
-
/* share a single thread for all cpus with TCG */
if (!tcg_cpu_thread) {
cpu->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(cpu->thread, qemu_tcg_cpu_thread_fn, env,
+ 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
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 = cpu->thread;
} else {
cpu->thread = tcg_cpu_thread;
- env->halt_cond = tcg_halt_cond;
+ cpu->halt_cond = tcg_halt_cond;
}
}
@@ -1013,11 +1013,11 @@ static void qemu_kvm_start_vcpu(CPUArchState *env)
CPUState *cpu = ENV_GET_CPU(env);
cpu->thread = g_malloc0(sizeof(QemuThread));
- env->halt_cond = g_malloc0(sizeof(QemuCond));
- qemu_cond_init(env->halt_cond);
+ 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);
}
}
@@ -1027,11 +1027,11 @@ static void qemu_dummy_start_vcpu(CPUArchState *env)
CPUState *cpu = ENV_GET_CPU(env);
cpu->thread = g_malloc0(sizeof(QemuThread));
- env->halt_cond = g_malloc0(sizeof(QemuCond));
- qemu_cond_init(env->halt_cond);
+ 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 (env->created == 0) {
+ while (!cpu->created) {
qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
}
}
@@ -1039,14 +1039,15 @@ static void qemu_dummy_start_vcpu(CPUArchState *env)
void qemu_init_vcpu(void *_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(env);
+ qemu_tcg_init_vcpu(cpu);
} else {
qemu_dummy_start_vcpu(env);
}
@@ -1055,8 +1056,9 @@ void qemu_init_vcpu(void *_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);
}
@@ -1064,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
@@ -1137,17 +1139,18 @@ static void tcg_exec_all(void)
}
for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->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;
}
}
@@ -1192,10 +1195,8 @@ 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
}
@@ -1204,7 +1205,8 @@ CpuInfoList *qmp_query_cpus(Error **errp)
CpuInfoList *head = NULL, *cur_item = NULL;
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);
@@ -1214,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;