mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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',
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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')
|
||||
|
||||
@@ -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, ...)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user