Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging

* Atomic memslot updates for KVM (Emanuele, David)
* libvhost-user/libvduse warnings fixes (Marcel)
* i386 TCG fixes (Joe, myself)
* Remove compilation errors when -Werror=maybe-uninitialized (Eric)
* fix GLIB_VERSION for cross-compilation (Paolo)

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmO+hUYUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroM5+Qf9HIy2QDdGZJ1fA3AUhp7bCJgotlRF
# 2NMFwo3P/Vwe4qMzzRGkMpsDLFhJx6j1V+sSyeLNxCPtidHccFcmKJOlTqmGeT0k
# HccK07cgAXSZUtvog2xid7PeNpi8OQjKih2Gn/FnN9Tjtad7yMYfXO3O5ttkRV+7
# F8qXBkm4J74l5zs+UMOXUj9y4PudjRFPS0q/lti82eg8mUZ33BZtBkP18Qjq45GM
# wLcemfId0Z6e4s4fmVeTobZ31ltz/B6HDkoD59pQSK6QW2VBIAoO64Hw6FdZnu5W
# PltBsDy5cboKHibkb/ySZQUMhb7UemKFyf7eRWkdlnSSHHFdL/K4x7x7DA==
# =0b+g
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 11 Jan 2023 09:45:42 GMT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# 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

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (29 commits)
  configure: remove backwards-compatibility code
  target/i386: fix operand size of unary SSE operations
  libvduse: Add extra compiler warnings
  libvhost-user: Add extra compiler warnings
  libvhost-user: Fix assignment in vring_set_avail_event
  libvduse: Fix assignment in vring_set_avail_event
  libvduse: Switch to unsigned int for inuse field in struct VduseVirtq
  libvduse: Provide _GNU_SOURCE when compiling outside of QEMU
  libvhost-user: Change dev->postcopy_ufd assignment to make it C90 compliant
  libvhost-user: Declare uffdio_register early to make it C90 compliant
  libvhost-user: Use unsigned int i for some for-loop iterations
  libvhost-user: Cast rc variable to avoid compiler warning
  libvhost-user: Replace typeof with __typeof__
  libvhost-user: Provide _GNU_SOURCE when compiling outside of QEMU
  hw/display: avoid creating empty loadable modules
  enforce use of G_GNUC_PRINTF attributes
  tests: add G_GNUC_PRINTF for various functions
  util/error: add G_GNUC_PRINTF for various functions
  tools/virtiofsd: add G_GNUC_PRINTF for logging functions
  hw/xen: use G_GNUC_PRINTF/SCANF for various functions
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2023-01-12 13:51:36 +00:00
46 changed files with 456 additions and 109 deletions
+3 -6
View File
@@ -6,8 +6,7 @@
script:
- mkdir build
- cd build
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
--disable-user --target-list-exclude="arm-softmmu cris-softmmu
i386-softmmu microblaze-softmmu mips-softmmu mipsel-softmmu
mips64-softmmu ppc-softmmu riscv32-softmmu sh4-softmmu
@@ -32,8 +31,7 @@
script:
- mkdir build
- cd build
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
--disable-tools --enable-${ACCEL:-kvm} $EXTRA_CONFIGURE_OPTS
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
@@ -44,8 +42,7 @@
script:
- mkdir build
- cd build
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
- ../configure --enable-werror --disable-docs $QEMU_CONFIGURE_OPTS
--disable-system --target-list-exclude="aarch64_be-linux-user
alpha-linux-user cris-linux-user m68k-linux-user microblazeel-linux-user
nios2-linux-user or1k-linux-user ppc-linux-user sparc-linux-user
+154
View File
@@ -0,0 +1,154 @@
/*
* Lock to inhibit accelerator ioctls
*
* Copyright (c) 2022 Red Hat Inc.
*
* Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qemu/thread.h"
#include "qemu/main-loop.h"
#include "hw/core/cpu.h"
#include "sysemu/accel-blocker.h"
static QemuLockCnt accel_in_ioctl_lock;
static QemuEvent accel_in_ioctl_event;
void accel_blocker_init(void)
{
qemu_lockcnt_init(&accel_in_ioctl_lock);
qemu_event_init(&accel_in_ioctl_event, false);
}
void accel_ioctl_begin(void)
{
if (likely(qemu_mutex_iothread_locked())) {
return;
}
/* block if lock is taken in kvm_ioctl_inhibit_begin() */
qemu_lockcnt_inc(&accel_in_ioctl_lock);
}
void accel_ioctl_end(void)
{
if (likely(qemu_mutex_iothread_locked())) {
return;
}
qemu_lockcnt_dec(&accel_in_ioctl_lock);
/* change event to SET. If event was BUSY, wake up all waiters */
qemu_event_set(&accel_in_ioctl_event);
}
void accel_cpu_ioctl_begin(CPUState *cpu)
{
if (unlikely(qemu_mutex_iothread_locked())) {
return;
}
/* block if lock is taken in kvm_ioctl_inhibit_begin() */
qemu_lockcnt_inc(&cpu->in_ioctl_lock);
}
void accel_cpu_ioctl_end(CPUState *cpu)
{
if (unlikely(qemu_mutex_iothread_locked())) {
return;
}
qemu_lockcnt_dec(&cpu->in_ioctl_lock);
/* change event to SET. If event was BUSY, wake up all waiters */
qemu_event_set(&accel_in_ioctl_event);
}
static bool accel_has_to_wait(void)
{
CPUState *cpu;
bool needs_to_wait = false;
CPU_FOREACH(cpu) {
if (qemu_lockcnt_count(&cpu->in_ioctl_lock)) {
/* exit the ioctl, if vcpu is running it */
qemu_cpu_kick(cpu);
needs_to_wait = true;
}
}
return needs_to_wait || qemu_lockcnt_count(&accel_in_ioctl_lock);
}
void accel_ioctl_inhibit_begin(void)
{
CPUState *cpu;
/*
* We allow to inhibit only when holding the BQL, so we can identify
* when an inhibitor wants to issue an ioctl easily.
*/
g_assert(qemu_mutex_iothread_locked());
/* Block further invocations of the ioctls outside the BQL. */
CPU_FOREACH(cpu) {
qemu_lockcnt_lock(&cpu->in_ioctl_lock);
}
qemu_lockcnt_lock(&accel_in_ioctl_lock);
/* Keep waiting until there are running ioctls */
while (true) {
/* Reset event to FREE. */
qemu_event_reset(&accel_in_ioctl_event);
if (accel_has_to_wait()) {
/*
* If event is still FREE, and there are ioctls still in progress,
* wait.
*
* If an ioctl finishes before qemu_event_wait(), it will change
* the event state to SET. This will prevent qemu_event_wait() from
* blocking, but it's not a problem because if other ioctls are
* still running the loop will iterate once more and reset the event
* status to FREE so that it can wait properly.
*
* If an ioctls finishes while qemu_event_wait() is blocking, then
* it will be waken up, but also here the while loop makes sure
* to re-enter the wait if there are other running ioctls.
*/
qemu_event_wait(&accel_in_ioctl_event);
} else {
/* No ioctl is running */
return;
}
}
}
void accel_ioctl_inhibit_end(void)
{
CPUState *cpu;
qemu_lockcnt_unlock(&accel_in_ioctl_lock);
CPU_FOREACH(cpu) {
qemu_lockcnt_unlock(&cpu->in_ioctl_lock);
}
}
+97 -11
View File
@@ -31,6 +31,7 @@
#include "sysemu/kvm_int.h"
#include "sysemu/runstate.h"
#include "sysemu/cpus.h"
#include "sysemu/accel-blocker.h"
#include "qemu/bswap.h"
#include "exec/memory.h"
#include "exec/ram_addr.h"
@@ -46,6 +47,7 @@
#include "sysemu/hw_accel.h"
#include "kvm-cpus.h"
#include "sysemu/dirtylimit.h"
#include "qemu/range.h"
#include "hw/boards.h"
#include "monitor/stats.h"
@@ -1292,6 +1294,7 @@ void kvm_set_max_memslot_size(hwaddr max_slot_size)
kvm_max_slot_size = max_slot_size;
}
/* Called with KVMMemoryListener.slots_lock held */
static void kvm_set_phys_mem(KVMMemoryListener *kml,
MemoryRegionSection *section, bool add)
{
@@ -1326,14 +1329,12 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
ram = memory_region_get_ram_ptr(mr) + mr_offset;
ram_start_offset = memory_region_get_ram_addr(mr) + mr_offset;
kvm_slots_lock();
if (!add) {
do {
slot_size = MIN(kvm_max_slot_size, size);
mem = kvm_lookup_matching_slot(kml, start_addr, slot_size);
if (!mem) {
goto out;
return;
}
if (mem->flags & KVM_MEM_LOG_DIRTY_PAGES) {
/*
@@ -1371,7 +1372,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
start_addr += slot_size;
size -= slot_size;
} while (size);
goto out;
return;
}
/* register the new slot */
@@ -1396,9 +1397,6 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml,
ram += slot_size;
size -= slot_size;
} while (size);
out:
kvm_slots_unlock();
}
static void *kvm_dirty_ring_reaper_thread(void *data)
@@ -1455,18 +1453,95 @@ static void kvm_region_add(MemoryListener *listener,
MemoryRegionSection *section)
{
KVMMemoryListener *kml = container_of(listener, KVMMemoryListener, listener);
KVMMemoryUpdate *update;
memory_region_ref(section->mr);
kvm_set_phys_mem(kml, section, true);
update = g_new0(KVMMemoryUpdate, 1);
update->section = *section;
QSIMPLEQ_INSERT_TAIL(&kml->transaction_add, update, next);
}
static void kvm_region_del(MemoryListener *listener,
MemoryRegionSection *section)
{
KVMMemoryListener *kml = container_of(listener, KVMMemoryListener, listener);
KVMMemoryUpdate *update;
kvm_set_phys_mem(kml, section, false);
memory_region_unref(section->mr);
update = g_new0(KVMMemoryUpdate, 1);
update->section = *section;
QSIMPLEQ_INSERT_TAIL(&kml->transaction_del, update, next);
}
static void kvm_region_commit(MemoryListener *listener)
{
KVMMemoryListener *kml = container_of(listener, KVMMemoryListener,
listener);
KVMMemoryUpdate *u1, *u2;
bool need_inhibit = false;
if (QSIMPLEQ_EMPTY(&kml->transaction_add) &&
QSIMPLEQ_EMPTY(&kml->transaction_del)) {
return;
}
/*
* We have to be careful when regions to add overlap with ranges to remove.
* We have to simulate atomic KVM memslot updates by making sure no ioctl()
* is currently active.
*
* The lists are order by addresses, so it's easy to find overlaps.
*/
u1 = QSIMPLEQ_FIRST(&kml->transaction_del);
u2 = QSIMPLEQ_FIRST(&kml->transaction_add);
while (u1 && u2) {
Range r1, r2;
range_init_nofail(&r1, u1->section.offset_within_address_space,
int128_get64(u1->section.size));
range_init_nofail(&r2, u2->section.offset_within_address_space,
int128_get64(u2->section.size));
if (range_overlaps_range(&r1, &r2)) {
need_inhibit = true;
break;
}
if (range_lob(&r1) < range_lob(&r2)) {
u1 = QSIMPLEQ_NEXT(u1, next);
} else {
u2 = QSIMPLEQ_NEXT(u2, next);
}
}
kvm_slots_lock();
if (need_inhibit) {
accel_ioctl_inhibit_begin();
}
/* Remove all memslots before adding the new ones. */
while (!QSIMPLEQ_EMPTY(&kml->transaction_del)) {
u1 = QSIMPLEQ_FIRST(&kml->transaction_del);
QSIMPLEQ_REMOVE_HEAD(&kml->transaction_del, next);
kvm_set_phys_mem(kml, &u1->section, false);
memory_region_unref(u1->section.mr);
g_free(u1);
}
while (!QSIMPLEQ_EMPTY(&kml->transaction_add)) {
u1 = QSIMPLEQ_FIRST(&kml->transaction_add);
QSIMPLEQ_REMOVE_HEAD(&kml->transaction_add, next);
memory_region_ref(u1->section.mr);
kvm_set_phys_mem(kml, &u1->section, true);
g_free(u1);
}
if (need_inhibit) {
accel_ioctl_inhibit_end();
}
kvm_slots_unlock();
}
static void kvm_log_sync(MemoryListener *listener,
@@ -1610,8 +1685,12 @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
kml->slots[i].slot = i;
}
QSIMPLEQ_INIT(&kml->transaction_add);
QSIMPLEQ_INIT(&kml->transaction_del);
kml->listener.region_add = kvm_region_add;
kml->listener.region_del = kvm_region_del;
kml->listener.commit = kvm_region_commit;
kml->listener.log_start = kvm_log_start;
kml->listener.log_stop = kvm_log_stop;
kml->listener.priority = 10;
@@ -2310,6 +2389,7 @@ static int kvm_init(MachineState *ms)
assert(TARGET_PAGE_SIZE <= qemu_real_host_page_size());
s->sigmask_len = 8;
accel_blocker_init();
#ifdef KVM_CAP_SET_GUEST_DEBUG
QTAILQ_INIT(&s->kvm_sw_breakpoints);
@@ -3014,7 +3094,9 @@ int kvm_vm_ioctl(KVMState *s, int type, ...)
va_end(ap);
trace_kvm_vm_ioctl(type, arg);
accel_ioctl_begin();
ret = ioctl(s->vmfd, type, arg);
accel_ioctl_end();
if (ret == -1) {
ret = -errno;
}
@@ -3032,7 +3114,9 @@ int kvm_vcpu_ioctl(CPUState *cpu, int type, ...)
va_end(ap);
trace_kvm_vcpu_ioctl(cpu->cpu_index, type, arg);
accel_cpu_ioctl_begin(cpu);
ret = ioctl(cpu->kvm_fd, type, arg);
accel_cpu_ioctl_end(cpu);
if (ret == -1) {
ret = -errno;
}
@@ -3050,7 +3134,9 @@ int kvm_device_ioctl(int fd, int type, ...)
va_end(ap);
trace_kvm_device_ioctl(fd, type, arg);
accel_ioctl_begin();
ret = ioctl(fd, type, arg);
accel_ioctl_end();
if (ret == -1) {
ret = -errno;
}
+1 -1
View File
@@ -1,4 +1,4 @@
specific_ss.add(files('accel-common.c'))
specific_ss.add(files('accel-common.c', 'accel-blocker.c'))
softmmu_ss.add(files('accel-softmmu.c'))
user_ss.add(files('accel-user.c'))
+2 -13
View File
@@ -238,7 +238,6 @@ static void qemu_chr_open_pp_fd(Chardev *chr,
}
#endif
#ifdef HAVE_CHARDEV_PARPORT
static void qmp_chardev_open_parallel(Chardev *chr,
ChardevBackend *backend,
bool *be_opened,
@@ -276,29 +275,21 @@ static void char_parallel_class_init(ObjectClass *oc, void *data)
cc->parse = qemu_chr_parse_parallel;
cc->open = qmp_chardev_open_parallel;
#if defined(__linux__)
cc->chr_ioctl = pp_ioctl;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
defined(__DragonFly__)
cc->chr_ioctl = pp_ioctl;
#endif
}
static void char_parallel_finalize(Object *obj)
{
#if defined(__linux__)
Chardev *chr = CHARDEV(obj);
ParallelChardev *drv = PARALLEL_CHARDEV(chr);
int fd = drv->fd;
#if defined(__linux__)
pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
ioctl(fd, PPRELEASE);
#endif
close(fd);
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
defined(__DragonFly__)
/* FIXME: close fd? */
#endif
}
static const TypeInfo char_parallel_type_info = {
@@ -315,5 +306,3 @@ static void register_types(void)
}
type_init(register_types);
#endif
+4 -1
View File
@@ -14,9 +14,12 @@ chardev_ss.add(files(
))
chardev_ss.add(when: 'CONFIG_POSIX', if_true: [files(
'char-fd.c',
'char-parallel.c',
'char-pty.c',
), util])
if targetos in ['linux', 'gnu/kfreebsd', 'freebsd', 'dragonfly']
chardev_ss.add(files('char-parallel.c'))
endif
chardev_ss.add(when: 'CONFIG_WIN32', if_true: files(
'char-console.c',
'char-win-stdio.c',
Vendored
+2 -11
View File
@@ -1183,6 +1183,7 @@ add_to warn_flags -Wnested-externs
add_to warn_flags -Wendif-labels
add_to warn_flags -Wexpansion-to-defined
add_to warn_flags -Wimplicit-fallthrough=2
add_to warn_flags -Wmissing-format-attribute
nowarn_flags=
add_to nowarn_flags -Wno-initializer-overrides
@@ -2375,7 +2376,7 @@ echo "QEMU_OBJCFLAGS=$QEMU_OBJCFLAGS" >> $config_host_mak
echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
echo "GLIB_LIBS=$glib_libs" >> $config_host_mak
echo "GLIB_BINDIR=$glib_bindir" >> $config_host_mak
echo "GLIB_VERSION=$(pkg-config --modversion glib-2.0)" >> $config_host_mak
echo "GLIB_VERSION=$($pkg_config --modversion glib-2.0)" >> $config_host_mak
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
echo "EXESUF=$EXESUF" >> $config_host_mak
@@ -2567,16 +2568,6 @@ if test "$skip_meson" = no; then
if test "$?" -ne 0 ; then
error_exit "meson setup failed"
fi
else
if test -f meson-private/cmd_line.txt; then
# Adjust old command line options whose type was changed
# Avoids having to use "setup --wipe" when Meson is upgraded
perl -i -ne '
s/^gettext = true$/gettext = auto/;
s/^gettext = false$/gettext = disabled/;
/^b_staticpic/ && next;
print;' meson-private/cmd_line.txt
fi
fi
# Save the configure command line for later reuse.
+2 -1
View File
@@ -239,7 +239,8 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
}
}
static int gstring_printf(FILE *stream, const char *fmt, ...)
static int G_GNUC_PRINTF(2, 3)
gstring_printf(FILE *stream, const char *fmt, ...)
{
/* We abuse the FILE parameter to pass a GString. */
GString *s = (GString *)stream;
+2
View File
@@ -238,6 +238,7 @@ static void cpu_common_initfn(Object *obj)
cpu->cflags_next_tb = -1;
qemu_mutex_init(&cpu->work_mutex);
qemu_lockcnt_init(&cpu->in_ioctl_lock);
QSIMPLEQ_INIT(&cpu->work_list);
QTAILQ_INIT(&cpu->breakpoints);
QTAILQ_INIT(&cpu->watchpoints);
@@ -249,6 +250,7 @@ static void cpu_common_finalize(Object *obj)
{
CPUState *cpu = CPU(obj);
qemu_lockcnt_destroy(&cpu->in_ioctl_lock);
qemu_mutex_destroy(&cpu->work_mutex);
}
+12 -8
View File
@@ -73,10 +73,12 @@ if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
virtio_gpu_ss.add(when: 'CONFIG_VHOST_USER_GPU', if_true: files('vhost-user-gpu.c'))
hw_display_modules += {'virtio-gpu': virtio_gpu_ss}
virtio_gpu_gl_ss = ss.source_set()
virtio_gpu_gl_ss.add(when: ['CONFIG_VIRTIO_GPU', virgl, opengl],
if_true: [files('virtio-gpu-gl.c', 'virtio-gpu-virgl.c'), pixman, virgl])
hw_display_modules += {'virtio-gpu-gl': virtio_gpu_gl_ss}
if virgl.found() and opengl.found()
virtio_gpu_gl_ss = ss.source_set()
virtio_gpu_gl_ss.add(when: ['CONFIG_VIRTIO_GPU', virgl, opengl],
if_true: [files('virtio-gpu-gl.c', 'virtio-gpu-virgl.c'), pixman, virgl])
hw_display_modules += {'virtio-gpu-gl': virtio_gpu_gl_ss}
endif
endif
if config_all_devices.has_key('CONFIG_VIRTIO_PCI')
@@ -87,10 +89,12 @@ if config_all_devices.has_key('CONFIG_VIRTIO_PCI')
if_true: files('vhost-user-gpu-pci.c'))
hw_display_modules += {'virtio-gpu-pci': virtio_gpu_pci_ss}
virtio_gpu_pci_gl_ss = ss.source_set()
virtio_gpu_pci_gl_ss.add(when: ['CONFIG_VIRTIO_GPU', 'CONFIG_VIRTIO_PCI', virgl, opengl],
if_true: [files('virtio-gpu-pci-gl.c'), pixman])
hw_display_modules += {'virtio-gpu-pci-gl': virtio_gpu_pci_gl_ss}
if virgl.found() and opengl.found()
virtio_gpu_pci_gl_ss = ss.source_set()
virtio_gpu_pci_gl_ss.add(when: ['CONFIG_VIRTIO_GPU', 'CONFIG_VIRTIO_PCI', virgl, opengl],
if_true: [files('virtio-gpu-pci-gl.c'), pixman])
hw_display_modules += {'virtio-gpu-pci-gl': virtio_gpu_pci_gl_ss}
endif
endif
if config_all_devices.has_key('CONFIG_VIRTIO_VGA')
+1
View File
@@ -561,6 +561,7 @@ void xen_device_backend_printf(XenDevice *xendev, const char *key,
}
}
G_GNUC_SCANF(3, 4)
static int xen_device_backend_scanf(XenDevice *xendev, const char *key,
const char *fmt, ...)
{
+1
View File
@@ -196,6 +196,7 @@ const char *xenbus_strstate(enum xenbus_state state)
* 2 == noisy debug messages (logfile only).
* 3 == will flood your log (logfile only).
*/
G_GNUC_PRINTF(3, 0)
static void xen_pv_output_msg(struct XenLegacyDevice *xendev,
FILE *f, const char *fmt, va_list args)
{
+3
View File
@@ -398,6 +398,9 @@ struct CPUState {
uint32_t kvm_fetch_index;
uint64_t dirty_pages;
/* Use by accel-block: CPU is executing an ioctl() */
QemuLockCnt in_ioctl_lock;
/* Used for events with 'vcpu' and *without* the 'disabled' properties */
DECLARE_BITMAP(trace_dstate_delayed, CPU_TRACE_DSTATE_MAX_EVENTS);
DECLARE_BITMAP(trace_dstate, CPU_TRACE_DSTATE_MAX_EVENTS);
+4 -2
View File
@@ -31,10 +31,12 @@ void xs_node_printf(struct xs_handle *xsh, xs_transaction_t tid,
/* Read from node/key unless node is empty, in which case read from key */
int xs_node_vscanf(struct xs_handle *xsh, xs_transaction_t tid,
const char *node, const char *key, Error **errp,
const char *fmt, va_list ap);
const char *fmt, va_list ap)
G_GNUC_SCANF(6, 0);
int xs_node_scanf(struct xs_handle *xsh, xs_transaction_t tid,
const char *node, const char *key, Error **errp,
const char *fmt, ...);
const char *fmt, ...)
G_GNUC_SCANF(6, 7);
/* Watch node/key unless node is empty, in which case watch key */
void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
+2 -1
View File
@@ -94,7 +94,8 @@ void xen_device_frontend_printf(XenDevice *xendev, const char *key,
G_GNUC_PRINTF(3, 4);
int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
const char *fmt, ...);
const char *fmt, ...)
G_GNUC_SCANF(3, 4);
void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
Error **errp);
-5
View File
@@ -427,11 +427,6 @@ void qemu_anon_ram_free(void *ptr, size_t size);
#define HAVE_CHARDEV_SERIAL 1
#endif
#if defined(__linux__) || defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || defined(__DragonFly__)
#define HAVE_CHARDEV_PARPORT 1
#endif
#if defined(__HAIKU__)
#define SIGIO SIGPOLL
#endif
+56
View File
@@ -0,0 +1,56 @@
/*
* Accelerator blocking API, to prevent new ioctls from starting and wait the
* running ones finish.
* This mechanism differs from pause/resume_all_vcpus() in that it does not
* release the BQL.
*
* Copyright (c) 2022 Red Hat Inc.
*
* Author: Emanuele Giuseppe Esposito <eesposit@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.
*/
#ifndef ACCEL_BLOCKER_H
#define ACCEL_BLOCKER_H
#include "qemu/osdep.h"
#include "sysemu/cpus.h"
extern void accel_blocker_init(void);
/*
* accel_{cpu_}ioctl_begin/end:
* Mark when ioctl is about to run or just finished.
*
* accel_{cpu_}ioctl_begin will block after accel_ioctl_inhibit_begin() is
* called, preventing new ioctls to run. They will continue only after
* accel_ioctl_inibith_end().
*/
extern void accel_ioctl_begin(void);
extern void accel_ioctl_end(void);
extern void accel_cpu_ioctl_begin(CPUState *cpu);
extern void accel_cpu_ioctl_end(CPUState *cpu);
/*
* accel_ioctl_inhibit_begin: start critical section
*
* This function makes sure that:
* 1) incoming accel_{cpu_}ioctl_begin() calls block
* 2) wait that all ioctls that were already running reach
* accel_{cpu_}ioctl_end(), kicking vcpus if necessary.
*
* This allows the caller to access shared data or perform operations without
* worrying of concurrent vcpus accesses.
*/
extern void accel_ioctl_inhibit_begin(void);
/*
* accel_ioctl_inhibit_end: end critical section started by
* accel_ioctl_inhibit_begin()
*
* This function allows blocked accel_{cpu_}ioctl_begin() to continue.
*/
extern void accel_ioctl_inhibit_end(void);
#endif /* ACCEL_BLOCKER_H */
+8
View File
@@ -12,6 +12,7 @@
#include "exec/memory.h"
#include "qapi/qapi-types-common.h"
#include "qemu/accel.h"
#include "qemu/queue.h"
#include "sysemu/kvm.h"
typedef struct KVMSlot
@@ -31,10 +32,17 @@ typedef struct KVMSlot
ram_addr_t ram_start_offset;
} KVMSlot;
typedef struct KVMMemoryUpdate {
QSIMPLEQ_ENTRY(KVMMemoryUpdate) next;
MemoryRegionSection section;
} KVMMemoryUpdate;
typedef struct KVMMemoryListener {
MemoryListener listener;
KVMSlot *slots;
int as_id;
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add;
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_del;
} KVMMemoryListener;
#define KVM_MSI_HASHTAB_SIZE 256
+7 -2
View File
@@ -16,6 +16,10 @@
* later. See the COPYING file in the top-level directory.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
@@ -97,7 +101,7 @@ struct VduseVirtq {
uint16_t signalled_used;
bool signalled_used_valid;
int index;
int inuse;
unsigned int inuse;
bool ready;
int fd;
VduseDev *dev;
@@ -578,7 +582,8 @@ void vduse_queue_notify(VduseVirtq *vq)
static inline void vring_set_avail_event(VduseVirtq *vq, uint16_t val)
{
*((uint16_t *)&vq->vring.used->ring[vq->vring.num]) = htole16(val);
uint16_t val_le = htole16(val);
memcpy(&vq->vring.used->ring[vq->vring.num], &val_le, sizeof(uint16_t));
}
static bool vduse_queue_map_single_desc(VduseVirtq *vq, unsigned int *p_num_sg,
+7 -1
View File
@@ -1,6 +1,12 @@
project('libvduse', 'c',
license: 'GPL-2.0-or-later',
default_options: ['c_std=gnu99'])
default_options: ['warning_level=1', 'c_std=gnu99'])
cc = meson.get_compiler('c')
add_project_arguments(cc.get_supported_arguments('-Wsign-compare',
'-Wdeclaration-after-statement',
'-Wstrict-aliasing'),
native: false, language: 'c')
libvduse = static_library('vduse',
files('libvduse.c'),

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