From b6444a42c06371d5abba78d2553a088a8490a65b Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Thu, 3 May 2012 00:34:15 +0200 Subject: ppce500_spin: Store PowerPCCPU in SpinKick MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Needed for moving stopped field to CPUState. Signed-off-by: Andreas Färber --- hw/ppce500_spin.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'hw/ppce500_spin.c') diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c index 55aa9dc8a2..04e7e65d44 100644 --- a/hw/ppce500_spin.c +++ b/hw/ppce500_spin.c @@ -49,7 +49,7 @@ typedef struct spin_state { } SpinState; typedef struct spin_kick { - CPUPPCState *env; + PowerPCCPU *cpu; SpinInfo *spin; } SpinKick; @@ -92,7 +92,7 @@ static void mmubooke_create_initial_mapping(CPUPPCState *env, static void spin_kick(void *data) { SpinKick *kick = data; - CPUPPCState *env = kick->env; + CPUPPCState *env = &kick->cpu->env; SpinInfo *curspin = kick->spin; hwaddr map_size = 64 * 1024 * 1024; hwaddr map_start; @@ -158,7 +158,7 @@ static void spin_write(void *opaque, hwaddr addr, uint64_t value, if (!(ldq_p(&curspin->addr) & 1)) { /* run CPU */ SpinKick kick = { - .env = env, + .cpu = ppc_env_get_cpu(env), .spin = curspin, }; -- cgit 1.4.1 From f324e7667a3c1f1aed9a5169a63aaac628feef47 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Wed, 2 May 2012 23:26:21 +0200 Subject: cpu: Move stopped field to CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change its type to bool. Signed-off-by: Andreas Färber --- cpu-defs.h | 1 - cpus.c | 30 ++++++++++++++++++------------ hw/ppce500_spin.c | 3 ++- include/qemu/cpu.h | 2 ++ 4 files changed, 22 insertions(+), 14 deletions(-) (limited to 'hw/ppce500_spin.c') diff --git a/cpu-defs.h b/cpu-defs.h index 7a6378c5a1..83bf1089a6 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -205,7 +205,6 @@ typedef struct CPUWatchpoint { /* user data */ \ void *opaque; \ \ - uint32_t stopped; /* Artificially stopped */ \ struct QemuCond *halt_cond; \ struct qemu_work_item *queued_work_first, *queued_work_last; \ const char *cpu_model_str; \ diff --git a/cpus.c b/cpus.c index 2341ebb68c..4654f0878b 100644 --- a/cpus.c +++ b/cpus.c @@ -69,7 +69,7 @@ static bool cpu_thread_is_idle(CPUArchState *env) if (cpu->stop || env->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) || @@ -432,7 +432,9 @@ void cpu_synchronize_all_post_init(void) int cpu_is_stopped(CPUArchState *env) { - return !runstate_is_running() || env->stopped; + CPUState *cpu = ENV_GET_CPU(env); + + return !runstate_is_running() || cpu->stopped; } static void do_vm_stop(RunState state) @@ -455,7 +457,7 @@ static int cpu_can_run(CPUArchState *env) if (cpu->stop) { return 0; } - if (env->stopped || !runstate_is_running()) { + if (cpu->stopped || !runstate_is_running()) { return 0; } return 1; @@ -463,9 +465,11 @@ static int cpu_can_run(CPUArchState *env) 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) @@ -693,7 +697,7 @@ static void qemu_wait_io_event_common(CPUArchState *env) if (cpu->stop) { cpu->stop = false; - env->stopped = 1; + cpu->stopped = true; qemu_cond_signal(&qemu_pause_cond); } flush_queued_work(env); @@ -829,7 +833,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) 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 */ @@ -930,7 +934,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; @@ -957,7 +962,7 @@ void pause_all_vcpus(void) while (penv) { CPUState *pcpu = ENV_GET_CPU(penv); pcpu->stop = 0; - penv->stopped = 1; + pcpu->stopped = true; penv = penv->next_cpu; } return; @@ -982,7 +987,7 @@ void resume_all_vcpus(void) while (penv) { CPUState *pcpu = ENV_GET_CPU(penv); pcpu->stop = false; - penv->stopped = 0; + pcpu->stopped = false; qemu_cpu_kick(penv); penv = penv->next_cpu; } @@ -1045,10 +1050,11 @@ 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()) { @@ -1063,7 +1069,7 @@ void cpu_stop_current(void) if (cpu_single_env) { CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env); cpu_single_cpu->stop = false; - cpu_single_env->stopped = 1; + cpu_single_cpu->stopped = true; cpu_exit(cpu_single_env); qemu_cond_signal(&qemu_pause_cond); } @@ -1155,7 +1161,7 @@ static void tcg_exec_all(void) cpu_handle_guest_debug(env); break; } - } else if (cpu->stop || env->stopped) { + } else if (cpu->stop || cpu->stopped) { break; } } diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c index 04e7e65d44..fb5461d588 100644 --- a/hw/ppce500_spin.c +++ b/hw/ppce500_spin.c @@ -92,6 +92,7 @@ static void mmubooke_create_initial_mapping(CPUPPCState *env, static void spin_kick(void *data) { SpinKick *kick = data; + CPUState *cpu = CPU(kick->cpu); CPUPPCState *env = &kick->cpu->env; SpinInfo *curspin = kick->spin; hwaddr map_size = 64 * 1024 * 1024; @@ -113,7 +114,7 @@ static void spin_kick(void *data) env->halted = 0; env->exception_index = -1; - env->stopped = 0; + cpu->stopped = false; qemu_cpu_kick(env); } diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h index 04c7848b8f..83378c54ae 100644 --- a/include/qemu/cpu.h +++ b/include/qemu/cpu.h @@ -56,6 +56,7 @@ typedef struct CPUClass { * CPUState: * @created: Indicates whether the CPU thread has been successfully created. * @stop: Indicates a pending stop request. + * @stopped: Indicates the CPU has been artificially stopped. * * State of one CPU core or thread. */ @@ -71,6 +72,7 @@ struct CPUState { bool thread_kicked; bool created; bool stop; + bool stopped; /* TODO Move common fields from CPUArchState here. */ }; -- cgit 1.4.1 From c08d7424d600dce915a5506e95d55a359c243c66 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Thu, 3 May 2012 04:34:15 +0200 Subject: cpus: Pass CPUState to qemu_cpu_kick() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPUArchState is no longer needed there. Signed-off-by: Andreas Färber --- cpus.c | 13 +++++-------- exec.c | 2 +- hw/ppc.c | 4 ++-- hw/ppce500_spin.c | 2 +- hw/spapr_rtas.c | 5 ++++- hw/sun4m.c | 2 +- hw/sun4u.c | 2 +- include/qemu/cpu.h | 8 ++++++++ kvm-all.c | 2 +- qemu-common.h | 1 - target-ppc/kvm.c | 3 +-- target-s390x/kvm.c | 2 +- 12 files changed, 26 insertions(+), 20 deletions(-) (limited to 'hw/ppce500_spin.c') diff --git a/cpus.c b/cpus.c index 5f915239ac..b802d38885 100644 --- a/cpus.c +++ b/cpus.c @@ -661,7 +661,7 @@ void run_on_cpu(CPUArchState *env, void (*func)(void *data), void *data) wi.next = NULL; wi.done = false; - qemu_cpu_kick(env); + qemu_cpu_kick(cpu); while (!wi.done) { CPUArchState *self_env = cpu_single_env; @@ -870,11 +870,8 @@ static void qemu_cpu_kick_thread(CPUState *cpu) #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(cpu->halt_cond); if (!tcg_enabled() && !cpu->thread_kicked) { qemu_cpu_kick_thread(cpu); @@ -950,7 +947,7 @@ void pause_all_vcpus(void) while (penv) { CPUState *pcpu = ENV_GET_CPU(penv); pcpu->stop = true; - qemu_cpu_kick(penv); + qemu_cpu_kick(pcpu); penv = penv->next_cpu; } @@ -971,7 +968,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; } } @@ -986,7 +983,7 @@ void resume_all_vcpus(void) CPUState *pcpu = ENV_GET_CPU(penv); pcpu->stop = false; pcpu->stopped = false; - qemu_cpu_kick(penv); + qemu_cpu_kick(pcpu); penv = penv->next_cpu; } } diff --git a/exec.c b/exec.c index a85a9b1fd2..038e40d09b 100644 --- a/exec.c +++ b/exec.c @@ -1704,7 +1704,7 @@ static void tcg_handle_interrupt(CPUArchState *env, int mask) * case its halted. */ if (!qemu_cpu_is_self(cpu)) { - qemu_cpu_kick(env); + qemu_cpu_kick(cpu); return; } diff --git a/hw/ppc.c b/hw/ppc.c index ada100b1c5..fa7ae74f0d 100644 --- a/hw/ppc.c +++ b/hw/ppc.c @@ -206,7 +206,7 @@ static void ppc970_set_irq(void *opaque, int pin, int level) } else { LOG_IRQ("%s: restart the CPU\n", __func__); env->halted = 0; - qemu_cpu_kick(env); + qemu_cpu_kick(CPU(cpu)); } break; case PPC970_INPUT_HRESET: @@ -335,7 +335,7 @@ static void ppc40x_set_irq(void *opaque, int pin, int level) } else { LOG_IRQ("%s: restart the CPU\n", __func__); env->halted = 0; - qemu_cpu_kick(env); + qemu_cpu_kick(CPU(cpu)); } break; case PPC40x_INPUT_DEBUG: diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c index fb5461d588..7f8c8428b6 100644 --- a/hw/ppce500_spin.c +++ b/hw/ppce500_spin.c @@ -115,7 +115,7 @@ static void spin_kick(void *data) env->halted = 0; env->exception_index = -1; cpu->stopped = false; - qemu_cpu_kick(env); + qemu_cpu_kick(cpu); } static void spin_write(void *opaque, hwaddr addr, uint64_t value, diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c index ce76c5856a..6d5c48a740 100644 --- a/hw/spapr_rtas.c +++ b/hw/spapr_rtas.c @@ -163,6 +163,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr, uint32_t nret, target_ulong rets) { target_ulong id, start, r3; + CPUState *cpu; CPUPPCState *env; if (nargs != 3 || nret != 1) { @@ -175,6 +176,8 @@ static void rtas_start_cpu(sPAPREnvironment *spapr, r3 = rtas_ld(args, 2); for (env = first_cpu; env; env = env->next_cpu) { + cpu = ENV_GET_CPU(env); + if (env->cpu_index != id) { continue; } @@ -194,7 +197,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr, env->gpr[3] = r3; env->halted = 0; - qemu_cpu_kick(env); + qemu_cpu_kick(cpu); rtas_st(rets, 0, 0); return; diff --git a/hw/sun4m.c b/hw/sun4m.c index 02673b228e..1a786762aa 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -259,7 +259,7 @@ static void cpu_kick_irq(SPARCCPU *cpu) env->halted = 0; cpu_check_irqs(env); - qemu_cpu_kick(env); + qemu_cpu_kick(CPU(cpu)); } static void cpu_set_irq(void *opaque, int irq, int level) diff --git a/hw/sun4u.c b/hw/sun4u.c index 162117129c..b2b51e30c2 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -317,7 +317,7 @@ static void cpu_kick_irq(SPARCCPU *cpu) env->halted = 0; cpu_check_irqs(env); - qemu_cpu_kick(env); + qemu_cpu_kick(CPU(cpu)); } static void cpu_set_ivec_irq(void *opaque, int irq, int level) diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h index 75e0f8dc68..bfeb2245ab 100644 --- a/include/qemu/cpu.h +++ b/include/qemu/cpu.h @@ -95,6 +95,14 @@ void cpu_reset(CPUState *cpu); */ bool qemu_cpu_is_self(CPUState *cpu); +/** + * qemu_cpu_kick: + * @cpu: The vCPU to kick. + * + * Kicks @cpu's thread. + */ +void qemu_cpu_kick(CPUState *cpu); + /** * cpu_is_stopped: * @cpu: The CPU to check. diff --git a/kvm-all.c b/kvm-all.c index 74d2652f02..e41e1c9531 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -833,7 +833,7 @@ static void kvm_handle_interrupt(CPUArchState *env, int mask) env->interrupt_request |= mask; if (!qemu_cpu_is_self(cpu)) { - qemu_cpu_kick(env); + qemu_cpu_kick(cpu); } } diff --git a/qemu-common.h b/qemu-common.h index 2094742f2b..2011c00fe2 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -324,7 +324,6 @@ void cpu_save(QEMUFile *f, void *opaque); int cpu_load(QEMUFile *f, void *opaque, int version_id); /* Unblock cpu */ -void qemu_cpu_kick(void *env); void qemu_cpu_kick_self(void); /* work queue */ diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index d7d8e8fef0..6aacff0624 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -76,9 +76,8 @@ static QEMUTimer *idle_timer; static void kvm_kick_cpu(void *opaque) { PowerPCCPU *cpu = opaque; - CPUPPCState *env = &cpu->env; - qemu_cpu_kick(env); + qemu_cpu_kick(CPU(cpu)); } int kvm_arch_init(KVMState *s) diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index a66ac4341c..94de764264 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -403,7 +403,7 @@ static int s390_cpu_restart(S390CPU *cpu) kvm_s390_interrupt(env, KVM_S390_RESTART, 0); s390_add_running_cpu(env); - qemu_cpu_kick(env); + qemu_cpu_kick(CPU(cpu)); dprintf("DONE: SIGP cpu restart: %p\n", env); return 0; } -- cgit 1.4.1 From f100f0b38fe43c683f437a8fa3e449d6752f6a58 Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Thu, 3 May 2012 14:58:47 +0200 Subject: cpus: Pass CPUState to run_on_cpu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPUArchState is no longer needed. Move the declaration to include/qemu/cpu.h and add documentation. Signed-off-by: Andreas Färber --- cpu-all.h | 1 - cpus.c | 3 +-- hw/kvm/apic.c | 2 +- hw/kvmvapic.c | 6 ++++-- hw/ppce500_spin.c | 2 +- include/qemu/cpu.h | 10 ++++++++++ kvm-all.c | 7 +++++-- target-i386/helper.c | 4 ++-- 8 files changed, 24 insertions(+), 11 deletions(-) (limited to 'hw/ppce500_spin.c') diff --git a/cpu-all.h b/cpu-all.h index 0356684e2f..c9c51b83ac 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -464,7 +464,6 @@ void cpu_watchpoint_remove_all(CPUArchState *env, int mask); #define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */ void cpu_single_step(CPUArchState *env, int enabled); -void run_on_cpu(CPUArchState *env, void (*func)(void *data), void *data); #if !defined(CONFIG_USER_ONLY) diff --git a/cpus.c b/cpus.c index 76f32fc050..bee09b996f 100644 --- a/cpus.c +++ b/cpus.c @@ -640,9 +640,8 @@ 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) { - CPUState *cpu = ENV_GET_CPU(env); struct qemu_work_item wi; if (qemu_cpu_is_self(cpu)) { diff --git a/hw/kvm/apic.c b/hw/kvm/apic.c index e4a7307ca5..8b65d513db 100644 --- a/hw/kvm/apic.c +++ b/hw/kvm/apic.c @@ -143,7 +143,7 @@ static void do_inject_external_nmi(void *data) static void kvm_apic_external_nmi(APICCommonState *s) { - run_on_cpu(&s->cpu->env, do_inject_external_nmi, s); + run_on_cpu(CPU(s->cpu), do_inject_external_nmi, s); } static uint64_t kvm_apic_mem_read(void *opaque, hwaddr addr, diff --git a/hw/kvmvapic.c b/hw/kvmvapic.c index 5e0a7c9384..dc111ee8e6 100644 --- a/hw/kvmvapic.c +++ b/hw/kvmvapic.c @@ -475,11 +475,13 @@ static void vapic_enable_tpr_reporting(bool enable) VAPICEnableTPRReporting info = { .enable = enable, }; + X86CPU *cpu; CPUX86State *env; for (env = first_cpu; env != NULL; env = env->next_cpu) { + cpu = x86_env_get_cpu(env); info.apic = env->apic_state; - run_on_cpu(env, vapic_do_enable_tpr_reporting, &info); + run_on_cpu(CPU(cpu), vapic_do_enable_tpr_reporting, &info); } } @@ -717,7 +719,7 @@ static int vapic_post_load(void *opaque, int version_id) } if (s->state == VAPIC_ACTIVE) { if (smp_cpus == 1) { - run_on_cpu(first_cpu, do_vapic_enable, s); + run_on_cpu(ENV_GET_CPU(first_cpu), do_vapic_enable, s); } else { zero = g_malloc0(s->rom_state.vapic_size); cpu_physical_memory_rw(s->vapic_paddr, zero, diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c index 7f8c8428b6..c1a155bd31 100644 --- a/hw/ppce500_spin.c +++ b/hw/ppce500_spin.c @@ -163,7 +163,7 @@ static void spin_write(void *opaque, hwaddr addr, uint64_t value, .spin = curspin, }; - run_on_cpu(env, spin_kick, &kick); + run_on_cpu(CPU(kick.cpu), spin_kick, &kick); } } diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h index f04da6ec4f..33f01d9a6f 100644 --- a/include/qemu/cpu.h +++ b/include/qemu/cpu.h @@ -125,5 +125,15 @@ void qemu_cpu_kick(CPUState *cpu); */ bool cpu_is_stopped(CPUState *cpu); +/** + * run_on_cpu: + * @cpu: The vCPU to run on. + * @func: The function to be executed. + * @data: Data to pass to the function. + * + * Schedules the function @func for execution on the vCPU @cpu. + */ +void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data); + #endif diff --git a/kvm-all.c b/kvm-all.c index e41e1c9531..b6d0483576 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1500,8 +1500,10 @@ static void do_kvm_cpu_synchronize_state(void *_env) void kvm_cpu_synchronize_state(CPUArchState *env) { + CPUState *cpu = ENV_GET_CPU(env); + if (!env->kvm_vcpu_dirty) { - run_on_cpu(env, do_kvm_cpu_synchronize_state, env); + run_on_cpu(cpu, do_kvm_cpu_synchronize_state, env); } } @@ -1787,6 +1789,7 @@ static void kvm_invoke_set_guest_debug(void *data) int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) { + CPUState *cpu = ENV_GET_CPU(env); struct kvm_set_guest_debug_data data; data.dbg.control = reinject_trap; @@ -1797,7 +1800,7 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) kvm_arch_update_guest_debug(env, &data.dbg); data.env = env; - run_on_cpu(env, kvm_invoke_set_guest_debug, &data); + run_on_cpu(cpu, kvm_invoke_set_guest_debug, &data); return data.err; } diff --git a/target-i386/helper.c b/target-i386/helper.c index 45f4bed57f..bf206cfa97 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1177,7 +1177,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank, return; } - run_on_cpu(cenv, do_inject_x86_mce, ¶ms); + run_on_cpu(CPU(cpu), do_inject_x86_mce, ¶ms); if (flags & MCE_INJECT_BROADCAST) { params.bank = 1; params.status = MCI_STATUS_VAL | MCI_STATUS_UC; @@ -1189,7 +1189,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank, continue; } params.env = env; - run_on_cpu(cenv, do_inject_x86_mce, ¶ms); + run_on_cpu(CPU(cpu), do_inject_x86_mce, ¶ms); } } } -- cgit 1.4.1