summaryrefslogtreecommitdiffstats
path: root/debian/patches/v7.2.2.diff
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/v7.2.2.diff')
-rw-r--r--debian/patches/v7.2.2.diff514
1 files changed, 514 insertions, 0 deletions
diff --git a/debian/patches/v7.2.2.diff b/debian/patches/v7.2.2.diff
new file mode 100644
index 00000000..719617f6
--- /dev/null
+++ b/debian/patches/v7.2.2.diff
@@ -0,0 +1,514 @@
+Subject: v7.2.2
+Date: Sat, 29 Apr 2023 12:09:18 +0300
+From: Michael Tokarev <mjt@tls.msk.ru>
+Forwarded: not-needed
+
+This is a difference between upstream qemu v7.2.1
+and upstream qemu v7.2.2.
+
+ VERSION | 2 +-
+ block/vhdx-log.c | 2 +-
+ hw/arm/boot.c | 5 ++++-
+ hw/net/vmxnet3.c | 2 +-
+ hw/nvme/ctrl.c | 3 +++
+ hw/rdma/vmw/pvrdma_cmd.c | 6 ++++++
+ include/qemu/osdep.h | 2 +-
+ io/channel-tls.c | 3 +++
+ linux-user/fd-trans.c | 10 ++++++---
+ linux-user/fd-trans.h | 1 +
+ linux-user/generic/target_resource.h | 4 ++--
+ linux-user/syscall.c | 21 ++++++++++++------
+ qga/commands.c | 5 ++---
+ qga/installer/qemu-ga.wxs | 1 +
+ qga/vss-win32/install.cpp | 2 +-
+ target/arm/cpu.h | 3 +++
+ target/s390x/arch_dump.c | 2 +-
+ target/s390x/cpu.h | 1 +
+ target/s390x/s390x-internal.h | 3 ++-
+ target/s390x/tcg/insn-data.h.inc | 4 ++--
+ target/s390x/tcg/mem_helper.c | 1 +
+ target/s390x/tcg/translate.c | 41 ++++++++++++++++++++++++++++--------
+ ui/gtk.c | 4 +++-
+ util/fdmon-epoll.c | 25 ++++++++++++++++------
+ 24 files changed, 112 insertions(+), 41 deletions(-)
+
+diff --git a/VERSION b/VERSION
+index b26a34e470..77f5bec5b2 100644
+--- a/VERSION
++++ b/VERSION
+@@ -1 +1 @@
+-7.2.1
++7.2.2
+diff --git a/block/vhdx-log.c b/block/vhdx-log.c
+index 572582b87b..0866897a85 100644
+--- a/block/vhdx-log.c
++++ b/block/vhdx-log.c
+@@ -980,7 +980,7 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
+ sector_write = merged_sector;
+ } else if (i == sectors - 1 && trailing_length) {
+ /* partial sector at the end of the buffer */
+- ret = bdrv_pread(bs->file, file_offset,
++ ret = bdrv_pread(bs->file, file_offset + trailing_length,
+ VHDX_LOG_SECTOR_SIZE - trailing_length,
+ merged_sector + trailing_length, 0);
+ if (ret < 0) {
+diff --git a/hw/arm/boot.c b/hw/arm/boot.c
+index 15c2bf1867..725bab8adc 100644
+--- a/hw/arm/boot.c
++++ b/hw/arm/boot.c
+@@ -686,7 +686,10 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
+ rom_ptr_for_as(as, addr, size));
+
+- g_free(fdt);
++ if (fdt != ms->fdt) {
++ g_free(ms->fdt);
++ ms->fdt = fdt;
++ }
+
+ return size;
+
+diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
+index d2ab527ef4..56559cda24 100644
+--- a/hw/net/vmxnet3.c
++++ b/hw/net/vmxnet3.c
+@@ -1441,7 +1441,7 @@ static void vmxnet3_activate_device(VMXNET3State *s)
+ vmxnet3_setup_rx_filtering(s);
+ /* Cache fields from shared memory */
+ s->mtu = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.misc.mtu);
+- assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu < VMXNET3_MAX_MTU);
++ assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu <= VMXNET3_MAX_MTU);
+ VMW_CFPRN("MTU is %u", s->mtu);
+
+ s->max_rx_frags =
+diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
+index 1d3e058452..749a6938dd 100644
+--- a/hw/nvme/ctrl.c
++++ b/hw/nvme/ctrl.c
+@@ -2491,6 +2491,9 @@ static uint16_t nvme_dsm(NvmeCtrl *n, NvmeRequest *req)
+ status = nvme_h2c(n, (uint8_t *)iocb->range, sizeof(NvmeDsmRange) * nr,
+ req);
+ if (status) {
++ g_free(iocb->range);
++ qemu_aio_unref(iocb);
++
+ return status;
+ }
+
+diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c
+index da7ddfa548..89db963c46 100644
+--- a/hw/rdma/vmw/pvrdma_cmd.c
++++ b/hw/rdma/vmw/pvrdma_cmd.c
+@@ -796,6 +796,12 @@ int pvrdma_exec_cmd(PVRDMADev *dev)
+
+ dsr_info = &dev->dsr_info;
+
++ if (!dsr_info->dsr) {
++ /* Buggy or malicious guest driver */
++ rdma_error_report("Exec command without dsr, req or rsp buffers");
++ goto out;
++ }
++
+ if (dsr_info->req->hdr.cmd >= sizeof(cmd_handlers) /
+ sizeof(struct cmd_handler)) {
+ rdma_error_report("Unsupported command");
+diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
+index b9c4307779..3d6cb431ad 100644
+--- a/include/qemu/osdep.h
++++ b/include/qemu/osdep.h
+@@ -177,7 +177,7 @@ extern "C" {
+ * supports QEMU_ERROR, this will be reported at compile time; otherwise
+ * this will be reported at link time due to the missing symbol.
+ */
+-extern G_NORETURN
++G_NORETURN extern
+ void QEMU_ERROR("code path is reachable")
+ qemu_build_not_reached_always(void);
+ #if defined(__OPTIMIZE__) && !defined(__NO_INLINE__)
+diff --git a/io/channel-tls.c b/io/channel-tls.c
+index 4ce890a538..4ce08ccc28 100644
+--- a/io/channel-tls.c
++++ b/io/channel-tls.c
+@@ -74,6 +74,9 @@ qio_channel_tls_new_server(QIOChannel *master,
+ ioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
+
+ ioc->master = master;
++ if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
++ qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SHUTDOWN);
++ }
+ object_ref(OBJECT(master));
+
+ ioc->session = qcrypto_tls_session_new(
+diff --git a/linux-user/fd-trans.c b/linux-user/fd-trans.c
+index 7b25468d02..146aaaafaa 100644
+--- a/linux-user/fd-trans.c
++++ b/linux-user/fd-trans.c
+@@ -1622,7 +1622,7 @@ TargetFdTrans target_signalfd_trans = {
+ .host_to_target_data = host_to_target_data_signalfd,
+ };
+
+-static abi_long swap_data_eventfd(void *buf, size_t len)
++static abi_long swap_data_u64(void *buf, size_t len)
+ {
+ uint64_t *counter = buf;
+ int i;
+@@ -1640,8 +1640,12 @@ static abi_long swap_data_eventfd(void *buf, size_t len)
+ }
+
+ TargetFdTrans target_eventfd_trans = {
+- .host_to_target_data = swap_data_eventfd,
+- .target_to_host_data = swap_data_eventfd,
++ .host_to_target_data = swap_data_u64,
++ .target_to_host_data = swap_data_u64,
++};
++
++TargetFdTrans target_timerfd_trans = {
++ .host_to_target_data = swap_data_u64,
+ };
+
+ #if defined(CONFIG_INOTIFY) && (defined(TARGET_NR_inotify_init) || \
+diff --git a/linux-user/fd-trans.h b/linux-user/fd-trans.h
+index 1b9fa2041c..910faaf237 100644
+--- a/linux-user/fd-trans.h
++++ b/linux-user/fd-trans.h
+@@ -130,6 +130,7 @@ extern TargetFdTrans target_netlink_route_trans;
+ extern TargetFdTrans target_netlink_audit_trans;
+ extern TargetFdTrans target_signalfd_trans;
+ extern TargetFdTrans target_eventfd_trans;
++extern TargetFdTrans target_timerfd_trans;
+ #if (defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)) || \
+ (defined(CONFIG_INOTIFY1) && defined(TARGET_NR_inotify_init1) && \
+ defined(__NR_inotify_init1))
+diff --git a/linux-user/generic/target_resource.h b/linux-user/generic/target_resource.h
+index 539d8c4677..37d3eb09b3 100644
+--- a/linux-user/generic/target_resource.h
++++ b/linux-user/generic/target_resource.h
+@@ -12,8 +12,8 @@ struct target_rlimit {
+ };
+
+ struct target_rlimit64 {
+- uint64_t rlim_cur;
+- uint64_t rlim_max;
++ abi_ullong rlim_cur;
++ abi_ullong rlim_max;
+ };
+
+ #define TARGET_RLIM_INFINITY ((abi_ulong)-1)
+diff --git a/linux-user/syscall.c b/linux-user/syscall.c
+index 24b25759be..9ca30149d4 100644
+--- a/linux-user/syscall.c
++++ b/linux-user/syscall.c
+@@ -1755,6 +1755,11 @@ static inline abi_long target_to_host_sockaddr(int fd, struct sockaddr *addr,
+ lladdr = (struct target_sockaddr_ll *)addr;
+ lladdr->sll_ifindex = tswap32(lladdr->sll_ifindex);
+ lladdr->sll_hatype = tswap16(lladdr->sll_hatype);
++ } else if (sa_family == AF_INET6) {
++ struct sockaddr_in6 *in6addr;
++
++ in6addr = (struct sockaddr_in6 *)addr;
++ in6addr->sin6_scope_id = tswap32(in6addr->sin6_scope_id);
+ }
+ unlock_user(target_saddr, target_addr, 0);
+
+@@ -12883,8 +12888,8 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
+ if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
+ return -TARGET_EFAULT;
+ }
+- rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
+- rnew.rlim_max = tswap64(target_rnew->rlim_max);
++ __get_user(rnew.rlim_cur, &target_rnew->rlim_cur);
++ __get_user(rnew.rlim_max, &target_rnew->rlim_max);
+ unlock_user_struct(target_rnew, arg3, 0);
+ rnewp = &rnew;
+ }
+@@ -12894,8 +12899,8 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
+ if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
+ return -TARGET_EFAULT;
+ }
+- target_rold->rlim_cur = tswap64(rold.rlim_cur);
+- target_rold->rlim_max = tswap64(rold.rlim_max);
++ __put_user(rold.rlim_cur, &target_rold->rlim_cur);
++ __put_user(rold.rlim_max, &target_rold->rlim_max);
+ unlock_user_struct(target_rold, arg4, 1);
+ }
+ return ret;
+@@ -13115,8 +13120,12 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
+
+ #if defined(TARGET_NR_timerfd_create) && defined(CONFIG_TIMERFD)
+ case TARGET_NR_timerfd_create:
+- return get_errno(timerfd_create(arg1,
+- target_to_host_bitmask(arg2, fcntl_flags_tbl)));
++ ret = get_errno(timerfd_create(arg1,
++ target_to_host_bitmask(arg2, fcntl_flags_tbl)));
++ if (ret >= 0) {
++ fd_trans_register(ret, &target_timerfd_trans);
++ }
++ return ret;
+ #endif
+
+ #if defined(TARGET_NR_timerfd_gettime) && defined(CONFIG_TIMERFD)
+diff --git a/qga/commands.c b/qga/commands.c
+index 7ff551d092..6cf978322e 100644
+--- a/qga/commands.c
++++ b/qga/commands.c
+@@ -32,9 +32,8 @@
+ #define GUEST_FILE_READ_COUNT_MAX (48 * MiB)
+
+ /* Note: in some situations, like with the fsfreeze, logging may be
+- * temporarilly disabled. if it is necessary that a command be able
+- * to log for accounting purposes, check ga_logging_enabled() beforehand,
+- * and use the QERR_QGA_LOGGING_DISABLED to generate an error
++ * temporarily disabled. if it is necessary that a command be able
++ * to log for accounting purposes, check ga_logging_enabled() beforehand.
+ */
+ void slog(const gchar *fmt, ...)
+ {
+diff --git a/qga/installer/qemu-ga.wxs b/qga/installer/qemu-ga.wxs
+index 813d1c6ca6..3442383627 100644
+--- a/qga/installer/qemu-ga.wxs
++++ b/qga/installer/qemu-ga.wxs
+@@ -31,6 +31,7 @@
+ />
+ <Media Id="1" Cabinet="qemu_ga.$(var.QEMU_GA_VERSION).cab" EmbedCab="yes" />
+ <Property Id="WHSLogo">1</Property>
++ <Property Id="ARPNOMODIFY" Value="yes" Secure="yes" />
+ <MajorUpgrade
+ DowngradeErrorMessage="Error: A newer version of QEMU guest agent is already installed."
+ />
+diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp
+index b57508fbe0..b8087e5baa 100644
+--- a/qga/vss-win32/install.cpp
++++ b/qga/vss-win32/install.cpp
+@@ -518,7 +518,7 @@ namespace _com_util
+ /* Stop QGA VSS provider service using Winsvc API */
+ STDAPI StopService(void)
+ {
+- HRESULT hr;
++ HRESULT hr = S_OK;
+ SC_HANDLE manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ SC_HANDLE service = NULL;
+
+diff --git a/target/arm/cpu.h b/target/arm/cpu.h
+index 9aeed3c848..a9cd7178f8 100644
+--- a/target/arm/cpu.h
++++ b/target/arm/cpu.h
+@@ -2407,6 +2407,9 @@ static inline bool arm_is_el3_or_mon(CPUARMState *env)
+ /* Return true if the processor is in secure state */
+ static inline bool arm_is_secure(CPUARMState *env)
+ {
++ if (arm_feature(env, ARM_FEATURE_M)) {
++ return env->v7m.secure;
++ }
+ if (arm_is_el3_or_mon(env)) {
+ return true;
+ }
+diff --git a/target/s390x/arch_dump.c b/target/s390x/arch_dump.c
+index a2329141e8..a7c44ba49d 100644
+--- a/target/s390x/arch_dump.c
++++ b/target/s390x/arch_dump.c
+@@ -248,7 +248,7 @@ static int s390x_write_elf64_notes(const char *note_name,
+ notep = g_malloc(note_size);
+ }
+
+- memset(notep, 0, sizeof(note));
++ memset(notep, 0, note_size);
+
+ /* Setup note header data */
+ notep->hdr.n_descsz = cpu_to_be32(content_size);
+diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
+index 7d6d01325b..8aaf8dd5a3 100644
+--- a/target/s390x/cpu.h
++++ b/target/s390x/cpu.h
+@@ -87,6 +87,7 @@ struct CPUArchState {
+ uint64_t cc_vr;
+
+ uint64_t ex_value;
++ uint64_t ex_target;
+
+ uint64_t __excp_addr;
+ uint64_t psa;
+diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h
+index 5d4361d35b..825252d728 100644
+--- a/target/s390x/s390x-internal.h
++++ b/target/s390x/s390x-internal.h
+@@ -11,6 +11,7 @@
+ #define S390X_INTERNAL_H
+
+ #include "cpu.h"
++#include "fpu/softfloat.h"
+
+ #ifndef CONFIG_USER_ONLY
+ typedef struct LowCore {
+@@ -299,7 +300,7 @@ uint32_t set_cc_nz_f128(float128 v);
+ uint8_t s390_softfloat_exc_to_ieee(unsigned int exc);
+ int s390_swap_bfp_rounding_mode(CPUS390XState *env, int m3);
+ void s390_restore_bfp_rounding_mode(CPUS390XState *env, int old_mode);
+-int float_comp_to_cc(CPUS390XState *env, int float_compare);
++int float_comp_to_cc(CPUS390XState *env, FloatRelation float_compare);
+
+ #define DCMASK_ZERO 0x0c00
+ #define DCMASK_NORMAL 0x0300
+diff --git a/target/s390x/tcg/insn-data.h.inc b/target/s390x/tcg/insn-data.h.inc
+index 54d4250c9f..2a5fc99818 100644
+--- a/target/s390x/tcg/insn-data.h.inc
++++ b/target/s390x/tcg/insn-data.h.inc
+@@ -199,8 +199,8 @@
+ C(0xe55c, CHSI, SIL, GIE, m1_32s, i2, 0, 0, 0, cmps64)
+ C(0xe558, CGHSI, SIL, GIE, m1_64, i2, 0, 0, 0, cmps64)
+ /* COMPARE HALFWORD RELATIVE LONG */
+- C(0xc605, CHRL, RIL_b, GIE, r1_o, mri2_32s, 0, 0, 0, cmps32)
+- C(0xc604, CGHRL, RIL_b, GIE, r1_o, mri2_64, 0, 0, 0, cmps64)
++ C(0xc605, CHRL, RIL_b, GIE, r1_o, mri2_16s, 0, 0, 0, cmps32)
++ C(0xc604, CGHRL, RIL_b, GIE, r1_o, mri2_16s, 0, 0, 0, cmps64)
+ /* COMPARE HIGH */
+ C(0xb9cd, CHHR, RRE, HW, r1_sr32, r2_sr32, 0, 0, 0, cmps32)
+ C(0xb9dd, CHLR, RRE, HW, r1_sr32, r2_o, 0, 0, 0, cmps32)
+diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
+index 3758b9e688..7e7de5e2f1 100644
+--- a/target/s390x/tcg/mem_helper.c
++++ b/target/s390x/tcg/mem_helper.c
+@@ -2618,6 +2618,7 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
+ that ex_value is non-zero, which flags that we are in a state
+ that requires such execution. */
+ env->ex_value = insn | ilen;
++ env->ex_target = addr;
+ }
+
+ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,
+diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
+index 1e599ac259..e328aa5b97 100644
+--- a/target/s390x/tcg/translate.c
++++ b/target/s390x/tcg/translate.c
+@@ -5962,9 +5962,25 @@ static void in2_a2(DisasContext *s, DisasOps *o)
+ }
+ #define SPEC_in2_a2 0
+
++static TCGv gen_ri2(DisasContext *s)
++{
++ int64_t delta = (int64_t)get_field(s, i2) * 2;
++ TCGv ri2;
++
++ if (unlikely(s->ex_value)) {
++ ri2 = tcg_temp_new_i64();
++ tcg_gen_ld_i64(ri2, cpu_env, offsetof(CPUS390XState, ex_target));
++ tcg_gen_addi_i64(ri2, ri2, delta);
++ } else {
++ ri2 = tcg_constant_i64(s->base.pc_next + delta);
++ }
++
++ return ri2;
++}
++
+ static void in2_ri2(DisasContext *s, DisasOps *o)
+ {
+- o->in2 = tcg_const_i64(s->base.pc_next + (int64_t)get_field(s, i2) * 2);
++ o->in2 = gen_ri2(s);
+ }
+ #define SPEC_in2_ri2 0
+
+@@ -6050,31 +6066,38 @@ static void in2_m2_64a(DisasContext *s, DisasOps *o)
+ #define SPEC_in2_m2_64a 0
+ #endif
+
++static void in2_mri2_16s(DisasContext *s, DisasOps *o)
++{
++ o->in2 = tcg_temp_new_i64();
++ tcg_gen_qemu_ld16s(o->in2, gen_ri2(s), get_mem_index(s));
++}
++#define SPEC_in2_mri2_16s 0
++
+ static void in2_mri2_16u(DisasContext *s, DisasOps *o)
+ {
+- in2_ri2(s, o);
+- tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
++ o->in2 = tcg_temp_new_i64();
++ tcg_gen_qemu_ld16u(o->in2, gen_ri2(s), get_mem_index(s));
+ }
+ #define SPEC_in2_mri2_16u 0
+
+ static void in2_mri2_32s(DisasContext *s, DisasOps *o)
+ {
+- in2_ri2(s, o);
+- tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
++ o->in2 = tcg_temp_new_i64();
++ tcg_gen_qemu_ld32s(o->in2, gen_ri2(s), get_mem_index(s));
+ }
+ #define SPEC_in2_mri2_32s 0
+
+ static void in2_mri2_32u(DisasContext *s, DisasOps *o)
+ {
+- in2_ri2(s, o);
+- tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
++ o->in2 = tcg_temp_new_i64();
++ tcg_gen_qemu_ld32u(o->in2, gen_ri2(s), get_mem_index(s));
+ }
+ #define SPEC_in2_mri2_32u 0
+
+ static void in2_mri2_64(DisasContext *s, DisasOps *o)
+ {
+- in2_ri2(s, o);
+- tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
++ o->in2 = tcg_temp_new_i64();
++ tcg_gen_qemu_ld64(o->in2, gen_ri2(s), get_mem_index(s));
+ }
+ #define SPEC_in2_mri2_64 0
+
+diff --git a/ui/gtk.c b/ui/gtk.c
+index 4817623c8f..dfaf6d33c3 100644
+--- a/ui/gtk.c
++++ b/ui/gtk.c
+@@ -1783,7 +1783,9 @@ static void gd_vc_chr_accept_input(Chardev *chr)
+ VCChardev *vcd = VC_CHARDEV(chr);
+ VirtualConsole *vc = vcd->console;
+
+- gd_vc_send_chars(vc);
++ if (vc) {
++ gd_vc_send_chars(vc);
++ }
+ }
+
+ static void gd_vc_chr_set_echo(Chardev *chr, bool echo)
+diff --git a/util/fdmon-epoll.c b/util/fdmon-epoll.c
+index e11a8a022e..1683aa1105 100644
+--- a/util/fdmon-epoll.c
++++ b/util/fdmon-epoll.c
+@@ -127,6 +127,8 @@ static bool fdmon_epoll_try_enable(AioContext *ctx)
+
+ bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd)
+ {
++ bool ok;
++
+ if (ctx->epollfd < 0) {
+ return false;
+ }
+@@ -136,14 +138,23 @@ bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd)
+ return false;
+ }
+
+- if (npfd >= EPOLL_ENABLE_THRESHOLD) {
+- if (fdmon_epoll_try_enable(ctx)) {
+- return true;
+- } else {
+- fdmon_epoll_disable(ctx);
+- }
++ if (npfd < EPOLL_ENABLE_THRESHOLD) {
++ return false;
++ }
++
++ /* The list must not change while we add fds to epoll */
++ if (!qemu_lockcnt_dec_if_lock(&ctx->list_lock)) {
++ return false;
++ }
++
++ ok = fdmon_epoll_try_enable(ctx);
++
++ qemu_lockcnt_inc_and_unlock(&ctx->list_lock);
++
++ if (!ok) {
++ fdmon_epoll_disable(ctx);
+ }
+- return false;
++ return ok;
+ }
+
+ void fdmon_epoll_setup(AioContext *ctx)