mirror of https://github.com/xemu-project/xemu.git
cpus: make pause_all_cpus() play with SMP on single threaded TCG
pause_all_cpus() is sometimes called from a VCPU thread (e.g. s390x during special reset). It cannot deal with multiple VCPUs per Thread (single threaded TCG) yet. Booting an s390x guest with -smp 2 and single threaded TCG from disk currently fails. The DIAG 308 will issue a pause_all_cpus() and wait forever for the CPUs to actually stop. But it is waiting for itself. So let's stop all VCPUs belonging to the current thread. Factor out stopping of a VCPU. Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20171129191215.11323-1-david@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
09df29b665
commit
ebd05fea9b
32
cpus.c
32
cpus.c
|
@ -1057,13 +1057,22 @@ static void qemu_tcg_destroy_vcpu(CPUState *cpu)
|
|||
{
|
||||
}
|
||||
|
||||
static void qemu_cpu_stop(CPUState *cpu, bool exit)
|
||||
{
|
||||
g_assert(qemu_cpu_is_self(cpu));
|
||||
cpu->stop = false;
|
||||
cpu->stopped = true;
|
||||
if (exit) {
|
||||
cpu_exit(cpu);
|
||||
}
|
||||
qemu_cond_broadcast(&qemu_pause_cond);
|
||||
}
|
||||
|
||||
static void qemu_wait_io_event_common(CPUState *cpu)
|
||||
{
|
||||
atomic_mb_set(&cpu->thread_kicked, false);
|
||||
if (cpu->stop) {
|
||||
cpu->stop = false;
|
||||
cpu->stopped = true;
|
||||
qemu_cond_broadcast(&qemu_pause_cond);
|
||||
qemu_cpu_stop(cpu, false);
|
||||
}
|
||||
process_queued_cpu_work(cpu);
|
||||
}
|
||||
|
@ -1610,12 +1619,12 @@ void pause_all_vcpus(void)
|
|||
|
||||
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
|
||||
CPU_FOREACH(cpu) {
|
||||
cpu->stop = true;
|
||||
qemu_cpu_kick(cpu);
|
||||
}
|
||||
|
||||
if (qemu_in_vcpu_thread()) {
|
||||
cpu_stop_current();
|
||||
if (qemu_cpu_is_self(cpu)) {
|
||||
qemu_cpu_stop(cpu, true);
|
||||
} else {
|
||||
cpu->stop = true;
|
||||
qemu_cpu_kick(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
while (!all_vcpus_paused()) {
|
||||
|
@ -1799,10 +1808,7 @@ void qemu_init_vcpu(CPUState *cpu)
|
|||
void cpu_stop_current(void)
|
||||
{
|
||||
if (current_cpu) {
|
||||
current_cpu->stop = false;
|
||||
current_cpu->stopped = true;
|
||||
cpu_exit(current_cpu);
|
||||
qemu_cond_broadcast(&qemu_pause_cond);
|
||||
qemu_cpu_stop(current_cpu, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue