cpus: extract out qtest-specific code to accel/qtest

register a "CpusAccel" interface for qtest as well.

Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Claudio Fontana 2020-07-07 10:21:10 +02:00 committed by Paolo Bonzini
parent a77dabc33b
commit 1583a38988
7 changed files with 125 additions and 65 deletions

View File

@ -2492,7 +2492,7 @@ M: Laurent Vivier <lvivier@redhat.com>
R: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: softmmu/qtest.c
F: accel/qtest.c
F: accel/qtest/
F: tests/qtest/
X: tests/qtest/bios-tables-test-allowed-diff.h

View File

@ -1,6 +1,6 @@
softmmu_ss.add(files('accel.c'))
specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], if_true: files('qtest.c'))
subdir('qtest')
subdir('kvm')
subdir('tcg')
subdir('xen')

7
accel/qtest/meson.build Normal file
View File

@ -0,0 +1,7 @@
qtest_ss = ss.source_set()
qtest_ss.add(files(
'qtest.c',
'qtest-cpus.c',
))
specific_ss.add_all(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], if_true: qtest_ss)

91
accel/qtest/qtest-cpus.c Normal file
View File

@ -0,0 +1,91 @@
/*
* QTest accelerator code
*
* Copyright IBM, Corp. 2011
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#include "qemu/osdep.h"
#include "qemu/rcu.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "sysemu/accel.h"
#include "sysemu/qtest.h"
#include "sysemu/cpus.h"
#include "sysemu/cpu-timers.h"
#include "qemu/guest-random.h"
#include "qemu/main-loop.h"
#include "hw/core/cpu.h"
#include "qtest-cpus.h"
static void *qtest_cpu_thread_fn(void *arg)
{
#ifdef _WIN32
error_report("qtest is not supported under Windows");
exit(1);
#else
CPUState *cpu = arg;
sigset_t waitset;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
cpu->can_do_io = 1;
current_cpu = cpu;
sigemptyset(&waitset);
sigaddset(&waitset, SIG_IPI);
/* signal CPU creation */
cpu_thread_signal_created(cpu);
qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
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();
qemu_wait_io_event(cpu);
} while (!cpu->unplug);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
#endif
}
static void qtest_start_vcpu_thread(CPUState *cpu)
{
char thread_name[VCPU_THREAD_NAME_SIZE];
cpu->thread = g_malloc0(sizeof(QemuThread));
cpu->halt_cond = g_malloc0(sizeof(QemuCond));
qemu_cond_init(cpu->halt_cond);
snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY",
cpu->cpu_index);
qemu_thread_create(cpu->thread, thread_name, qtest_cpu_thread_fn, cpu,
QEMU_THREAD_JOINABLE);
}
const CpusAccel qtest_cpus = {
.create_vcpu_thread = qtest_start_vcpu_thread,
.get_virtual_clock = qtest_get_virtual_clock,
};

17
accel/qtest/qtest-cpus.h Normal file
View File

@ -0,0 +1,17 @@
/*
* Accelerator CPUS Interface
*
* Copyright 2020 SUSE LLC
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef QTEST_CPUS_H
#define QTEST_CPUS_H
#include "sysemu/cpus.h"
extern const CpusAccel qtest_cpus;
#endif /* QTEST_CPUS_H */

View File

@ -12,6 +12,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/rcu.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qemu/option.h"
@ -20,9 +21,15 @@
#include "sysemu/qtest.h"
#include "sysemu/cpus.h"
#include "sysemu/cpu-timers.h"
#include "qemu/guest-random.h"
#include "qemu/main-loop.h"
#include "hw/core/cpu.h"
#include "qtest-cpus.h"
static int qtest_init_accel(MachineState *ms)
{
cpus_register_accel(&qtest_cpus);
return 0;
}

View File

@ -40,7 +40,6 @@
#include "qemu/thread.h"
#include "qemu/plugin.h"
#include "sysemu/cpus.h"
#include "sysemu/qtest.h"
#include "qemu/main-loop.h"
#include "qemu/option.h"
#include "qemu/bitmap.h"
@ -247,9 +246,6 @@ int64_t cpus_get_virtual_clock(void)
if (cpus_accel && cpus_accel->get_virtual_clock) {
return cpus_accel->get_virtual_clock();
}
if (qtest_enabled()) { /* for qtest_clock_warp */
return qtest_get_virtual_clock();
}
return cpu_get_clock();
}
@ -482,51 +478,6 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
return NULL;
}
static void *qemu_dummy_cpu_thread_fn(void *arg)
{
#ifdef _WIN32
error_report("qtest is not supported under Windows");
exit(1);
#else
CPUState *cpu = arg;
sigset_t waitset;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
cpu->can_do_io = 1;
current_cpu = cpu;
sigemptyset(&waitset);
sigaddset(&waitset, SIG_IPI);
/* signal CPU creation */
cpu_thread_signal_created(cpu);
qemu_guest_random_seed_thread_part2(cpu->random_seed);
do {
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();
qemu_wait_io_event(cpu);
} while (!cpu->unplug);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
#endif
}
static void *qemu_hax_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
@ -904,19 +855,6 @@ void cpus_register_accel(const CpusAccel *ca)
cpus_accel = ca;
}
static void qemu_dummy_start_vcpu(CPUState *cpu)
{
char thread_name[VCPU_THREAD_NAME_SIZE];
cpu->thread = g_malloc0(sizeof(QemuThread));
cpu->halt_cond = g_malloc0(sizeof(QemuCond));
qemu_cond_init(cpu->halt_cond);
snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY",
cpu->cpu_index);
qemu_thread_create(cpu->thread, thread_name, qemu_dummy_cpu_thread_fn, cpu,
QEMU_THREAD_JOINABLE);
}
void qemu_init_vcpu(CPUState *cpu)
{
MachineState *ms = MACHINE(qdev_get_machine());
@ -946,7 +884,7 @@ void qemu_init_vcpu(CPUState *cpu)
} else if (whpx_enabled()) {
qemu_whpx_start_vcpu(cpu);
} else {
qemu_dummy_start_vcpu(cpu);
g_assert_not_reached();
}
while (!cpu->created) {