Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* socket option parsing fix (Daniel)
* SCSI fixes (Fam)
* Readline double-free fix (Greg)
* More HVF attribution fixes (Izik)
* WHPX (Windows Hypervisor Platform Extensions) support (Justin)
* POLLHUP handler (Klim)
* ivshmem fixes (Ladi)
* memfd memory backend (Marc-André)
* improved error message (Marcelo)
* Memory fixes (Peter Xu, Zhecheng)
* Remove obsolete code and comments (Peter M.)
* qdev API improvements (Philippe)
* Add CONFIG_I2C switch (Thomas)

# gpg: Signature made Wed 07 Feb 2018 15:24:08 GMT
# gpg:                using RSA key BFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream: (47 commits)
  Add the WHPX acceleration enlightenments
  Introduce the WHPX impl
  Add the WHPX vcpu API
  Add the Windows Hypervisor Platform accelerator.
  tests/test-filter-redirector: move close()
  tests: use memfd in vhost-user-test
  vhost-user-test: make read-guest-mem setup its own qemu
  tests: keep compiling failing vhost-user tests
  Add memfd based hostmem
  memfd: add hugetlbsize argument
  memfd: add hugetlb support
  memfd: add error argument, instead of perror()
  cpus: join thread when removing a vCPU
  cpus: hvf: unregister thread with RCU
  cpus: tcg: unregister thread with RCU, fix exiting of loop on unplug
  cpus: dummy: unregister thread with RCU, exit loop on unplug
  cpus: kvm: unregister thread with RCU
  cpus: hax: register/unregister thread with RCU, exit loop on unplug
  ivshmem: Disable irqfd on device reset
  ivshmem: Improve MSI irqfd error handling
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

# Conflicts:
#	cpus.c
This commit is contained in:
Peter Maydell
2018-02-07 20:40:36 +00:00
90 changed files with 2464 additions and 347 deletions
+2 -1
View File
@@ -13,12 +13,13 @@ addons:
- libattr1-dev
- libbrlapi-dev
- libcap-ng-dev
- libgcc-6-dev
- libgnutls-dev
- libgtk-3-dev
- libiscsi-dev
- liblttng-ust-dev
- libnfs-dev
- libncurses5-dev
- libnfs-dev
- libnss3-dev
- libpixman-1-dev
- libpng12-dev
+5 -1
View File
@@ -235,6 +235,7 @@ static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot)
{
KVMState *s = kvm_state;
struct kvm_userspace_memory_region mem;
int ret;
mem.slot = slot->slot | (kml->as_id << 16);
mem.guest_phys_addr = slot->start_addr;
@@ -248,7 +249,10 @@ static int kvm_set_user_memory_region(KVMMemoryListener *kml, KVMSlot *slot)
kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
}
mem.memory_size = slot->memory_size;
return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
ret = kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
trace_kvm_set_user_memory(mem.slot, mem.flags, mem.guest_phys_addr,
mem.memory_size, mem.userspace_addr, ret);
return ret;
}
int kvm_destroy_vcpu(CPUState *cpu)
+1
View File
@@ -12,4 +12,5 @@ kvm_irqchip_commit_routes(void) ""
kvm_irqchip_add_msi_route(char *name, int vector, int virq) "dev %s vector %d virq %d"
kvm_irqchip_update_msi_route(int virq) "Updating MSI route virq=%d"
kvm_irqchip_release_virq(int virq) "virq %d"
kvm_set_user_memory(uint32_t slot, uint32_t flags, uint64_t guest_phys_addr, uint64_t memory_size, uint64_t userspace_addr, int ret) "Slot#%d flags=0x%x gpa=0x%"PRIx64 " size=0x%"PRIx64 " ua=0x%"PRIx64 " ret=%d"
+5 -4
View File
@@ -1,4 +1,5 @@
obj-$(call lnot,$(CONFIG_HAX)) += hax-stub.o
obj-$(call lnot,$(CONFIG_HVF)) += hvf-stub.o
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
obj-$(call lnot,$(CONFIG_TCG)) += tcg-stub.o
obj-$(call lnot,$(CONFIG_HAX)) += hax-stub.o
obj-$(call lnot,$(CONFIG_HVF)) += hvf-stub.o
obj-$(call lnot,$(CONFIG_WHPX)) += whpx-stub.o
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
obj-$(call lnot,$(CONFIG_TCG)) += tcg-stub.o
+48
View File
@@ -0,0 +1,48 @@
/*
* QEMU Windows Hypervisor Platform accelerator (WHPX) stub
*
* Copyright Microsoft Corp. 2017
*
* 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-common.h"
#include "cpu.h"
#include "sysemu/whpx.h"
int whpx_init_vcpu(CPUState *cpu)
{
return -1;
}
int whpx_vcpu_exec(CPUState *cpu)
{
return -1;
}
void whpx_destroy_vcpu(CPUState *cpu)
{
}
void whpx_vcpu_kick(CPUState *cpu)
{
}
void whpx_cpu_synchronize_state(CPUState *cpu)
{
}
void whpx_cpu_synchronize_post_reset(CPUState *cpu)
{
}
void whpx_cpu_synchronize_post_init(CPUState *cpu)
{
}
void whpx_cpu_synchronize_pre_loadvm(CPUState *cpu)
{
}
-33
View File
@@ -503,39 +503,6 @@ int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
}
#elif defined(__ia64)
#ifndef __ISR_VALID
/* This ought to be in <bits/siginfo.h>... */
# define __ISR_VALID 1
#endif
int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
{
siginfo_t *info = pinfo;
ucontext_t *uc = puc;
unsigned long ip;
int is_write = 0;
ip = uc->uc_mcontext.sc_ip;
switch (host_signum) {
case SIGILL:
case SIGFPE:
case SIGSEGV:
case SIGBUS:
case SIGTRAP:
if (info->si_code && (info->si_segvflags & __ISR_VALID)) {
/* ISR.W (write-access) is bit 33: */
is_write = (info->si_isr >> 33) & 1;
}
break;
default:
break;
}
return handle_cpu_signal(ip, info, is_write, (sigset_t *)&uc->uc_sigmask);
}
#elif defined(__s390__)
int cpu_signal_handler(int host_signum, void *pinfo,
+2
View File
@@ -8,3 +8,5 @@ common-obj-$(CONFIG_LINUX) += hostmem-file.o
common-obj-y += cryptodev.o
common-obj-y += cryptodev-builtin.o
common-obj-$(CONFIG_LINUX) += hostmem-memfd.o
+170
View File
@@ -0,0 +1,170 @@
/*
* QEMU host memfd memory backend
*
* Copyright (C) 2018 Red Hat Inc
*
* Authors:
* Marc-André Lureau <marcandre.lureau@redhat.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-common.h"
#include "sysemu/hostmem.h"
#include "sysemu/sysemu.h"
#include "qom/object_interfaces.h"
#include "qemu/memfd.h"
#include "qapi/error.h"
#define TYPE_MEMORY_BACKEND_MEMFD "memory-backend-memfd"
#define MEMORY_BACKEND_MEMFD(obj) \
OBJECT_CHECK(HostMemoryBackendMemfd, (obj), TYPE_MEMORY_BACKEND_MEMFD)
typedef struct HostMemoryBackendMemfd HostMemoryBackendMemfd;
struct HostMemoryBackendMemfd {
HostMemoryBackend parent_obj;
bool hugetlb;
uint64_t hugetlbsize;
bool seal;
};
static void
memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
{
HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(backend);
char *name;
int fd;
if (!backend->size) {
error_setg(errp, "can't create backend with size 0");
return;
}
if (host_memory_backend_mr_inited(backend)) {
return;
}
backend->force_prealloc = mem_prealloc;
fd = qemu_memfd_create(TYPE_MEMORY_BACKEND_MEMFD, backend->size,
m->hugetlb, m->hugetlbsize, m->seal ?
F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL : 0,
errp);
if (fd == -1) {
return;
}
name = object_get_canonical_path(OBJECT(backend));
memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
name, backend->size, true, fd, errp);
g_free(name);
}
static bool
memfd_backend_get_hugetlb(Object *o, Error **errp)
{
return MEMORY_BACKEND_MEMFD(o)->hugetlb;
}
static void
memfd_backend_set_hugetlb(Object *o, bool value, Error **errp)
{
MEMORY_BACKEND_MEMFD(o)->hugetlb = value;
}
static void
memfd_backend_set_hugetlbsize(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(obj);
Error *local_err = NULL;
uint64_t value;
if (host_memory_backend_mr_inited(MEMORY_BACKEND(obj))) {
error_setg(&local_err, "cannot change property value");
goto out;
}
visit_type_size(v, name, &value, &local_err);
if (local_err) {
goto out;
}
if (!value) {
error_setg(&local_err, "Property '%s.%s' doesn't take value '%"
PRIu64 "'", object_get_typename(obj), name, value);
goto out;
}
m->hugetlbsize = value;
out:
error_propagate(errp, local_err);
}
static void
memfd_backend_get_hugetlbsize(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(obj);
uint64_t value = m->hugetlbsize;
visit_type_size(v, name, &value, errp);
}
static bool
memfd_backend_get_seal(Object *o, Error **errp)
{
return MEMORY_BACKEND_MEMFD(o)->seal;
}
static void
memfd_backend_set_seal(Object *o, bool value, Error **errp)
{
MEMORY_BACKEND_MEMFD(o)->seal = value;
}
static void
memfd_backend_instance_init(Object *obj)
{
HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(obj);
/* default to sealed file */
m->seal = true;
}
static void
memfd_backend_class_init(ObjectClass *oc, void *data)
{
HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
bc->alloc = memfd_backend_memory_alloc;
object_class_property_add_bool(oc, "hugetlb",
memfd_backend_get_hugetlb,
memfd_backend_set_hugetlb,
&error_abort);
object_class_property_add(oc, "hugetlbsize", "int",
memfd_backend_get_hugetlbsize,
memfd_backend_set_hugetlbsize,
NULL, NULL, &error_abort);
object_class_property_add_bool(oc, "seal",
memfd_backend_get_seal,
memfd_backend_set_seal,
&error_abort);
}
static const TypeInfo memfd_backend_info = {
.name = TYPE_MEMORY_BACKEND_MEMFD,
.parent = TYPE_MEMORY_BACKEND,
.instance_init = memfd_backend_instance_init,
.class_init = memfd_backend_class_init,
.instance_size = sizeof(HostMemoryBackendMemfd),
};
static void register_types(void)
{
type_register_static(&memfd_backend_info);
}
type_init(register_types);
+26 -22
View File
@@ -51,23 +51,6 @@ typedef struct {
static void pty_chr_update_read_handler_locked(Chardev *chr);
static void pty_chr_state(Chardev *chr, int connected);
static gboolean pty_chr_timer(gpointer opaque)
{
struct Chardev *chr = CHARDEV(opaque);
PtyChardev *s = PTY_CHARDEV(opaque);
qemu_mutex_lock(&chr->chr_write_lock);
s->timer_src = NULL;
g_source_unref(s->open_source);
s->open_source = NULL;
if (!s->connected) {
/* Next poll ... */
pty_chr_update_read_handler_locked(chr);
}
qemu_mutex_unlock(&chr->chr_write_lock);
return FALSE;
}
static void pty_chr_timer_cancel(PtyChardev *s)
{
if (s->timer_src) {
@@ -77,6 +60,31 @@ static void pty_chr_timer_cancel(PtyChardev *s)
}
}
static void pty_chr_open_src_cancel(PtyChardev *s)
{
if (s->open_source) {
g_source_destroy(s->open_source);
g_source_unref(s->open_source);
s->open_source = NULL;
}
}
static gboolean pty_chr_timer(gpointer opaque)
{
struct Chardev *chr = CHARDEV(opaque);
PtyChardev *s = PTY_CHARDEV(opaque);
qemu_mutex_lock(&chr->chr_write_lock);
pty_chr_timer_cancel(s);
pty_chr_open_src_cancel(s);
if (!s->connected) {
/* Next poll ... */
pty_chr_update_read_handler_locked(chr);
}
qemu_mutex_unlock(&chr->chr_write_lock);
return FALSE;
}
/* Called with chr_write_lock held. */
static void pty_chr_rearm_timer(Chardev *chr, int ms)
{
@@ -195,11 +203,7 @@ static void pty_chr_state(Chardev *chr, int connected)
PtyChardev *s = PTY_CHARDEV(chr);
if (!connected) {
if (s->open_source) {
g_source_destroy(s->open_source);
g_source_unref(s->open_source);
s->open_source = NULL;
}
pty_chr_open_src_cancel(s);
remove_fd_in_watch(chr);
s->connected = 0;
/* (re-)connect poll interval for idle guests: once per second.
+22
View File
@@ -42,6 +42,7 @@ typedef struct {
QIOChannel *ioc; /* Client I/O channel */
QIOChannelSocket *sioc; /* Client master channel */
QIONetListener *listener;
GSource *hup_source;
QCryptoTLSCreds *tls_creds;
int connected;
int max_size;
@@ -352,6 +353,12 @@ static void tcp_chr_free_connection(Chardev *chr)
s->read_msgfds_num = 0;
}
if (s->hup_source != NULL) {
g_source_destroy(s->hup_source);
g_source_unref(s->hup_source);
s->hup_source = NULL;
}
tcp_set_msgfds(chr, NULL, 0);
remove_fd_in_watch(chr);
object_unref(OBJECT(s->sioc));
@@ -455,6 +462,15 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
return TRUE;
}
static gboolean tcp_chr_hup(QIOChannel *channel,
GIOCondition cond,
void *opaque)
{
Chardev *chr = CHARDEV(opaque);
tcp_chr_disconnect(chr);
return G_SOURCE_REMOVE;
}
static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
{
SocketChardev *s = SOCKET_CHARDEV(chr);
@@ -528,6 +544,12 @@ static void tcp_chr_connect(void *opaque)
tcp_chr_read,
chr, chr->gcontext);
}
s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
chr, NULL);
g_source_attach(s->hup_source, chr->gcontext);
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}
Vendored
+107 -6
View File
@@ -222,6 +222,17 @@ supported_hvf_target() {
return 1
}
supported_whpx_target() {
test "$whpx" = "yes" || return 1
glob "$1" "*-softmmu" || return 1
case "${1%-softmmu}" in
i386|x86_64)
return 0
;;
esac
return 1
}
supported_target() {
case "$1" in
*-softmmu)
@@ -248,6 +259,7 @@ supported_target() {
supported_xen_target "$1" && return 0
supported_hax_target "$1" && return 0
supported_hvf_target "$1" && return 0
supported_whpx_target "$1" && return 0
print_error "TCG disabled, but hardware accelerator not available for '$target'"
return 1
}
@@ -338,10 +350,12 @@ vhost_user=""
kvm="no"
hax="no"
hvf="no"
whpx="no"
rdma=""
gprof="no"
debug_tcg="no"
debug="no"
sanitizers="no"
fortify_source=""
strip_opt="yes"
tcg_interpreter="no"
@@ -636,8 +650,6 @@ elif check_define _ARCH_PPC ; then
fi
elif check_define __mips__ ; then
cpu="mips"
elif check_define __ia64__ ; then
cpu="ia64"
elif check_define __s390__ ; then
if check_define __s390x__ ; then
cpu="s390x"
@@ -995,6 +1007,10 @@ for opt do
strip_opt="no"
fortify_source="no"
;;
--enable-sanitizers) sanitizers="yes"
;;
--disable-sanitizers) sanitizers="no"
;;
--enable-sparse) sparse="yes"
;;
--disable-sparse) sparse="no"
@@ -1055,6 +1071,10 @@ for opt do
;;
--enable-hvf) hvf="yes"
;;
--disable-whpx) whpx="no"
;;
--enable-whpx) whpx="yes"
;;
--disable-tcg-interpreter) tcg_interpreter="no"
;;
--enable-tcg-interpreter) tcg_interpreter="yes"
@@ -1476,6 +1496,7 @@ Advanced options (experts only):
--firmwarepath=PATH search PATH for firmware files
--with-confsuffix=SUFFIX suffix for QEMU data inside datadir/libdir/sysconfdir [$confsuffix]
--enable-debug enable common debug build options
--enable-sanitizers enable default sanitizers
--disable-strip disable stripping binaries
--disable-werror disable compilation abort on warning
--disable-stack-protector disable compiler-provided stack protection
@@ -1553,6 +1574,7 @@ disabled with --disable-FEATURE, default is enabled if available:
kvm KVM acceleration support
hax HAX acceleration support
hvf Hypervisor.framework acceleration support
whpx Windows Hypervisor Platform acceleration support
rdma RDMA-based migration support
vde support for vde network
netmap support for netmap network
@@ -2450,6 +2472,30 @@ if test "$xen_pv_domain_build" = "yes" &&
"which requires Xen support."
fi
##########################################
# Windows Hypervisor Platform accelerator (WHPX) check
if test "$whpx" != "no" ; then
cat > $TMPC << EOF
#include <windows.h>
#include <winhvplatform.h>
#include <winhvemulation.h>
int main(void) {
WHV_CAPABILITY whpx_cap;
WHvGetCapability(WHvCapabilityCodeFeatures, &whpx_cap, sizeof(whpx_cap));
return 0;
}
EOF
if compile_prog "" "-lwinhvplatform -lwinhvemulation" ; then
libs_softmmu="$libs_softmmu -lwinhvplatform -lwinhvemulation"
whpx="yes"
else
if test "$whpx" = "yes"; then
feature_not_found "winhvplatform" "winhvemulation is not installed"
fi
whpx="no"
fi
fi
##########################################
# Sparse probe
if test "$sparse" != "no" ; then
@@ -4743,9 +4789,6 @@ if test "$coroutine_pool" = ""; then
fi
if test "$debug_stack_usage" = "yes"; then
if test "$cpu" = "ia64" -o "$cpu" = "hppa"; then
error_exit "stack usage debugging is not supported for $cpu"
fi
if test "$coroutine_pool" = "yes"; then
echo "WARN: disabling coroutine pool for stack usage debugging"
coroutine_pool=no
@@ -5204,10 +5247,46 @@ if compile_prog "" "" ; then
have_utmpx=yes
fi
##########################################
# checks for sanitizers
write_c_skeleton
have_asan=no
have_ubsan=no
have_asan_iface_h=no
have_asan_iface_fiber=no
if test "$sanitizers" = "yes" ; then
if compile_prog "$CPU_CFLAGS -Werror -fsanitize=address" ""; then
have_asan=yes
fi
if compile_prog "$CPU_CFLAGS -Werror -fsanitize=undefined" ""; then
have_ubsan=yes
fi
if check_include "sanitizer/asan_interface.h" ; then
have_asan_iface_h=yes
fi
cat > $TMPC << EOF
#include <sanitizer/asan_interface.h>
int main(void) {
__sanitizer_start_switch_fiber(0, 0, 0);
return 0;
}
EOF
if compile_prog "$CPU_CFLAGS -Werror -fsanitize=address" "" ; then
have_asan_iface_fiber=yes
fi
fi
##########################################
# End of CC checks
# After here, no more $cc or $ld runs
write_c_skeleton
if test "$gcov" = "yes" ; then
CFLAGS="-fprofile-arcs -ftest-coverage -g $CFLAGS"
LDFLAGS="-fprofile-arcs -ftest-coverage $LDFLAGS"
@@ -5228,6 +5307,20 @@ else
CFLAGS="-O2 $CFLAGS"
fi
if test "$have_asan" = "yes"; then
CFLAGS="-fsanitize=address $CFLAGS"
if test "$have_asan_iface_h" = "no" ; then
echo "ASAN build enabled, but ASAN header missing." \
"Without code annotation, the report may be inferior."
elif test "$have_asan_iface_fiber" = "no" ; then
echo "ASAN build enabled, but ASAN header is too old." \
"Without code annotation, the report may be inferior."
fi
fi
if test "$have_ubsan" = "yes"; then
CFLAGS="-fsanitize=undefined $CFLAGS"
fi
##########################################
# Do we have libnfs
if test "$libnfs" != "no" ; then
@@ -5596,6 +5689,7 @@ echo "Install blobs $blobs"
echo "KVM support $kvm"
echo "HAX support $hax"
echo "HVF support $hvf"
echo "WHPX support $whpx"
echo "TCG support $tcg"
if test "$tcg" = "yes" ; then
echo "TCG debug enabled $debug_tcg"
@@ -5763,7 +5857,7 @@ if test "$mingw32" = "yes" ; then
echo "CONFIG_QGA_NTDDDISK=y" >> $config_host_mak
fi
if test "$guest_agent_msi" = "yes"; then
echo "QEMU_GA_MSI_ENABLED=yes" >> $config_host_mak
echo "QEMU_GA_MSI_ENABLED=yes" >> $config_host_mak
echo "QEMU_GA_MSI_MINGW_DLL_PATH=${QEMU_GA_MSI_MINGW_DLL_PATH}" >> $config_host_mak
echo "QEMU_GA_MSI_WITH_VSS=${QEMU_GA_MSI_WITH_VSS}" >> $config_host_mak
echo "QEMU_GA_MSI_ARCH=${QEMU_GA_MSI_ARCH}" >> $config_host_mak
@@ -6211,6 +6305,10 @@ if test "$valgrind_h" = "yes" ; then
echo "CONFIG_VALGRIND_H=y" >> $config_host_mak
fi
if test "$have_asan_iface_fiber" = "yes" ; then
echo "CONFIG_ASAN_IFACE_FIBER=y" >> $config_host_mak
fi
if test "$has_environ" = "yes" ; then
echo "CONFIG_HAS_ENVIRON=y" >> $config_host_mak
fi
@@ -6692,6 +6790,9 @@ fi
if supported_hvf_target $target; then
echo "CONFIG_HVF=y" >> $config_target_mak
fi
if supported_whpx_target $target; then
echo "CONFIG_WHPX=y" >> $config_target_mak
fi
if test "$target_bigendian" = "yes" ; then
echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
fi
+90 -23
View File
@@ -38,6 +38,7 @@
#include "sysemu/kvm.h"
#include "sysemu/hax.h"
#include "sysemu/hvf.h"
#include "sysemu/whpx.h"
#include "qmp-commands.h"
#include "exec/exec-all.h"
@@ -1205,6 +1206,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
cpu->created = false;
qemu_cond_signal(&qemu_cpu_cond);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
}
@@ -1233,7 +1235,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
while (1) {
do {
qemu_mutex_unlock_iothread();
do {
int sig;
@@ -1245,8 +1247,9 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
}
qemu_mutex_lock_iothread();
qemu_wait_io_event(cpu);
}
} while (!cpu->unplug);
rcu_unregister_thread();
return NULL;
#endif
}
@@ -1465,6 +1468,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
deal_with_unplugged_cpus();
}
rcu_unregister_thread();
return NULL;
}
@@ -1473,6 +1477,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
CPUState *cpu = arg;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
@@ -1484,7 +1489,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
hax_init_vcpu(cpu);
qemu_cond_signal(&qemu_cpu_cond);
while (1) {
do {
if (cpu_can_run(cpu)) {
r = hax_smp_cpu_exec(cpu);
if (r == EXCP_DEBUG) {
@@ -1493,7 +1498,8 @@ static void *qemu_hax_cpu_thread_fn(void *arg)
}
qemu_wait_io_event(cpu);
}
} while (!cpu->unplug || cpu_can_run(cpu));
rcu_unregister_thread();
return NULL;
}
@@ -1536,6 +1542,50 @@ static void *qemu_hvf_cpu_thread_fn(void *arg)
cpu->created = false;
qemu_cond_signal(&qemu_cpu_cond);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
}
static void *qemu_whpx_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
current_cpu = cpu;
r = whpx_init_vcpu(cpu);
if (r < 0) {
fprintf(stderr, "whpx_init_vcpu failed: %s\n", strerror(-r));
exit(1);
}
/* signal CPU creation */
cpu->created = true;
qemu_cond_signal(&qemu_cpu_cond);
do {
if (cpu_can_run(cpu)) {
r = whpx_vcpu_exec(cpu);
if (r == EXCP_DEBUG) {
cpu_handle_guest_debug(cpu);
}
}
while (cpu_thread_is_idle(cpu)) {
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
}
qemu_wait_io_event_common(cpu);
} while (!cpu->unplug || cpu_can_run(cpu));
whpx_destroy_vcpu(cpu);
cpu->created = false;
qemu_cond_signal(&qemu_cpu_cond);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
}
@@ -1599,18 +1649,17 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
/* Ignore everything else? */
break;
}
} else if (cpu->unplug) {
qemu_tcg_destroy_vcpu(cpu);
cpu->created = false;
qemu_cond_signal(&qemu_cpu_cond);
qemu_mutex_unlock_iothread();
return NULL;
}
atomic_mb_set(&cpu->exit_request, 0);
qemu_wait_io_event(cpu);
}
} while (!cpu->unplug || cpu_can_run(cpu));
qemu_tcg_destroy_vcpu(cpu);
cpu->created = false;
qemu_cond_signal(&qemu_cpu_cond);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
}
@@ -1630,9 +1679,11 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
}
#else /* _WIN32 */
if (!qemu_cpu_is_self(cpu)) {
if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) {
error_report("%s: QueueUserAPC failed with error %lu", __func__,
GetLastError());
if (whpx_enabled()) {
whpx_vcpu_kick(cpu);
} else if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) {
fprintf(stderr, "%s: QueueUserAPC failed with error %lu\n",
__func__, GetLastError());
exit(1);
}
}
@@ -1747,19 +1798,14 @@ void resume_all_vcpus(void)
}
}
void cpu_remove(CPUState *cpu)
void cpu_remove_sync(CPUState *cpu)
{
cpu->stop = true;
cpu->unplug = true;
qemu_cpu_kick(cpu);
}
void cpu_remove_sync(CPUState *cpu)
{
cpu_remove(cpu);
while (cpu->created) {
qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
}
qemu_mutex_unlock_iothread();
qemu_thread_join(cpu->thread);
qemu_mutex_lock_iothread();
}
/* For temporary buffers for forming a name */
@@ -1877,6 +1923,25 @@ static void qemu_hvf_start_vcpu(CPUState *cpu)
}
}
static void qemu_whpx_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/WHPX",
cpu->cpu_index);
qemu_thread_create(cpu->thread, thread_name, qemu_whpx_cpu_thread_fn,
cpu, QEMU_THREAD_JOINABLE);
#ifdef _WIN32
cpu->hThread = qemu_thread_get_handle(cpu->thread);
#endif
while (!cpu->created) {
qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
}
}
static void qemu_dummy_start_vcpu(CPUState *cpu)
{
char thread_name[VCPU_THREAD_NAME_SIZE];
@@ -1915,6 +1980,8 @@ void qemu_init_vcpu(CPUState *cpu)
qemu_hvf_start_vcpu(cpu);
} else if (tcg_enabled()) {
qemu_tcg_init_vcpu(cpu);
} else if (whpx_enabled()) {
qemu_whpx_start_vcpu(cpu);
} else {
qemu_dummy_start_vcpu(cpu);
}
+1
View File
@@ -67,6 +67,7 @@ CONFIG_CADENCE=y
CONFIG_XGMAC=y
CONFIG_EXYNOS4=y
CONFIG_PXA2XX=y
CONFIG_I2C=y
CONFIG_BITBANG_I2C=y
CONFIG_FRAMEBUFFER=y
CONFIG_XILINX_SPIPS=y
+1
View File
@@ -62,3 +62,4 @@ CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
CONFIG_PXB=y
CONFIG_ACPI_VMGENID=y
CONFIG_FW_CFG_DMA=y
CONFIG_I2C=y
+1
View File
@@ -34,3 +34,4 @@ CONFIG_ISA_TESTDEV=y
CONFIG_EMPTY_SLOT=y
CONFIG_MIPS_CPS=y
CONFIG_MIPS_ITU=y
CONFIG_I2C=y
+1
View File
@@ -23,6 +23,7 @@ CONFIG_PLATFORM_BUS=y
CONFIG_ETSEC=y
CONFIG_SM501=y
CONFIG_IDE_SII3112=y
CONFIG_I2C=y
# For Macs
CONFIG_MAC=y
+1
View File
@@ -17,3 +17,4 @@ CONFIG_XILINX=y
CONFIG_XILINX_ETHLITE=y
CONFIG_SM501=y
CONFIG_IDE_SII3112=y
CONFIG_I2C=y
+1
View File
@@ -62,3 +62,4 @@ CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
CONFIG_PXB=y
CONFIG_ACPI_VMGENID=y
CONFIG_FW_CFG_DMA=y
CONFIG_I2C=y
+24
View File
@@ -1075,6 +1075,30 @@ static void device_class_init(ObjectClass *class, void *data)
dc->user_creatable = true;
}
void device_class_set_parent_reset(DeviceClass *dc,
DeviceReset dev_reset,
DeviceReset *parent_reset)
{
*parent_reset = dc->reset;
dc->reset = dev_reset;
}
void device_class_set_parent_realize(DeviceClass *dc,
DeviceRealize dev_realize,
DeviceRealize *parent_realize)
{
*parent_realize = dc->realize;
dc->realize = dev_realize;
}
void device_class_set_parent_unrealize(DeviceClass *dc,
DeviceUnrealize dev_unrealize,
DeviceUnrealize *parent_unrealize)
{
*parent_unrealize = dc->unrealize;
dc->unrealize = dev_unrealize;
}
void device_reset(DeviceState *dev)
{
DeviceClass *klass = DEVICE_GET_CLASS(dev);
+1 -1
View File
@@ -98,7 +98,7 @@
#define FIMD_WINCON_BUFSTATUS ((1 << 21) | (1 << 31))
#define FIMD_WINCON_BUF0_STAT ((0 << 21) | (0 << 31))
#define FIMD_WINCON_BUF1_STAT ((1 << 21) | (0 << 31))
#define FIMD_WINCON_BUF2_STAT ((0 << 21) | (1 << 31))
#define FIMD_WINCON_BUF2_STAT ((0 << 21) | (1U << 31))
#define FIMD_WINCON_BUFSELECT ((1 << 20) | (1 << 30))
#define FIMD_WINCON_BUF0_SEL ((0 << 20) | (0 << 30))
#define FIMD_WINCON_BUF1_SEL ((1 << 20) | (0 << 30))

Some files were not shown because too many files have changed in this diff Show More