Fixes for 11.1-rc2
Subsystems (3)
The following changes since commit 6333226c2abb72f31648c251624c56e70993d625:
Merge tag 'pull-9p-20260725' of https://github.com/cschoenebeck/qemu into staging (2026-07-26 08:30:07 -0400)
are available in the Git repository at:
https://gitlab.com/marcandre.lureau/qemu.git tags/fix-pr-v1
for you to fetch changes up to 0e83d6894534cfe4cf071381ea8466cc689e044e:
migration/rdma: annotate and simplify wait_comp_channel() (2026-07-27 15:51:03 +0400)
----------------------------------------------------------------
Fixes for 11.1-rc2
----------------------------------------------------------------
Akihiko Odaki (5):
hw/display/virtio-gpu: Remove the bytes_pp field hw/display/virtio-gpu: Fix empty blob discrimination hw/display/virtio-gpu: Initialize blob mapping for ATTACH_BACKING hw/display/virtio-gpu: Avoid leaking migration blocker hw/display/virtio-gpu: Block Rutabaga migration
Haotian Jiang (2):
hw/display/qxl: unregister vm_change_state handler and BHs
virtio-gpu: fix NULL deref in rutabaga set_scanout
Marc-André Lureau (16):
hw/display/vhost-user-gpu: validate message payload sizes ui/vnc: remove redundant rows computation
net/colo: fix g_hash_table_destroy assertion on uninitialized filter target/i386/sev: fix MemoryRegion reference leaks in gpa2hva callers docs/hyperv: fix misleading hv-crash shutdown description hw/display/virtio-gpu-rutabaga: zero-init capset info response hw/cxl: fix invalid free on early return
hw/hexagon: fix machine->fdt leak in qom-test block/blkio: fix compiler false-positive warning
monitor: annotate monitor_qmp_dispatcher_pop_any() as coroutine
migration: fix qemu_get_counted_string annotation
io: add missing coroutine annotation
block: add missing coroutine annotation
qcow2: remove invalid qcow2_check_refcounts calls hw/9pfs: annotate V9fsTransport callbacks as coroutine_fn migration/rdma: annotate and simplify wait_comp_channel()
docs/system/i386/hyperv.rst | 12 ++++++---- hw/9pfs/9p.h | 26 ++++++++++++--------- hw/display/qxl.h | 1 + include/hw/virtio/virtio-gpu.h | 1 - include/io/channel.h | 4 ++-- include/system/memory.h | 2 ++ block/blkio.c | 5 ++-- block/commit.c | 5 ++-- block/qcow2-snapshot.c | 18 --------------- hw/9pfs/9p.c | 31 +++++++++++++++---------- hw/9pfs/virtio-9p-device.c | 24 +++++++++++--------- hw/9pfs/xen-9p-backend.c | 34 ++++++++++++++-------------- hw/cxl/cxl-host.c | 2 +- hw/display/qxl.c | 16 ++++++++++++- hw/display/vhost-user-gpu.c | 38 +++++++++++++++++++++++++++++++ hw/display/virtio-gpu-base.c | 37 +++++++++++++----------------- hw/display/virtio-gpu-rutabaga.c | 21 ++++++++++++++--- hw/display/virtio-gpu.c | 49 ++++++++++++++++++++++++---------------- hw/hexagon/virt.c | 9 +------- io/channel.c | 5 ++-- migration/qemu-file.c | 2 +- migration/rdma.c | 12 ++++------ monitor/qmp.c | 3 ++- net/filter-rewriter.c | 2 +- target/i386/sev.c | 4 ++-- ui/vnc.c | 1 - 26 files changed, 214 insertions(+), 150 deletions(-)
[GIT PULL 03/23] ui/vnc: remove redundant rows computation
"rows" was already computed in an earlier commit 3543c2b855 ("ui/vnc:
fix OOB write in vnc_refresh_lossy_rect").
--- ui/vnc.c | 1 - 1 file changed, 1 deletion(-)
ui/vnc.c +0 -1
@@ -3016,7 +3016,6 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y, y =QEMU_ALIGN_DOWN (y,VNC_STAT_RECT ); x =QEMU_ALIGN_DOWN (x,VNC_STAT_RECT ); - rows =MIN (VNC_STAT_RECT , height - y); rows =MIN (VNC_STAT_RECT , height - y);if (rows <=0 ) {
Signature · 1 line
2.55.0
[GIT PULL 06/23] target/i386/sev: fix MemoryRegion reference leaks in gpa2hva callers
In reply to Marc-André Lureaugpa2hva() returns a referenced MemoryRegion via its p_mr out-parameter (inherited from memory_region_find()), but both SEV callers were failing to release it.
Message-ID: <[email protected]>
--- include/system/memory.h | 2 ++ target/i386/sev.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-)
include/system/memory.h +2 -0
@@ -1085,6 +1085,8 @@ void memory_region_ref(MemoryRegion *mr);*/ void memory_region_unref (MemoryRegion *mr); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MemoryRegion, memory_region_unref) +/** * memory_region_init_io: Initialize an I/O memory region. *
target/i386/sev.c +2 -2
@@ -1569,7 +1569,7 @@ snp_populate_metadata_pages(SevSnpGuestState *sev_snp,OvmfSevMetadataDesc *desc;int type, ret, i;void *hva; -MemoryRegion *mr =NULL ; +g_autoptr (MemoryRegion) mr =NULL ;for (i =0 ; i < metadata->num_desc; i++) { desc = &metadata->descs[i];
@@ -2063,7 +2063,7 @@ int sev_inject_launch_secret(const char *packet_hdr, const char *secret,int error, ret =1 ;void *hva;gsize hdr_sz =0 , data_sz =0 ; -MemoryRegion *mr =NULL ; +g_autoptr (MemoryRegion) mr =NULL ;SevCommonState *sev_common =SEV_COMMON (MACHINE (qdev_get_machine ())->cgs);if (!sev_common) {
Signature · 1 line
2.55.0
[GIT PULL 05/23] net/colo: fix g_hash_table_destroy assertion on uninitialized filter
In reply to Marc-André Lureaucolo_rewriter_cleanup() unconditionally destroys connection_track_table, but the table is only allocated in colo_rewriter_setup(). When the filter-rewriter object is finalized without having been set up (e.g. during qom-test property enumeration), the pointer is NULL and g_hash_table_destroy() fires an assertion.
Use g_clear_pointer() to skip the destroy when the table was never initialized.
Message-ID: <[email protected]>
--- net/filter-rewriter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/filter-rewriter.c +1 -1
@@ -373,7 +373,7 @@ static void colo_rewriter_cleanup(NetFilterState *nf)g_free (s->incoming_queue); } -g_hash_table_destroy (s->connection_track_table); +g_clear_pointer (&s->connection_track_table, g_hash_table_destroy); }static void colo_rewriter_setup (NetFilterState *nf,Error **errp)
Signature · 1 line
2.55.0
[GIT PULL 07/23] virtio-gpu: fix NULL deref in rutabaga set_scanout
In reply to Marc-André LureauFrom: Haotian Jiang <[email protected]>
rutabaga_cmd_set_scanout() checks scanout_id < VIRTIO_GPU_MAX_SCANOUTS (16), but does not check scanout_id < conf.max_outputs like the base class (virtio-gpu.c) and virgl backend (virtio-gpu-virgl.c) do.
With the default max_outputs=1, virtio_gpu_base_device_realize only initializes scanout[0].con. A guest submitting SET_SCANOUT with scanout_id >= 1 takes the con=NULL path, and qemu_console_set_surface(NULL, NULL) dereferences con->ds, crashing QEMU.
Replace VIRTIO_GPU_MAX_SCANOUTS with vb->conf.max_outputs in the CHECK, since realization already ensures max_outputs <= VIRTIO_GPU_MAX_SCANOUTS.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3897
Cc: [email protected]
Message-ID: <[email protected]>
--- hw/display/virtio-gpu-rutabaga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
hw/display/virtio-gpu-rutabaga.c +1 -1
@@ -302,7 +302,7 @@ rutabaga_cmd_set_scanout(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd)trace_virtio_gpu_cmd_set_scanout (ss.scanout_id, ss.resource_id, ss.r.width, ss.r.height, ss.r.x, ss.r.y); -CHECK (ss.scanout_id <VIRTIO_GPU_MAX_SCANOUTS , cmd); +CHECK (ss.scanout_id < vb->conf.max_outputs, cmd); scanout = &vb->scanout[ss.scanout_id];if (ss.resource_id ==0 ) {
Signature · 1 line
2.55.0
[GIT PULL 04/23] hw/display/qxl: unregister vm_change_state handler and BHs
In reply to Marc-André LureauFrom: Haotian Jiang <[email protected]>
qxl_realize_common() registers a vm_change_state handler via qemu_add_vm_change_state_handler() and creates three bottom halves (update_irq, update_area_bh, cursor_bh), but none are ever cleaned up. The return value of qemu_add_vm_change_state_handler() is discarded, so the handler is never removed from the global list, and there is no PCIDeviceClass.exit callback to delete the BHs.
When a secondary QXL device (hotpluggable by default) is hot-unplugged via device_del, the PCIQXLDevice memory is freed but the vm_state handler and BH entries remain with dangling opaque pointers. On the next VM state change (stop/cont/migrate) or BH dispatch, the callback dereferences freed memory, causing a use-after-free.
Fix this by storing the VMChangeStateEntry returned by qemu_add_vm_change_state_handler() and adding a qxl_exit() callback that deletes the vm_state handler, all three BHs, and the guest_surfaces.cmds allocation before the device memory is freed.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3607
Message-ID: <[email protected]>
--- hw/display/qxl.h | 1 + hw/display/qxl.c | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-)
hw/display/qxl.h +1 -0
@@ -83,6 +83,7 @@ struct PCIQXLDevice {/* thread signaling */ QEMUBH *update_irq; +VMChangeStateEntry *vmstate_handler;/* ram pci bar */ QXLRam *ram;
hw/display/qxl.c +15 -1
@@ -2203,7 +2203,8 @@ static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp)error_report_err (err); } -qemu_add_vm_change_state_handler (qxl_vm_change_state_handler, qxl); + qxl->vmstate_handler = +qemu_add_vm_change_state_handler (qxl_vm_change_state_handler, qxl); qxl->update_irq =qemu_bh_new_guarded (qxl_update_irq_bh, qxl, &DEVICE (qxl)->mem_reentrancy_guard);
@@ -2475,6 +2476,18 @@ static const Property qxl_properties[] = { DEFINE_PROP_UINT32("yres", PCIQXLDevice, yres, 0), }; +static void qxl_exit (PCIDevice *dev) +{ +PCIQXLDevice *qxl =PCI_QXL (dev); + +/* TODO: complete cleanup, error paths etc */ +g_clear_pointer (&qxl->vmstate_handler, qemu_del_vm_change_state_handler); +g_clear_pointer (&qxl->update_irq, qemu_bh_delete); +g_clear_pointer (&qxl->update_area_bh, qemu_bh_delete); +g_clear_pointer (&qxl->ssd.cursor_bh, qemu_bh_delete); +g_clear_pointer (&qxl->guest_surfaces.cmds, g_free); +} +static void qxl_pci_class_init (ObjectClass *klass,const void *data) {DeviceClass *dc =DEVICE_CLASS (klass);
@@ -2482,6 +2495,7 @@ static void qxl_pci_class_init(ObjectClass *klass, const void *data) k->vendor_id =REDHAT_PCI_VENDOR_ID ; k->device_id =QXL_DEVICE_ID_STABLE ; + k->exit = qxl_exit;set_bit (DEVICE_CATEGORY_DISPLAY , dc->categories);device_class_set_legacy_reset (dc, qxl_reset_handler); dc->vmsd = &qxl_vmstate;
Signature · 1 line
2.55.0
[GIT PULL 02/23] hw/display/vhost-user-gpu: validate message payload sizes
In reply to Marc-André LureauA malicious or buggy vhost-user-gpu backend can send messages with undersized payloads, leading to out-of-bounds reads when the handler accesses struct fields beyond the allocated buffer. However, vhost-user-gpu is considered trusted by QEMU by design (it has access to shared memory etc).
Add a centralized minimum payload size check in vhost_user_gpu_chr_read() that rejects messages before dispatch, and a per-pixel bounds check in the VHOST_USER_GPU_UPDATE handler to ensure the variable-length data covers the declared width x height.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3866
--- hw/display/vhost-user-gpu.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
hw/display/vhost-user-gpu.c +38 -0
@@ -119,6 +119,31 @@ static VhostUserGpuMsg m __attribute__ ((unused));static void vhost_user_gpu_update_blocked (VhostUserGPU *g,bool blocked); +static size_t +vhost_user_gpu_min_payload_size (VhostUserGpuRequest request) +{ +switch (request) { +case VHOST_USER_GPU_CURSOR_POS : +case VHOST_USER_GPU_CURSOR_POS_HIDE : +return sizeof (VhostUserGpuCursorPos); +case VHOST_USER_GPU_CURSOR_UPDATE : +return sizeof (VhostUserGpuCursorUpdate); +case VHOST_USER_GPU_GET_EDID : +return sizeof (VhostUserGpuEdidRequest); +case VHOST_USER_GPU_SCANOUT : +return sizeof (VhostUserGpuScanout); +case VHOST_USER_GPU_DMABUF_SCANOUT : +return sizeof (VhostUserGpuDMABUFScanout); +case VHOST_USER_GPU_DMABUF_SCANOUT2 : +return sizeof (VhostUserGpuDMABUFScanout2); +case VHOST_USER_GPU_DMABUF_UPDATE : +case VHOST_USER_GPU_UPDATE : +return sizeof (VhostUserGpuUpdate); +default : +return 0 ; + } +} +static void vhost_user_gpu_handle_cursor (VhostUserGPU *g,VhostUserGpuMsg *msg) {
@@ -322,6 +347,14 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)if (m->scanout_id >= g->parent_obj.conf.max_outputs) {break ; } + +if ((uint64_t )m->width * m->height > + (msg->size -sizeof (VhostUserGpuUpdate)) /sizeof (uint32_t )) { +error_report ("vhost-user-gpu: update payload too small" +" for %ux%u" , m->width, m->height); +break ; + } + s = &g->parent_obj.scanout[m->scanout_id]; con = s->con; pixman_image_t *image =
@@ -396,6 +429,11 @@ vhost_user_gpu_chr_read(void *opaque) msg->flags = flags; msg->size = size; +if (size <vhost_user_gpu_min_payload_size (request)) { +error_report ("vhost-user-gpu: message %d payload too small" , request); + goto end; + } +if (request ==VHOST_USER_GPU_CURSOR_UPDATE || request ==VHOST_USER_GPU_CURSOR_POS || request ==VHOST_USER_GPU_CURSOR_POS_HIDE ) {
Signature · 1 line
2.55.0
[GIT PULL 14/23] hw/cxl: fix invalid free on early return
In reply to Marc-André Lureaudocs/devel/style.rst:
* Variables declared with g_auto* MUST always be initialized, otherwise the cleanup function will use uninitialized stack memory
--- hw/cxl/cxl-host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
hw/cxl/cxl-host.c +1 -1
@@ -279,7 +279,7 @@ static void cxl_fmws_direct_passthrough_setup(CXLDirectPTState *state,MemoryRegion *mr =NULL ;uint64_t vmr_size =0 , pmr_size =0 , offset =0 ;MemoryRegion *direct_mr; - g_autofree char *direct_mr_name; + g_autofree char *direct_mr_name = NULL;unsigned int idx = state->hdm_decoder_idx;if (ct3d->hostvmem) {
Signature · 1 line
2.55.0
[GIT PULL 13/23] hw/display/virtio-gpu-rutabaga: zero-init capset info response
In reply to Marc-André Lureaurutabaga_cmd_get_capset_info() only fills in capset_id, capset_max_version and capset_max_size before sending the response to the guest. The remaining fields of struct virtio_gpu_resp_capset_info, including hdr.fence_id, hdr.ctx_id and hdr.ring_idx, are left with stack garbage and leaked to the guest, including host pointers useful for an ASLR bypass.
Zero the response first, matching virgl_cmd_get_capset_info().
Not a real risk thanks to -ftrivial-auto-var-init=zero, but only with gcc >= 12 or clang >= 16.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3609
--- hw/display/virtio-gpu-rutabaga.c | 2 ++ 1 file changed, 2 insertions(+)
hw/display/virtio-gpu-rutabaga.c +2 -0
@@ -556,6 +556,8 @@ rutabaga_cmd_get_capset_info(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd)VIRTIO_GPU_FILL_CMD (info); +memset (&resp,0 ,sizeof (resp)); + result =rutabaga_get_capset_info (vr->rutabaga, info.capset_index, &resp.capset_id, &resp.capset_max_version, &resp.capset_max_size);
Signature · 1 line
2.55.0
[GIT PULL 08/23] docs/hyperv: fix misleading hv-crash shutdown description
In reply to Marc-André LureauThe documentation stated that writing to HV_X64_MSR_CRASH_CTL unconditionally causes the guest to shutdown. In reality, it triggers qemu_system_guest_panicked() via KVM_SYSTEM_EVENT_CRASH and the resulting action depends on the generic panic action policy (-action panic=...), which defaults to shutdown.
Message-ID: <[email protected]>
--- docs/system/i386/hyperv.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
docs/system/i386/hyperv.rst +8 -4
@@ -71,8 +71,11 @@ Existing enlightenments by the guest when it crashes, HV_X64_MSR_CRASH_P0..HV_X64_MSR_CRASH_P5 MSRs contain additional crash information. This information is outputted in QEMU log and through QAPI. - Note: unlike under genuine Hyper-V, write to HV_X64_MSR_CRASH_CTL causes guest - to shutdown. This effectively blocks crash dump generation by Windows. + Note: unlike under genuine Hyper-V, write to HV_X64_MSR_CRASH_CTL triggers + ``qemu_system_guest_panicked()`` via ``KVM_SYSTEM_EVENT_CRASH`` and the + resulting action depends on the ``-action panic=...`` policy (default: + ``shutdown``). With the default action, this effectively blocks crash dump + generation by Windows. ``hv-time`` Enables two Hyper-V-specific clocksources available to the guest: MSR-based
@@ -304,8 +307,9 @@ currently implemented Hyper-V enlightenments with the following exceptions: ``hv-version-id-snumber`` can be left unchanged, guests are not supposed to behave differently when different Hyper-V version is presented to them. - ``hv-crash`` must only be enabled if the crash information is consumed via - QAPI by higher levels of the virtualization stack. Enabling this feature - effectively prevents Windows from creating dumps upon crashes. + QAPI by higher levels of the virtualization stack. With the default + ``-action panic=shutdown`` policy, enabling this feature effectively + prevents Windows from creating dumps upon crashes. - ``hv-reenlightenment`` can only be used on hardware which supports TSC scaling or when guest migration is not needed. - ``hv-spinlocks`` should be set to e.g. 0xfff when host CPUs are overcommited
Signature · 1 line
2.55.0
[GIT PULL 10/23] hw/display/virtio-gpu: Initialize blob mapping for ATTACH_BACKING
In reply to Marc-André LureauFrom: Akihiko Odaki <[email protected]>
It is necessary for blob cursor and scanout.
Message-ID: <[email protected]>
--- hw/display/virtio-gpu.c | 4 ++++ 1 file changed, 4 insertions(+)
hw/display/virtio-gpu.c +4 -0
@@ -992,6 +992,10 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g, cmd->error =VIRTIO_GPU_RESP_ERR_UNSPEC ;return ; } + +if (!res->image) { +virtio_gpu_init_udmabuf (res); + } } static void
Signature · 1 line
2.55.0
[GIT PULL 17/23] monitor: annotate monitor_qmp_dispatcher_pop_any() as coroutine
In reply to Marc-André LureauThe function calls qemu_coroutine_yield(), and is called from monitor_qmp_dispatcher_co().
--- monitor/qmp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
monitor/qmp.c +2 -1
@@ -342,7 +342,8 @@ static QMPRequest *monitor_qmp_requests_pop_any_with_lock(void)return req_obj; } -static QMPRequest *monitor_qmp_dispatcher_pop_any (void ) +static QMPRequest * coroutine_fn +monitor_qmp_dispatcher_pop_any (void) {while (true) {/*
Signature · 1 line
2.55.0
[GIT PULL 15/23] hw/hexagon: fix machine->fdt leak in qom-test
In reply to Marc-André Lureauvirt_instance_init() built the FDT unconditionally at QOM instance-init time, so simply instantiating the object (e.g. via qom-test's introspection, without ever realizing the machine) leaked the 1MB FDT blob: machine_finalize() does not free machine->fdt.
Other boards (arm/virt, riscv/virt, ...) build the FDT lazily from their MachineClass::init callback, which only runs when the machine is actually selected to boot. Do the same here by moving create_fdt() into virt_init().
--- hw/hexagon/virt.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
hw/hexagon/virt.c +1 -8
@@ -175,13 +175,6 @@ static void fdt_add_cpu_nodes(const HexagonVirtMachineState *vms) -static void virt_instance_init (Object *obj) -{ -HexagonVirtMachineState *vms =HEXAGON_VIRT_MACHINE (obj); - -create_fdt (vms); -} -void hexagon_load_fdt (const HexagonVirtMachineState *vms) {MachineState *ms =MACHINE (vms);
@@ -242,6 +235,7 @@ static void virt_init(MachineState *ms)DeviceState *cpu0;int32_t clk_phandle; +create_fdt (vms);qemu_fdt_setprop_string (ms->fdt,"/chosen" ,"bootargs" , ms->kernel_cmdline); vms->sys =get_system_memory ();
@@ -341,7 +335,6 @@ static const TypeInfo virt_machine_types[] = { { .parent = TYPE_HEXAGON_COMMON_MACHINE, .instance_size = sizeof(HexagonVirtMachineState), .class_init = virt_class_init, - .instance_init = virt_instance_init, } };DEFINE_TYPES (virt_machine_types)
Signature · 1 line
2.55.0
[GIT PULL 01/23] hw/display/virtio-gpu: Remove the bytes_pp field
In reply to Marc-André LureauFrom: Akihiko Odaki <[email protected]>
virtio_gpu_do_set_scanout() validates the stride field of struct virtio_gpu_framebuffer against the bytes_pp field, but bytes_pp in the migration stream may be inconsistent with the format field, which pixman_image_create_bits() uses when it accesses the framebuffer. That validation is therefore incomplete.
To avoid the trouble of synchronizing the two fields, remove bytes_pp, and always derive its value from format. Removing bytes_pp is safe because no released version of QEMU uses its migrated value.
Message-ID: <[email protected]>
--- include/hw/virtio/virtio-gpu.h | 1 - hw/display/virtio-gpu.c | 27 +++++++++++++++++---------- 2 files changed, 17 insertions(+), 11 deletions(-)
include/hw/virtio/virtio-gpu.h +0 -1
@@ -66,7 +66,6 @@ struct virtio_gpu_simple_resource {struct virtio_gpu_framebuffer {pixman_format_code_t format; -uint32_t bytes_pp;uint32_t width, height;uint32_t stride;uint32_t offset;
hw/display/virtio-gpu.c +17 -10
@@ -617,6 +617,11 @@ void virtio_gpu_update_scanout(VirtIOGPU *g, scanout->fb = *fb; } +static uint32_t virtio_gpu_format_bytes_pp (pixman_format_code_t format) +{ +return DIV_ROUND_UP (PIXMAN_FORMAT_BPP (format),8 ); +} + static bool virtio_gpu_do_set_scanout(VirtIOGPU *g, uint32_t scanout_id, struct virtio_gpu_framebuffer *fb,
@@ -625,6 +630,7 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g, uint32_t *error) {struct virtio_gpu_scanout *scanout; +uint32_t bytes_pp =virtio_gpu_format_bytes_pp (fb->format);uint8_t *data; scanout = &g->parent_obj.scanout[scanout_id];
@@ -646,10 +652,10 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g,return false; } -if (fb->stride < (uint64_t )fb->width * fb->bytes_pp) { +if (fb->stride < (uint64_t )fb->width * bytes_pp) {qemu_log_mask (LOG_GUEST_ERROR ,"%s: stride %u too small for width %u at %u bpp\n" , - __func__, fb->stride, fb->width, fb->bytes_pp); + __func__, fb->stride, fb->width, bytes_pp); *error =VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER ;return false; }
@@ -720,6 +726,7 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,struct virtio_gpu_simple_resource *res;struct virtio_gpu_framebuffer fb = {0 };struct virtio_gpu_set_scanout ss; +uint32_t bytes_pp;VIRTIO_GPU_FILL_CMD (ss);virtio_gpu_bswap_32 (&ss,sizeof (ss));
@@ -745,11 +752,11 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g, } fb.format =pixman_image_get_format (res->image); - fb.bytes_pp =DIV_ROUND_UP (PIXMAN_FORMAT_BPP (fb.format),8 ); + bytes_pp =virtio_gpu_format_bytes_pp (fb.format); fb.width =pixman_image_get_width (res->image); fb.height =pixman_image_get_height (res->image); fb.stride =pixman_image_get_stride (res->image); - fb.offset = ss.r.x * fb.bytes_pp + ss.r.y * fb.stride; + fb.offset = ss.r.x * bytes_pp + ss.r.y * fb.stride;virtio_gpu_do_set_scanout (g, ss.scanout_id, &fb, res, &ss.r, &cmd->error);
@@ -760,6 +767,7 @@ bool virtio_gpu_scanout_blob_to_fb(struct virtio_gpu_framebuffer *fb, uint64_t blob_size) {uint64_t fbend; +uint32_t bytes_pp; fb->format =virtio_gpu_get_pixman_format (ss->format);if (!fb->format) {
@@ -769,15 +777,15 @@ bool virtio_gpu_scanout_blob_to_fb(struct virtio_gpu_framebuffer *fb,return false; } - fb->bytes_pp =DIV_ROUND_UP (PIXMAN_FORMAT_BPP (fb->format),8 ); + bytes_pp =virtio_gpu_format_bytes_pp (fb->format); fb->width = ss->width; fb->height = ss->height; fb->stride = ss->strides[0 ]; -if (fb->stride < (uint64_t )fb->width * fb->bytes_pp) { +if (fb->stride < (uint64_t )fb->width * bytes_pp) {qemu_log_mask (LOG_GUEST_ERROR ,"%s: stride %u too small for width %u at %u bpp\n" , - __func__, fb->stride, fb->width, fb->bytes_pp); + __func__, fb->stride, fb->width, bytes_pp);return false; }
@@ -788,7 +796,7 @@ bool virtio_gpu_scanout_blob_to_fb(struct virtio_gpu_framebuffer *fb,return false; } - fb->offset = ss->offsets[0 ] + ss->r.x * fb->bytes_pp + ss->r.y * fb->stride; + fb->offset = ss->offsets[0 ] + ss->r.x * bytes_pp + ss->r.y * fb->stride; fbend = fb->offset; fbend += (uint64_t ) fb->stride * ss->r.height;
@@ -1238,8 +1246,7 @@ static const VMStateDescription vmstate_virtio_gpu_scanout = { VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout), VMSTATE_UINT32_TEST(fb.format, struct virtio_gpu_scanout, scanout_vmstate_after_v2), - VMSTATE_UINT32_TEST(fb.bytes_pp, struct virtio_gpu_scanout, - scanout_vmstate_after_v2), +VMSTATE_UNUSED_TEST (scanout_vmstate_after_v2,4 ), VMSTATE_UINT32_TEST(fb.width, struct virtio_gpu_scanout, scanout_vmstate_after_v2), VMSTATE_UINT32_TEST(fb.height, struct virtio_gpu_scanout,
Signature · 1 line
2.55.0
[GIT PULL 09/23] hw/display/virtio-gpu: Fix empty blob discrimination
In reply to Marc-André LureauFrom: Akihiko Odaki <[email protected]>
Discriminating blobs by checking whether blob_size is nonzero fails for empty blobs. Identify 2D resources by their non-NULL image instead.
Message-ID: <[email protected]>
--- hw/display/virtio-gpu.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
hw/display/virtio-gpu.c +9 -9
@@ -56,18 +56,18 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,return ; } -if (res->blob_size) { -if (res->blob_size < (s->current_cursor->width * - s->current_cursor->height *4 )) { -return ; - } - data = res->blob; - }else { +if (res->image) {if (pixman_image_get_width (res->image) != s->current_cursor->width ||pixman_image_get_height (res->image) != s->current_cursor->height) {return ; } data =pixman_image_get_data (res->image); + }else { +if (res->blob_size < (s->current_cursor->width * + s->current_cursor->height *4 )) { +return ; + } + data = res->blob; } pixels = s->current_cursor->width * s->current_cursor->height;
@@ -1286,7 +1286,7 @@ static int virtio_gpu_save(QEMUFile *f, void *opaque, size_t size,assert (QTAILQ_EMPTY (&g->cmdq)); QTAILQ_FOREACH(res, &g->reslist, next) { -if (res->blob_size) { +if (!res->image) {continue ; }qemu_put_be32 (f, res->resource_id);
@@ -1437,7 +1437,7 @@ static int virtio_gpu_blob_save(QEMUFile *f, void *opaque, size_t size,assert (QTAILQ_EMPTY (&g->cmdq)); QTAILQ_FOREACH(res, &g->reslist, next) { -if (!res->blob_size) { +if (res->image) {continue ; }assert (!res->image);
Signature · 1 line
2.55.0
[GIT PULL 19/23] io: add missing coroutine annotation
In reply to Marc-André Lureau--- include/io/channel.h | 4 ++-- io/channel.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-)
include/io/channel.h +2 -2
@@ -1016,8 +1016,8 @@ void qio_channel_wait(QIOChannel *ioc,* This will work with/without a coroutine context, by automatically select * the proper API to wait. */ -void qio_channel_wait_cond (QIOChannel *ioc, -GIOCondition condition); +void coroutine_mixed_fn qio_channel_wait_cond(QIOChannel *ioc, +GIOCondition condition);/** * qio_channel_set_aio_fd_handler:
io/channel.c +3 -2
@@ -905,8 +905,9 @@ void qio_channel_wait(QIOChannel *ioc,g_main_context_unref (ctxt); } -void qio_channel_wait_cond (QIOChannel *ioc, -GIOCondition condition) +void coroutine_mixed_fn +qio_channel_wait_cond (QIOChannel *ioc, +GIOCondition condition) {if (qemu_in_coroutine ()) {qio_channel_yield (ioc, condition);
Signature · 1 line
2.55.0
[GIT PULL 12/23] hw/display/virtio-gpu: Block Rutabaga migration
In reply to Marc-André LureauFrom: Akihiko Odaki <[email protected]>
The migration stream encoding is not defined for Rutabaga yet.
Message-ID: <[email protected]>
--- hw/display/virtio-gpu-rutabaga.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
hw/display/virtio-gpu-rutabaga.c +15 -2
@@ -9,6 +9,7 @@#include "hw/virtio/virtio-gpu.h" #include "hw/virtio/virtio-gpu-pixman.h" #include "hw/virtio/virtio-iommu.h" +#include "migration/blocker.h" #include <glib/gmem.h> #include <rutabaga_gfx/rutabaga_gfx_ffi.h>
@@ -1078,6 +1079,7 @@ static void virtio_gpu_rutabaga_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)static void virtio_gpu_rutabaga_realize (DeviceState *qdev,Error **errp) { +ERRP_GUARD ();uint32_t num_capsets;VirtIOGPUBase *bdev =VIRTIO_GPU_BASE (qdev);VirtIOGPU *gpudev =VIRTIO_GPU (qdev);
@@ -1087,12 +1089,17 @@ static void virtio_gpu_rutabaga_realize(DeviceState *qdev, Error **errp)return ;#endif -if (!virtio_gpu_rutabaga_init (gpudev, errp)) { +error_setg (&bdev->migration_blocker,"rutabaga is not yet migratable" ); +if (migrate_add_blocker (&bdev->migration_blocker, errp) <0 ) {return ; } +if (!virtio_gpu_rutabaga_init (gpudev, errp)) { + goto fail; + } +if (!virtio_gpu_rutabaga_get_num_capsets (gpudev, &num_capsets, errp)) { -return ; + goto fail; } bdev->conf.flags |= (1 <<VIRTIO_GPU_FLAG_RUTABAGA_ENABLED );
@@ -1101,6 +1108,12 @@ static void virtio_gpu_rutabaga_realize(DeviceState *qdev, Error **errp) bdev->virtio_config.num_capsets = num_capsets;virtio_gpu_device_realize (qdev, errp); +if (!*errp) { +return ; + } + +fail: +migrate_del_blocker (&bdev->migration_blocker); }static const Property virtio_gpu_rutabaga_properties[] = {
Signature · 1 line
2.55.0
[GIT PULL 11/23] hw/display/virtio-gpu: Avoid leaking migration blocker
In reply to Marc-André LureauFrom: Akihiko Odaki <[email protected]>
virtio_gpu_base_device_realize() leaks a migration blocker if a check of the output list fails after adding one. Perform the check before adding a migration blocker to avoid the leak. This also simplifies the code by merging two loops.
Message-ID: <[email protected]>
--- hw/display/virtio-gpu-base.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-)
hw/display/virtio-gpu-base.c +16 -21
@@ -195,6 +195,11 @@ virtio_gpu_base_device_realize(DeviceState *qdev,return false; } + g->enabled_output_bitmask =1 ; + + g->req_state[0 ].width = g->conf.xres; + g->req_state[0 ].height = g->conf.yres; +for (output_idx =0 , node = g->conf.outputs; node; output_idx++, node = node->next) {if (output_idx == g->conf.max_outputs) {
@@ -207,6 +212,17 @@ virtio_gpu_base_device_realize(DeviceState *qdev, node->value->name, EDID_NAME_MAX_LENGTH);return false; } +if (node->value->has_xres != node->value->has_yres) { +error_setg (errp, +"must set both outputs[%zd].xres and outputs[%zd].yres" , + output_idx, output_idx); +return false; + } +if (node->value->has_xres && node->value->has_yres) { + g->enabled_output_bitmask |= (1 << output_idx); + g->req_state[output_idx].width = node->value->xres; + g->req_state[output_idx].height = node->value->yres; + } }if (virtio_gpu_virgl_enabled (g->conf)) {
@@ -229,27 +245,6 @@ virtio_gpu_base_device_realize(DeviceState *qdev,virtio_add_queue (vdev,16 , cursor_cb); } - g->enabled_output_bitmask =1 ; - - g->req_state[0 ].width = g->conf.xres; - g->req_state[0 ].height = g->conf.yres; - -for (output_idx =0 , node = g->conf.outputs; - node && output_idx < g->conf.max_outputs; - output_idx++, node = node->next) { -if (node->value->has_xres != node->value->has_yres) { -error_setg (errp, -"must set both outputs[%zd].xres and outputs[%zd].yres" , - output_idx, output_idx); -return false; - } -if (node->value->has_xres && node->value->has_yres) { - g->enabled_output_bitmask |= (1 << output_idx); - g->req_state[output_idx].width = node->value->xres; - g->req_state[output_idx].height = node->value->yres; - } - } - g->hw_ops = &virtio_gpu_ops;for (i =0 ; i < g->conf.max_outputs; i++) { g->scanout[i].con =
Signature · 1 line
2.55.0
Re: [GIT PULL 11/23] hw/display/virtio-gpu: Avoid leaking migration blocker
Quoted 23 lines · Marc-André Lureau
From: Akihiko Odaki <[email protected]>
virtio_gpu_base_device_realize()leaks a migration blocker if a check of the output list fails after adding one. Perform the check before adding a migration blocker to avoid the leak. This also simplifies the code by merging two loops.Fixes d3a4969dc5ac ("Support per-head resolutions with virtio-gpu")Signed-off-by Akihiko Odaki <[email protected]>Reviewed-by Marc-André Lureau <[email protected]>Message-ID: <[email protected]>
--- hw/display/virtio-gpu-base.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-)hw/display/virtio-gpu-base.c +1
-0@@ -207,6 +212,17 @@ virtio_gpu_base_device_realize(DeviceState *qdev, node->value->name, EDID_NAME_MAX_LENGTH);return false; } +if (node->value->has_xres != node->value->has_yres) {
hw/display/virtio-gpu-base.c virtio_gpu_base_device_realize(DeviceState *qdev, · line 225
Quoted 10 lines
hw/display/virtio-gpu-base.c +10
-0+error_setg (errp, +"must set both outputs[%zd].xres and outputs[%zd].yres" , + output_idx, output_idx); +return false; + } +if (node->value->has_xres && node->value->has_yres) { + g->enabled_output_bitmask |= (1 << output_idx); + g->req_state[output_idx].width = node->value->xres; + g->req_state[output_idx].height = node->value->yres; + }
Hi; Coverity points out an issue with this change (CID 1664272):
just before this added code there is an existing check:
if (node->value && node->value->name &&
strlen(node->value->name) > EDID_NAME_MAX_LENGTH) {
...
}That check assumes that node->value can be NULL, but this added code assumes node->value is not NULL and unconditionally dereferences it. Which is correct ?
thanks
-- PMM
[GIT PULL 20/23] block: add missing coroutine annotation
In reply to Marc-André LureauThe function was extracted without carrying the annotation.
--- block/commit.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
block/commit.c +3 -2
@@ -128,8 +128,9 @@ static void commit_clean(Job *job)blk_unref (s->top); } -static int commit_iteration (CommitBlockJob *s,int64_t offset, -int64_t *requested_bytes,void *buf) +static int coroutine_fn +commit_iteration (CommitBlockJob *s,int64_t offset, +int64_t *requested_bytes,void *buf) {BlockErrorAction action;int64_t bytes = *requested_bytes;
Signature · 1 line
2.55.0
[GIT PULL 22/23] hw/9pfs: annotate V9fsTransport callbacks as coroutine_fn
In reply to Marc-André LureauAll V9fsTransport callbacks are invoked exclusively from coroutine context (the v9fs_* PDU handlers). Annotate the function pointer types in V9fsTransport and all implementations (virtio and xen backends), as well as intermediate callers in 9p.c (pdu_marshal, pdu_unmarshal, v9fs_init_qiov_from_pdu, etc.).
--- hw/9pfs/9p.h | 26 +++++++++++++++----------- hw/9pfs/9p.c | 31 +++++++++++++++++++------------ hw/9pfs/virtio-9p-device.c | 24 +++++++++++++----------- hw/9pfs/xen-9p-backend.c | 34 +++++++++++++++++----------------- 4 files changed, 64 insertions(+), 51 deletions(-)
hw/9pfs/9p.h +15 -11
@@ -472,17 +472,21 @@ void pdu_submit(V9fsPDU *pdu, P9MsgHeader *hdr);void v9fs_reset (V9fsState *s);struct V9fsTransport { -ssize_t (*pdu_vmarshal)(V9fsPDU *pdu,size_t offset,const char *fmt, -va_list ap); -ssize_t (*pdu_vunmarshal)(V9fsPDU *pdu,size_t offset,const char *fmt, -va_list ap); -void (*init_in_iov_from_pdu)(V9fsPDU *pdu,struct iovec **piov, -unsigned int *pniov,size_t size); -void (*init_out_iov_from_pdu)(V9fsPDU *pdu,struct iovec **piov, -unsigned int *pniov,size_t size); -void (*push_and_notify)(V9fsPDU *pdu); -size_t (*msize_limit)(V9fsState *s); -size_t (*response_buffer_size)(V9fsPDU *pdu); + ssize_t coroutine_fn (*pdu_vmarshal)(V9fsPDU *pdu, size_t offset, +const char *fmt,va_list ap); + ssize_t coroutine_fn (*pdu_vunmarshal)(V9fsPDU *pdu, size_t offset, +const char *fmt,va_list ap); + void coroutine_fn (*init_in_iov_from_pdu)(V9fsPDU *pdu, +struct iovec **piov, +unsigned int *pniov, +size_t size); + void coroutine_fn (*init_out_iov_from_pdu)(V9fsPDU *pdu, +struct iovec **piov, +unsigned int *pniov, +size_t size); + void coroutine_fn (*push_and_notify)(V9fsPDU *pdu); + size_t coroutine_fn (*msize_limit)(V9fsState *s); + size_t coroutine_fn (*response_buffer_size)(V9fsPDU *pdu); };#endif
hw/9pfs/9p.c +19 -12
@@ -55,7 +55,8 @@ enum {P9ARRAY_DEFINE_TYPE (V9fsPath, v9fs_path_free); -static ssize_t pdu_marshal (V9fsPDU *pdu,size_t offset,const char *fmt, ...) +static ssize_t coroutine_fn +pdu_marshal (V9fsPDU *pdu,size_t offset,const char *fmt, ...) {ssize_t ret;va_list ap;
@@ -67,7 +68,8 @@ static ssize_t pdu_marshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)return ret; } -static ssize_t pdu_unmarshal (V9fsPDU *pdu,size_t offset,const char *fmt, ...) +static ssize_t coroutine_fn +pdu_unmarshal (V9fsPDU *pdu,size_t offset,const char *fmt, ...) {ssize_t ret;va_list ap;
@@ -1841,7 +1843,8 @@ out_nofid:pdu_complete (pdu, err); } -static int v9fs_walk_marshal (V9fsPDU *pdu,uint16_t nwnames,V9fsQID *qids) +static int coroutine_fn +v9fs_walk_marshal (V9fsPDU *pdu,uint16_t nwnames,V9fsQID *qids) {int i;ssize_t err;
@@ -2363,9 +2366,10 @@ out_nofid:* The resulting QEMUIOVector has heap-allocated iovecs and must be cleaned up * with qemu_iovec_destroy(). */ -static void v9fs_init_qiov_from_pdu (QEMUIOVector *qiov,V9fsPDU *pdu, -size_t skip,size_t size, -bool is_write) +static void coroutine_fn +v9fs_init_qiov_from_pdu (QEMUIOVector *qiov,V9fsPDU *pdu, +size_t skip,size_t size, +bool is_write) {QEMUIOVector elem;struct iovec *iov;
@@ -2382,8 +2386,9 @@ static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu,qemu_iovec_concat (qiov, &elem, skip, size); } -static int v9fs_xattr_read (V9fsState *s,V9fsPDU *pdu,V9fsFidState *fidp, -uint64_t off,uint32_t max_count) +static int coroutine_fn +v9fs_xattr_read (V9fsState *s,V9fsPDU *pdu,V9fsFidState *fidp, +uint64_t off,uint32_t max_count) {ssize_t err;size_t offset =7 ;
@@ -2793,9 +2798,10 @@ out_nofid:pdu_complete (pdu, retval); } -static int v9fs_xattr_write (V9fsState *s,V9fsPDU *pdu,V9fsFidState *fidp, -uint64_t off,uint32_t count, -struct iovec *sg,int cnt) +static int coroutine_fn +v9fs_xattr_write (V9fsState *s,V9fsPDU *pdu,V9fsFidState *fidp, +uint64_t off,uint32_t count, +struct iovec *sg,int cnt) {int i, to_copy;ssize_t err =0 ;
@@ -3729,7 +3735,8 @@ out_nofid:pdu_complete (pdu, err); } -static int v9fs_fill_statfs (V9fsState *s,V9fsPDU *pdu,struct statfs *stbuf) +static int coroutine_fn +v9fs_fill_statfs (V9fsState *s,V9fsPDU *pdu,struct statfs *stbuf) {uint32_t f_type;uint32_t f_bsize;
hw/9pfs/virtio-9p-device.c +13 -11
@@ -28,7 +28,7 @@#include "qemu/module.h" #include "system/qtest.h" -static void virtio_9p_push_and_notify (V9fsPDU *pdu) +static void coroutine_fn virtio_9p_push_and_notify(V9fsPDU *pdu) {V9fsState *s = pdu->s;V9fsVirtioState *v =container_of (s, V9fsVirtioState, state);
@@ -117,8 +117,8 @@ static void virtio_9p_reset(VirtIODevice *vdev)v9fs_reset (&v->state); } -static ssize_t virtio_pdu_vmarshal (V9fsPDU *pdu,size_t offset, -const char *fmt,va_list ap) +static ssize_t coroutine_fn +virtio_pdu_vmarshal (V9fsPDU *pdu,size_t offset,const char *fmt,va_list ap) {V9fsState *s = pdu->s;V9fsVirtioState *v =container_of (s, V9fsVirtioState, state);
@@ -135,8 +135,8 @@ static ssize_t virtio_pdu_vmarshal(V9fsPDU *pdu, size_t offset,return ret; } -static ssize_t virtio_pdu_vunmarshal (V9fsPDU *pdu,size_t offset, -const char *fmt,va_list ap) +static ssize_t coroutine_fn +virtio_pdu_vunmarshal (V9fsPDU *pdu,size_t offset,const char *fmt,va_list ap) {V9fsState *s = pdu->s;V9fsVirtioState *v =container_of (s, V9fsVirtioState, state);
@@ -152,8 +152,9 @@ static ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, size_t offset,return ret; } -static void virtio_init_in_iov_from_pdu (V9fsPDU *pdu,struct iovec **piov, -unsigned int *pniov,size_t size) +static void coroutine_fn +virtio_init_in_iov_from_pdu (V9fsPDU *pdu,struct iovec **piov, +unsigned int *pniov,size_t size) {V9fsState *s = pdu->s;V9fsVirtioState *v =container_of (s, V9fsVirtioState, state);
@@ -172,8 +173,9 @@ static void virtio_init_in_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov, *pniov = elem->in_num; } -static void virtio_init_out_iov_from_pdu (V9fsPDU *pdu,struct iovec **piov, -unsigned int *pniov,size_t size) +static void coroutine_fn +virtio_init_out_iov_from_pdu (V9fsPDU *pdu,struct iovec **piov, +unsigned int *pniov,size_t size) {V9fsState *s = pdu->s;V9fsVirtioState *v =container_of (s, V9fsVirtioState, state);
@@ -192,13 +194,13 @@ static void virtio_init_out_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov, *pniov = elem->out_num; } -static size_t virtio_9p_msize_limit (V9fsState *s) +static size_t coroutine_fn virtio_9p_msize_limit(V9fsState *s) {const size_t guestPageSize =4096 ;return (VIRTQUEUE_MAX_SIZE -2 ) * guestPageSize; } -static size_t virtio_9p_response_buffer_size (V9fsPDU *pdu) +static size_t coroutine_fn virtio_9p_response_buffer_size(V9fsPDU *pdu) {V9fsState *s = pdu->s;V9fsVirtioState *v =container_of (s, V9fsVirtioState, state);
hw/9pfs/xen-9p-backend.c +17 -17
@@ -136,10 +136,10 @@ static void xen_9pfs_out_sg(Xen9pfsRing *ring, } } -static ssize_t xen_9pfs_pdu_vmarshal (V9fsPDU *pdu, -size_t offset, -const char *fmt, -va_list ap) +static ssize_t coroutine_fn xen_9pfs_pdu_vmarshal(V9fsPDU *pdu, +size_t offset, +const char *fmt, +va_list ap) {Xen9pfsDev *xen_9pfs =container_of (pdu->s, Xen9pfsDev, state);struct iovec in_sg[2 ];
@@ -161,10 +161,10 @@ static ssize_t xen_9pfs_pdu_vmarshal(V9fsPDU *pdu,return ret; } -static ssize_t xen_9pfs_pdu_vunmarshal (V9fsPDU *pdu, -size_t offset, -const char *fmt, -va_list ap) +static ssize_t coroutine_fn xen_9pfs_pdu_vunmarshal(V9fsPDU *pdu, +size_t offset, +const char *fmt, +va_list ap) {Xen9pfsDev *xen_9pfs =container_of (pdu->s, Xen9pfsDev, state);struct iovec out_sg[2 ];
@@ -185,10 +185,10 @@ static ssize_t xen_9pfs_pdu_vunmarshal(V9fsPDU *pdu,return ret; } -static void xen_9pfs_init_out_iov_from_pdu (V9fsPDU *pdu, -struct iovec **piov, -unsigned int *pniov, -size_t size) +static void coroutine_fn xen_9pfs_init_out_iov_from_pdu(V9fsPDU *pdu, +struct iovec **piov, +unsigned int *pniov, +size_t size) {Xen9pfsDev *xen_9pfs =container_of (pdu->s, Xen9pfsDev, state);Xen9pfsRing *ring = &xen_9pfs->rings[pdu->tag % xen_9pfs->num_rings];
@@ -202,10 +202,10 @@ static void xen_9pfs_init_out_iov_from_pdu(V9fsPDU *pdu, *pniov = num; } -static void xen_9pfs_init_in_iov_from_pdu (V9fsPDU *pdu, -struct iovec **piov, -unsigned int *pniov, -size_t size) +static void coroutine_fn xen_9pfs_init_in_iov_from_pdu(V9fsPDU *pdu, +struct iovec **piov, +unsigned int *pniov, +size_t size) {Xen9pfsDev *xen_9pfs =container_of (pdu->s, Xen9pfsDev, state);Xen9pfsRing *ring = &xen_9pfs->rings[pdu->tag % xen_9pfs->num_rings];
@@ -234,7 +234,7 @@ again: *pniov = num; } -static void xen_9pfs_push_and_notify (V9fsPDU *pdu) +static void coroutine_fn xen_9pfs_push_and_notify(V9fsPDU *pdu) {RING_IDX prod;Xen9pfsDev *priv =container_of (pdu->s, Xen9pfsDev, state);
Signature · 1 line
2.55.0
[GIT PULL 18/23] migration: fix qemu_get_counted_string annotation
In reply to Marc-André Lureau--- migration/qemu-file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
migration/qemu-file.c +1 -1
@@ -830,7 +830,7 @@ uint64_t qemu_get_be64(QEMUFile *f)* else 0 * (Note a 0 length string will return 0 either way) */ -size_t coroutine_fn qemu_get_counted_string(QEMUFile *f, char buf[256]) +size_t coroutine_mixed_fn qemu_get_counted_string(QEMUFile *f, char buf[256]) {size_t len =qemu_get_byte (f);size_t res =qemu_get_buffer (f, (uint8_t *)buf, len);
Signature · 1 line
2.55.0
[GIT PULL 23/23] migration/rdma: annotate and simplify wait_comp_channel()
In reply to Marc-André LureauThe function calls yield_until_fd_readable() (coroutine_fn) when in coroutine context, and polls with qemu_poll_ns() otherwise.
Replace the migration-state proxy check with qemu_in_coroutine(), which directly tests what matters.
--- migration/rdma.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
migration/rdma.c +4 -8
@@ -1348,17 +1348,13 @@ static int qemu_rdma_poll(RDMAContext *rdma, struct ibv_cq *cq,/* Wait for activity on the completion channel. * Returns 0 on success, none-0 on error. */ -static int qemu_rdma_wait_comp_channel (RDMAContext *rdma, -struct ibv_comp_channel *comp_channel) +static int coroutine_mixed_fn +qemu_rdma_wait_comp_channel (RDMAContext *rdma, +struct ibv_comp_channel *comp_channel) {struct rdma_cm_event *cm_event; -/* -* Coroutine doesn't start until migration_fd_process_incoming() -* so don't yield unless we know we're running inside of a coroutine. -*/ -if (rdma->migration_started_on_destination && -migration_incoming_get_current ()->state ==MIGRATION_STATUS_ACTIVE ) { +if (qemu_in_coroutine ()) {yield_until_fd_readable (comp_channel->fd); }else {/* This is the source side, we're in a separate thread
Signature · 1 line
2.55.0
[GIT PULL 16/23] block/blkio: fix compiler false-positive warning
In reply to Marc-André LureauUnder some optimization, gcc produces a false-positive:
../block/blkio.c: In function ‘blkio_co_getlength’:
../block/blkio.c:943:8: error: ‘ret’ may be used uninitialized [-Werror=maybe-uninitialized]
943 | if (ret < 0) {
| ^
Replace WITH_QEMU_LOCK_GUARD with the simpler QEMU_LOCK_GUARD.
--- block/blkio.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
block/blkio.c +2 -3
@@ -937,9 +937,8 @@ static int64_t coroutine_fn blkio_co_getlength(BlockDriverState *bs)uint64_t capacity;int ret; - WITH_QEMU_LOCK_GUARD(&s->blkio_lock) { - ret =blkio_get_uint64 (s->blkio,"capacity" , &capacity); - } +QEMU_LOCK_GUARD (&s->blkio_lock); + ret =blkio_get_uint64 (s->blkio,"capacity" , &capacity);if (ret <0 ) {return -ret; }
Signature · 1 line
2.55.0
[GIT PULL 21/23] qcow2: remove invalid qcow2_check_refcounts calls
In reply to Marc-André LureauThose DEBUG_ALLOC-guarded are dead code incorrectly calling coroutine fn from non-coroutine. Remove it.
--- block/qcow2-snapshot.c | 18 ------------------ 1 file changed, 18 deletions(-)
block/qcow2-snapshot.c +0 -18
@@ -740,12 +740,6 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)ROUND_UP (sn->vm_state_size, s->cluster_size), QCOW2_DISCARD_NEVER, false); -#ifdef DEBUG_ALLOC - { -BdrvCheckResult result = {0 }; -qcow2_check_refcounts (bs, &result,0 ); - } -#endif return 0 ; fail:
@@ -893,12 +887,6 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) goto fail; } -#ifdef DEBUG_ALLOC - { -BdrvCheckResult result = {0 }; -qcow2_check_refcounts (bs, &result,0 ); - } -#endif return 0 ; fail:
@@ -975,12 +963,6 @@ int qcow2_snapshot_delete(BlockDriverState *bs,return ret; } -#ifdef DEBUG_ALLOC - { -BdrvCheckResult result = {0 }; -qcow2_check_refcounts (bs, &result,0 ); - } -#endif return 0 ; }
Signature · 1 line
2.55.0
Stefan Hajnoczi
AppliedApplied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/11.1 for any user-visible changes.