mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
+2
-1
@@ -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
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -62,3 +62,4 @@ CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
|
||||
CONFIG_PXB=y
|
||||
CONFIG_ACPI_VMGENID=y
|
||||
CONFIG_FW_CFG_DMA=y
|
||||
CONFIG_I2C=y
|
||||
|
||||
@@ -34,3 +34,4 @@ CONFIG_ISA_TESTDEV=y
|
||||
CONFIG_EMPTY_SLOT=y
|
||||
CONFIG_MIPS_CPS=y
|
||||
CONFIG_MIPS_ITU=y
|
||||
CONFIG_I2C=y
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,3 +17,4 @@ CONFIG_XILINX=y
|
||||
CONFIG_XILINX_ETHLITE=y
|
||||
CONFIG_SM501=y
|
||||
CONFIG_IDE_SII3112=y
|
||||
CONFIG_I2C=y
|
||||
|
||||
@@ -62,3 +62,4 @@ CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
|
||||
CONFIG_PXB=y
|
||||
CONFIG_ACPI_VMGENID=y
|
||||
CONFIG_FW_CFG_DMA=y
|
||||
CONFIG_I2C=y
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user