Merge remote branch 'qemu-kvm/uq/master' into staging
This commit is contained in:
commit
724c689357
12
cpu-exec.c
12
cpu-exec.c
|
@ -230,11 +230,13 @@ int cpu_exec(CPUState *env1)
|
||||||
env = env1;
|
env = env1;
|
||||||
|
|
||||||
#if defined(TARGET_I386)
|
#if defined(TARGET_I386)
|
||||||
/* put eflags in CPU temporary format */
|
if (!kvm_enabled()) {
|
||||||
CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
/* put eflags in CPU temporary format */
|
||||||
DF = 1 - (2 * ((env->eflags >> 10) & 1));
|
CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
||||||
CC_OP = CC_OP_EFLAGS;
|
DF = 1 - (2 * ((env->eflags >> 10) & 1));
|
||||||
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
CC_OP = CC_OP_EFLAGS;
|
||||||
|
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
||||||
|
}
|
||||||
#elif defined(TARGET_SPARC)
|
#elif defined(TARGET_SPARC)
|
||||||
#elif defined(TARGET_M68K)
|
#elif defined(TARGET_M68K)
|
||||||
env->cc_op = CC_OP_FLAGS;
|
env->cc_op = CC_OP_FLAGS;
|
||||||
|
|
24
kvm-all.c
24
kvm-all.c
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/kvm.h>
|
#include <linux/kvm.h>
|
||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
|
#include "qemu-barrier.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#include "gdbstub.h"
|
#include "gdbstub.h"
|
||||||
|
@ -730,7 +731,7 @@ void kvm_flush_coalesced_mmio_buffer(void)
|
||||||
ent = &ring->coalesced_mmio[ring->first];
|
ent = &ring->coalesced_mmio[ring->first];
|
||||||
|
|
||||||
cpu_physical_memory_write(ent->phys_addr, ent->data, ent->len);
|
cpu_physical_memory_write(ent->phys_addr, ent->data, ent->len);
|
||||||
/* FIXME smp_wmb() */
|
smp_wmb();
|
||||||
ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX;
|
ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -753,11 +754,13 @@ int kvm_cpu_exec(CPUState *env)
|
||||||
dprintf("kvm_cpu_exec()\n");
|
dprintf("kvm_cpu_exec()\n");
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
#ifndef CONFIG_IOTHREAD
|
||||||
if (env->exit_request) {
|
if (env->exit_request) {
|
||||||
dprintf("interrupt exit requested\n");
|
dprintf("interrupt exit requested\n");
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (env->kvm_vcpu_dirty) {
|
if (env->kvm_vcpu_dirty) {
|
||||||
kvm_arch_put_registers(env);
|
kvm_arch_put_registers(env);
|
||||||
|
@ -771,6 +774,7 @@ int kvm_cpu_exec(CPUState *env)
|
||||||
kvm_arch_post_run(env, run);
|
kvm_arch_post_run(env, run);
|
||||||
|
|
||||||
if (ret == -EINTR || ret == -EAGAIN) {
|
if (ret == -EINTR || ret == -EAGAIN) {
|
||||||
|
cpu_exit(env);
|
||||||
dprintf("io window exit\n");
|
dprintf("io window exit\n");
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -1116,3 +1120,21 @@ void kvm_remove_all_breakpoints(CPUState *current_env)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif /* !KVM_CAP_SET_GUEST_DEBUG */
|
#endif /* !KVM_CAP_SET_GUEST_DEBUG */
|
||||||
|
|
||||||
|
int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset)
|
||||||
|
{
|
||||||
|
struct kvm_signal_mask *sigmask;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!sigset)
|
||||||
|
return kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, NULL);
|
||||||
|
|
||||||
|
sigmask = qemu_malloc(sizeof(*sigmask) + sizeof(*sigset));
|
||||||
|
|
||||||
|
sigmask->len = 8;
|
||||||
|
memcpy(sigmask->sigset, sigset, sizeof(*sigset));
|
||||||
|
r = kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, sigmask);
|
||||||
|
free(sigmask);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
1
kvm.h
1
kvm.h
|
@ -53,6 +53,7 @@ int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
|
||||||
target_ulong len, int type);
|
target_ulong len, int type);
|
||||||
void kvm_remove_all_breakpoints(CPUState *current_env);
|
void kvm_remove_all_breakpoints(CPUState *current_env);
|
||||||
int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap);
|
int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap);
|
||||||
|
int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset);
|
||||||
|
|
||||||
int kvm_pit_in_kernel(void);
|
int kvm_pit_in_kernel(void);
|
||||||
int kvm_irqchip_in_kernel(void);
|
int kvm_irqchip_in_kernel(void);
|
||||||
|
|
32
osdep.c
32
osdep.c
|
@ -37,6 +37,10 @@
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_EVENTFD
|
||||||
|
#include <sys/eventfd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#elif defined(CONFIG_BSD)
|
#elif defined(CONFIG_BSD)
|
||||||
|
@ -280,6 +284,34 @@ ssize_t qemu_write_full(int fd, const void *buf, size_t count)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
/*
|
||||||
|
* Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set.
|
||||||
|
*/
|
||||||
|
int qemu_eventfd(int fds[2])
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#ifdef CONFIG_EVENTFD
|
||||||
|
ret = eventfd(0, 0);
|
||||||
|
if (ret >= 0) {
|
||||||
|
fds[0] = ret;
|
||||||
|
qemu_set_cloexec(ret);
|
||||||
|
if ((fds[1] = dup(ret)) == -1) {
|
||||||
|
close(ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
qemu_set_cloexec(fds[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno != ENOSYS) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return qemu_pipe(fds);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates a pipe with FD_CLOEXEC set on both file descriptors
|
* Creates a pipe with FD_CLOEXEC set on both file descriptors
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef __QEMU_BARRIER_H
|
||||||
|
#define __QEMU_BARRIER_H 1
|
||||||
|
|
||||||
|
/* FIXME: arch dependant, x86 version */
|
||||||
|
#define smp_wmb() asm volatile("" ::: "memory")
|
||||||
|
|
||||||
|
#endif
|
|
@ -172,6 +172,7 @@ ssize_t qemu_write_full(int fd, const void *buf, size_t count)
|
||||||
void qemu_set_cloexec(int fd);
|
void qemu_set_cloexec(int fd);
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
int qemu_eventfd(int pipefd[2]);
|
||||||
int qemu_pipe(int pipefd[2]);
|
int qemu_pipe(int pipefd[2]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -158,9 +158,6 @@ struct kvm_para_features {
|
||||||
#endif
|
#endif
|
||||||
#ifdef KVM_CAP_PV_MMU
|
#ifdef KVM_CAP_PV_MMU
|
||||||
{ KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
|
{ KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
|
||||||
#endif
|
|
||||||
#ifdef KVM_CAP_CR3_CACHE
|
|
||||||
{ KVM_CAP_CR3_CACHE, KVM_FEATURE_CR3_CACHE },
|
|
||||||
#endif
|
#endif
|
||||||
{ -1, -1 }
|
{ -1, -1 }
|
||||||
};
|
};
|
||||||
|
|
123
vl.c
123
vl.c
|
@ -270,6 +270,12 @@ uint8_t qemu_uuid[16];
|
||||||
static QEMUBootSetHandler *boot_set_handler;
|
static QEMUBootSetHandler *boot_set_handler;
|
||||||
static void *boot_set_opaque;
|
static void *boot_set_opaque;
|
||||||
|
|
||||||
|
#ifdef SIGRTMIN
|
||||||
|
#define SIG_IPI (SIGRTMIN+4)
|
||||||
|
#else
|
||||||
|
#define SIG_IPI SIGUSR1
|
||||||
|
#endif
|
||||||
|
|
||||||
static int default_serial = 1;
|
static int default_serial = 1;
|
||||||
static int default_parallel = 1;
|
static int default_parallel = 1;
|
||||||
static int default_virtcon = 1;
|
static int default_virtcon = 1;
|
||||||
|
@ -3170,14 +3176,15 @@ static int io_thread_fd = -1;
|
||||||
|
|
||||||
static void qemu_event_increment(void)
|
static void qemu_event_increment(void)
|
||||||
{
|
{
|
||||||
static const char byte = 0;
|
/* Write 8 bytes to be compatible with eventfd. */
|
||||||
|
static uint64_t val = 1;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
if (io_thread_fd == -1)
|
if (io_thread_fd == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = write(io_thread_fd, &byte, sizeof(byte));
|
ret = write(io_thread_fd, &val, sizeof(val));
|
||||||
} while (ret < 0 && errno == EINTR);
|
} while (ret < 0 && errno == EINTR);
|
||||||
|
|
||||||
/* EAGAIN is fine, a read must be pending. */
|
/* EAGAIN is fine, a read must be pending. */
|
||||||
|
@ -3194,7 +3201,7 @@ static void qemu_event_read(void *opaque)
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
|
|
||||||
/* Drain the notify pipe */
|
/* Drain the notify pipe. For eventfd, only 8 bytes will be read. */
|
||||||
do {
|
do {
|
||||||
len = read(fd, buffer, sizeof(buffer));
|
len = read(fd, buffer, sizeof(buffer));
|
||||||
} while ((len == -1 && errno == EINTR) || len == sizeof(buffer));
|
} while ((len == -1 && errno == EINTR) || len == sizeof(buffer));
|
||||||
|
@ -3205,7 +3212,7 @@ static int qemu_event_init(void)
|
||||||
int err;
|
int err;
|
||||||
int fds[2];
|
int fds[2];
|
||||||
|
|
||||||
err = qemu_pipe(fds);
|
err = qemu_eventfd(fds);
|
||||||
if (err == -1)
|
if (err == -1)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
@ -3338,9 +3345,11 @@ static QemuCond qemu_cpu_cond;
|
||||||
static QemuCond qemu_system_cond;
|
static QemuCond qemu_system_cond;
|
||||||
static QemuCond qemu_pause_cond;
|
static QemuCond qemu_pause_cond;
|
||||||
|
|
||||||
static void block_io_signals(void);
|
static void tcg_block_io_signals(void);
|
||||||
|
static void kvm_block_io_signals(CPUState *env);
|
||||||
static void unblock_io_signals(void);
|
static void unblock_io_signals(void);
|
||||||
static int tcg_has_work(void);
|
static int tcg_has_work(void);
|
||||||
|
static int cpu_has_work(CPUState *env);
|
||||||
|
|
||||||
static int qemu_init_main_loop(void)
|
static int qemu_init_main_loop(void)
|
||||||
{
|
{
|
||||||
|
@ -3361,6 +3370,15 @@ static int qemu_init_main_loop(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qemu_wait_io_event_common(CPUState *env)
|
||||||
|
{
|
||||||
|
if (env->stop) {
|
||||||
|
env->stop = 0;
|
||||||
|
env->stopped = 1;
|
||||||
|
qemu_cond_signal(&qemu_pause_cond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void qemu_wait_io_event(CPUState *env)
|
static void qemu_wait_io_event(CPUState *env)
|
||||||
{
|
{
|
||||||
while (!tcg_has_work())
|
while (!tcg_has_work())
|
||||||
|
@ -3377,24 +3395,54 @@ static void qemu_wait_io_event(CPUState *env)
|
||||||
qemu_mutex_unlock(&qemu_fair_mutex);
|
qemu_mutex_unlock(&qemu_fair_mutex);
|
||||||
|
|
||||||
qemu_mutex_lock(&qemu_global_mutex);
|
qemu_mutex_lock(&qemu_global_mutex);
|
||||||
if (env->stop) {
|
qemu_wait_io_event_common(env);
|
||||||
env->stop = 0;
|
}
|
||||||
env->stopped = 1;
|
|
||||||
qemu_cond_signal(&qemu_pause_cond);
|
static void qemu_kvm_eat_signal(CPUState *env, int timeout)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
int r, e;
|
||||||
|
siginfo_t siginfo;
|
||||||
|
sigset_t waitset;
|
||||||
|
|
||||||
|
ts.tv_sec = timeout / 1000;
|
||||||
|
ts.tv_nsec = (timeout % 1000) * 1000000;
|
||||||
|
|
||||||
|
sigemptyset(&waitset);
|
||||||
|
sigaddset(&waitset, SIG_IPI);
|
||||||
|
|
||||||
|
qemu_mutex_unlock(&qemu_global_mutex);
|
||||||
|
r = sigtimedwait(&waitset, &siginfo, &ts);
|
||||||
|
e = errno;
|
||||||
|
qemu_mutex_lock(&qemu_global_mutex);
|
||||||
|
|
||||||
|
if (r == -1 && !(e == EAGAIN || e == EINTR)) {
|
||||||
|
fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qemu_kvm_wait_io_event(CPUState *env)
|
||||||
|
{
|
||||||
|
while (!cpu_has_work(env))
|
||||||
|
qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
|
||||||
|
|
||||||
|
qemu_kvm_eat_signal(env, 0);
|
||||||
|
qemu_wait_io_event_common(env);
|
||||||
|
}
|
||||||
|
|
||||||
static int qemu_cpu_exec(CPUState *env);
|
static int qemu_cpu_exec(CPUState *env);
|
||||||
|
|
||||||
static void *kvm_cpu_thread_fn(void *arg)
|
static void *kvm_cpu_thread_fn(void *arg)
|
||||||
{
|
{
|
||||||
CPUState *env = arg;
|
CPUState *env = arg;
|
||||||
|
|
||||||
block_io_signals();
|
|
||||||
qemu_thread_self(env->thread);
|
qemu_thread_self(env->thread);
|
||||||
if (kvm_enabled())
|
if (kvm_enabled())
|
||||||
kvm_init_vcpu(env);
|
kvm_init_vcpu(env);
|
||||||
|
|
||||||
|
kvm_block_io_signals(env);
|
||||||
|
|
||||||
/* signal CPU creation */
|
/* signal CPU creation */
|
||||||
qemu_mutex_lock(&qemu_global_mutex);
|
qemu_mutex_lock(&qemu_global_mutex);
|
||||||
env->created = 1;
|
env->created = 1;
|
||||||
|
@ -3407,7 +3455,7 @@ static void *kvm_cpu_thread_fn(void *arg)
|
||||||
while (1) {
|
while (1) {
|
||||||
if (cpu_can_run(env))
|
if (cpu_can_run(env))
|
||||||
qemu_cpu_exec(env);
|
qemu_cpu_exec(env);
|
||||||
qemu_wait_io_event(env);
|
qemu_kvm_wait_io_event(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -3419,7 +3467,7 @@ static void *tcg_cpu_thread_fn(void *arg)
|
||||||
{
|
{
|
||||||
CPUState *env = arg;
|
CPUState *env = arg;
|
||||||
|
|
||||||
block_io_signals();
|
tcg_block_io_signals();
|
||||||
qemu_thread_self(env->thread);
|
qemu_thread_self(env->thread);
|
||||||
|
|
||||||
/* signal CPU creation */
|
/* signal CPU creation */
|
||||||
|
@ -3445,7 +3493,7 @@ void qemu_cpu_kick(void *_env)
|
||||||
CPUState *env = _env;
|
CPUState *env = _env;
|
||||||
qemu_cond_broadcast(env->halt_cond);
|
qemu_cond_broadcast(env->halt_cond);
|
||||||
if (kvm_enabled())
|
if (kvm_enabled())
|
||||||
qemu_thread_signal(env->thread, SIGUSR1);
|
qemu_thread_signal(env->thread, SIG_IPI);
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemu_cpu_self(void *_env)
|
int qemu_cpu_self(void *_env)
|
||||||
|
@ -3464,7 +3512,7 @@ static void cpu_signal(int sig)
|
||||||
cpu_exit(cpu_single_env);
|
cpu_exit(cpu_single_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void block_io_signals(void)
|
static void tcg_block_io_signals(void)
|
||||||
{
|
{
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
struct sigaction sigact;
|
struct sigaction sigact;
|
||||||
|
@ -3473,15 +3521,48 @@ static void block_io_signals(void)
|
||||||
sigaddset(&set, SIGUSR2);
|
sigaddset(&set, SIGUSR2);
|
||||||
sigaddset(&set, SIGIO);
|
sigaddset(&set, SIGIO);
|
||||||
sigaddset(&set, SIGALRM);
|
sigaddset(&set, SIGALRM);
|
||||||
|
sigaddset(&set, SIGCHLD);
|
||||||
pthread_sigmask(SIG_BLOCK, &set, NULL);
|
pthread_sigmask(SIG_BLOCK, &set, NULL);
|
||||||
|
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
sigaddset(&set, SIGUSR1);
|
sigaddset(&set, SIG_IPI);
|
||||||
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
|
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
|
||||||
|
|
||||||
memset(&sigact, 0, sizeof(sigact));
|
memset(&sigact, 0, sizeof(sigact));
|
||||||
sigact.sa_handler = cpu_signal;
|
sigact.sa_handler = cpu_signal;
|
||||||
sigaction(SIGUSR1, &sigact, NULL);
|
sigaction(SIG_IPI, &sigact, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dummy_signal(int sig)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kvm_block_io_signals(CPUState *env)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
sigset_t set;
|
||||||
|
struct sigaction sigact;
|
||||||
|
|
||||||
|
sigemptyset(&set);
|
||||||
|
sigaddset(&set, SIGUSR2);
|
||||||
|
sigaddset(&set, SIGIO);
|
||||||
|
sigaddset(&set, SIGALRM);
|
||||||
|
sigaddset(&set, SIGCHLD);
|
||||||
|
sigaddset(&set, SIG_IPI);
|
||||||
|
pthread_sigmask(SIG_BLOCK, &set, NULL);
|
||||||
|
|
||||||
|
pthread_sigmask(SIG_BLOCK, NULL, &set);
|
||||||
|
sigdelset(&set, SIG_IPI);
|
||||||
|
|
||||||
|
memset(&sigact, 0, sizeof(sigact));
|
||||||
|
sigact.sa_handler = dummy_signal;
|
||||||
|
sigaction(SIG_IPI, &sigact, NULL);
|
||||||
|
|
||||||
|
r = kvm_set_signal_mask(env, &set);
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(r));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unblock_io_signals(void)
|
static void unblock_io_signals(void)
|
||||||
|
@ -3495,7 +3576,7 @@ static void unblock_io_signals(void)
|
||||||
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
|
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
|
||||||
|
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
sigaddset(&set, SIGUSR1);
|
sigaddset(&set, SIG_IPI);
|
||||||
pthread_sigmask(SIG_BLOCK, &set, NULL);
|
pthread_sigmask(SIG_BLOCK, &set, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3504,7 +3585,7 @@ static void qemu_signal_lock(unsigned int msecs)
|
||||||
qemu_mutex_lock(&qemu_fair_mutex);
|
qemu_mutex_lock(&qemu_fair_mutex);
|
||||||
|
|
||||||
while (qemu_mutex_trylock(&qemu_global_mutex)) {
|
while (qemu_mutex_trylock(&qemu_global_mutex)) {
|
||||||
qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
|
qemu_thread_signal(tcg_cpu_thread, SIG_IPI);
|
||||||
if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
|
if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3545,7 +3626,7 @@ static void pause_all_vcpus(void)
|
||||||
|
|
||||||
while (penv) {
|
while (penv) {
|
||||||
penv->stop = 1;
|
penv->stop = 1;
|
||||||
qemu_thread_signal(penv->thread, SIGUSR1);
|
qemu_thread_signal(penv->thread, SIG_IPI);
|
||||||
qemu_cpu_kick(penv);
|
qemu_cpu_kick(penv);
|
||||||
penv = (CPUState *)penv->next_cpu;
|
penv = (CPUState *)penv->next_cpu;
|
||||||
}
|
}
|
||||||
|
@ -3554,7 +3635,7 @@ static void pause_all_vcpus(void)
|
||||||
qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
|
qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
|
||||||
penv = first_cpu;
|
penv = first_cpu;
|
||||||
while (penv) {
|
while (penv) {
|
||||||
qemu_thread_signal(penv->thread, SIGUSR1);
|
qemu_thread_signal(penv->thread, SIG_IPI);
|
||||||
penv = (CPUState *)penv->next_cpu;
|
penv = (CPUState *)penv->next_cpu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3567,7 +3648,7 @@ static void resume_all_vcpus(void)
|
||||||
while (penv) {
|
while (penv) {
|
||||||
penv->stop = 0;
|
penv->stop = 0;
|
||||||
penv->stopped = 0;
|
penv->stopped = 0;
|
||||||
qemu_thread_signal(penv->thread, SIGUSR1);
|
qemu_thread_signal(penv->thread, SIG_IPI);
|
||||||
qemu_cpu_kick(penv);
|
qemu_cpu_kick(penv);
|
||||||
penv = (CPUState *)penv->next_cpu;
|
penv = (CPUState *)penv->next_cpu;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue