aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2023-01-12 13:51:36 +0000
committerPeter Maydell <peter.maydell@linaro.org>2023-01-12 13:51:36 +0000
commit3db29dcac23da85486704ef9e7a8e7217f7829cd (patch)
tree22b79bebadf2616dd733f6ed0223cdba7b0cd43d
parenta35fa426ee9d88a1d335e6681e4f936edb2f24ee (diff)
parent75cc286485742feeb00f4b446f5682765792323e (diff)
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>
-rw-r--r--.gitlab-ci.d/crossbuild-template.yml9
-rw-r--r--accel/accel-blocker.c154
-rw-r--r--accel/kvm/kvm-all.c108
-rw-r--r--accel/meson.build2
-rw-r--r--chardev/char-parallel.c15
-rw-r--r--chardev/meson.build5
-rwxr-xr-xconfigure13
-rw-r--r--disas.c3
-rw-r--r--hw/core/cpu-common.c2
-rw-r--r--hw/display/meson.build20
-rw-r--r--hw/xen/xen-bus.c1
-rw-r--r--hw/xen/xen_pvdev.c1
-rw-r--r--include/hw/core/cpu.h3
-rw-r--r--include/hw/xen/xen-bus-helper.h6
-rw-r--r--include/hw/xen/xen-bus.h3
-rw-r--r--include/qemu/osdep.h5
-rw-r--r--include/sysemu/accel-blocker.h56
-rw-r--r--include/sysemu/kvm_int.h8
-rw-r--r--subprojects/libvduse/libvduse.c9
-rw-r--r--subprojects/libvduse/meson.build8
-rw-r--r--subprojects/libvhost-user/libvhost-user.c36
-rw-r--r--subprojects/libvhost-user/meson.build8
-rw-r--r--target/i386/ops_sse.h4
-rw-r--r--target/i386/tcg/decode-new.c.inc11
-rw-r--r--target/i386/tcg/seg_helper.c8
-rw-r--r--tests/fp/meson.build1
-rw-r--r--tests/qtest/ahci-test.c3
-rw-r--r--tests/qtest/arm-cpu-features.c1
-rw-r--r--tests/qtest/erst-test.c2
-rw-r--r--tests/qtest/ide-test.c3
-rw-r--r--tests/qtest/ivshmem-test.c4
-rw-r--r--tests/qtest/libqmp.c2
-rw-r--r--tests/qtest/libqos/libqos-pc.h6
-rw-r--r--tests/qtest/libqos/libqos-spapr.h6
-rw-r--r--tests/qtest/libqos/libqos.h6
-rw-r--r--tests/qtest/libqos/virtio-9p.c1
-rw-r--r--tests/qtest/migration-helpers.h1
-rw-r--r--tests/qtest/rtas-test.c2
-rw-r--r--tests/qtest/usb-hcd-uhci-test.c4
-rw-r--r--tests/unit/test-qmp-cmds.c13
-rw-r--r--tools/virtiofsd/fuse_log.c1
-rw-r--r--tools/virtiofsd/fuse_log.h6
-rw-r--r--tools/virtiofsd/passthrough_ll.c1
-rw-r--r--util/error-report.c1
-rw-r--r--util/error.c1
-rw-r--r--util/meson.build2
46 files changed, 456 insertions, 109 deletions
diff --git a/.gitlab-ci.d/crossbuild-template.yml b/.gitlab-ci.d/crossbuild-template.yml
index 5e8892fd49..6d709628f1 100644
--- a/.gitlab-ci.d/crossbuild-template.yml
+++ b/.gitlab-ci.d/crossbuild-template.yml
@@ -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
diff --git a/accel/accel-blocker.c b/accel/accel-blocker.c
new file mode 100644
index 0000000000..1e7f423462
--- /dev/null
+++ b/accel/accel-blocker.c
@@ -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);
+ }
+}
+
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index e86c33e0e6..7e6a6076b1 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -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;
+
+ update = g_new0(KVMMemoryUpdate, 1);
+ update->section = *section;
- memory_region_ref(section->mr);
- kvm_set_phys_mem(kml, section, true);
+ 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;
+
+ 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, section, false);
- memory_region_unref(section->mr);
+ 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;
}
diff --git a/accel/meson.build b/accel/meson.build
index 3a480cc2ef..49558dd232 100644
--- a/accel/meson.build
+++ b/accel/meson.build
@@ -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'))
diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c
index 05e7efbd6c..a5164f975a 100644
--- a/chardev/char-parallel.c
+++ b/chardev/char-parallel.c
@@ -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
diff --git a/chardev/meson.build b/chardev/meson.build
index 664f77b887..789b50056a 100644
--- a/chardev/meson.build
+++ b/chardev/meson.build
@@ -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',
diff --git a/configure b/configure
index 2281892657..9e407ce2e3 100755
--- a/configure
+++ b/configure
@@ -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.
diff --git a/disas.c b/disas.c
index 94d3b45042..3b31315f40 100644
--- a/disas.c
+++ b/disas.c
@@ -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;
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
index b177e761f0..5ccc3837b6 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -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);
}
diff --git a/hw/display/meson.build b/hw/display/meson.build
index 7a725ed80e..f860c2c562 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -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')
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 645a29a5a0..df3f6b9ae0 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -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, ...)
{
diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c
index 037152f063..1a5177b354 100644
--- a/hw/xen/xen_pvdev.c
+++ b/hw/xen/xen_pvdev.c
@@ -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)
{
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 8830546121..2417597236 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -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);
diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helper.h
index 629a904d1a..8782f30550 100644
--- a/include/hw/xen/xen-bus-helper.h
+++ b/include/hw/xen/xen-bus-helper.h
@@ -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,
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 713e763348..4d966a2dbb 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -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);
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 7d059ad526..bd23a08595 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -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
diff --git a/include/sysemu/accel-blocker.h b/include/sysemu/accel-blocker.h
new file mode 100644
index 0000000000..72020529ef
--- /dev/null
+++ b/include/sysemu/accel-blocker.h
@@ -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 */
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index 3b4adcdc10..60b520a13e 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -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
diff --git a/subprojects/libvduse/libvduse.c b/subprojects/libvduse/libvduse.c
index e089d4d546..377959a0b4 100644
--- a/subprojects/libvduse/libvduse.c
+++ b/subprojects/libvduse/libvduse.c
@@ -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,
diff --git a/subprojects/libvduse/meson.build b/subprojects/libvduse/meson.build
index ba08f5ee1a..3e3b53da33 100644
--- a/subprojects/libvduse/meson.build
+++ b/subprojects/libvduse/meson.build
@@ -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'),
diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c
index d6ee6e7d91..fc69783d2b 100644
--- a/subprojects/libvhost-user/libvhost-user.c
+++ b/subprojects/libvhost-user/libvhost-user.c
@@ -13,6 +13,10 @@
* later. See the COPYING file in the top-level directory.
*/
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
/* this code avoids GLib dependency */
#include <stdlib.h>
#include <stdio.h>
@@ -58,8 +62,8 @@
#endif /* !__GNUC__ */
#ifndef MIN
#define MIN(x, y) ({ \
- typeof(x) _min1 = (x); \
- typeof(y) _min2 = (y); \
+ __typeof__(x) _min1 = (x); \
+ __typeof__(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
#endif
@@ -188,7 +192,7 @@ vu_panic(VuDev *dev, const char *msg, ...)
void *
vu_gpa_to_va(VuDev *dev, uint64_t *plen, uint64_t guest_addr)
{
- int i;
+ unsigned int i;
if (*plen == 0) {
return NULL;
@@ -214,7 +218,7 @@ vu_gpa_to_va(VuDev *dev, uint64_t *plen, uint64_t guest_addr)
static void *
qva_to_va(VuDev *dev, uint64_t qemu_addr)
{
- int i;
+ unsigned int i;
/* Find matching memory region. */
for (i = 0; i < dev->nregions; i++) {
@@ -335,7 +339,7 @@ vu_message_read_default(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
goto fail;
}
- assert(rc == vmsg->size);
+ assert((uint32_t)rc == vmsg->size);
}
return true;
@@ -617,11 +621,13 @@ map_ring(VuDev *dev, VuVirtq *vq)
static bool
generate_faults(VuDev *dev) {
- int i;
+ unsigned int i;
for (i = 0; i < dev->nregions; i++) {
VuDevRegion *dev_region = &dev->regions[i];
int ret;
#ifdef UFFDIO_REGISTER
+ struct uffdio_register reg_struct;
+
/*
* We should already have an open ufd. Mark each memory
* range as ufd.
@@ -655,7 +661,7 @@ generate_faults(VuDev *dev) {
"%s: Failed to madvise(NOHUGEPAGE) region %d: %s\n",
__func__, i, strerror(errno));
}
- struct uffdio_register reg_struct;
+
reg_struct.range.start = (uintptr_t)dev_region->mmap_addr;
reg_struct.range.len = dev_region->size + dev_region->mmap_offset;
reg_struct.mode = UFFDIO_REGISTER_MODE_MISSING;
@@ -825,7 +831,7 @@ static inline bool reg_equal(VuDevRegion *vudev_reg,
static bool
vu_rem_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
VhostUserMemoryRegion m = vmsg->payload.memreg.region, *msg_region = &m;
- int i;
+ unsigned int i;
bool found = false;
if (vmsg->fd_num > 1) {
@@ -891,7 +897,7 @@ vu_rem_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
static bool
vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
{
- int i;
+ unsigned int i;
VhostUserMemory m = vmsg->payload.memory, *memory = &m;
dev->nregions = memory->nregions;
@@ -968,7 +974,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
static bool
vu_set_mem_table_exec(VuDev *dev, VhostUserMsg *vmsg)
{
- int i;
+ unsigned int i;
VhostUserMemory m = vmsg->payload.memory, *memory = &m;
for (i = 0; i < dev->nregions; i++) {
@@ -1593,12 +1599,13 @@ vu_set_config(VuDev *dev, VhostUserMsg *vmsg)
static bool
vu_set_postcopy_advise(VuDev *dev, VhostUserMsg *vmsg)
{
- dev->postcopy_ufd = -1;
#ifdef UFFDIO_API
struct uffdio_api api_struct;
dev->postcopy_ufd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
vmsg->size = 0;
+#else
+ dev->postcopy_ufd = -1;
#endif
if (dev->postcopy_ufd == -1) {
@@ -1976,7 +1983,7 @@ end:
void
vu_deinit(VuDev *dev)
{
- int i;
+ unsigned int i;
for (i = 0; i < dev->nregions; i++) {
VuDevRegion *r = &dev->regions[i];
@@ -2471,14 +2478,13 @@ vring_used_flags_unset_bit(VuVirtq *vq, int mask)
static inline void
vring_set_avail_event(VuVirtq *vq, uint16_t val)
{
- uint16_t *avail;
+ uint16_t val_le = htole16(val);
if (!vq->notification) {
return;
}
- avail = (uint16_t *)&vq->vring.used->ring[vq->vring.num];
- *avail = htole16(val);
+ memcpy(&vq->vring.used->ring[vq->vring.num], &val_le, sizeof(uint16_t));
}
void
diff --git a/subprojects/libvhost-user/meson.build b/subprojects/libvhost-user/meson.build
index 39825d9404..a18014e7f2 100644
--- a/subprojects/libvhost-user/meson.build
+++ b/subprojects/libvhost-user/meson.build
@@ -1,6 +1,12 @@
project('libvhost-user', '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')
threads = dependency('threads')
glib = dependency('glib-2.0')
diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h
index 3cbc36a59d..0bd6bfad8a 100644
--- a/target/i386/ops_sse.h
+++ b/target/i386/ops_sse.h
@@ -2470,6 +2470,8 @@ void helper_vpermdq_ymm(Reg *d, Reg *v, Reg *s, uint32_t order)
r0 = s->Q(2);
r1 = s->Q(3);
break;
+ default: /* default case added to help the compiler to avoid warnings */
+ g_assert_not_reached();
}
switch ((order >> 4) & 3) {
case 0:
@@ -2488,6 +2490,8 @@ void helper_vpermdq_ymm(Reg *d, Reg *v, Reg *s, uint32_t order)
r2 = s->Q(2);
r3 = s->Q(3);
break;
+ default: /* default case added to help the compiler to avoid warnings */
+ g_assert_not_reached();
}
d->Q(0) = r0;
d->Q(1) = r1;
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 80c579164f..d5fd8d965c 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -105,6 +105,7 @@
#define vex3 .vex_class = 3,
#define vex4 .vex_class = 4,
#define vex4_unal .vex_class = 4, .vex_special = X86_VEX_SSEUnaligned,
+#define vex4_rep5 .vex_class = 4, .vex_special = X86_VEX_REPScalar,
#define vex5 .vex_class = 5,
#define vex6 .vex_class = 6,
#define vex7 .vex_class = 7,
@@ -839,8 +840,8 @@ static const X86OpEntry opcodes_0F[256] = {
[0x50] = X86_OP_ENTRY3(MOVMSK, G,y, None,None, U,x, vex7 p_00_66),
[0x51] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
- [0x52] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex5 p_00_f3),
- [0x53] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex5 p_00_f3),
+ [0x52] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex4_rep5 p_00_f3),
+ [0x53] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex4_rep5 p_00_f3),
[0x54] = X86_OP_ENTRY3(PAND, V,x, H,x, W,x, vex4 p_00_66), /* vand */
[0x55] = X86_OP_ENTRY3(PANDN, V,x, H,x, W,x, vex4 p_00_66), /* vandn */
[0x56] = X86_OP_ENTRY3(POR, V,x, H,x, W,x, vex4 p_00_66), /* vor */
@@ -878,7 +879,7 @@ static const X86OpEntry opcodes_0F[256] = {
[0x58] = X86_OP_ENTRY3(VADD, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
[0x59] = X86_OP_ENTRY3(VMUL, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
- [0x5a] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex3 p_00_66_f3_f2),
+ [0x5a] = X86_OP_GROUP3(sse_unary, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
[0x5b] = X86_OP_GROUP0(0F5B),
[0x5c] = X86_OP_ENTRY3(VSUB, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
[0x5d] = X86_OP_ENTRY3(VMIN, V,x, H,x, W,x, vex2_rep3 p_00_66_f3_f2),
@@ -1447,9 +1448,9 @@ static bool validate_vex(DisasContext *s, X86DecodedInsn *decode)
* Instructions which differ between 00/66 and F2/F3 in the
* exception classification and the size of the memory operand.
*/
- assert(e->vex_class == 1 || e->vex_class == 2);
+ assert(e->vex_class == 1 || e->vex_class == 2 || e->vex_class == 4);
if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
- e->vex_class = 3;
+ e->vex_class = e->vex_class < 4 ? 3 : 5;
if (s->vex_l) {
goto illegal;
}
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index 539189b4d1..03b58e94a2 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -882,7 +882,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
dt = &env->idt;
if (intno * 16 + 15 > dt->limit) {
- raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2);
+ raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
}
ptr = dt->base + intno * 16;
e1 = cpu_ldl_kernel(env, ptr);
@@ -895,18 +895,18 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
case 15: /* 386 trap gate */
break;
default:
- raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2);
+ raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
break;
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
cpl = env->hflags & HF_CPL_MASK;
/* check privilege if software int */
if (is_int && dpl < cpl) {
- raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2);
+ raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
}
/* check valid bit */
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(env, EXCP0B_NOSEG, intno * 16 + 2);
+ raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);
}
selector = e1 >> 16;
offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff);
diff --git a/tests/fp/meson.build b/tests/fp/meson.build
index 6258e2bd7d..312a4d301f 100644
--- a/tests/fp/meson.build
+++ b/tests/fp/meson.build
@@ -37,6 +37,7 @@ tfcflags = [
'-Wno-missing-prototypes',
'-Wno-return-type',
'-Wno-unused-function',
+ '-Wno-missing-format-attribute',
'-Wno-error',
]
diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c
index 66652fed04..1967cd5898 100644
--- a/tests/qtest/ahci-test.c
+++ b/tests/qtest/ahci-test.c
@@ -154,6 +154,7 @@ static void ahci_migrate(AHCIQState *from, AHCIQState *to, const char *uri)
/**
* Start a Q35 machine and bookmark a handle to the AHCI device.
*/
+G_GNUC_PRINTF(1, 0)
static AHCIQState *ahci_vboot(const char *cli, va_list ap)
{
AHCIQState *s;
@@ -171,6 +172,7 @@ static AHCIQState *ahci_vboot(const char *cli, va_list ap)
/**
* Start a Q35 machine and bookmark a handle to the AHCI device.
*/
+G_GNUC_PRINTF(1, 2)
static AHCIQState *ahci_boot(const char *cli, ...)
{
AHCIQState *s;
@@ -209,6 +211,7 @@ static void ahci_shutdown(AHCIQState *ahci)
* Boot and fully enable the HBA device.
* @see ahci_boot, ahci_pci_enable and ahci_hba_enable.
*/
+G_GNUC_PRINTF(1, 2)
static AHCIQState *ahci_boot_and_enable(const char *cli, ...)
{
AHCIQState *ahci;
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
index 5a14527386..8691802950 100644
--- a/tests/qtest/arm-cpu-features.c
+++ b/tests/qtest/arm-cpu-features.c
@@ -32,6 +32,7 @@ static QDict *do_query_no_props(QTestState *qts, const char *cpu_type)
QUERY_TAIL, cpu_type);
}
+G_GNUC_PRINTF(3, 4)
static QDict *do_query(QTestState *qts, const char *cpu_type,
const char *fmt, ...)
{
diff --git a/tests/qtest/erst-test.c b/tests/qtest/erst-test.c
index 974e8bcfe5..c45bee7f05 100644
--- a/tests/qtest/erst-test.c
+++ b/tests/qtest/erst-test.c
@@ -98,7 +98,7 @@ static void setup_vm_cmd(ERSTState *s, const char *cmd)
const char *arch = qtest_get_arch();
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- s->qs = qtest_pc_boot(cmd);
+ s->qs = qtest_pc_boot("%s", cmd);
} else {
g_printerr("erst-test tests are only available on x86\n");
exit(EXIT_FAILURE);
diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c
index dbe1563b23..dcb050bf9b 100644
--- a/tests/qtest/ide-test.c
+++ b/tests/qtest/ide-test.c
@@ -125,6 +125,7 @@ static QGuestAllocator guest_malloc;
static char *tmp_path[2];
static char *debug_path;
+G_GNUC_PRINTF(1, 2)
static QTestState *ide_test_start(const char *cmdline_fmt, ...)
{
QTestState *qts;
@@ -788,7 +789,7 @@ static void test_flush_nodev(void)
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
- qts = ide_test_start("");
+ qts = ide_test_start("%s", "");
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
diff --git a/tests/qtest/ivshmem-test.c b/tests/qtest/ivshmem-test.c
index cd550c8935..9bf8e78df6 100644
--- a/tests/qtest/ivshmem-test.c
+++ b/tests/qtest/ivshmem-test.c
@@ -109,9 +109,9 @@ static void setup_vm_cmd(IVState *s, const char *cmd, bool msix)
const char *arch = qtest_get_arch();
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- s->qs = qtest_pc_boot(cmd);
+ s->qs = qtest_pc_boot("%s", cmd);
} else if (strcmp(arch, "ppc64") == 0) {
- s->qs = qtest_spapr_boot(cmd);
+ s->qs = qtest_spapr_boot("%s", cmd);
} else {
g_printerr("ivshmem-test tests are only available on x86 or ppc64\n");
exit(EXIT_FAILURE);
diff --git a/tests/qtest/libqmp.c b/tests/qtest/libqmp.c
index 2b08382e5d..a89cab03c3 100644
--- a/tests/qtest/libqmp.c
+++ b/tests/qtest/libqmp.c
@@ -134,7 +134,7 @@ static void socket_send_fds(int socket_fd, int *fds, size_t fds_num,
* in the case that they choose to discard all replies up until
* a particular EVENT is received.
*/
-static void
+static G_GNUC_PRINTF(4, 0) void
_qmp_fd_vsend_fds(int fd, int *fds, size_t fds_num,
const char *fmt, va_list ap)
{
diff --git a/tests/qtest/libqos/libqos-pc.h b/tests/qtest/libqos/libqos-pc.h
index 1a9923ead4..a2e4209a49 100644
--- a/tests/qtest/libqos/libqos-pc.h
+++ b/tests/qtest/libqos/libqos-pc.h
@@ -3,8 +3,10 @@
#include "libqos.h"
-QOSState *qtest_pc_vboot(const char *cmdline_fmt, va_list ap);
-QOSState *qtest_pc_boot(const char *cmdline_fmt, ...);
+QOSState *qtest_pc_vboot(const char *cmdline_fmt, va_list ap)
+ G_GNUC_PRINTF(1, 0);
+QOSState *qtest_pc_boot(const char *cmdline_fmt, ...)
+ G_GNUC_PRINTF(1, 2);
void qtest_pc_shutdown(QOSState *qs);
#endif
diff --git a/tests/qtest/libqos/libqos-spapr.h b/tests/qtest/libqos/libqos-spapr.h
index c61338917a..e4483c14f8 100644
--- a/tests/qtest/libqos/libqos-spapr.h
+++ b/tests/qtest/libqos/libqos-spapr.h
@@ -3,8 +3,10 @@
#include "libqos.h"
-QOSState *qtest_spapr_vboot(const char *cmdline_fmt, va_list ap);
-QOSState *qtest_spapr_boot(const char *cmdline_fmt, ...);
+QOSState *qtest_spapr_vboot(const char *cmdline_fmt, va_list ap)
+ G_GNUC_PRINTF(1, 0);
+QOSState *qtest_spapr_boot(const char *cmdline_fmt, ...)
+ G_GNUC_PRINTF(1, 2);
void qtest_spapr_shutdown(QOSState *qs);
/* List of capabilities needed to silence warnings with TCG */
diff --git a/tests/qtest/libqos/libqos.h b/tests/qtest/libqos/libqos.h
index 9b4dd509f0..12d05b2365 100644
--- a/tests/qtest/libqos/libqos.h
+++ b/tests/qtest/libqos/libqos.h
@@ -21,8 +21,10 @@ struct QOSState {
QOSOps *ops;
};
-QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap);
-QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...);
+QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap)
+ G_GNUC_PRINTF(2, 0);
+QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...)
+ G_GNUC_PRINTF(2, 3);
void qtest_common_shutdown(QOSState *qs);
void qtest_shutdown(QOSState *qs);
bool have_qemu_img(void);
diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c
index 7f21028256..186fcc1141 100644
--- a/tests/qtest/libqos/virtio-9p.c
+++ b/tests/qtest/libqos/virtio-9p.c
@@ -211,6 +211,7 @@ static void *virtio_9p_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
* variable arguments of this function to this
* replacement string
*/
+G_GNUC_PRINTF(3, 4)
static void regex_replace(GString *haystack, const char *pattern,
const char *replace_fmt, ...)
{
diff --git a/tests/qtest/migration-helpers.h b/tests/qtest/migration-helpers.h
index db0684de48..a188b62787 100644
--- a/tests/qtest/migration-helpers.h
+++ b/tests/qtest/migration-helpers.h
@@ -25,6 +25,7 @@ QDict *wait_command_fd(QTestState *who, int fd, const char *command, ...);
G_GNUC_PRINTF(2, 3)
QDict *wait_command(QTestState *who, const char *command, ...);
+G_GNUC_PRINTF(2, 3)
QDict *qmp_command(QTestState *who, const char *command, ...);
G_GNUC_PRINTF(3, 4)
diff --git a/tests/qtest/rtas-test.c b/tests/qtest/rtas-test.c
index 50df60e5b2..1ba42b37d2 100644
--- a/tests/qtest/rtas-test.c
+++ b/tests/qtest/rtas-test.c
@@ -13,7 +13,7 @@ static void run_test_rtas_get_time_of_day(const char *machine)
uint64_t ret;
time_t t1, t2;
- qs = qtest_spapr_boot(machine);
+ qs = qtest_spapr_boot("%s", machine);
t1 = time(NULL);
ret = qrtas_get_time_of_day(qs->qts, &qs->alloc, &tm, &ns);
diff --git a/tests/qtest/usb-hcd-uhci-test.c b/tests/qtest/usb-hcd-uhci-test.c
index 7a117b64d9..f264d2bf73 100644
--- a/tests/qtest/usb-hcd-uhci-test.c
+++ b/tests/qtest/usb-hcd-uhci-test.c
@@ -72,9 +72,9 @@ int main(int argc, char **argv)
qtest_add_func("/uhci/pci/hotplug/usb-storage", test_usb_storage_hotplug);
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- qs = qtest_pc_boot(cmd);
+ qs = qtest_pc_boot("%s", cmd);
} else if (strcmp(arch, "ppc64") == 0) {
- qs = qtest_spapr_boot(cmd);
+ qs = qtest_spapr_boot("%s", cmd);
} else {
g_printerr("usb-hcd-uhci-test tests are only "
"available on x86 or ppc64\n");
diff --git a/tests/unit/test-qmp-cmds.c b/tests/unit/test-qmp-cmds.c
index 2373cd64cb..6d52b4e5d8 100644
--- a/tests/unit/test-qmp-cmds.c
+++ b/tests/unit/test-qmp-cmds.c
@@ -138,6 +138,7 @@ void qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
}
+G_GNUC_PRINTF(2, 3)
static QObject *do_qmp_dispatch(bool allow_oob, const char *template, ...)
{
va_list ap;
@@ -160,6 +161,7 @@ static QObject *do_qmp_dispatch(bool allow_oob, const char *template, ...)
return ret;
}
+G_GNUC_PRINTF(3, 4)
static void do_qmp_dispatch_error(bool allow_oob, ErrorClass cls,
const char *template, ...)
{
@@ -269,7 +271,7 @@ static void test_dispatch_cmd_io(void)
static void test_dispatch_cmd_deprecated(void)
{
- const char *cmd = "{ 'execute': 'test-command-features1' }";
+ #define cmd "{ 'execute': 'test-command-features1' }"
QDict *ret;
memset(&compat_policy, 0, sizeof(compat_policy));
@@ -287,12 +289,13 @@ static void test_dispatch_cmd_deprecated(void)
compat_policy.deprecated_input = COMPAT_POLICY_INPUT_REJECT;
do_qmp_dispatch_error(false, ERROR_CLASS_COMMAND_NOT_FOUND, cmd);
+ #undef cmd
}
static void test_dispatch_cmd_arg_deprecated(void)
{
- const char *cmd = "{ 'execute': 'test-features0',"
- " 'arguments': { 'fs1': { 'foo': 42 } } }";
+ #define cmd "{ 'execute': 'test-features0'," \
+ " 'arguments': { 'fs1': { 'foo': 42 } } }"
QDict *ret;
memset(&compat_policy, 0, sizeof(compat_policy));
@@ -310,11 +313,12 @@ static void test_dispatch_cmd_arg_deprecated(void)
compat_policy.deprecated_input = COMPAT_POLICY_INPUT_REJECT;
do_qmp_dispatch_error(false, ERROR_CLASS_GENERIC_ERROR, cmd);
+ #undef cmd
}
static void test_dispatch_cmd_ret_deprecated(void)
{
- const char *cmd = "{ 'execute': 'test-features0' }";
+ #define cmd "{ 'execute': 'test-features0' }"
QDict *ret;
memset(&compat_policy, 0, sizeof(compat_policy));
@@ -334,6 +338,7 @@ static void test_dispatch_cmd_ret_deprecated(void)
ret = qobject_to(QDict, do_qmp_dispatch(false, cmd));
assert(ret && qdict_size(ret) == 0);
qobject_unref(ret);
+ #undef cmd
}
/* test generated dealloc functions for generated types */
diff --git a/tools/virtiofsd/fuse_log.c b/tools/virtiofsd/fuse_log.c
index 745d88cd2a..2de3f48ee7 100644
--- a/tools/virtiofsd/fuse_log.c
+++ b/tools/virtiofsd/fuse_log.c
@@ -12,6 +12,7 @@
#include "fuse_log.h"
+G_GNUC_PRINTF(2, 0)
static void default_log_func(__attribute__((unused)) enum fuse_log_level level,
const char *fmt, va_list ap)
{
diff --git a/tools/virtiofsd/fuse_log.h b/tools/virtiofsd/fuse_log.h
index 8d7091bd4d..e5c2967ab9 100644
--- a/tools/virtiofsd/fuse_log.h
+++ b/tools/virtiofsd/fuse_log.h
@@ -45,7 +45,8 @@ enum fuse_log_level {
* @param ap format string arguments
*/
typedef void (*fuse_log_func_t)(enum fuse_log_level level, const char *fmt,
- va_list ap);
+ va_list ap)
+ G_GNUC_PRINTF(2, 0);
/**
* Install a custom log handler function.
@@ -68,6 +69,7 @@ void fuse_set_log_func(fuse_log_func_t func);
* @param level severity level (FUSE_LOG_ERR, FUSE_LOG_DEBUG, etc)
* @param fmt sprintf-style format string including newline
*/
-void fuse_log(enum fuse_log_level level, const char *fmt, ...);
+void fuse_log(enum fuse_log_level level, const char *fmt, ...)
+ G_GNUC_PRINTF(2, 3);
#endif /* FUSE_LOG_H_ */
diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c
index 20f0f41f99..40ea2ed27f 100644
--- a/tools/virtiofsd/passthrough_ll.c
+++ b/tools/virtiofsd/passthrough_ll.c
@@ -4182,6 +4182,7 @@ static void setup_nofile_rlimit(unsigned long rlimit_nofile)
}
}
+G_GNUC_PRINTF(2, 0)
static void log_func(enum fuse_log_level level, const char *fmt, va_list ap)
{
g_autofree char *localfmt = NULL;
diff --git a/util/error-report.c b/util/error-report.c
index 5edb2e6040..6e44a55732 100644
--- a/util/error-report.c
+++ b/util/error-report.c
@@ -193,6 +193,7 @@ real_time_iso8601(void)
* a single phrase, with no newline or trailing punctuation.
* Prepend the current location and append a newline.
*/
+G_GNUC_PRINTF(2, 0)
static void vreport(report_type type, const char *fmt, va_list ap)
{
gchar *timestr;
diff --git a/util/error.c b/util/error.c
index b6c89d1412..1e7af665b8 100644
--- a/util/error.c
+++ b/util/error.c
@@ -45,6 +45,7 @@ static void error_handle_fatal(Error **errp, Error *err)
}
}
+G_GNUC_PRINTF(6, 0)
static void error_setv(Error **errp,
const char *src, int line, const char *func,
ErrorClass err_class, const char *fmt, va_list ap,
diff --git a/util/meson.build b/util/meson.build
index d8d109ff84..26c73e586b 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -58,6 +58,7 @@ util_ss.add(files('yank.c'))
util_ss.add(files('int128.c'))
util_ss.add(files('memalign.c'))
util_ss.add(files('interval-tree.c'))
+util_ss.add(files('lockcnt.c'))
if have_user
util_ss.add(files('selfmap.c'))
@@ -72,7 +73,6 @@ endif
if have_block or have_ga
util_ss.add(files('aiocb.c', 'async.c'))
util_ss.add(files('base64.c'))
- util_ss.add(files('lockcnt.c'))
util_ss.add(files('main-loop.c'))
util_ss.add(files('qemu-coroutine.c', 'qemu-coroutine-lock.c', 'qemu-coroutine-io.c'))
util_ss.add(files('coroutine-@0@.c'.format(config_host['CONFIG_COROUTINE_BACKEND'])))