mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
qtest: add test framework
The idea behind qtest is pretty simple. Instead of executing a CPU via TCG or KVM, rely on an external process to send events to the device model that the CPU would normally generate. qtest presents itself as an accelerator. In addition, a new option is added to establish a qtest server (-qtest) that takes a character device. This is what allows the external process to send CPU events to the device model. qtest uses a simple line based protocol to send the events. Documentation of that protocol is in qtest.c. I considered reusing the monitor for this job. Adding interrupts would be a bit difficult. In addition, logging would also be difficult. qtest has extensive logging support. All protocol commands are logged with time stamps using a new command line option (-qtest-log). Logging is important since ultimately, this is a feature for debugging. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
b93b63f574
commit
c7f0f3b1c8
8 changed files with 473 additions and 4 deletions
62
cpus.c
62
cpus.c
|
@ -741,6 +741,48 @@ 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;
|
||||
sigset_t waitset;
|
||||
int r;
|
||||
|
||||
qemu_mutex_lock_iothread();
|
||||
qemu_thread_get_self(env->thread);
|
||||
env->thread_id = qemu_get_thread_id();
|
||||
|
||||
sigemptyset(&waitset);
|
||||
sigaddset(&waitset, SIG_IPI);
|
||||
|
||||
/* signal CPU creation */
|
||||
env->created = 1;
|
||||
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(env);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void tcg_exec_all(void);
|
||||
|
||||
static void *qemu_tcg_cpu_thread_fn(void *arg)
|
||||
|
@ -803,7 +845,7 @@ void qemu_cpu_kick(void *_env)
|
|||
CPUArchState *env = _env;
|
||||
|
||||
qemu_cond_broadcast(env->halt_cond);
|
||||
if (kvm_enabled() && !env->thread_kicked) {
|
||||
if (!tcg_enabled() && !env->thread_kicked) {
|
||||
qemu_cpu_kick_thread(env);
|
||||
env->thread_kicked = true;
|
||||
}
|
||||
|
@ -832,7 +874,7 @@ int qemu_cpu_is_self(void *_env)
|
|||
|
||||
void qemu_mutex_lock_iothread(void)
|
||||
{
|
||||
if (kvm_enabled()) {
|
||||
if (!tcg_enabled()) {
|
||||
qemu_mutex_lock(&qemu_global_mutex);
|
||||
} else {
|
||||
iothread_requesting_mutex = true;
|
||||
|
@ -947,6 +989,18 @@ static void qemu_kvm_start_vcpu(CPUArchState *env)
|
|||
}
|
||||
}
|
||||
|
||||
static void qemu_dummy_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_dummy_cpu_thread_fn, env,
|
||||
QEMU_THREAD_JOINABLE);
|
||||
while (env->created == 0) {
|
||||
qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_init_vcpu(void *_env)
|
||||
{
|
||||
CPUArchState *env = _env;
|
||||
|
@ -956,8 +1010,10 @@ void qemu_init_vcpu(void *_env)
|
|||
env->stopped = 1;
|
||||
if (kvm_enabled()) {
|
||||
qemu_kvm_start_vcpu(env);
|
||||
} else {
|
||||
} else if (tcg_enabled()) {
|
||||
qemu_tcg_init_vcpu(env);
|
||||
} else {
|
||||
qemu_dummy_start_vcpu(env);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue