pci, vhost, virtio, iommu, apci: features, fixes
Subsystems (4)
The following changes since commit 1df256f5968e9f7c3c4533a1383b071c044a36d6:
Merge tag 'qom-qapi-pr-pr-v1' of https://gitlab.com/marcandre.lureau/qemu into staging (2026-09-08 18:35:31 +0100)
are available in the Git repository at:
https://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
for you to fetch changes up to 2f8991c0b9c400f55897849a538580039b61865a:
MAINTAINERS: add Junjie Cao as CXL reviewer (2026-09-11 04:59:15 -0400)
----------------------------------------------------------------
pci, vhost, virtio, iommu, apci: features, fixes
new vhost-user-media device
virtio-net now supports live-TAP local migration
cxl now supports CFMW restrictions and per-window options intel_iommu now supports concurrent page fault handling with PRI pci now batches memory transactions around mapping updates vhost-user-blk now allows toggling inflight-migration at runtime virtio-rtc now supports smeared UTC clock type intel_iommu now exposes SMPWC when SVM is enabled
new reviewer for CXL patches
Fixes, cleanups all over the place
----------------------------------------------------------------
Albert Esteve (4):
linux-headers: add VIRTIO_ID_MEDIA
hw/display: add vhost-user-media device hw/display/vhost-user-media: add shared memory region BAR
linux-headers: Update to Linux v7.3-rc1
Alexandr Moshkov (6):
vhost-user: add skip_drain param to do_vhost_virtqueue_stop
vhost-user: add GET_VRING_BASE_SKIP_DRAIN message
vhost-user: use skip_drain with GET_VRING_BASE_SKIP_DRAIN message
vhost-user-blk: make inflight-migration prop mutable on running vm
vhost-user-blk: move inflight_needed higher
vhost-user-blk: use GET_VRING_BASE_SKIP_DRAIN when inflight-migration is on
Alyssa Ross (1):
vhost-user.rst: fix typo
Bin Guo (2):
libvhost-user: accept the postcopy client base ack in vu_add_mem_reg()
libvhost-user: return the backend mapping address for added regions
Clément MATHIEU--DRIF (4):
intel_iommu: Support concurrent page fault handling with PRI
intel_iommu: Only set dirty bit when PTE exposes write permission
intel_iommu: Always write all the flags passed to vtd_set_flag_in_pte
intel_iommu: Expose SMPWC when SVM is enabled
Davidlohr Bueso (5):
tests/bios-tables-test: Exclude CEDT.cxl for the CFMW restriction change hw/cxl: Drop Back-Invalidate from default CFMW window restrictions tests/acpi/cxl: Update CEDT.cxl for the default CFMW restrictions hw/cxl: Add configurable CXL Fixed Memory Window restriction flags tests/qtest/cxl: Add CXL Fixed Memory Window restriction flag tests
Denis V. Lunev (2):
pci: batch BAR remapping into one memory transaction
pci: load a device's config inside one memory transaction
GuoHan Zhao (1):
virtio-crypto: clean up every data queue
Hanna Czenczek (6):
hw/virtio-blk: Account discard operations hw/virtio-blk: Complete zone-append cookies hw/nvme: Fix block accounting in nvme_copy() hw/nvme: Fix block accounting for compare hw/ide: Have ide_dma_cb() complete accounting hw/scsi-disk: Fix accounting for IGNORE, ret > 0
Jia Jia (2):
virtio: reduce code duplication for split ring hw/virtio: reject inverted virtio-iommu IOVA ranges
Junjie Cao (3):
hw/cxl: Fix guest-triggerable QEMU exit on reserved interleave ways hw/cxl: fix the CDAT DOE overlapping the Flex Bus DVSEC when sn= is set
MAINTAINERS: add Junjie Cao as CXL reviewer
Kuan-Wei Chiu (1):
virtio-rtc: Report smeared UTC clock type
Laurent Vivier (2):
hw/net/virtio-net: check packet size before VLAN tag access in receive_filter() hw/net/virtio-net: strip trailing padding when caching RSC segment
Michael S. Tsirkin (7):
virtio: fix exit(1) on DMA mapping failure during migration restore
virtio: fix config_len DoS in migration restore path
virtio-pci: reject Q_ENABLE write on already-enabled queue
meson: disable "maybe uninitilized" errors with -Og
virtio-balloon: fix free-page BH teardown on unrealize net/tap-solaris: Fix resource leaks on error paths
virtio-net: validate IHL in virtio_net_rsc_extract_unit4 before use
Philippe Mathieu-Daudé (4):
hw/acpi: Make AcpiGedState const in build_ged_aml() hw/hotplug: Mark various HotplugHandlerClass variables as const hw/hotplug: Reduce some HotplugHandler variables scope hw/hotplug: Constify HotplugHandler
Sairaj Kodilkar (7):
amd_iommu: Return empty efr for stub call
tests/acpi: x86: Allow IVRS acpi table changes
amd_iommu: acpi-build: update PA, GVA and VA size macros
acpi_build: Use IOMMU pci device to build IOMMU DeviceID
acpi_build: Build IVRS feature report using extended feature register
amd_iommu: acpi-build: Remove unsupported PPR and HE feature tests/acpi: x86: update golden masters for IVRS
Stefan Hajnoczi (1):
virtio-scsi: set dataplane_started to false upon failure
Vladimir Sementsov-Ogievskiy (16):
net/tap: rework tap_parse_script
net/tap: improve script/downscript options documentation net/tap: deprecate "no" as special value for script/downscript net/tap: move vhost-net open() calls to tap_parse_vhost_fds() net/tap: move vhost initialization to tap_setup_vhost() net/tap: use container_of instead of DO_UPCAST net/tap: QOMify tap backend
net/tap: add TYPE_VMSTATE_IF interface
qapi: add local migration parameter
migration/fd: fix fd leak when fd is not valid for migration migration/fd: add errp parameter to migration_fd_valid()
migration: check that transfer is UNIX socket when "local" set
virtio-net: support local migration of backend net/tap: disable read polling for stopped VM net/tap: support local migration with virtio-net tests/functional: add test_tap_migration
Xiong Weimin (1):
hw/virtio: Propagate vhost_virtqueue_mask errors
MAINTAINERS | 7 + docs/about/deprecated.rst | 18 + docs/interop/vhost-user.rst | 44 ++- docs/system/devices/cxl.rst | 25 +- docs/system/i386/microvm.rst | 4 +- docs/system/i386/xenpvh.rst | 2 +- docs/system/ppc/ppce500.rst | 4 +- docs/system/riscv/microchip-icicle-kit.rst | 2 +- docs/system/riscv/sifive_u.rst | 2 +- meson.build | 4 + qapi/machine.json | 28 ++ qapi/migration.json | 21 +- qapi/net.json | 45 ++- hw/i386/amd_iommu.h | 27 +- hw/i386/intel_iommu_internal.h | 1 + hw/s390x/ccw-device.h | 2 +- include/hw/acpi/cpu.h | 4 +- include/hw/acpi/cpu_hotplug.h | 2 +- include/hw/acpi/generic_event_device.h | 3 +- include/hw/acpi/ich9.h | 10 +- include/hw/acpi/memory_hotplug.h | 4 +- include/hw/acpi/pcihp.h | 8 +- include/hw/core/boards.h | 4 +- include/hw/core/hotplug.h | 13 +- include/hw/core/qdev.h | 14 +- include/hw/cxl/cxl.h | 12 + include/hw/i386/microvm.h | 4 +- include/hw/i386/x86.h | 10 +- include/hw/mem/nvdimm.h | 2 +- include/hw/pci/pci_bridge.h | 6 +- include/hw/pci/pcie.h | 8 +- include/hw/pci/shpc.h | 6 +- include/hw/ppc/spapr_nvdimm.h | 2 +- include/hw/virtio/vhost-backend.h | 1 + include/hw/virtio/vhost-user-media.h | 46 +++ include/hw/virtio/vhost-user.h | 2 +- include/hw/virtio/vhost.h | 16 +- include/hw/virtio/virtio-balloon.h | 1 + include/hw/virtio/virtio-net.h | 1 + include/hw/virtio/virtio.h | 2 +- include/migration/misc.h | 2 + include/migration/vmstate.h | 2 + include/net/net.h | 9 + include/net/tap.h | 2 + include/standard-headers/linux/ethtool.h | 6 + include/standard-headers/linux/virtio_ids.h | 1 + linux-headers/linux/iommufd.h | 45 ++- linux-headers/linux/userfaultfd.h | 54 ++- linux-headers/linux/vduse.h | 28 ++ linux-headers/linux/vfio.h | 21 ++ linux-headers/linux/vfio_zdev.h | 2 + backends/cryptodev-vhost.c | 2 +- backends/vhost-user.c | 2 +- hw/acpi/acpi-cpu-hotplug-stub.c | 4 +- hw/acpi/acpi-mem-hotplug-stub.c | 4 +- hw/acpi/acpi-nvdimm-stub.c | 2 +- hw/acpi/acpi-pci-hotplug-stub.c | 8 +- hw/acpi/cpu.c | 6 +- hw/acpi/cxl.c | 2 +- hw/acpi/generic_event_device.c | 13 +- hw/acpi/ich9.c | 10 +- hw/acpi/memory_hotplug.c | 7 +- hw/acpi/nvdimm.c | 2 +- hw/acpi/pcihp.c | 11 +- hw/acpi/piix4.c | 12 +- hw/arm/virt.c | 23 +- hw/block/vhost-user-blk.c | 60 +++- hw/block/virtio-blk.c | 38 ++- hw/char/virtio-serial-bus.c | 6 +- hw/core/hotplug.c | 16 +- hw/core/qdev-hotplug.c | 10 +- hw/core/qdev.c | 2 +- hw/cxl/cxl-host.c | 48 ++- hw/display/vhost-user-media-pci.c | 115 +++++++ hw/display/vhost-user-media.c | 388 ++++++++++++++++++++++ hw/i386/acpi-build.c | 65 ++-- hw/i386/amd_iommu-stub.c | 2 +- hw/i386/amd_iommu.c | 2 +- hw/i386/intel_iommu.c | 118 ++++--- hw/i386/intel_iommu_accel.c | 6 + hw/i386/microvm.c | 12 +- hw/i386/pc.c | 28 +- hw/i386/x86-common.c | 8 +- hw/ide/core.c | 3 +- hw/intc/loongarch_dintc.c | 8 +- hw/intc/loongarch_extioi_common.c | 4 +- hw/intc/loongarch_ipi.c | 4 +- hw/loongarch/virt.c | 44 +-- hw/mem/cxl_type3.c | 6 +- hw/net/vhost_net.c | 9 +- hw/net/virtio-net.c | 131 +++++++- hw/nvme/ctrl.c | 78 +++-- hw/pci-bridge/pci_bridge_dev.c | 6 +- hw/pci/pci.c | 8 + hw/pci/pcie.c | 10 +- hw/pci/pcie_port.c | 2 +- hw/pci/shpc.c | 11 +- hw/ppc/e500plat.c | 4 +- hw/ppc/spapr.c | 48 +-- hw/ppc/spapr_nvdimm.c | 2 +- hw/ppc/spapr_pci.c | 12 +- hw/remote/machine.c | 2 +- hw/riscv/virt.c | 6 +- hw/s390x/css-bridge.c | 2 +- hw/s390x/s390-pci-bus.c | 12 +- hw/s390x/s390-virtio-ccw.c | 16 +- hw/s390x/virtio-ccw-md.c | 10 +- hw/s390x/virtio-ccw.c | 2 +- hw/scsi/scsi-disk.c | 7 + hw/scsi/vhost-scsi-common.c | 2 +- hw/scsi/virtio-scsi-dataplane.c | 2 +- hw/scsi/virtio-scsi.c | 10 +- hw/scsi/vmw_pvscsi.c | 4 +- hw/virtio/vdpa-dev.c | 2 +- hw/virtio/vhost-user-base.c | 2 +- hw/virtio/vhost-user-fs.c | 2 +- hw/virtio/vhost-user-scmi.c | 2 +- hw/virtio/vhost-user.c | 47 ++- hw/virtio/vhost-vsock-common.c | 2 +- hw/virtio/vhost.c | 44 ++- hw/virtio/virtio-balloon.c | 19 +- hw/virtio/virtio-crypto.c | 5 +- hw/virtio/virtio-iommu.c | 17 +- hw/virtio/virtio-md-pci.c | 10 +- hw/virtio/virtio-pci.c | 7 + hw/virtio/virtio-rtc.c | 3 +- hw/virtio/virtio.c | 85 ++--- hw/xen/xen-bus.c | 2 +- migration/fd.c | 28 +- migration/migration.c | 13 + migration/options.c | 18 +- net/net.c | 14 +- net/tap-solaris.c | 69 ++-- net/tap.c | 448 ++++++++++++++++++++----- stubs/hotplug-stubs.c | 6 +- subprojects/libvhost-user/libvhost-user.c | 34 +- system/qdev-monitor.c | 4 +- tests/qtest/cxl-test.c | 95 ++++++ hw/display/Kconfig | 5 + hw/display/meson.build | 3 + qemu-options.hx | 13 +- tests/data/acpi/x86/q35/CEDT.cxl | Bin 184 -> 184 bytes tests/data/acpi/x86/q35/IVRS.ivrs | Bin 176 -> 176 bytes tests/functional/x86_64/meson.build | 1 + tests/functional/x86_64/test_tap_migration.py | 461 ++++++++++++++++++++++++++ 145 files changed, 2884 insertions(+), 663 deletions(-) create mode 100644 include/hw/virtio/vhost-user-media.h create mode 100644 hw/display/vhost-user-media-pci.c create mode 100644 hw/display/vhost-user-media.c create mode 100755 tests/functional/x86_64/test_tap_migration.py
[PULL v2 04/75] hw/cxl: Fix guest-triggerable QEMU exit on reserved interleave ways
From: Junjie Cao <[email protected]>
A buggy or malicious guest can program a committed HDM decoder with a reserved Interleave Ways encoding (e.g. 0x5-0x7, 0xb-0xf). Two call sites pass &error_fatal to cxl_interleave_ways_dec(), which calls exit(1) on the reserved encoding before the subsequent decoded_iw == 0 guards can run:
- cxl-host.c update_non_interleaved(): called at commit time from hdm_decoder_commit() via cfmws_update_non_interleaved(), so a guest writing COMMIT with a reserved IW terminates QEMU immediately. This is the primary trigger on the current tree.
- cxl_type3.c cxl_type3_dpa(): called on memory access while iterating past committed decoders to accumulate dpa_base. Once the commit-time exit is removed, the decoder stays committed with the reserved encoding, so a later guest access outside that decoder's range would otherwise hit this second &error_fatal; both are fixed here.
Pass NULL instead of &error_fatal at both sites so that the reserved encoding returns zero and the existing guards handle it gracefully.
This can be reproduced by writing the HDM Decoder 0 Control register with a reserved IW encoding and the COMMIT bit set (e.g. IW=0x5, COMMIT=1).
Message-ID: <[email protected]>
--- hw/cxl/cxl-host.c | 2 +- hw/mem/cxl_type3.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
hw/cxl/cxl-host.c +1 -1
@@ -442,7 +442,7 @@ static int update_non_interleaved(Object *obj, void *opaque) } } - interleave_ways_dec =cxl_interleave_ways_dec (iw, &error_fatal); + interleave_ways_dec =cxl_interleave_ways_dec (iw,NULL );if (interleave_ways_dec ==0 ) {return 0 ; }
hw/mem/cxl_type3.c +1 -1
@@ -1200,7 +1200,7 @@ static bool cxl_type3_dpa(CXLType3Dev *ct3d, hwaddr host_addr, uint64_t *dpa) }if (((uint64_t )host_addr < decoder_base) || (hpa_offset >= decoder_size)) { -int decoded_iw =cxl_interleave_ways_dec (iw, &error_fatal); +int decoded_iw =cxl_interleave_ways_dec (iw,NULL );if (decoded_iw ==0 ) {return false;
Signature · 1 line
MST
[PULL v2 01/75] virtio: fix exit(1) on DMA mapping failure during migration restore
In reply to Michael S. TsirkinWhen QEMU restores pending virtio requests from a migration stream, it calls qemu_get_virtqueue_element(), which calls virtqueue_map() and virtqueue_map_iovec() to re-map the saved DMA fragment addresses into the destination address space. If the addresses in the migration stream are corrupted, and as a result dma_memory_map() returns NULL or a shorter-than-expected length, virtqueue_map_iovec() calls exit(1), terminating the destination QEMU process instead of failing the migration cleanly.
Convert virtqueue_map_iovec() and virtqueue_map() from void to bool. On failure, virtqueue_map_iovec() unmaps any entries it has already mapped and returns false; virtqueue_map() similarly cleans up the in_sg entries if out_sg mapping fails. qemu_get_virtqueue_element() now checks the return value, frees the element and returns NULL on failure, allowing the migration restore path to propagate a clean error. The callers in virtio-blk, virtio-serial-bus and virtio-scsi that invoke qemu_get_virtqueue_element() during load are updated to check for NULL and return an error code.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3888
--- include/hw/virtio/virtio.h | 2 +- hw/block/virtio-blk.c | 4 +++ hw/char/virtio-serial-bus.c | 4 +++ hw/scsi/virtio-scsi.c | 4 +++ hw/virtio/virtio.c | 49 +++++++++++++++++++++++++++---------- 5 files changed, 49 insertions(+), 14 deletions(-)
include/hw/virtio/virtio.h +1 -1
@@ -320,7 +320,7 @@ bool virtqueue_rewind(VirtQueue *vq, unsigned int num);void virtqueue_fill (VirtQueue *vq,const VirtQueueElement *elem,unsigned int len,unsigned int idx); -void virtqueue_map (VirtIODevice *vdev,VirtQueueElement *elem); +bool virtqueue_map (VirtIODevice *vdev,VirtQueueElement *elem);void *virtqueue_pop (VirtQueue *vq,size_t sz);unsigned int virtqueue_drop_all (VirtQueue *vq);void *qemu_get_virtqueue_element (VirtIODevice *vdev,QEMUFile *f,size_t sz);
hw/block/virtio-blk.c +4 -0
@@ -1384,6 +1384,10 @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f, } req =qemu_get_virtqueue_element (vdev, f,sizeof (VirtIOBlockReq)); +if (!req) { +error_report ("Failed to restore virtio-blk request" ); +return -EINVAL ; + }virtio_blk_init_request (s,virtio_get_queue (vdev, vq_idx), req); WITH_QEMU_LOCK_GUARD(&s->rq_lock) {
hw/char/virtio-serial-bus.c +4 -0
@@ -764,6 +764,10 @@ static int fetch_active_ports_list(QEMUFile *f, port->elem =qemu_get_virtqueue_element (vdev, f,sizeof (VirtQueueElement)); +if (!port->elem) { +error_report ("Failed to restore virtio-serial element" ); +return -EINVAL ; + }/* * Port was throttled on source machine. Let's
hw/scsi/virtio-scsi.c +4 -0
@@ -274,6 +274,10 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)assert (n < vs->conf.num_queues); req =qemu_get_virtqueue_element (vdev, f,sizeof (VirtIOSCSIReq) + vs->cdb_size); +if (!req) { +error_report ("Failed to restore virtio-scsi request" ); +return NULL ; + }virtio_scsi_init_req (s, vs->cmd_vqs[n], req); if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,
hw/virtio/virtio.c +36 -13
79 lines not on this page · raw message
Signature · 1 line
MST
Re: [PULL v2 01/75] virtio: fix exit(1) on DMA mapping failure during migration restore
Quoted 10 lines · Michael S. Tsirkin
When QEMU restores pending virtio requests from a migration stream, it calls
qemu_get_virtqueue_element(), which callsvirtqueue_map()andvirtqueue_map_iovec()to re-map the saved DMA fragment addresses into the destination address space. If the addresses in the migration stream are corrupted, and as a resultdma_memory_map()returns NULL or a shorter-than-expected length,virtqueue_map_iovec()calls exit(1), terminating the destination QEMU process instead of failing the migration cleanly.
Quoted 10 lines
Convert
virtqueue_map_iovec()andvirtqueue_map()from void to bool. On failure,virtqueue_map_iovec()unmaps any entries it has already mapped and returns false;virtqueue_map()similarly cleans up thein_sgentries ifout_sgmapping fails.qemu_get_virtqueue_element()now checks the return value, frees the element and returns NULL on failure, allowing the migration restore path to propagate a clean error. The callers in virtio-blk, virtio-serial-bus and virtio-scsi that invokeqemu_get_virtqueue_element()during load are updated to check for NULL and return an error code.
Hi; Coverity points out an error in the error handling code added here (CID 1686764):
Quoted 13 lines
hw/virtio/virtio.c +3
-2-static void virtqueue_map_iovec (VirtIODevice *vdev,struct iovec *sg, +static bool virtqueue_map_iovec (VirtIODevice *vdev,struct iovec *sg,hwaddr *addr,unsigned int num_sg,bool is_write) {unsigned int i;hwaddr len; +DMADirection dir = is_write ?DMA_DIRECTION_FROM_DEVICE : +DMA_DIRECTION_TO_DEVICE ;for (i =0 ; i < num_sg; i++) { len = sg[i].iov_len; - sg[i].iov_base = dma_memory_map(vdev->dma_as,
hw/virtio/virtio.c static void virtqueue_undo_map_desc(AddressSpace *as, · line 1698
Quoted 10 lines
hw/virtio/virtio.c +3
-5- addr[i], &len, is_write ? -DMA_DIRECTION_FROM_DEVICE : -DMA_DIRECTION_TO_DEVICE , - MEMTXATTRS_UNSPECIFIED); + sg[i].iov_base =dma_memory_map (vdev->dma_as, addr[i], &len, + dir,MEMTXATTRS_UNSPECIFIED );if (!sg[i].iov_base) {error_report ("virtio: error trying to map MMIO memory" ); -exit (1 ); + goto err_undo_map;
If dma_memory_map() fails on the first iteration, we will jump to err_undo_map, with i == 0....
hw/virtio/virtio.c static void virtqueue_undo_map_desc(AddressSpace *as, · line 1709
Quoted 12 lines
} if (len != sg[i].iov_len) { error_report("virtio: unexpected memory split");hw/virtio/virtio.c +6
-1-exit (1 ); +dma_memory_unmap (vdev->dma_as, sg[i].iov_base, len, dir,0 ); + goto err_undo_map; } } +return true; + +err_undo_map: +while (i-- >0 ) {
...but since 'i' is an unsigned type, that will mean that "i--" here underflows to an extremely large value. This loop will then iterate many times unmapping random things.
hw/virtio/virtio.c static void virtqueue_undo_map_desc(AddressSpace *as, · line 1714
Quoted 5 lines
hw/virtio/virtio.c +4
-0+dma_memory_unmap (vdev->dma_as, sg[i].iov_base, sg[i].iov_len, + dir,0 ); + } +return false; }
thanks
-- PMM
Re: [PULL v2 01/75] virtio: fix exit(1) on DMA mapping failure during migration restore
Quoted 52 lines · Peter Maydell
Quoted 10 lines · Michael S. Tsirkin
When QEMU restores pending virtio requests from a migration stream, it calls
qemu_get_virtqueue_element(), which callsvirtqueue_map()andvirtqueue_map_iovec()to re-map the saved DMA fragment addresses into the destination address space. If the addresses in the migration stream are corrupted, and as a resultdma_memory_map()returns NULL or a shorter-than-expected length,virtqueue_map_iovec()calls exit(1), terminating the destination QEMU process instead of failing the migration cleanly.Quoted 10 lines
Convert
virtqueue_map_iovec()andvirtqueue_map()from void to bool. On failure,virtqueue_map_iovec()unmaps any entries it has already mapped and returns false;virtqueue_map()similarly cleans up thein_sgentries ifout_sgmapping fails.qemu_get_virtqueue_element()now checks the return value, frees the element and returns NULL on failure, allowing the migration restore path to propagate a clean error. The callers in virtio-blk, virtio-serial-bus and virtio-scsi that invokeqemu_get_virtqueue_element()during load are updated to check for NULL and return an error code.Hi; Coverity points out an error in the error handling code added here (CID 1686764):
Quoted 13 lines
hw/virtio/virtio.c +3
-2-static void virtqueue_map_iovec (VirtIODevice *vdev,struct iovec *sg, +static bool virtqueue_map_iovec (VirtIODevice *vdev,struct iovec *sg,hwaddr *addr,unsigned int num_sg,bool is_write) {unsigned int i;hwaddr len; +DMADirection dir = is_write ?DMA_DIRECTION_FROM_DEVICE : +DMA_DIRECTION_TO_DEVICE ;for (i =0 ; i < num_sg; i++) { len = sg[i].iov_len; - sg[i].iov_base = dma_memory_map(vdev->dma_as,hw/virtio/virtio.c static void virtqueue_undo_map_desc(AddressSpace *as, · line 1698
Quoted 10 lines
hw/virtio/virtio.c +3
-5- addr[i], &len, is_write ? -DMA_DIRECTION_FROM_DEVICE : -DMA_DIRECTION_TO_DEVICE , - MEMTXATTRS_UNSPECIFIED); + sg[i].iov_base =dma_memory_map (vdev->dma_as, addr[i], &len, + dir,MEMTXATTRS_UNSPECIFIED );if (!sg[i].iov_base) {error_report ("virtio: error trying to map MMIO memory" ); -exit (1 ); + goto err_undo_map;If
dma_memory_map()fails on the first iteration, we will jump toerr_undo_map, with i == 0....
Quoted 16 lines
hw/virtio/virtio.c static void virtqueue_undo_map_desc(AddressSpace *as, · line 1709
Quoted 12 lines
} if (len != sg[i].iov_len) { error_report("virtio: unexpected memory split");hw/virtio/virtio.c +6
-1-exit (1 ); +dma_memory_unmap (vdev->dma_as, sg[i].iov_base, len, dir,0 ); + goto err_undo_map; } } +return true; + +err_undo_map: +while (i-- >0 ) {...but since 'i' is an unsigned type, that will mean that "i--" here underflows to an extremely large value. This loop will then iterate many times unmapping random things.
I apologize, since when is 0 > 0 true?
Quoted 8 lines
hw/virtio/virtio.c static void virtqueue_undo_map_desc(AddressSpace *as, · line 1714
Quoted 5 lines
hw/virtio/virtio.c +4
-0+dma_memory_unmap (vdev->dma_as, sg[i].iov_base, sg[i].iov_len, + dir,0 ); + } +return false; }thanks
-- PMM
Re: [PULL v2 01/75] virtio: fix exit(1) on DMA mapping failure during migration restore
Quoted 72 lines · Michael S. Tsirkin
Quoted 52 lines · Peter Maydell
Quoted 10 lines · Michael S. Tsirkin
When QEMU restores pending virtio requests from a migration stream, it calls
qemu_get_virtqueue_element(), which callsvirtqueue_map()andvirtqueue_map_iovec()to re-map the saved DMA fragment addresses into the destination address space. If the addresses in the migration stream are corrupted, and as a resultdma_memory_map()returns NULL or a shorter-than-expected length,virtqueue_map_iovec()calls exit(1), terminating the destination QEMU process instead of failing the migration cleanly.Quoted 10 lines
Convert
virtqueue_map_iovec()andvirtqueue_map()from void to bool. On failure,virtqueue_map_iovec()unmaps any entries it has already mapped and returns false;virtqueue_map()similarly cleans up thein_sgentries ifout_sgmapping fails.qemu_get_virtqueue_element()now checks the return value, frees the element and returns NULL on failure, allowing the migration restore path to propagate a clean error. The callers in virtio-blk, virtio-serial-bus and virtio-scsi that invokeqemu_get_virtqueue_element()during load are updated to check for NULL and return an error code.Hi; Coverity points out an error in the error handling code added here (CID 1686764):
Quoted 13 lines
hw/virtio/virtio.c +3
-2-static void virtqueue_map_iovec (VirtIODevice *vdev,struct iovec *sg, +static bool virtqueue_map_iovec (VirtIODevice *vdev,struct iovec *sg,hwaddr *addr,unsigned int num_sg,bool is_write) {unsigned int i;hwaddr len; +DMADirection dir = is_write ?DMA_DIRECTION_FROM_DEVICE : +DMA_DIRECTION_TO_DEVICE ;for (i =0 ; i < num_sg; i++) { len = sg[i].iov_len; - sg[i].iov_base = dma_memory_map(vdev->dma_as,hw/virtio/virtio.c static void virtqueue_undo_map_desc(AddressSpace *as, · line 1698
Quoted 10 lines
hw/virtio/virtio.c +3
-5- addr[i], &len, is_write ? -DMA_DIRECTION_FROM_DEVICE : -DMA_DIRECTION_TO_DEVICE , - MEMTXATTRS_UNSPECIFIED); + sg[i].iov_base =dma_memory_map (vdev->dma_as, addr[i], &len, + dir,MEMTXATTRS_UNSPECIFIED );if (!sg[i].iov_base) {error_report ("virtio: error trying to map MMIO memory" ); -exit (1 ); + goto err_undo_map;If
dma_memory_map()fails on the first iteration, we will jump toerr_undo_map, with i == 0....Quoted 16 lines
hw/virtio/virtio.c static void virtqueue_undo_map_desc(AddressSpace *as, · line 1709
Quoted 12 lines
} if (len != sg[i].iov_len) { error_report("virtio: unexpected memory split");hw/virtio/virtio.c +6
-1-exit (1 ); +dma_memory_unmap (vdev->dma_as, sg[i].iov_base, len, dir,0 ); + goto err_undo_map; } } +return true; + +err_undo_map: +while (i-- >0 ) {...but since 'i' is an unsigned type, that will mean that "i--" here underflows to an extremely large value. This loop will then iterate many times unmapping random things.
Quoted 1 line
I apologize, since when is 0 > 0 true?
Whoops, yes, I misread the code here. The loop counter will underflow, but we never use that underflowed result. Coverity complains just because it sees an underflow at all. I've reclassified the issue as false-positive; sorry for the noise.
thanks
-- PMM
[PULL v2 05/75] linux-headers: add VIRTIO_ID_MEDIA
In reply to Michael S. TsirkinFrom: Albert Esteve <[email protected]>
The ID was added in Linux commit 2187be212179 ("virtio: Add ID for virtio media") and is included in v7.3-rc1.
Message-ID: <[email protected]>
--- include/standard-headers/linux/virtio_ids.h | 1 + 1 file changed, 1 insertion(+)
include/standard-headers/linux/virtio_ids.h +1 -0
@@ -69,6 +69,7 @@#define VIRTIO_ID_BT 40/* virtio bluetooth */ #define VIRTIO_ID_GPIO 41/* virtio gpio */ #define VIRTIO_ID_SPI 45/* virtio spi */ +#define VIRTIO_ID_MEDIA 48/* virtio media */ /* * Virtio Transitional IDs
Signature · 1 line
MST
[PULL v2 09/75] net/tap: rework tap_parse_script
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
Factor out tap_is_explicit_no_script() helper, to simplify further changes.
Avoid extra copying by simpler code flow: first check for NULL / empty / "no" cases, then get default or do copying respectively.
Message-ID: <[email protected]>
--- net/tap.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-)
net/tap.c +23 -7
@@ -92,19 +92,35 @@ static void launch_script(const char *setup_script, const char *ifname,static void tap_send (void *opaque);static void tap_writable (void *opaque); -static char *tap_parse_script (const char *script_arg,const char *default_path) +static bool tap_is_explicit_no_script (const char *script_arg_value) { - g_autofree char *res = g_strdup(script_arg); - -if (!res) { - res =get_relocated_path (default_path); +if (!script_arg_value) { +return false; } -if (res[0 ] =='\0' ||strcmp (res,"no" ) ==0 ) { +if (script_arg_value[0 ] =='\0' ) { +return true; + } + +if (strcmp (script_arg_value,"no" ) ==0 ) { +return true; + } + +return false; +} + +static char *tap_parse_script (const char *script_arg_value, +const char *default_path) +{ +if (tap_is_explicit_no_script (script_arg_value)) {return NULL ; } -return g_steal_pointer (&res); +if (!script_arg_value) { +return get_relocated_path (default_path); + } + +return g_strdup (script_arg_value); }static void tap_update_fd_handler (TAPState *s)
Signature · 1 line
MST
[PULL v2 10/75] net/tap: improve script/downscript options documentation
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
Properly document defaults and special values of "" and "no".
Message-ID: <[email protected]>
--- qapi/net.json | 10 ++++++++-- qemu-options.hx | 9 +++++---- 2 files changed, 13 insertions(+), 6 deletions(-)
qapi/net.json +8 -2
@@ -399,9 +399,15 @@ # @fds: multiple file descriptors of already opened multiqueue capable # tap # -# @script: script to initialize the interface +# @script: script to initialize the interface. An empty string or +# "no" disables script execution. Defaults to +# ``<sysconfdir>/qemu-ifup``, where ``<sysconfdir>`` is the +# system configuration directory at build time (typically /etc). # -# @downscript: script to shut down the interface +# @downscript: script to shut down the interface. An empty string or +# "no" disables script execution. Defaults to +# ``<sysconfdir>/qemu-ifdown``, where ``<sysconfdir>`` is the +# system configuration directory at build time (typically /etc). # # @br: bridge name (since 2.8) #
qemu-options.hx +5 -4
@@ -3022,7 +3022,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, " use network scripts 'file' (default=" DEFAULT_NETWORK_SCRIPT ")\n" " to configure it and 'dfile' (default=" DEFAULT_NETWORK_DOWN_SCRIPT ")\n" " to deconfigure it\n" - " use '[down]script=no' to disable script execution\n" + " use '[down]script=no' or '[down]script=' to disable script execution\n" " use network helper 'helper' (default=" DEFAULT_BRIDGE_HELPER ") to\n" " configure it\n" " use 'fd=h' to connect to an already opened TAP interface\n"
@@ -3558,9 +3558,10 @@ SRST Use the network script file to configure it and the network script dfile to deconfigure it. If name is not provided, the OS automatically provides one. The default network configure script is - ``/etc/qemu-ifup`` and the default network deconfigure script is - ``/etc/qemu-ifdown``. Use ``script=no`` or ``downscript=no`` to - disable script execution. + ``<sysconfdir>/qemu-ifup`` and the default network deconfigure script is + ``<sysconfdir>/qemu-ifdown``, where ``<sysconfdir>`` is the system + configuration directory at build time (typically ``/etc``). + Use ``[down]script=no`` or ``[down]script=`` to disable script execution. If running QEMU as an unprivileged user, use the network helper to configure the TAP interface and attach it to the bridge.
Signature · 1 line
MST
[PULL v2 13/75] net/tap: move vhost initialization to tap_setup_vhost()
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
Make a new helper function in a way it can be reused later for TAP fd-migration feature: we'll need to initialize vhost in a later point when we doesn't have access to QAPI parameters.
Based-on: <[email protected]>
Based-on: <[email protected]>
Message-ID: <[email protected]>
--- net/tap.c | 62 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 24 deletions(-)
net/tap.c +38 -24
@@ -71,6 +71,8 @@ static const int kernel_feature_bits[] = { typedef struct TAPState { NetClientState nc; int fd; + int vhostfd; + uint32_t vhost_busyloop_timeout; char down_script[1024]; char down_script_arg[128]; uint8_t buf[NET_BUFSIZE];
@@ -722,6 +724,38 @@ static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr,return fd; } +static bool tap_setup_vhost (TAPState *s,Error **errp) +{ +VhostNetOptions options; + +if (s->vhostfd ==-1 ) { +return true; + } + + options.backend_type =VHOST_BACKEND_TYPE_KERNEL ; + options.net_backend = &s->nc; + options.busyloop_timeout = s->vhost_busyloop_timeout; + options.opaque = (void *)(uintptr_t )s->vhostfd; + options.nvqs =2 ; + options.feature_bits = kernel_feature_bits; + options.get_acked_features =NULL ; + options.save_acked_features =NULL ; + options.max_tx_queue_size =0 ; + options.is_vhost_user = false; + + s->vhost_net =vhost_net_init (&options); +if (!s->vhost_net) { +error_setg (errp, +"vhost-net requested but could not be initialized" ); +return false; + } + +/* vhostfd ownership is passed to s->vhost_net */ + s->vhostfd =-1 ; + +return true; +} + static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, const char *name, const char *ifname, const char *script,
@@ -756,30 +790,10 @@ static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, } } -if (vhostfd !=-1 ) { -VhostNetOptions options; - - options.backend_type =VHOST_BACKEND_TYPE_KERNEL ; - options.net_backend = &s->nc; -if (tap->has_poll_us) { - options.busyloop_timeout = tap->poll_us; - }else { - options.busyloop_timeout =0 ; - } - options.opaque = (void *)(uintptr_t )vhostfd; - options.nvqs =2 ; - options.feature_bits = kernel_feature_bits; - options.get_acked_features =NULL ; - options.save_acked_features =NULL ; - options.max_tx_queue_size =0 ; - options.is_vhost_user = false; - - s->vhost_net =vhost_net_init (&options); -if (!s->vhost_net) { -error_setg (errp, -"vhost-net requested but could not be initialized" ); - goto failed; - } + s->vhostfd = vhostfd; + s->vhost_busyloop_timeout = tap->has_poll_us ? tap->poll_us :0 ; +if (!tap_setup_vhost (s, errp)) { +return false; }return true;
Signature · 1 line
MST
[PULL v2 02/75] virtio: fix config_len DoS in migration restore path
In reply to Michael S. Tsirkinvirtio_load() reads config_len from the migration stream into a local int32_t variable and then, if the incoming length exceeds the device's own config size, skips the surplus one byte at a time in a loop. Two defects in this loop allow a malicious or truncated migration stream to cause a prolonged CPU spin on the destination QEMU.
First, the local variable is int32_t while vdev->config_len is size_t. The C standard converts the signed operand to the unsigned type for the comparison, so any value with the high bit set becomes a very large size_t that exceeds the device config length. The loop then counts the signed counter down through all negative values and back around, effectively running for up to 2^32 iterations.
Second, once the file stream reaches EOF, qemu_get_byte() returns 0 without advancing the read position. Without a check for file errors, the loop spins until the counter reaches the device config length. An attacker who sends a large config_len and then closes the stream can hold the destination QEMU busy for attacker-controlled time.
Change the local config_len to uint32_t so that the comparison with size_t is unsigned and values with the high bit set are treated as large-but-finite skip counts. In addition, check qemu_file_get_error() after each byte read and return failure immediately when the stream signals EOF or an I/O error.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3891
--- hw/virtio/virtio.c | 3 +++ 1 file changed, 3 insertions(+)
hw/virtio/virtio.c +3 -0
@@ -3584,6 +3584,9 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)return -1 ; }qemu_get_byte (f); +if (qemu_file_get_error (f)) { +return -1 ; + } config_len--; }
Signature · 1 line
MST
[PULL v2 15/75] net/tap: QOMify tap backend
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
We prepare for being able to migrate TAP backend. We'll need a user change-able property for it, which can be set from machine type. So, let's QOMify it first.
Message-ID: <[email protected]>
--- include/net/net.h | 7 +++++++ include/net/tap.h | 2 ++ net/net.c | 14 +++++++------- net/tap.c | 48 +++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 56 insertions(+), 15 deletions(-)
include/net/net.h +7 -0
@@ -161,6 +161,13 @@ char *qemu_mac_strdup_printf(const uint8_t *macaddr);NetClientState *qemu_find_netdev (const char *id);int qemu_find_net_clients_except (const char *id,NetClientState **ncs,NetClientDriver type,int max); +void qemu_net_client_setup (NetClientState *nc, +NetClientInfo *info, +NetClientState *peer, +const char *model, +const char *name, +NetClientDestructor *destructor, +bool is_datapath); NetClientState *qemu_new_net_client(NetClientInfo *info, NetClientState *peer, const char *model,
include/net/tap.h +2 -0
@@ -28,6 +28,8 @@#include "standard-headers/linux/virtio_net.h" +#define TYPE_TAP_NETDEV "tap-netdev" +int tap_enable (NetClientState *nc);int tap_disable (NetClientState *nc);
net/net.c +7 -7
@@ -261,13 +261,13 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender,int iovcnt, void *opaque); -static void qemu_net_client_setup (NetClientState *nc, -NetClientInfo *info, -NetClientState *peer, -const char *model, -const char *name, -NetClientDestructor *destructor, -bool is_datapath) +void qemu_net_client_setup (NetClientState *nc, +NetClientInfo *info, +NetClientState *peer, +const char *model, +const char *name, +NetClientDestructor *destructor, +bool is_datapath) { nc->info = info; nc->model =g_strdup (model);
net/tap.c +40 -8
87 lines not on this page · raw message
Signature · 1 line
MST
[PULL v2 11/75] net/tap: deprecate "no" as special value for script/downscript
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
The interface is ambiguous, as "no" is valid file name. So, using "no" as a special value to disable script is deprecated. Use an empty string ("script=" / "downscript=") instead.
In a future version, "no" will be treated as a plain file name, just like any other non-empty value.
Document the deprecation in docs/about/deprecated.rst, qapi/net.json, and qemu-options.hx. Update other docs to use empty string instead of "no". Add a warning.
Message-ID: <[email protected]>
--- docs/about/deprecated.rst | 18 ++++++++++++++++++ docs/system/i386/microvm.rst | 4 ++-- docs/system/i386/xenpvh.rst | 2 +- docs/system/ppc/ppce500.rst | 4 ++-- docs/system/riscv/microchip-icicle-kit.rst | 2 +- docs/system/riscv/sifive_u.rst | 2 +- qapi/net.json | 14 ++++++++++---- net/tap.c | 17 +++++++++++------ qemu-options.hx | 8 ++++++-- 9 files changed, 52 insertions(+), 19 deletions(-)
docs/about/deprecated.rst +18 -0
@@ -71,6 +71,15 @@ flexible enough. The monitor objects have been converted to QOM, so ``-mon mode=control`` is replaced by ``-object monitor-qmp``. The short convenience options are not deprecated, only ``-mon``. +``script=no`` and ``downscript=no`` for ``-netdev tap`` (since 11.2) +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +The special value ``"no"`` for the ``script`` and ``downscript`` +parameters of ``-netdev tap`` disables script execution. This special +treatment of ``"no"`` is deprecated. Use an empty string (``script=`` +or ``downscript=``) to disable script execution instead. In a future +version, ``"no"`` will be treated as a plain file name. + QEMU Machine Protocol (QMP) commands ------------------------------------
@@ -164,6 +173,15 @@ Use ``job-finalize`` instead. Use ``query-accelerators`` instead. +``"no"`` as value of ``script``/``downscript`` for tap in ``netdev_add`` (since 11.2) +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +The special value ``"no"`` for the ``script`` and ``downscript`` +parameters of ``netdev_add`` with ``type=tap`` disables script +execution. This special treatment of ``"no"`` is deprecated. Use an +empty string instead. In a future version, ``"no"`` will be treated as +a plain file name. + Human Machine Protocol (HMP) commands -------------------------------------
docs/system/i386/microvm.rst +2 -2
@@ -79,7 +79,7 @@ legacy ``ISA serial`` device as console:: -serial stdio \ -drive id=test,file=test.img,format=raw,if=none \ -device virtio-blk-device,drive=test \ - -netdev tap,id=tap0,script=no,downscript=no \ + -netdev tap,id=tap0,script=,downscript= \ -device virtio-net-device,netdev=tap0 While the example above works, you might be interested in reducing the
@@ -103,7 +103,7 @@ disabled:: -device virtconsole,chardev=virtiocon0 \ -drive id=test,file=test.img,format=raw,if=none \ -device virtio-blk-device,drive=test \ - -netdev tap,id=tap0,script=no,downscript=no \ + -netdev tap,id=tap0,script=,downscript= \ -device virtio-net-device,netdev=tap0
docs/system/i386/xenpvh.rst +1 -1
@@ -42,7 +42,7 @@ case you need to construct one manually: -vnc none \ -display none \ -device virtio-net-pci,id=nic0,netdev=net0,mac=00:16:3e:5c:81:78 \ - -netdev type=tap,id=net0,ifname=vif3.0-emu,br=xenbr0,script=no,downscript=no \ + -netdev type=tap,id=net0,ifname=vif3.0-emu,br=xenbr0,script=,downscript= \ -smp 4,maxcpus=4 \ -nographic \ -machine xenpvh,ram-low-base=0,ram-low-size=2147483648,ram-high-base=4294967296,ram-high-size=2147483648,pci-ecam-base=824633720832,pci-ecam-size=268435456,pci-mmio-base=4026531840,pci-mmio-size=33554432,pci-mmio-high-base=824902156288,pci-mmio-high-size=68719476736 \
docs/system/ppc/ppce500.rst +2 -2
@@ -158,14 +158,14 @@ interface at PCI address 0.1.0, but we can switch that to an e1000 NIC by: $ qemu-system-ppc64 -M ppce500 -smp 4 -m 2G \ -display none -serial stdio \ -bios u-boot \ - -nic tap,ifname=tap0,script=no,downscript=no,model=e1000 + -nic tap,ifname=tap0,script=,downscript=,model=e1000 The QEMU ``ppce500`` machine can also dynamically instantiate an eTSEC device if “-device eTSEC” is given to QEMU: .. code-block:: bash - -netdev tap,ifname=tap0,script=no,downscript=no,id=net0 -device eTSEC,netdev=net0 + -netdev tap,ifname=tap0,script=,downscript=,id=net0 -device eTSEC,netdev=net0 Root file system on flash drive -------------------------------
docs/system/riscv/microchip-icicle-kit.rst +1 -1
@@ -84,7 +84,7 @@ Then we can boot the machine by: $ qemu-system-riscv64 -M microchip-icicle-kit -smp 5 -m 2G \ -sd path/to/sdcard.img \ -nic user,model=cadence_gem \ - -nic tap,ifname=tap,model=cadence_gem,script=no \ + -nic tap,ifname=tap,model=cadence_gem,script= \ -display none -serial stdio \ -kernel path/to/u-boot/build/dir/u-boot.bin \ -dtb path/to/u-boot/build/dir/u-boot.dtb
docs/system/riscv/sifive_u.rst +1 -1
@@ -199,7 +199,7 @@ To boot the VxWorks kernel in QEMU with the ``sifive_u`` machine, use: $ qemu-system-riscv64 -M sifive_u -smp 5 -m 2G \ -display none -serial stdio \ - -nic tap,ifname=tap0,script=no,downscript=no \ + -nic tap,ifname=tap0,script=,downscript= \ -kernel /path/to/vxWorks \ -append "gem(0,0)host:vxWorks h=192.168.200.1 e=192.168.200.2:ffffff00 u=target pw=vxTarget f=0x01"
qapi/net.json +10 -4
@@ -399,15 +399,21 @@ # @fds: multiple file descriptors of already opened multiqueue capable # tap # -# @script: script to initialize the interface. An empty string or -# "no" disables script execution. Defaults to +# @script: script to initialize the interface. An empty string +# disables script execution. Defaults to # ``<sysconfdir>/qemu-ifup``, where ``<sysconfdir>`` is the # system configuration directory at build time (typically /etc). +# Using "no" to disable script execution is deprecated (since +# 11.2); use an empty string instead. In a future version, "no" +# will be treated as a plain file name. # -# @downscript: script to shut down the interface. An empty string or -# "no" disables script execution. Defaults to +# @downscript: script to shut down the interface. An empty string +# disables script execution. Defaults to # ``<sysconfdir>/qemu-ifdown``, where ``<sysconfdir>`` is the # system configuration directory at build time (typically /etc). +# Using "no" to disable script execution is deprecated (since +# 11.2); use an empty string instead. In a future version, "no" +# will be treated as a plain file name. # # @br: bridge name (since 2.8) #
net/tap.c +11 -6
@@ -92,7 +92,8 @@ static void launch_script(const char *setup_script, const char *ifname,static void tap_send (void *opaque);static void tap_writable (void *opaque); -static bool tap_is_explicit_no_script (const char *script_arg_value) +static bool tap_is_explicit_no_script (const char *script_arg_name, +const char *script_arg_value) {if (!script_arg_value) {return false;
@@ -103,16 +104,19 @@ static bool tap_is_explicit_no_script(const char *script_arg_value) }if (strcmp (script_arg_value,"no" ) ==0 ) { +warn_report ("'%s=no' is deprecated; use '%s=' instead" , + script_arg_name, script_arg_name);return true; }return false; } -static char *tap_parse_script (const char *script_arg_value, +static char *tap_parse_script (const char *script_arg_name, +const char *script_arg_value,const char *default_path) { -if (tap_is_explicit_no_script (script_arg_value)) { +if (tap_is_explicit_no_script (script_arg_name, script_arg_value)) {return NULL ; }
@@ -741,7 +745,7 @@ static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,qemu_set_info_str (&s->nc,"helper=%s" , tap->helper); }else {qemu_set_info_str (&s->nc,"ifname=%s,script=%s,downscript=%s" , ifname, - script ?:"no" , downscript ?:"no" ); + script ?:"" , downscript ?:"" );if (downscript) {snprintf (s->down_script,sizeof (s->down_script),"%s" , downscript);
@@ -947,9 +951,10 @@ int net_init_tap(const Netdev *netdev, const char *name, } }else { g_autofree char *script = -tap_parse_script (tap->script,DEFAULT_NETWORK_SCRIPT ); +tap_parse_script ("script" , tap->script,DEFAULT_NETWORK_SCRIPT ); g_autofree char *downscript = -tap_parse_script (tap->downscript,DEFAULT_NETWORK_DOWN_SCRIPT ); +tap_parse_script ("downscript" , tap->downscript, +DEFAULT_NETWORK_DOWN_SCRIPT );if (tap->ifname) {pstrcpy (ifname,sizeof ifname, tap->ifname);
qemu-options.hx +6 -2
@@ -3022,7 +3022,8 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, " use network scripts 'file' (default=" DEFAULT_NETWORK_SCRIPT ")\n" " to configure it and 'dfile' (default=" DEFAULT_NETWORK_DOWN_SCRIPT ")\n" " to deconfigure it\n" - " use '[down]script=no' or '[down]script=' to disable script execution\n" + " use '[down]script=' to disable script execution\n" + " ('[down]script=no' is deprecated and will be treated as a file name in future)\n" " use network helper 'helper' (default=" DEFAULT_BRIDGE_HELPER ") to\n" " configure it\n" " use 'fd=h' to connect to an already opened TAP interface\n"
@@ -3561,7 +3562,10 @@ SRST ``<sysconfdir>/qemu-ifup`` and the default network deconfigure script is ``<sysconfdir>/qemu-ifdown``, where ``<sysconfdir>`` is the system configuration directory at build time (typically ``/etc``). - Use ``[down]script=no`` or ``[down]script=`` to disable script execution. + Use ``[down]script=`` to disable script execution. + Using ``[down]script=no`` is deprecated; it disables script + execution now, but in a future version it will be treated as a + plain file name. If running QEMU as an unprivileged user, use the network helper to configure the TAP interface and attach it to the bridge.
Signature · 1 line
MST
[PULL v2 06/75] hw/display: add vhost-user-media device
In reply to Michael S. TsirkinFrom: Albert Esteve <[email protected]>
Add the QEMU side of the vhost-user-media device, which connects to a virtio-media vhost-user backend daemon implementing the V4L2 API over the virtio-media protocol.
The virtio-media device is specified in the VirtIO specification v1.4, section 5.22:
https://docs.oasis-open.org/virtio/virtio/v1.4/cs01/virtio-v1.4-cs01.html
Tested with the rust-vmm vhost-device-media backend [1]:
cargo run -- -s /path/to/media.sock -d /dev/video0 --backend v4l2-proxy
Example invocation:
qemu-system-x86_64 \
-chardev socket,path=/path/to/media.sock,id=media \
-device vhost-user-media-pci,chardev=media,id=media[1] https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-media
Message-ID: <[email protected]>
--- MAINTAINERS | 6 + include/hw/virtio/vhost-user-media.h | 46 ++++ hw/display/vhost-user-media-pci.c | 80 ++++++ hw/display/vhost-user-media.c | 348 +++++++++++++++++++++++++++ hw/virtio/virtio.c | 3 +- hw/display/Kconfig | 5 + hw/display/meson.build | 3 + 7 files changed, 490 insertions(+), 1 deletion(-) create mode 100644 include/hw/virtio/vhost-user-media.h create mode 100644 hw/display/vhost-user-media-pci.c create mode 100644 hw/display/vhost-user-media.c
MAINTAINERS +6 -0
@@ -2690,6 +2690,12 @@ S: Supported F: include/hw/virtio/vhost-user-rtc.h F: hw/virtio/vhost-user-rtc* +vhost-user-media +M: Albert Esteve <[email protected]> +S: Supported +F: hw/display/vhost-user-media* +F: include/hw/virtio/vhost-user-media.h + virtio-crypto M: Gonglei <[email protected]> S: Supported
include/hw/virtio/vhost-user-media.h new file +46 -0
46 lines not on this page · raw message
hw/display/vhost-user-media-pci.c new file +80 -0
80 lines not on this page · raw message
hw/display/vhost-user-media.c new file +348 -0
348 lines not on this page · raw message
hw/virtio/virtio.c +2 -1
@@ -198,7 +198,8 @@ const char *virtio_device_names[] = { [VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol", [VIRTIO_ID_BT] = "virtio-bluetooth", [VIRTIO_ID_GPIO] = "virtio-gpio", - [VIRTIO_ID_SPI] = "virtio-spi" + [VIRTIO_ID_SPI] = "virtio-spi", + [VIRTIO_ID_MEDIA] = "virtio-media", };static const char *virtio_id_to_name (uint16_t device_id)
hw/display/Kconfig +5 -0
@@ -120,6 +120,11 @@ config VHOST_USER_VGA default y depends on VIRTIO_VGA && VHOST_USER_GPU +config VHOST_USER_MEDIA + bool + default y + depends on VIRTIO && VHOST_USER + config DPCD bool select AUX
hw/display/meson.build +3 -0
@@ -37,6 +37,9 @@ system_ss.add(when: 'CONFIG_NEXTCUBE', if_true: files('next-fb.c')) system_ss.add(when: 'CONFIG_VGA', if_true: files('vga.c')) system_ss.add(when: 'CONFIG_VIRTIO', if_true: files('virtio-dmabuf.c')) system_ss.add(when: 'CONFIG_DM163', if_true: files('dm163.c')) +system_ss.add(when: 'CONFIG_VHOST_USER_MEDIA', if_true: files('vhost-user-media.c')) +system_ss.add(when: ['CONFIG_VHOST_USER_MEDIA', 'CONFIG_VIRTIO_PCI'], + if_true: files('vhost-user-media-pci.c')) stub_ss.add([files('acpi-vga-stub.c'), pixman]) if (config_all_devices.has_key('CONFIG_VGA_CIRRUS') or
Signature · 1 line
MST
[PULL v2 28/75] hw/cxl: Add configurable CXL Fixed Memory Window restriction flags
In reply to Michael S. TsirkinFrom: Davidlohr Bueso <[email protected]>
Expose the CFMWS "Window Restrictions" (CXL r4.0 9.18.1.3) as named per-window machine properties -- device-coherent, host-only, volatile, persistent, fixed-config and back-invalidate -- so the advertised restrictions can be configured per window rather than left at the default.
No changes in default options. HDM-D and HDM-H are advertised by default; disabling one (device-coherent=off or host-only=off) narrows the window to the other. back-invalidate implies device-coherent (HDM-DB) and suppresses the host-only default. host-only coherent combined with back-invalidate is rejected as undefined behavior per the spec.
Message-ID: <[email protected]>
--- docs/system/devices/cxl.rst | 25 ++++++++++++-------- qapi/machine.json | 28 ++++++++++++++++++++++ include/hw/cxl/cxl.h | 12 ++++++++++ hw/acpi/cxl.c | 2 +- hw/cxl/cxl-host.c | 46 +++++++++++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 11 deletions(-)
docs/system/devices/cxl.rst +15 -10
@@ -384,8 +384,13 @@ An example of 4 devices below a switch suitable for 1, 2 or 4 way interleave:: -device cxl-type3,bus=swport3,persistent-memdev=cxl-mem3,lsa=cxl-lsa3,id=cxl-pmem3,sn=0x4 \ -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k -An example of 4 type3 devices with volatile memory below a switch. Two of the devices -use HDM-DB for coherence, which requires operating in Flit mode:: +An example of a mixed configuration across two host bridges, each with its +own CXL window. Below cxl.1, two type3 volatile devices behind a switch use +HDM-DB for coherence, which requires operating in Flit mode and a window +that permits the device-coherent Back-Invalidate model. Below cxl.2, two +plain host-only devices are directly attached and use the default window. +Because a window targets a host bridge, giving each coherency model its own +bridge keeps the window-to-device mapping explicit:: qemu-system-x86_64 -M q35,cxl=on -m 4G,maxmem=8G,slots=8 -smp 4 \ ...
@@ -395,17 +400,17 @@ use HDM-DB for coherence, which requires operating in Flit mode:: -object memory-backend-ram,id=cxl-mem3,share=on,size=256M \ -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1 \ -device cxl-rp,port=0,bus=cxl.1,id=root_port0,chassis=0,slot=0 \ - -device cxl-rp,port=1,bus=cxl.1,id=root_port1,chassis=0,slot=1 \ -device cxl-upstream,bus=root_port0,id=us0,x-256b-flit=on \ -device cxl-downstream,port=0,bus=us0,id=swport0,chassis=0,slot=4 \ - -device cxl-type3,bus=swport0,volatile-memdev=cxl-mem0,id=cxl-mem0,sn=0x1,x-256b-flit=on,hdm-db=on \ + -device cxl-type3,bus=swport0,volatile-memdev=cxl-mem0,id=cxl-vmem0,sn=0x1,x-256b-flit=on,hdm-db=on \ -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \ - -device cxl-type3,bus=swport1,volatile-memdev=cxl-mem1,id=cxl-mem1,sn=0x2,x-256b-flit=on,hdm-db=on \ - -device cxl-downstream,port=2,bus=us0,id=swport2,chassis=0,slot=6 \ - -device cxl-type3,bus=swport2,volatile-memdev=cxl-mem2,id=cxl-mem2,sn=0x3 \ - -device cxl-downstream,port=3,bus=us0,id=swport3,chassis=0,slot=7 \ - -device cxl-type3,bus=swport3,volatile-memdev=cxl-mem3,id=cxl-mem3,sn=0x4 \ - -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k + -device cxl-type3,bus=swport1,volatile-memdev=cxl-mem1,id=cxl-vmem1,sn=0x2,x-256b-flit=on,hdm-db=on \ + -device pxb-cxl,bus_nr=222,bus=pcie.0,id=cxl.2 \ + -device cxl-rp,port=0,bus=cxl.2,id=root_port1,chassis=0,slot=6 \ + -device cxl-type3,bus=root_port1,volatile-memdev=cxl-mem2,id=cxl-vmem2,sn=0x3 \ + -device cxl-rp,port=1,bus=cxl.2,id=root_port2,chassis=0,slot=7 \ + -device cxl-type3,bus=root_port2,volatile-memdev=cxl-mem3,id=cxl-vmem3,sn=0x4 \ + -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=4k,cxl-fmw.0.back-invalidate=on,cxl-fmw.1.targets.0=cxl.2,cxl-fmw.1.size=4G,cxl-fmw.1.interleave-granularity=4k A simple arm/virt example featuring a single direct connected CXL Type 3 Volatile Memory device::
qapi/machine.json +28 -0
@@ -552,15 +552,43 @@ # accesses will go to a given interleave target. Accepted values # [256, 512, 1k, 2k, 4k, 8k, 16k] # +# @device-coherent: Window permits device-coherent (minimally HDM-D) +# accesses. (since 11.1) +# +# @host-only: Window permits host-only coherent (HDM-H) accesses. +# (since 11.1) +# +# @volatile: Window permits volatile memory. (since 11.1) +# +# @persistent: Window permits persistent memory. (since 11.1) +# +# @fixed-config: Window has a fixed device configuration. Advertised +# in the CEDT only; not otherwise emulated. (since 11.1) +# +# @back-invalidate: Window permits Back-Invalidate (HDM-DB). Implies +# @device-coherent. (since 11.1) +# # @targets: Target root bridge IDs from -device ...,id=<ID> for each # root bridge. # +# Coherency defaults to both device-coherent and host-only; disabling +# one (host-only=off or device-coherent=off) narrows to the other. +# @back-invalidate implies device-coherent and is not host-only. +# @volatile and @persistent default on. host-only coherent combined +# with @back-invalidate is rejected as undefined behavior. +# # Since: 7.1 ## { 'struct': 'CXLFixedMemoryWindowOptions', 'data': { 'size': 'size', '*interleave-granularity': 'size', + '*device-coherent': 'bool', + '*host-only': 'bool', + '*volatile': 'bool', + '*persistent': 'bool', + '*fixed-config': 'bool', + '*back-invalidate': 'bool', 'targets': ['str'] }} ##
include/hw/cxl/cxl.h +12 -0
@@ -27,6 +27,17 @@typedef struct PXBCXLDev PXBCXLDev ; +/* +* CEDT CFMWS "Window Restrictions" bits (CXL r4.0 9.18.1.3), advertising +* which capabilities the host bridges below this window support. +*/ +#define CXL_FMW_DEVICE_COHERENT (1 << 0)/* HDM-D */ +#define CXL_FMW_HOST_ONLY (1 << 1)/* HDM-H */ +#define CXL_FMW_VOLATILE (1 << 2) +#define CXL_FMW_PERSISTENT (1 << 3) +#define CXL_FMW_FIXED_CONFIG (1 << 4) +#define CXL_FMW_BI (1 << 5)/* HDM-DB, Back-Invalidate */ + typedef struct CXLFixedWindow { SysBusDevice parent_obj; int index;
@@ -36,6 +47,7 @@ typedef struct CXLFixedWindow {uint8_t num_targets;uint8_t enc_int_ways;uint8_t enc_int_gran; +uint16_t restrictions;/* Todo: XOR based interleaving */ MemoryRegion mr;hwaddr base;
hw/acpi/cxl.c +1 -1
@@ -172,7 +172,7 @@ static void cedt_build_cfmws(CXLFixedWindow *fw, Aml *cedt)build_append_int_noprefix (table_data, fw->enc_int_gran,4 );/* Window Restrictions */ -build_append_int_noprefix (table_data,0x0f ,2 ); +build_append_int_noprefix (table_data, fw->restrictions,2 );/* QTG ID */ build_append_int_noprefix (table_data,0 ,2 );
hw/cxl/cxl-host.c +46 -0
52 lines not on this page · raw message
Signature · 1 line
MST
[PULL v2 08/75] virtio: reduce code duplication for split ring
In reply to Michael S. TsirkinFrom: Jia Jia <[email protected]>
virtio_queue_empty_rcu duplicates virtqueue_num_heads for no good reason, let's not do it. As a nice side effect, we gain better handling for misbehaving guests.
The virtio_device_disabled() check in virtio_queue_empty_rcu is redundant because virtqueue_split_pop() is only called through virtqueue_pop(), which already performs the check.
Message-ID: <[email protected]>
--- hw/virtio/virtio.c | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-)
hw/virtio/virtio.c +6 -24
@@ -717,26 +717,6 @@ static inline bool is_desc_avail(uint16_t flags, bool wrap_counter)return (avail != used) && (avail == wrap_counter); } -/* Fetch avail_idx from VQ memory only when we really need to know if -* guest has added some buffers. -* Called within rcu_read_lock(). */ -static int virtio_queue_empty_rcu (VirtQueue *vq) -{ -if (virtio_device_disabled (vq->vdev)) { -return 1 ; - } - -if (unlikely (!vq->vring.avail)) { -return 1 ; - } - -if (vq->shadow_avail_idx != vq->last_avail_idx) { -return 0 ; - } - -return vring_avail_idx (vq) == vq->last_avail_idx; -} -static int virtio_queue_split_empty (VirtQueue *vq) {bool empty;
@@ -1773,12 +1753,14 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz)address_space_cache_init_empty (&indirect_desc_cache);RCU_READ_LOCK_GUARD (); -if (virtio_queue_empty_rcu (vq)) { +if (unlikely (!vq->vring.avail)) { + goto done; + } + + rc =virtqueue_num_heads (vq, vq->last_avail_idx); +if (rc <=0 ) { goto done; } -/* Needed after virtio_queue_empty(), see comment in -* virtqueue_num_heads(). */ -smp_rmb ();/* When we start there are none of either input nor output. */ out_num = in_num = elem_entries =0 ;
Signature · 1 line
MST
[PULL v2 26/75] hw/cxl: Drop Back-Invalidate from default CFMW window restrictions
In reply to Michael S. TsirkinFrom: Davidlohr Bueso <[email protected]>
The default CXL Fixed Memory Window restrictions advertised host-only coherent together with Back-Invalidate. A window advertising both simultaneously is undefined behavior per CXL r4.0 9.18.1.3.
Drop Back-Invalidate from the default, leaving device-coherent + host-only + volatile + persistent.
Message-ID: <[email protected]>
--- hw/acpi/cxl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
hw/acpi/cxl.c +1 -1
@@ -172,7 +172,7 @@ static void cedt_build_cfmws(CXLFixedWindow *fw, Aml *cedt)build_append_int_noprefix (table_data, fw->enc_int_gran,4 );/* Window Restrictions */ -build_append_int_noprefix (table_data,0x2f ,2 ); +build_append_int_noprefix (table_data,0x0f ,2 );/* QTG ID */ build_append_int_noprefix (table_data,0 ,2 );
Signature · 1 line
MST
[PULL v2 07/75] hw/display/vhost-user-media: add shared memory region BAR
In reply to Michael S. TsirkinFrom: Albert Esteve <[email protected]>
Expose virtio-media shared memory region 0 (spec 5.22.6.1.6) as a prefetchable 64-bit PCI BAR (BAR 2) with a VirtIO shm capability. The size is obtained through GET_SHMEM_CONFIG and requires at least one shared region. The guest maps host-provisioned MMAP buffers into this window; QEMU creates a container region on realize, not a full-sized RAM allocation.
modern-pio-notify is rejected because it claims BAR 2.
vhost-user still needs shareable guest RAM, e.g.:
-object memory-backend-memfd,id=mem,size=4G,share=on \
-numa node,memdev=memMessage-ID: <[email protected]>
--- hw/display/vhost-user-media-pci.c | 35 ++++++++++++++++++++++++++ hw/display/vhost-user-media.c | 42 ++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-)
hw/display/vhost-user-media-pci.c +35 -0
@@ -13,12 +13,18 @@#include "hw/virtio/vhost-user-media.h" #include "hw/virtio/virtio-pci.h" +/* BAR 2 is used for the shared memory region exposed to the guest */ +#define VIRTIO_MEDIA_PCI_SHM_BAR 2 + +#define VIRTIO_MEDIA_PCI_SHMCAP_ID_SHM 0 +#define TYPE_VHOST_USER_MEDIA_PCI "vhost-user-media-pci-base" OBJECT_DECLARE_SIMPLE_TYPE(VHostUserMEDIAPCI, VHOST_USER_MEDIA_PCI)struct VHostUserMEDIAPCI {VirtIOPCIProxy parent_obj;VHostUserMEDIA vdev; +MemoryRegion shmbar; };static const Property vumedia_pci_properties[] = {
@@ -32,14 +38,43 @@ static void vumedia_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) {VHostUserMEDIAPCI *dev =VHOST_USER_MEDIA_PCI (vpci_dev);DeviceState *dev_state =DEVICE (&dev->vdev); +VirtIODevice *vdev =VIRTIO_DEVICE (dev_state); +VirtioSharedMemory *shmem; +uint64_t shm_size;if (vpci_dev->nvectors ==DEV_NVECTORS_UNSPECIFIED ) { vpci_dev->nvectors =1 ; } +if (vpci_dev->flags &VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY ) { +error_setg (errp,"modern-pio-notify is not supported due to PCI BAR " +"layout limitations" ); +return ; + } +if (!qdev_realize (dev_state,BUS (&vpci_dev->bus), errp)) {return ; } + + shmem =virtio_find_shmem_region (vdev,VIRTIO_MEDIA_PCI_SHMCAP_ID_SHM ); +if (!shmem) { +error_setg (errp,"vhost-user-media: missing shared memory region" ); +return ; + } + shm_size =memory_region_size (&shmem->mr); + +memory_region_init (&dev->shmbar,OBJECT (vpci_dev), +"vhost-media-pci-shmbar" , shm_size); +memory_region_add_subregion (&dev->shmbar,0 , &shmem->mr); +virtio_pci_add_shm_cap (vpci_dev,VIRTIO_MEDIA_PCI_SHM_BAR ,0 , + shm_size,VIRTIO_MEDIA_PCI_SHMCAP_ID_SHM ); + +/* After 'realized' so the memory region exists */ +pci_register_bar (&vpci_dev->pci_dev,VIRTIO_MEDIA_PCI_SHM_BAR , +PCI_BASE_ADDRESS_SPACE_MEMORY | +PCI_BASE_ADDRESS_MEM_PREFETCH | +PCI_BASE_ADDRESS_MEM_TYPE_64 , + &dev->shmbar); }static void vumedia_pci_class_init (ObjectClass *klass,const void *data)
hw/display/vhost-user-media.c +41 -1
64 lines not on this page · raw message
Signature · 1 line
MST
[PULL v2 32/75] hw/virtio-blk: Complete zone-append cookies
In reply to Michael S. TsirkinFrom: Hanna Czenczek <[email protected]>
virtio_blk_handle_zone_append() starts accounting via block_acct_start(), but this is actually never completed. Do so.
Message-ID: <[email protected]>
--- hw/block/virtio-blk.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
hw/block/virtio-blk.c +7 -1
@@ -755,7 +755,8 @@ static void virtio_blk_zone_append_complete(void *opaque, int ret) {ZoneCmdData *data = opaque;VirtIOBlockReq *req = data->req; -VirtIODevice *vdev =VIRTIO_DEVICE (req->dev); +VirtIOBlock *s = req->dev; +VirtIODevice *vdev =VIRTIO_DEVICE (s);int64_t append_sector, n;uint8_t err_status =VIRTIO_BLK_S_OK ;
@@ -778,6 +779,11 @@ static void virtio_blk_zone_append_complete(void *opaque, int ret) out:virtio_blk_req_complete (req, err_status); +if (err_status ==VIRTIO_BLK_S_OK ) { +block_acct_done (blk_get_stats (s->blk), &req->acct); + }else { +block_acct_failed (blk_get_stats (s->blk), &req->acct); + }g_free (req);g_free (data); }
Signature · 1 line
MST
[PULL v2 14/75] net/tap: use container_of instead of DO_UPCAST
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
We are going to QOMify tap backend, which includes deriving TAPState from Object. So "NetClientState nc" will not be a first member. Let's parepare for this change, and use container_of(), which will work regardless position of "nc" field.
Message-ID: <[email protected]>
--- net/tap.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
net/tap.c +18 -18
@@ -175,7 +175,7 @@ static ssize_t tap_write_packet(TAPState *s, const struct iovec *iov, int iovcntstatic ssize_t tap_receive_iov (NetClientState *nc,const struct iovec *iov,int iovcnt) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);const struct iovec *iovp = iov; g_autofree struct iovec *iov_copy = NULL;struct virtio_net_hdr hdr = { };
@@ -211,7 +211,7 @@ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)static void tap_send_completed (NetClientState *nc,ssize_t len) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);tap_read_poll (s, true); }
@@ -271,7 +271,7 @@ static void tap_send(void *opaque)static bool tap_has_ufo (NetClientState *nc) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );
@@ -280,7 +280,7 @@ static bool tap_has_ufo(NetClientState *nc)static bool tap_has_uso (NetClientState *nc) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );
@@ -289,7 +289,7 @@ static bool tap_has_uso(NetClientState *nc)static bool tap_has_tunnel (NetClientState *nc) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );return s->has_tunnel;
@@ -297,7 +297,7 @@ static bool tap_has_tunnel(NetClientState *nc)static bool tap_has_vnet_hdr (NetClientState *nc) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );
@@ -311,7 +311,7 @@ static bool tap_has_vnet_hdr_len(NetClientState *nc, int len)static void tap_set_vnet_hdr_len (NetClientState *nc,int len) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );
@@ -322,21 +322,21 @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len)static int tap_set_vnet_le (NetClientState *nc,bool is_le) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);return tap_fd_set_vnet_le (s->fd, is_le); }static int tap_set_vnet_be (NetClientState *nc,bool is_be) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);return tap_fd_set_vnet_be (s->fd, is_be); }static void tap_set_offload (NetClientState *nc,const NetOffloads *ol) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);if (s->fd <0 ) {return ; }
@@ -357,7 +357,7 @@ static void tap_exit_notify(Notifier *notifier, void *data)static void tap_cleanup (NetClientState *nc) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);if (s->vhost_net) {vhost_net_cleanup (s->vhost_net);
@@ -381,14 +381,14 @@ static void tap_cleanup(NetClientState *nc)static void tap_poll (NetClientState *nc,bool enable) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);tap_read_poll (s, enable);tap_write_poll (s, enable); }static bool tap_set_steering_ebpf (NetClientState *nc,int prog_fd) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );return tap_fd_set_steering_ebpf (s->fd, prog_fd) ==0 ;
@@ -396,7 +396,7 @@ static bool tap_set_steering_ebpf(NetClientState *nc, int prog_fd)int tap_get_fd (NetClientState *nc) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );return s->fd; }
@@ -408,7 +408,7 @@ int tap_get_fd(NetClientState *nc)*/ static VHostNetState *tap_get_vhost_net (NetClientState *nc) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);assert (nc->info->type ==NET_CLIENT_DRIVER_TAP );return s->vhost_net; }
@@ -447,7 +447,7 @@ static TAPState *net_tap_fd_init(NetClientState *peer, nc =qemu_new_net_client (&net_tap_info, peer, model, name); - s =DO_UPCAST (TAPState, nc, nc); + s =container_of (nc, TAPState, nc); s->fd = fd; s->host_vnet_hdr_len = vnet_hdr ?sizeof (struct virtio_net_hdr ) :0 ;
@@ -1016,7 +1016,7 @@ fail:int tap_enable (NetClientState *nc) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);int ret;if (s->enabled) {
@@ -1033,7 +1033,7 @@ int tap_enable(NetClientState *nc)int tap_disable (NetClientState *nc) { -TAPState *s =DO_UPCAST (TAPState, nc, nc); +TAPState *s =container_of (nc, TAPState, nc);int ret;if (s->enabled ==0 ) {
Signature · 1 line
MST
[PULL v2 55/75] hw/cxl: fix the CDAT DOE overlapping the Flex Bus DVSEC when sn= is set
In reply to Michael S. TsirkinFrom: Junjie Cao <[email protected]>
ct3_realize() adds the CDAT DOE at a fixed 0x190. Since 8700ee15de the four DVSECs take 0x90 bytes, which from 0x100 ends exactly at 0x190. With sn= the Device Serial Number capability pushes the block to 0x10c..0x19c, and the DOE, added later, overwrites the last 12 bytes of the Flex Bus Port DVSEC: Capability2, Control2 and Status2. Nothing catches this -- pcie_add_capability() checks bounds, not overlap, and the chain still walks because the DVSEC's next pointer becomes 0x190, inside its own body. Most cxl-type3 examples in docs/system/devices/cxl.rst set sn=.
Derive the offset from the DVSEC block instead, as cxl_upstream.c already does. Without sn= the layout is unchanged byte for byte; with sn= the DOE moves to 0x19c, below the AER capability at 0x200. The type 3 device has no VMStateDescription, so its config space never reaches the migration stream.
Message-ID: <[email protected]>
--- hw/mem/cxl_type3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
hw/mem/cxl_type3.c +2 -2
@@ -936,8 +936,8 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp) }/* DOE Initialization */ -pcie_doe_init (pci_dev, &ct3d->doe_cdat,0x190 , doe_cdat_prot, true, -CXL_T3_MSIX_PCIE_DOE_TABLE_ACCESS ); +pcie_doe_init (pci_dev, &ct3d->doe_cdat, cxl_cstate->dvsec_offset, + doe_cdat_prot, true,CXL_T3_MSIX_PCIE_DOE_TABLE_ACCESS ); cxl_cstate->cdat.build_cdat_table = ct3_build_cdat_table; cxl_cstate->cdat.free_cdat_table = ct3_free_cdat_table;
Signature · 1 line
MST
[PULL v2 27/75] tests/acpi/cxl: Update CEDT.cxl for the default CFMW restrictions
In reply to Michael S. TsirkinFrom: Davidlohr Bueso <[email protected]>
With the default CXL Fixed Memory Window restrictions changed to drop Back-Invalidate (keeping device-coherent and host-only), update the expected CEDT to advertise 0x0f instead of 0x2f.
[064h 0100 001h] Subtable Type : 01 [CXL Fixed Memory Window Structure]
[065h 0101 001h] Reserved : 00
[066h 0102 002h] Length : 0028
[068h 0104 004h] Reserved : 00000000
[06Ch 0108 008h] Window base address : 0000000110000000
[074h 0116 008h] Window size : 0000000100000000
[07Ch 0124 001h] Interleave Members : 00
[07Dh 0125 001h] Interleave Arithmetic : 00
[07Eh 0126 002h] Reserved : 0000
[080h 0128 004h] Granularity : 00000005
[084h 0132 002h] Restrictions : 000F
[086h 0134 002h] QtgId : 0000
[088h 0136 004h] First Target : 0000000C
Message-ID: <[email protected]>
--- tests/qtest/bios-tables-test-allowed-diff.h | 1 - tests/data/acpi/x86/q35/CEDT.cxl | Bin 184 -> 184 bytes 2 files changed, 1 deletion(-)
tests/qtest/bios-tables-test-allowed-diff.h +0 -1
@@ -1,2 +1 @@/* List of comma-separated changed AML files to ignore */ -"tests/data/acpi/x86/q35/CEDT.cxl",
tests/data/acpi/x86/q35/CEDT.cxl binary +0 -0
Signature · 1 line
MST
[PULL v2 03/75] virtio-pci: reject Q_ENABLE write on already-enabled queue
In reply to Michael S. TsirkinWhen the guest writes 1 to the VIRTIO_PCI_COMMON_Q_ENABLE field of a queue that is already enabled, QEMU re-applies the ring geometry stored in the PCI proxy shadow registers by calling virtio_queue_set_num() and virtio_queue_set_rings(). Those functions update the vring descriptor, available, and used addresses and the region cache, but they do not touch the host-side progress fields - last_avail_idx, shadow_avail_idx, used_idx, inuse, and the packed-ring wrap counters - which are only zeroed by __virtio_queue_reset().
Because the progress indices are stale while the ring layout is new, the host can treat the new ring as though there are up to 65535 pending descriptors already waiting, causing virtqueue_pop() to iterate far beyond what the guest actually posted. On virtio-iommu this translates into a stream of ATTACH/DETACH/MAP/UNMAP commands, driving the QEMU process toward OOM from guest-controlled BAR writes.
The virtio specification requires the driver to complete a full queue reset cycle before re-enabling a queue. Fix this by checking the proxy's per-queue enabled flag before processing the write. If the queue is already enabled, log the violation as a guest error and ignore the write.
--- hw/virtio/virtio-pci.c | 7 +++++++ 1 file changed, 7 insertions(+)
hw/virtio/virtio-pci.c +7 -0
@@ -1692,6 +1692,13 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,break ;case VIRTIO_PCI_COMMON_Q_ENABLE :if (val ==1 ) { +if (proxy->vqs[vdev->queue_sel].enabled) { +qemu_log_mask (LOG_GUEST_ERROR , +"%s: queue %d already enabled - " +"reset queue before re-enabling\n" , + __func__, vdev->queue_sel); +break ; + }virtio_queue_set_num (vdev, vdev->queue_sel, proxy->vqs[vdev->queue_sel].num); virtio_queue_set_rings(vdev, vdev->queue_sel,
Signature · 1 line
MST
[PULL v2 31/75] hw/virtio-blk: Account discard operations
In reply to Michael S. TsirkinFrom: Hanna Czenczek <[email protected]>
The acct_failed argument to virtio_blk_handle_rw_error() tells whether there is accounting for this operation or not. The only operation for which there is none is discarding, which seems to be because at the time of the introducing commit 37b06f8d46f ("virtio-blk: add DISCARD and WRITE_ZEROES features"), BlockAcctType did not yet have a BLOCK_ACCT_UNMAP variant.
It does have that now, though, so we may as well track those discard operations with it, and can thus remove the acct_failed parameter.
Message-ID: <[email protected]>
--- hw/block/virtio-blk.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-)
hw/block/virtio-blk.c +11 -15
@@ -69,7 +69,7 @@ void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status) }static int virtio_blk_handle_rw_error (VirtIOBlockReq *req,int error, -bool is_read,bool acct_failed) +bool is_read) {VirtIOBlock *s = req->dev;BlockErrorAction action =blk_get_error_action (s->blk, is_read, error);
@@ -85,9 +85,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, } }else if (action ==BLOCK_ERROR_ACTION_REPORT ) {virtio_blk_req_complete (req,VIRTIO_BLK_S_IOERR ); -if (acct_failed) { -block_acct_failed (blk_get_stats (s->blk), &req->acct); - } +block_acct_failed (blk_get_stats (s->blk), &req->acct);g_free (req); }
@@ -124,7 +122,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret)* the memory until the request is completed (which will * happen on the other side of the migration). */ -if (virtio_blk_handle_rw_error (req, -ret, is_read, true)) { +if (virtio_blk_handle_rw_error (req, -ret, is_read)) {continue ; } }
@@ -140,7 +138,7 @@ static void virtio_blk_flush_complete(void *opaque, int ret)VirtIOBlockReq *req = opaque;VirtIOBlock *s = req->dev; -if (ret &&virtio_blk_handle_rw_error (req, -ret,0 , true)) { +if (ret &&virtio_blk_handle_rw_error (req, -ret,0 )) {return ; }
@@ -153,17 +151,13 @@ static void virtio_blk_discard_write_zeroes_complete(void *opaque, int ret) {VirtIOBlockReq *req = opaque;VirtIOBlock *s = req->dev; -bool is_write_zeroes = (virtio_ldl_p (VIRTIO_DEVICE (s), &req->out.type) & - ~VIRTIO_BLK_T_BARRIER ) ==VIRTIO_BLK_T_WRITE_ZEROES ; -if (ret &&virtio_blk_handle_rw_error (req, -ret, false, is_write_zeroes)) { +if (ret &&virtio_blk_handle_rw_error (req, -ret, false)) {return ; }virtio_blk_req_complete (req,VIRTIO_BLK_S_OK ); -if (is_write_zeroes) { -block_acct_done (blk_get_stats (s->blk), &req->acct); - } +block_acct_done (blk_get_stats (s->blk), &req->acct);g_free (req); }
@@ -443,6 +437,9 @@ static uint8_t virtio_blk_handle_discard_write_zeroes(VirtIOBlockReq *req, goto err; } +block_acct_start (blk_get_stats (s->blk), &req->acct, bytes, +BLOCK_ACCT_UNMAP ); +blk_aio_pdiscard (s->blk, sector <<BDRV_SECTOR_BITS , bytes, virtio_blk_discard_write_zeroes_complete, req); }
@@ -450,9 +447,8 @@ static uint8_t virtio_blk_handle_discard_write_zeroes(VirtIOBlockReq *req,return VIRTIO_BLK_S_OK ; err: -if (is_write_zeroes) { -block_acct_invalid (blk_get_stats (s->blk),BLOCK_ACCT_WRITE ); - } +block_acct_invalid (blk_get_stats (s->blk), + is_write_zeroes ?BLOCK_ACCT_WRITE :BLOCK_ACCT_UNMAP );return err_status; }
Signature · 1 line
MST
[PULL v2 16/75] net/tap: add TYPE_VMSTATE_IF interface
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
We'll need it to implement TAP backend live migration.
Message-ID: <[email protected]>
--- net/tap.c | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-)
net/tap.c +34 -9
@@ -43,7 +43,6 @@#include "qemu/main-loop.h" #include "qemu/sockets.h" #include "hw/virtio/vhost.h" -#include "qom/object.h" #include "net/tap.h" #include "net/util.h"
@@ -91,6 +90,8 @@ struct TAPState {VHostNetState *vhost_net;unsigned host_vnet_hdr_len;Notifier exit; + +int queue_index; }; static void launch_script(const char *setup_script, const char *ifname,
@@ -419,10 +420,29 @@ static VHostNetState *tap_get_vhost_net(NetClientState *nc) } +static char *tap_vmstate_if_get_id (VMStateIf *obj) +{ +TAPState *s =TAP_NETDEV (obj); +char *res =g_strdup_printf ("%s/%d" , s->nc.name, s->queue_index); +return res; +} + +static void tap_class_init (ObjectClass *klass,const void *data) +{ +VMStateIfClass *vc =VMSTATE_IF_CLASS (klass); + + vc->get_id = tap_vmstate_if_get_id; +} +static const TypeInfo tap_netdev_info = { .name =TYPE_TAP_NETDEV , .parent =TYPE_OBJECT , .instance_size =sizeof (TAPState), + .class_init = tap_class_init, + .interfaces = (const InterfaceInfo []) { + {TYPE_VMSTATE_IF }, + { } + }, };static void tap_net_client_destructor (NetClientState *nc)
@@ -455,13 +475,16 @@ static NetClientInfo net_tap_info = {static TAPState *new_tap (NetClientState *peer,const char *model, -const char *name) +const char *name, +int queue_index) {TAPState *s =TAP_NETDEV (object_new (TYPE_TAP_NETDEV ));qemu_net_client_setup (&s->nc, &net_tap_info, peer, model, name, tap_net_client_destructor, true); + s->queue_index = queue_index; +return s; }
@@ -469,10 +492,11 @@ static TAPState *net_tap_fd_init(NetClientState *peer,const char *model, const char *name, int fd, - int vnet_hdr) + int vnet_hdr, + int queue_index) { NetOffloads ol = {}; -TAPState *s =new_tap (peer, model, name); +TAPState *s =new_tap (peer, model, name, queue_index); s->fd = fd; s->host_vnet_hdr_len = vnet_hdr ?sizeof (struct virtio_net_hdr ) :0 ;
@@ -709,7 +733,7 @@ int net_init_bridge(const Netdev *netdev, const char *name,close (fd);return -1 ; } - s =net_tap_fd_init (peer,"bridge" , name, fd, vnet_hdr); + s =net_tap_fd_init (peer,"bridge" , name, fd, vnet_hdr,0 );qemu_set_info_str (&s->nc,"helper=%s,br=%s" , helper, br);
@@ -785,10 +809,11 @@ static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,const char *name, const char *ifname, const char *script, const char *downscript, int vhostfd, - int vnet_hdr, int fd, Error **errp) + int vnet_hdr, int fd, int queue_index, + Error **errp) { TAPState *s = net_tap_fd_init(peer, tap->helper ? "bridge" : "tap", - name, fd, vnet_hdr); + name, fd, vnet_hdr, queue_index);bool sndbuf_required = tap->has_sndbuf;int sndbuf = (tap->has_sndbuf && tap->sndbuf) ?MIN (tap->sndbuf,INT_MAX ) :INT_MAX ;
@@ -989,7 +1014,7 @@ int net_init_tap(const Netdev *netdev, const char *name,if (!net_init_tap_one (tap, peer, name, ifname,NULL ,NULL , vhost_fds ? vhost_fds[i] :-1 , - vnet_hdr, fds[i], errp)) { + vnet_hdr, fds[i], i, errp)) { goto fail; } }
@@ -1024,7 +1049,7 @@ int net_init_tap(const Netdev *netdev, const char *name, i >= 1 ? NULL : script, i >= 1 ? NULL : downscript, vhost_fds ? vhost_fds[i] : -1, - vnet_hdr, fd, errp)) { + vnet_hdr, fd, i, errp)) { goto fail; } }
Signature · 1 line
MST
[PULL v2 37/75] meson: disable "maybe uninitilized" errors with -Og
In reply to Michael S. TsirkinGCC's "maybe uninitilized" warnings depend on optimizations for code flow analysis, and produce false positive errors with -Og. Default build gives us coverage with that, so let's just disable with -Og.
Message-ID: <f559b622eb2d1a384b4f30583a8af10531f4b032.1785144729.git.mst@redhat.com>
--- meson.build | 4 ++++ 1 file changed, 4 insertions(+)
meson.build +4 -0
@@ -746,6 +746,10 @@ warn_flags = [ '-Wno-typedef-redefinition', ] +if get_option('optimization') == 'g' + warn_flags += ['-Wno-error=maybe-uninitialized'] +endif + if host_os != 'darwin' tsa_has_cleanup = cc.compiles(''' struct __attribute__((capability("mutex"))) mutex {};
Signature · 1 line
MST
[PULL v2 20/75] migration: check that transfer is UNIX socket when "local" set
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
As documented, for "local", the migration channel must be direct UNIX socket connection from source to target (except for CPR_EXEC mode). We can't check for it being "direct", but let's at least check that we deal with UNIX socket.
Message-ID: <[email protected]>
--- migration/fd.c | 14 ++++++++++++++ migration/migration.c | 13 +++++++++++++ 2 files changed, 27 insertions(+)
migration/fd.c +14 -0
@@ -39,6 +39,20 @@ static bool fd_is_pipe(int fd)static bool migration_fd_valid (int fd,Error **errp) { +if (migrate_local () &&migrate_mode () !=MIG_MODE_CPR_EXEC ) { +struct sockaddr_storage ss; +socklen_t sslen =sizeof (ss); + +if (getsockname (fd, (struct sockaddr *)&ss, &sslen) <0 || + ss.ss_family !=AF_UNIX ) { +error_setg (errp, +"local migration requires a UNIX domain socket channel" ); +return false; + } + +return true; + } +if (fd_is_socket (fd) ||fd_is_pipe (fd)) {return true; }
migration/migration.c +13 -0
@@ -260,6 +260,19 @@ migration_capabilities_and_transport_compatible(MigrationAddress *addr, errp); } +if (migrate_local () &&migrate_mode () !=MIG_MODE_CPR_EXEC && + (addr->transport !=MIGRATION_ADDRESS_TYPE_SOCKET || + (addr->u.socket.type !=SOCKET_ADDRESS_TYPE_UNIX && + addr->u.socket.type !=SOCKET_ADDRESS_TYPE_FD ))) { +/* +* For SOCKET_ADDRESS_TYPE_FD we do check the fd itself later +* in migration_fd_valid(). +*/ +error_setg (errp, +"local migration requires a UNIX domain socket channel" ); +return false; + } +return true; }
Signature · 1 line
MST
[PULL v2 25/75] tests/bios-tables-test: Exclude CEDT.cxl for the CFMW restriction change
In reply to Michael S. TsirkinFrom: Davidlohr Bueso <[email protected]>
The next patch changes the default CXL Fixed Memory Window restrictions, dropping Back-Invalidate. Add CEDT.cxl to the allowed-diff list so the comparison passes until the expected blob is regenerated.
Message-ID: <[email protected]>
--- tests/qtest/bios-tables-test-allowed-diff.h | 1 + 1 file changed, 1 insertion(+)
tests/qtest/bios-tables-test-allowed-diff.h +1 -0
@@ -1 +1,2 @@/* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/x86/q35/CEDT.cxl",
Signature · 1 line
MST
[PULL v2 17/75] qapi: add local migration parameter
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
We are going to implement local-migration feature: some devices will be able to transfer open file descriptors through migration stream (which must UNIX domain socket for that purpose). This allows to transfer the whole backend state without reconnecting and restarting the backend service. For example, virtio-net will migrate its attached TAP netdev, together with its connected file descriptors.
In this commit we introduce a migration parameter, which enables the feature for devices that support it (none at the moment).
We can't simply auto-detect local migration by checking whether the migration channel is a UNIX domain socket: the UNIX socket may be only the first part of the transfer channel to a remote target. Hence an explicit parameter is needed. Moreover, "local" migration parameter may be useful in cpr-exec mode, when FDs are passed through exec instead of UNIX socket.
Message-ID: <[email protected]>
--- qapi/migration.json | 21 +++++++++++++++++---- include/migration/misc.h | 2 ++ migration/options.c | 18 +++++++++++++++++- 3 files changed, 36 insertions(+), 5 deletions(-)
qapi/migration.json +17 -4
@@ -830,7 +830,8 @@ 'zero-page-detection', 'direct-io', { 'name': 'x-rdma-chunk-size', 'features': [ 'unstable' ] }, - 'cpr-exec-command'] } + 'cpr-exec-command', + 'local'] } ## # @migrate-set-parameters:
@@ -1012,10 +1013,20 @@ # Must be set to the same value on both source and destination # before migration starts. (Since 11.1) # +# @local: Permit the use of optimizations for local migration. This +# must only be set when either both the source and destination +# QEMU processes are directly connected with a UNIX domain socket +# as the migration channel (to enable use of file descriptor +# passing) or cpr-exec migration mode is enabled (this way file +# descriptors are inherited by new process). Individual device +# backends may need additional configuration flags set to enable +# local migration optimizations. This will be documented against +# the device backends where it applies. (Since 11.2) +# # Features: # -# @unstable: Members @x-checkpoint-delay, @x-rdma-chunk-size, and -# @x-vcpu-dirty-limit-period are experimental. +# @unstable: Members @local, @x-checkpoint-delay, @x-rdma-chunk-size, +# and @x-vcpu-dirty-limit-period are experimental. # # Since: 2.4 ##
@@ -1053,7 +1064,9 @@ '*direct-io': 'bool', '*x-rdma-chunk-size': { 'type': 'uint64', 'features': [ 'unstable' ] }, - '*cpr-exec-command': [ 'str' ]} } + '*cpr-exec-command': [ 'str' ], + '*local': { 'type': 'bool', + 'features': [ 'unstable' ] } } } ## # @query-migrate-parameters:
include/migration/misc.h +2 -0
@@ -161,4 +161,6 @@ bool multifd_join_device_state_save_threads(void);void migration_request_switchover_ack_legacy (const char *requester); +bool migrate_local (void ); +#endif
migration/options.c +17 -1
@@ -14,6 +14,7 @@#include "qemu/osdep.h" #include "qemu/error-report.h" #include "qemu/units.h" +#include "qapi/util.h" #include "exec/target_page.h" #include "qapi/clone-visitor.h" #include "qapi/error.h"
@@ -25,6 +26,7 @@#include "migration/colo.h" #include "migration/cpr.h" #include "migration/misc.h" +#include "migration/options.h" #include "migration.h" #include "migration-stats.h" #include "qemu-file.h"
@@ -350,6 +352,12 @@ bool migrate_mapped_ram(void)return s->capabilities[MIGRATION_CAPABILITY_MAPPED_RAM ]; } +bool migrate_local (void ) +{ +MigrationState *s =migrate_get_current (); +return s->parameters.local; +} +bool migrate_ignore_shared (void ) {MigrationState *s =migrate_get_current ();
@@ -1101,7 +1109,7 @@ static void migrate_mark_all_params_present(MigrationParameters *p) &p->has_announce_step, &p->has_block_bitmap_mapping, &p->has_x_vcpu_dirty_limit_period, &p->has_vcpu_dirty_limit, &p->has_mode, &p->has_zero_page_detection, &p->has_direct_io, - &p->has_x_rdma_chunk_size, &p->has_cpr_exec_command, + &p->has_x_rdma_chunk_size, &p->has_cpr_exec_command, &p->has_local, }; len =ARRAY_SIZE (has_fields);
@@ -1449,6 +1457,10 @@ static void migrate_params_test_apply(MigrationParameters *params,qapi_free_strList (dest->cpr_exec_command); dest->cpr_exec_command =QAPI_CLONE (strList, params->cpr_exec_command); } + +if (params->has_local) { + dest->local = params->local; + } }static void migrate_params_apply (MigrationParameters *params)
@@ -1581,6 +1593,10 @@ static void migrate_params_apply(MigrationParameters *params) s->parameters.cpr_exec_command =QAPI_CLONE (strList, params->cpr_exec_command); } + +if (params->has_local) { + s->parameters.local = params->local; + } }void qmp_migrate_set_parameters (MigrationParameters *params,Error **errp)
Signature · 1 line
MST
[PULL v2 50/75] tests/acpi: x86: update golden masters for IVRS
In reply to Michael S. TsirkinFrom: Sairaj Kodilkar <[email protected]>
Differences between disassembled ASL files for IVRS:
/*
* Intel ACPI Component Architecture
* AML/ASL+ Disassembler version 20200925 (64-bit version)
* Copyright (c) 2000 - 2020 Intel Corporation
*
- * Disassembly of tests/data/acpi/x86/q35/IVRS.ivrs, Mon May 11 11:21:47 2026
+ * Disassembly of /tmp/aml-NGQ9O3, Mon May 11 11:21:47 2026
*
* ACPI Data Table [IVRS]
*
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue */
[000h 0000 4] Signature : "IVRS" [I/O Virtualization Reporting Structure] [004h 0004 4] Table Length : 000000B0 [008h 0008 1] Revision : 01 -[009h 0009 1] Checksum : 74 +[009h 0009 1] Checksum : CB [00Ah 0010 6] Oem ID : "BOCHS " [010h 0016 8] Oem Table ID : "BXPC " [018h 0024 4] Oem Revision : 00000001 [01Ch 0028 4] Asl Compiler ID : "BXPC" [020h 0032 4] Asl Compiler Revision : 00000001
-[024h 0036 4] Virtualization Info : 00002801 +[024h 0036 4] Virtualization Info : 00203441 [028h 0040 8] Reserved : 0000000000000000
[030h 0048 1] Subtable Type : 10 [Hardware Definition Block] -[031h 0049 1] Flags : D1 +[031h 0049 1] Flags : 51 [032h 0050 2] Length : 0038 [034h 0052 2] DeviceId : 0010
[036h 0054 2] Capability Offset : 0040 [038h 0056 8] Base Address : 00000000FED80000 [040h 0064 2] PCI Segment Group : 0000 [042h 0066 2] Virtualization Info : 0000 -[044h 0068 4] Feature Reporting : 00000044 +[044h 0068 4] Feature Reporting : A0000064
[048h 0072 1] Entry Type : 02 [049h 0073 2] Device ID : 0000 [04Bh 0075 1] Data Setting : 00
[04Ch 0076 1] Entry Type : 02 [04Dh 0077 2] Device ID : 0008 [04Fh 0079 1] Data Setting : 00
[050h 0080 1] Entry Type : 02 [051h 0081 2] Device ID : 0010 [053h 0083 1] Data Setting : 00
[054h 0084 1] Entry Type : 02 [055h 0085 2] Device ID : 00F8 [057h 0087 1] Data Setting : 00 @@ -62,33 +62,33 @@ [061h 0097 2] Device ID : 0000 [063h 0099 1] Data Setting : 00 [064h 0100 1] Handle : 00 [065h 0101 2] Source Used Device ID : 00A0 [067h 0103 1] Variety : 01
[068h 0104 1] Subtable Type : 11 [Hardware Definition Block] [069h 0105 1] Flags : 11 [06Ah 0106 2] Length : 0048 [06Ch 0108 2] DeviceId : 0010
[06Eh 0110 2] Capability Offset : 0040 [070h 0112 8] Base Address : 00000000FED80000 [078h 0120 2] PCI Segment Group : 0000 [07Ah 0122 2] Virtualization Info : 0000 [07Ch 0124 4] Attributes : 00000000 -[080h 0128 8] EFR Image : 00000000000029D3 +[080h 0128 8] EFR Image : 00000000000028D1 [088h 0136 8] Reserved : 0000000000000000
[090h 0144 1] Entry Type : 02 [091h 0145 2] Device ID : 0000 [093h 0147 1] Data Setting : 00
[094h 0148 1] Entry Type : 02 [095h 0149 2] Device ID : 0008 [097h 0151 1] Data Setting : 00
[098h 0152 1] Entry Type : 02 [099h 0153 2] Device ID : 0010 [09Bh 0155 1] Data Setting : 00
[09Ch 0156 1] Entry Type : 02
[09Dh 0157 2] Device ID : 00F8
@@ -98,27 +98,27 @@
[0A1h 0161 2] Device ID : 00FA
[0A3h 0163 1] Data Setting : 00
[0A4h 0164 1] Entry Type : 02 [0A5h 0165 2] Device ID : 00FB [0A7h 0167 1] Data Setting : 00
[0A8h 0168 1] Entry Type : 48 [0A9h 0169 2] Device ID : 0000 [0ABh 0171 1] Data Setting : 00 [0ACh 0172 1] Handle : 00 [0ADh 0173 2] Source Used Device ID : 00A0 [0AFh 0175 1] Variety : 01
Message-ID: <[email protected]>
--- tests/qtest/bios-tables-test-allowed-diff.h | 1 - tests/data/acpi/x86/q35/IVRS.ivrs | Bin 176 -> 176 bytes 2 files changed, 1 deletion(-)
tests/qtest/bios-tables-test-allowed-diff.h +0 -1
@@ -1,2 +1 @@/* List of comma-separated changed AML files to ignore */ -tests/data/acpi/x86/q35/IVRS .ivrs
tests/data/acpi/x86/q35/IVRS.ivrs binary +0 -0
Signature · 1 line
MST
[PULL v2 29/75] tests/qtest/cxl: Add CXL Fixed Memory Window restriction flag tests
In reply to Michael S. TsirkinFrom: Davidlohr Bueso <[email protected]>
Add a /pci/cxl/cfmw group exercising the configurable CFMWS Window Restrictions.
Message-ID: <[email protected]>
--- tests/qtest/cxl-test.c | 95 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+)
tests/qtest/cxl-test.c +95 -0
@@ -81,6 +81,13 @@"-object memory-backend-file,id=lsa3,mem-path=%s,size=256M " \"-device cxl-type3,bus=rp3,persistent-memdev=cxl-mem3,lsa=lsa3,id=pmem3 " +/* Single pxb + volatile type3 + one window; base for the CFMW tests. */ +#define QEMU_CFMW \ + "-machine q35,cxl=on " \ + "-device pxb-cxl,id=cxl.0,bus=pcie.0,bus_nr=52 " \ + QEMU_RP QEMU_T3D_VMEM \ + "-M cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.size=4G" +static void cxl_basic_hb (void ) {qtest_start ("-machine q35,cxl=on" );
@@ -117,6 +124,81 @@ static void cxl_2root_port(void)qtest_end (); } +/* +* CFMWS "Window Restrictions" (CXL r4.0 9.18.1.3) are configurable per +* window; check that valid restriction sets are accepted. +*/ +static void cxl_cfmw_default (void ) +{ +/* No coherency flag advertises both HDM-D and HDM-H. */ +qtest_start (QEMU_CFMW ); +qtest_end (); +} + +static void cxl_cfmw_host_only_off (void ) +{ +/* Disabling host-only leaves device-coherent (HDM-D). */ +qtest_start (QEMU_CFMW ",cxl-fmw.0.host-only=off" ); +qtest_end (); +} + +static void cxl_cfmw_device_coherent_off (void ) +{ +/* Disabling device-coherent leaves host-only (HDM-H). */ +qtest_start (QEMU_CFMW ",cxl-fmw.0.device-coherent=off" ); +qtest_end (); +} + +static void cxl_cfmw_back_invalidate (void ) +{ +/* Back-Invalidate implies device-coherent (HDM-DB). */ +qtest_start (QEMU_CFMW ",cxl-fmw.0.back-invalidate=on" ); +qtest_end (); +} + +static void cxl_cfmw_fixed_config (void ) +{ +qtest_start (QEMU_CFMW ",cxl-fmw.0.fixed-config=on" ); +qtest_end (); +} + +static void cxl_cfmw_device_and_host (void ) +{ +/* +* device-coherent and host-only may both be advertised (the spec +* permits multiple bits set); this must be accepted -- a regression +* guard against reinstating a device/host-only mutual exclusion. +*/ +qtest_start (QEMU_CFMW +",cxl-fmw.0.device-coherent=on,cxl-fmw.0.host-only=on" ); +qtest_end (); +} + +static void cxl_cfmw_volatile_only (void ) +{ +qtest_start (QEMU_CFMW ",cxl-fmw.0.persistent=off" ); +qtest_end (); +} + +static void cxl_cfmw_persistent_only (void ) +{ +qtest_start (QEMU_CFMW ",cxl-fmw.0.volatile=off" ); +qtest_end (); +} + +/* Two windows in one VM: a Back-Invalidate window and a host-only window. */ +static void cxl_cfmw_two_windows (void ) +{ +qtest_start ("-machine q35,cxl=on " +"-device pxb-cxl,id=cxl.0,bus=pcie.0,bus_nr=52 " +"-device pxb-cxl,id=cxl.1,bus=pcie.0,bus_nr=53 " +QEMU_RP QEMU_T3D_VMEM +"-M cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.size=4G," +"cxl-fmw.0.back-invalidate=on," +"cxl-fmw.1.targets.0=cxl.1,cxl-fmw.1.size=4G" ); +qtest_end (); +} +#ifdef CONFIG_POSIX static void cxl_t3d_deprecated (void ) {
@@ -233,6 +315,19 @@ int main(int argc, char **argv)qtest_add_func ("/pci/cxl/pxb_x2_with_window" , cxl_2pxb_with_window);qtest_add_func ("/pci/cxl/rp" , cxl_root_port);qtest_add_func ("/pci/cxl/rp_x2" , cxl_2root_port); +qtest_add_func ("/pci/cxl/cfmw/default" , cxl_cfmw_default); +qtest_add_func ("/pci/cxl/cfmw/host_only_off" , cxl_cfmw_host_only_off); +qtest_add_func ("/pci/cxl/cfmw/device_coherent_off" , + cxl_cfmw_device_coherent_off); +qtest_add_func ("/pci/cxl/cfmw/back_invalidate" , + cxl_cfmw_back_invalidate); +qtest_add_func ("/pci/cxl/cfmw/fixed_config" , cxl_cfmw_fixed_config); +qtest_add_func ("/pci/cxl/cfmw/device_and_host" , + cxl_cfmw_device_and_host); +qtest_add_func ("/pci/cxl/cfmw/volatile_only" , cxl_cfmw_volatile_only); +qtest_add_func ("/pci/cxl/cfmw/persistent_only" , + cxl_cfmw_persistent_only); +qtest_add_func ("/pci/cxl/cfmw/two_windows" , cxl_cfmw_two_windows);#ifdef CONFIG_POSIX qtest_add_func ("/pci/cxl/type3_device" , cxl_t3d_deprecated);qtest_add_func ("/pci/cxl/type3_device_pmem" , cxl_t3d_persistent);
Signature · 1 line
MST
[PULL v2 24/75] tests/functional: add test_tap_migration
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
Add test for a new local-migration migration of virtio-net/tap, with fd passing through UNIX socket.
Message-ID: <[email protected]>
--- tests/functional/x86_64/meson.build | 1 + tests/functional/x86_64/test_tap_migration.py | 461 ++++++++++++++++++ 2 files changed, 462 insertions(+) create mode 100755 tests/functional/x86_64/test_tap_migration.py
tests/functional/x86_64/meson.build +1 -0
@@ -51,4 +51,5 @@ tests_x86_64_system_thorough = [ 'virtio_balloon', 'virtio_gpu', 'rebuild_vmfd', + 'tap_migration', ]
tests/functional/x86_64/test_tap_migration.py new file +461 -0
461 lines not on this page · raw message
Signature · 1 line
MST
[PULL v2 69/75] vhost-user: add skip_drain param to do_vhost_virtqueue_stop
In reply to Michael S. TsirkinFrom: Alexandr Moshkov <[email protected]>
Currently do_vhost_virtqueue_stop always sends GET_VRING_BASE to the back-end, which requires the back-end to drain all in-flight I/O before stopping the vring.
Add a skip_drain parameter to do_vhost_virtqueue_stop and propagate it up through vhost_virtqueue_stop, vhost_dev_stop and their callers. The parameter will be used in a follow-up commit to send a new protocol message that instructs the back-end to suspend in-flight I/O immediately instead of draining it.
Message-ID: <[email protected]>
--- include/hw/virtio/vhost.h | 7 +++++-- backends/cryptodev-vhost.c | 2 +- backends/vhost-user.c | 2 +- hw/block/vhost-user-blk.c | 2 +- hw/display/vhost-user-media.c | 2 +- hw/net/vhost_net.c | 9 +++++---- hw/scsi/vhost-scsi-common.c | 2 +- hw/virtio/vdpa-dev.c | 2 +- hw/virtio/vhost-user-base.c | 2 +- hw/virtio/vhost-user-fs.c | 2 +- hw/virtio/vhost-user-scmi.c | 2 +- hw/virtio/vhost-vsock-common.c | 2 +- hw/virtio/vhost.c | 28 +++++++++++++++++++--------- 13 files changed, 39 insertions(+), 25 deletions(-)
include/hw/virtio/vhost.h +5 -2
@@ -228,6 +228,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings);* @hdev: common vhost_dev structure * @vdev: the VirtIODevice structure * @vrings: true to have vrings disabled in this call +* @skip_drain: true to notice back-end to skip draining all in-flight requests * * Stop the vhost device. After the device is stopped the notifiers * can be disabled (@vhost_dev_disable_notifiers) and the device can
@@ -235,7 +236,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings);* * Return: 0 on success, != 0 on error when stopping dev. */ -int vhost_dev_stop (struct vhost_dev *hdev,VirtIODevice *vdev,bool vrings); +int vhost_dev_stop (struct vhost_dev *hdev,VirtIODevice *vdev,bool vrings, +bool skip_drain);/** * vhost_dev_force_stop() - force stop the vhost device
@@ -396,7 +398,8 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);int vhost_virtqueue_start (struct vhost_dev *dev,struct VirtIODevice *vdev,struct vhost_virtqueue *vq,unsigned idx);int vhost_virtqueue_stop (struct vhost_dev *dev,struct VirtIODevice *vdev, -struct vhost_virtqueue *vq,unsigned idx); +struct vhost_virtqueue *vq,unsigned idx, +bool skip_drain);void vhost_dev_reset_inflight (struct vhost_inflight *inflight);void vhost_dev_free_inflight (struct vhost_inflight *inflight);
backends/cryptodev-vhost.c +1 -1
@@ -109,7 +109,7 @@ static voidcryptodev_vhost_stop_one (CryptoDevBackendVhost *crypto, VirtIODevice *dev) { -vhost_dev_stop (&crypto->dev, dev, false); +vhost_dev_stop (&crypto->dev, dev, false, false);vhost_dev_disable_notifiers (&crypto->dev, dev); }
backends/vhost-user.c +1 -1
@@ -108,7 +108,7 @@ vhost_user_backend_stop(VhostUserBackend *b)return 0 ; } - ret =vhost_dev_stop (&b->dev, b->vdev, true); + ret =vhost_dev_stop (&b->dev, b->vdev, true, false);if (k->set_guest_notifiers && (err = k->set_guest_notifiers (qbus->parent, b->dev.nvqs, false)) <0 ) {
hw/block/vhost-user-blk.c +1 -1
@@ -238,7 +238,7 @@ static int vhost_user_blk_stop(VirtIODevice *vdev)qemu_force_shutdown_requested (); ret = force_stop ?vhost_dev_force_stop (&s->dev, vdev, true) : -vhost_dev_stop (&s->dev, vdev, true); +vhost_dev_stop (&s->dev, vdev, true, false); err = k->set_guest_notifiers (qbus->parent, s->dev.nvqs, false);if (err <0 ) {
hw/display/vhost-user-media.c +1 -1
@@ -110,7 +110,7 @@ static void vu_media_stop(VirtIODevice *vdev)return ; } -vhost_dev_stop (&media->vhost_dev, vdev, true); +vhost_dev_stop (&media->vhost_dev, vdev, true, false); ret = k->set_guest_notifiers (qbus->parent, media->vhost_dev.nvqs, false);if (ret <0 ) {
hw/net/vhost_net.c +5 -4
@@ -384,7 +384,7 @@ fail:if (net->nc->info->poll) { net->nc->info->poll (net->nc, true); } -vhost_dev_stop (&net->dev, dev, false); +vhost_dev_stop (&net->dev, dev, false, false); fail_start:return r; }
@@ -403,7 +403,7 @@ static void vhost_net_stop_one(struct vhost_net *net,if (net->nc->info->poll) { net->nc->info->poll (net->nc, true); } -vhost_dev_stop (&net->dev, dev, false); +vhost_dev_stop (&net->dev, dev, false, false);if (net->nc->info->stop) { net->nc->info->stop (net->nc); }
@@ -636,7 +636,8 @@ void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc,vhost_virtqueue_stop (&net->dev, vdev, net->dev.vqs + idx, - net->dev.vq_index + idx); + net->dev.vq_index + idx, + false); } int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc,
@@ -686,7 +687,7 @@ err_start:assert (ret >=0 ); } -vhost_dev_stop (&net->dev, vdev, false); +vhost_dev_stop (&net->dev, vdev, false, false);return r; }
hw/scsi/vhost-scsi-common.c +1 -1
@@ -108,7 +108,7 @@ int vhost_scsi_common_stop(VHostSCSICommon *vsc)VirtioBusClass *k =VIRTIO_BUS_GET_CLASS (qbus);int ret =0 ; - ret =vhost_dev_stop (&vsc->dev, vdev, true); + ret =vhost_dev_stop (&vsc->dev, vdev, true, false);if (k->set_guest_notifiers) {int r = k->set_guest_notifiers (qbus->parent, vsc->dev.nvqs, false);
hw/virtio/vdpa-dev.c +1 -1
@@ -301,7 +301,7 @@ static void vhost_vdpa_device_stop(VirtIODevice *vdev)return ; } -vhost_dev_stop (&s->dev, vdev, false); +vhost_dev_stop (&s->dev, vdev, false, false); ret = k->set_guest_notifiers (qbus->parent, s->dev.nvqs, false);if (ret <0 ) {
hw/virtio/vhost-user-base.c +1 -1
@@ -78,7 +78,7 @@ static int vub_stop(VirtIODevice *vdev)return 0 ; } - ret =vhost_dev_stop (&vub->vhost_dev, vdev, true); + ret =vhost_dev_stop (&vub->vhost_dev, vdev, true, false); err = k->set_guest_notifiers (qbus->parent, vub->vhost_dev.nvqs, false);if (err <0 ) {
hw/virtio/vhost-user-fs.c +1 -1
@@ -111,7 +111,7 @@ static int vuf_stop(VirtIODevice *vdev)return 0 ; } - ret =vhost_dev_stop (&fs->vhost_dev, vdev, true); + ret =vhost_dev_stop (&fs->vhost_dev, vdev, true, false); err = k->set_guest_notifiers (qbus->parent, fs->vhost_dev.nvqs, false);if (err <0 ) {
hw/virtio/vhost-user-scmi.c +1 -1
@@ -101,7 +101,7 @@ static int vu_scmi_stop(VirtIODevice *vdev)return 0 ; } - ret =vhost_dev_stop (vhost_dev, vdev, true); + ret =vhost_dev_stop (vhost_dev, vdev, true, false); err = k->set_guest_notifiers (qbus->parent, vhost_dev->nvqs, false);if (err <0 ) {
hw/virtio/vhost-vsock-common.c +1 -1
@@ -106,7 +106,7 @@ int vhost_vsock_common_stop(VirtIODevice *vdev)return 0 ; } - ret =vhost_dev_stop (&vvc->vhost_dev, vdev, true); + ret =vhost_dev_stop (&vvc->vhost_dev, vdev, true, false); err = k->set_guest_notifiers (qbus->parent, vvc->vhost_dev.nvqs, false);if (err <0 ) {
hw/virtio/vhost.c +19 -9
@@ -23,6 +23,7 @@#include "qemu/log.h" #include "standard-headers/linux/vhost_types.h" #include "hw/virtio/virtio-bus.h" +#include "hw/virtio/vhost-user.h" #include "hw/mem/memory-device.h" #include "migration/blocker.h" #include "migration/qemu-file-types.h"
@@ -1499,8 +1500,13 @@ fail:static int do_vhost_virtqueue_stop (struct vhost_dev *dev,struct VirtIODevice *vdev,struct vhost_virtqueue *vq, -unsigned idx,bool force) +unsigned idx,bool force, +bool skip_drain) { +if (skip_drain) { +assert (vhost_user_has_protocol_feature (dev, +VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT )); + }int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index (dev, idx);struct vhost_vring_state state = { .index = vhost_vq_index,
@@ -1550,9 +1556,10 @@ static int do_vhost_virtqueue_stop(struct vhost_dev *dev,int vhost_virtqueue_stop (struct vhost_dev *dev,struct VirtIODevice *vdev,struct vhost_virtqueue *vq, -unsigned idx) +unsigned idx, +bool skip_drain) { -return do_vhost_virtqueue_stop (dev, vdev, vq, idx, false); +return do_vhost_virtqueue_stop (dev, vdev, vq, idx, false, skip_drain); } static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev,
@@ -2307,7 +2314,8 @@ fail_vq:vhost_virtqueue_stop (hdev, vdev, hdev->vqs + i, - hdev->vq_index + i); + hdev->vq_index + i, + false); } fail_mem:
@@ -2322,7 +2330,7 @@ fail_features:/* Host notifiers must be enabled at this point. */ static int do_vhost_dev_stop (struct vhost_dev *hdev,VirtIODevice *vdev, -bool vrings,bool force) +bool vrings,bool force,bool skip_drain) {int i;int rc =0 ;
@@ -2349,7 +2357,8 @@ static int do_vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, vdev, hdev->vqs + i, hdev->vq_index + i, - force); + force, + skip_drain); }if (hdev->vhost_ops->vhost_reset_status) { hdev->vhost_ops->vhost_reset_status (hdev);
@@ -2371,15 +2380,16 @@ static int do_vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev,return rc; } -int vhost_dev_stop (struct vhost_dev *hdev,VirtIODevice *vdev,bool vrings) +int vhost_dev_stop (struct vhost_dev *hdev,VirtIODevice *vdev,bool vrings, +bool skip_drain) { -return do_vhost_dev_stop (hdev, vdev, vrings, false); +return do_vhost_dev_stop (hdev, vdev, vrings, false, skip_drain); }int vhost_dev_force_stop (struct vhost_dev *hdev,VirtIODevice *vdev,bool vrings) { -return do_vhost_dev_stop (hdev, vdev, vrings, true); +return do_vhost_dev_stop (hdev, vdev, vrings, true, false); } int vhost_net_set_backend(struct vhost_dev *hdev,
Signature · 1 line
MST
[PULL v2 38/75] hw/net/virtio-net: strip trailing padding when caching RSC segment
In reply to Michael S. TsirkinFrom: Laurent Vivier <[email protected]>
When an RSC candidate packet has trailing padding bytes beyond the declared IP payload, virtio_net_rsc_cache_buf() copies the full wire size into the coalescing buffer and sets seg->size to that value. The bounds check in virtio_net_rsc_coalesce_data() uses the IP length field (o_ip_len) which does not include the padding, so the check can pass while the subsequent memmove() overflows the buffer.
Fix this by computing the actual IP packet size from the IP header and using it for both the memcpy and seg->size, so that seg->size stays in sync with the IP length field. virtio_net_rsc_sanity_check4/6() guarantees that ip_size <= size.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3879
Message-ID: <[email protected]>
--- hw/net/virtio-net.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
hw/net/virtio-net.c +20 -2
@@ -2200,13 +2200,31 @@ static void virtio_net_rsc_cache_buf(VirtioNetRscChain *chain, {uint16_t hdr_len;VirtioNetRscSeg *seg; +size_t ip_size; hdr_len = chain->n->guest_hdr_len; + +/* +* Strip any trailing padding beyond the IP payload so that seg->size +* stays in sync with the IP length field used by the bounds check in +* virtio_net_rsc_coalesce_data(). virtio_net_rsc_sanity_check4/6() +* guarantees that ip_size <= size. +*/ + ip_size = hdr_len +sizeof (struct eth_header ); +if (chain->proto ==ETH_P_IP ) { +struct ip_header *ip = (struct ip_header *)(buf + ip_size); + ip_size +=htons (ip->ip_len); + }else { +struct ip6_header *ip6 = (struct ip6_header *)(buf + ip_size); + ip_size +=sizeof (struct ip6_header ) + +htons (ip6->ip6_ctlun.ip6_un1.ip6_un1_plen); + } + seg =g_new (VirtioNetRscSeg,1 ); seg->buf =g_malloc (hdr_len +sizeof (struct eth_header ) +sizeof (struct ip6_header ) +VIRTIO_NET_MAX_TCP_PAYLOAD ); -memcpy (seg->buf, buf, size); - seg->size = size; +memcpy (seg->buf, buf, ip_size); + seg->size = ip_size; seg->packets =1 ; seg->dup_ack =0 ; seg->is_coalesced =0 ;
Signature · 1 line
MST
[PULL v2 65/75] hw/hotplug: Constify HotplugHandler
In reply to Michael S. TsirkinFrom: Philippe Mathieu-Daudé <[email protected]>
HotplugHandler value returned from qdev_get_hotplug_handler() points to the handler of and object implementing the TYPE_HOTPLUG_HANDLER interface. That handler mostly points to read-only section which shouldn't not be updated. Better protect it with the const qualifier.
Mechanical change using 'sed' then manually adapted coding style.
Message-ID: <[email protected]>
--- hw/s390x/ccw-device.h | 2 +- include/hw/acpi/cpu.h | 4 +-- include/hw/acpi/cpu_hotplug.h | 2 +- include/hw/acpi/generic_event_device.h | 3 +- include/hw/acpi/ich9.h | 10 +++--- include/hw/acpi/memory_hotplug.h | 4 +-- include/hw/acpi/pcihp.h | 8 ++--- include/hw/core/boards.h | 4 +-- include/hw/core/hotplug.h | 13 +++---- include/hw/core/qdev.h | 12 +++---- include/hw/i386/microvm.h | 4 +-- include/hw/i386/x86.h | 10 +++--- include/hw/mem/nvdimm.h | 2 +- include/hw/pci/pci_bridge.h | 6 ++-- include/hw/pci/pcie.h | 8 ++--- include/hw/pci/shpc.h | 6 ++-- include/hw/ppc/spapr_nvdimm.h | 2 +- hw/acpi/acpi-cpu-hotplug-stub.c | 4 +-- hw/acpi/acpi-mem-hotplug-stub.c | 4 +-- hw/acpi/acpi-nvdimm-stub.c | 2 +- hw/acpi/acpi-pci-hotplug-stub.c | 8 ++--- hw/acpi/cpu.c | 6 ++-- hw/acpi/generic_event_device.c | 11 +++--- hw/acpi/ich9.c | 10 +++--- hw/acpi/memory_hotplug.c | 6 ++-- hw/acpi/nvdimm.c | 2 +- hw/acpi/pcihp.c | 10 +++--- hw/acpi/piix4.c | 12 +++---- hw/arm/virt.c | 23 ++++++------ hw/char/virtio-serial-bus.c | 2 +- hw/core/hotplug.c | 8 ++--- hw/core/qdev-hotplug.c | 10 +++--- hw/core/qdev.c | 2 +- hw/i386/microvm.c | 12 +++---- hw/i386/pc.c | 28 +++++++-------- hw/i386/x86-common.c | 8 ++--- hw/intc/loongarch_dintc.c | 8 ++--- hw/intc/loongarch_extioi_common.c | 4 +-- hw/intc/loongarch_ipi.c | 4 +-- hw/loongarch/virt.c | 44 +++++++++++------------ hw/net/virtio-net.c | 4 +-- hw/nvme/ctrl.c | 8 ++--- hw/pci-bridge/pci_bridge_dev.c | 6 ++-- hw/pci/pcie.c | 10 +++--- hw/pci/pcie_port.c | 2 +- hw/pci/shpc.c | 10 +++--- hw/ppc/e500plat.c | 4 +-- hw/ppc/spapr.c | 48 +++++++++++++------------- hw/ppc/spapr_nvdimm.c | 2 +- hw/ppc/spapr_pci.c | 12 +++---- hw/remote/machine.c | 2 +- hw/riscv/virt.c | 6 ++-- hw/s390x/css-bridge.c | 2 +- hw/s390x/s390-pci-bus.c | 12 +++---- hw/s390x/s390-virtio-ccw.c | 16 ++++----- hw/s390x/virtio-ccw-md.c | 8 ++--- hw/s390x/virtio-ccw.c | 2 +- hw/scsi/virtio-scsi.c | 6 ++-- hw/scsi/vmw_pvscsi.c | 4 +-- hw/virtio/virtio-md-pci.c | 8 ++--- hw/xen/xen-bus.c | 2 +- stubs/hotplug-stubs.c | 6 ++-- system/qdev-monitor.c | 2 +- 63 files changed, 257 insertions(+), 253 deletions(-)
hw/s390x/ccw-device.h +1 -1
@@ -37,7 +37,7 @@ extern const VMStateDescription vmstate_ccw_dev;struct CCWDeviceClass {DeviceClass parent_class; -void (*unplug)(HotplugHandler *,DeviceState *,Error **); +void (*unplug)(const HotplugHandler *,DeviceState *,Error **);bool (*realize)(CcwDevice *,Error **);void (*refill_ids)(CcwDevice *); };
include/hw/acpi/cpu.h +2 -2
@@ -39,10 +39,10 @@ typedef struct CPUHotplugState {AcpiCpuStatus *devs; } CPUHotplugState; -void acpi_cpu_plug_cb (HotplugHandler *hotplug_dev, +void acpi_cpu_plug_cb (const HotplugHandler *hotplug_dev,CPUHotplugState *cpu_st,DeviceState *dev,Error **errp); -void acpi_cpu_unplug_request_cb (HotplugHandler *hotplug_dev, +void acpi_cpu_unplug_request_cb (const HotplugHandler *hotplug_dev,CPUHotplugState *cpu_st,DeviceState *dev,Error **errp);
include/hw/acpi/cpu_hotplug.h +1 -1
@@ -25,7 +25,7 @@ typedef struct AcpiCpuHotplug {uint8_t sts[ACPI_GPE_PROC_LEN ]; } AcpiCpuHotplug; -void legacy_acpi_cpu_plug_cb (HotplugHandler *hotplug_dev, +void legacy_acpi_cpu_plug_cb (const HotplugHandler *hotplug_dev,AcpiCpuHotplug *g,DeviceState *dev,Error **errp); void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
include/hw/acpi/generic_event_device.h +2 -1
@@ -136,7 +136,8 @@ typedef struct AcpiGedClass {ResettablePhases parent_phases; } AcpiGedClass; -void build_ged_aml (Aml *table,const char * name,HotplugHandler *hotplug_dev, +void build_ged_aml (Aml *table,const char *name, +const HotplugHandler *hotplug_dev,uint32_t ged_irq,AmlRegionSpace rs,hwaddr ged_base);void acpi_dsdt_add_power_button (Aml *scope);
include/hw/acpi/ich9.h +5 -5
@@ -85,15 +85,15 @@ void ich9_pm_reset_properties(ICH9LPCPMRegs *pm);void ich9_pm_add_class_properties (ObjectClass *oc,ptrdiff_t pm_offset); -void ich9_pm_device_pre_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void ich9_pm_device_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void ich9_pm_device_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void ich9_pm_device_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void ich9_pm_device_unplug_request_cb (HotplugHandler *hotplug_dev, +void ich9_pm_device_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void ich9_pm_device_unplug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void ich9_pm_device_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -bool ich9_pm_is_hotpluggable_bus (HotplugHandler *hotplug_dev,BusState *bus); +bool ich9_pm_is_hotpluggable_bus (const HotplugHandler *hotplug_dev,BusState *bus);void ich9_pm_ospm_status (AcpiDeviceIf *adev,ACPIOSTInfoList ***list);#endif /* HW_ACPI_ICH9_H */
include/hw/acpi/memory_hotplug.h +2 -2
@@ -36,9 +36,9 @@ typedef struct MemHotplugState {void acpi_memory_hotplug_init (MemoryRegion *as,Object *owner,MemHotplugState *state,hwaddr io_base); -void acpi_memory_plug_cb (HotplugHandler *hotplug_dev,MemHotplugState *mem_st, +void acpi_memory_plug_cb (const HotplugHandler *hotplug_dev,MemHotplugState *mem_st,DeviceState *dev,Error **errp); -void acpi_memory_unplug_request_cb (HotplugHandler *hotplug_dev, +void acpi_memory_unplug_request_cb (const HotplugHandler *hotplug_dev,MemHotplugState *mem_st,DeviceState *dev,Error **errp); void acpi_memory_unplug_cb(MemHotplugState *mem_st,
include/hw/acpi/pcihp.h +4 -4
@@ -66,13 +66,13 @@ void acpi_pcihp_init(Object *owner, AcpiPciHpState *, MemoryRegion *io, uint16_t io_base);bool acpi_pcihp_is_hotpluggable_bus (AcpiPciHpState *s,BusState *bus); -void acpi_pcihp_device_pre_plug_cb (HotplugHandler *hotplug_dev, +void acpi_pcihp_device_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void acpi_pcihp_device_plug_cb (HotplugHandler *hotplug_dev,AcpiPciHpState *s, +void acpi_pcihp_device_plug_cb (const HotplugHandler *hotplug_dev,AcpiPciHpState *s,DeviceState *dev,Error **errp); -void acpi_pcihp_device_unplug_cb (HotplugHandler *hotplug_dev,AcpiPciHpState *s, +void acpi_pcihp_device_unplug_cb (const HotplugHandler *hotplug_dev,AcpiPciHpState *s,DeviceState *dev,Error **errp); -void acpi_pcihp_device_unplug_request_cb (HotplugHandler *hotplug_dev, +void acpi_pcihp_device_unplug_request_cb (const HotplugHandler *hotplug_dev,AcpiPciHpState *s,DeviceState *dev,Error **errp);
include/hw/core/boards.h +2 -2
@@ -322,8 +322,8 @@ struct MachineClass {SMPCompatProps smp_props;const char *default_ram_id; - HotplugHandler *(*get_hotplug_handler)(MachineState *machine, - DeviceState *dev); +const HotplugHandler *(*get_hotplug_handler)(MachineState *machine, +DeviceState *dev);bool (*hotplug_allowed)(MachineState *state,DeviceState *dev,Error **errp); CpuInstanceProperties (*cpu_index_to_instance_props)(MachineState *machine,
include/hw/core/hotplug.h +7 -6
@@ -30,7 +30,7 @@ typedef struct HotplugHandler HotplugHandler;* @plugged_dev: a device that has been (un)plugged * @errp: returns an error if this function fails */ -typedef void (*hotplug_fn )(HotplugHandler *plug_handler, +typedef void (*hotplug_fn )(const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp);/**
@@ -59,7 +59,8 @@ struct HotplugHandlerClass {hotplug_fn plug;hotplug_fn unplug_request;hotplug_fn unplug; -bool (*is_hotpluggable_bus)(HotplugHandler *plug_handler,BusState *bus); +bool (*is_hotpluggable_bus)(const HotplugHandler *plug_handler, +BusState *bus); };/**
@@ -67,7 +68,7 @@ struct HotplugHandlerClass {* * Call #HotplugHandlerClass.plug callback of @plug_handler. */ -void hotplug_handler_plug (HotplugHandler *plug_handler, +void hotplug_handler_plug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp);
@@ -76,7 +77,7 @@ void hotplug_handler_plug(HotplugHandler *plug_handler,* * Call #HotplugHandlerClass.pre_plug callback of @plug_handler. */ -void hotplug_handler_pre_plug (HotplugHandler *plug_handler, +void hotplug_handler_pre_plug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp);
@@ -85,7 +86,7 @@ void hotplug_handler_pre_plug(HotplugHandler *plug_handler,* * Calls #HotplugHandlerClass.unplug_request callback of @plug_handler. */ -void hotplug_handler_unplug_request (HotplugHandler *plug_handler, +void hotplug_handler_unplug_request (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp);/**
@@ -93,7 +94,7 @@ void hotplug_handler_unplug_request(HotplugHandler *plug_handler,* * Calls #HotplugHandlerClass.unplug callback of @plug_handler. */ -void hotplug_handler_unplug (HotplugHandler *plug_handler, +void hotplug_handler_unplug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp);#endif
include/hw/core/qdev.h +6 -6
@@ -386,7 +386,7 @@ struct BusState {/* public: */ DeviceState *parent;char *name; -HotplugHandler *hotplug_handler; +const HotplugHandler *hotplug_handler;int max_index;bool realized;bool full;
@@ -514,8 +514,8 @@ bool qdev_realize_and_unref(DeviceState *dev, BusState *bus, Error **errp);void qdev_unrealize (DeviceState *dev);void qdev_set_legacy_instance_id (DeviceState *dev,int alias_id,int required_for_version); -HotplugHandler *qdev_get_bus_hotplug_handler (DeviceState *dev); -HotplugHandler *qdev_get_machine_hotplug_handler (DeviceState *dev); +const HotplugHandler *qdev_get_bus_hotplug_handler (DeviceState *dev); +const HotplugHandler *qdev_get_machine_hotplug_handler (DeviceState *dev);bool qdev_hotplug_allowed (DeviceState *dev,BusState *bus,Error **errp);bool qdev_hotunplug_allowed (DeviceState *dev,Error **errp);
@@ -529,10 +529,10 @@ bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp);* Return: pointer to object that implements TYPE_HOTPLUG_HANDLER interface * or NULL if there aren't any. */ -HotplugHandler *qdev_get_hotplug_handler (DeviceState *dev); +const HotplugHandler *qdev_get_hotplug_handler (DeviceState *dev);void qdev_unplug (DeviceState *dev,Error **errp);int qdev_sync_config (DeviceState *dev,Error **errp); -void qdev_simple_device_unplug_cb (HotplugHandler *hotplug_dev, +void qdev_simple_device_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp);void qdev_machine_creation_done (void );bool qdev_machine_modified (void );
@@ -1065,7 +1065,7 @@ void qbus_set_bus_hotplug_handler(BusState *bus);static inline bool qbus_is_hotpluggable (BusState *bus) { -HotplugHandler *plug_handler = bus->hotplug_handler; +const HotplugHandler *plug_handler = bus->hotplug_handler;bool ret = !!plug_handler;if (plug_handler) {
include/hw/i386/microvm.h +2 -2
@@ -76,8 +76,8 @@struct MicrovmMachineClass {X86MachineClass parent; -HotplugHandler *(*orig_hotplug_handler)(MachineState *machine, -DeviceState *dev); +const HotplugHandler *(*orig_hotplug_handler)(MachineState *machine, +DeviceState *dev);void (*x86_load_linux)(X86MachineState *x86ms,FWCfgState *fw_cfg,int acpi_data_size); };
include/hw/i386/x86.h +5 -5
@@ -46,7 +46,7 @@ struct X86MachineState {qemu_irq *gsi;DeviceState *ioapic2;GMappedFile *initrd_mapped_file; -HotplugHandler *acpi_dev; +const HotplugHandler *acpi_dev;/* * Map the whole BIOS just underneath the 4 GiB address boundary. Only used
@@ -112,13 +112,13 @@ uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms,void x86_cpus_init (X86MachineState *pcms,int default_cpu_version);void x86_rtc_set_cpus_count (ISADevice *rtc,uint16_t cpus_count); -void x86_cpu_pre_plug (HotplugHandler *hotplug_dev, +void x86_cpu_pre_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void x86_cpu_plug (HotplugHandler *hotplug_dev, +void x86_cpu_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void x86_cpu_unplug_request_cb (HotplugHandler *hotplug_dev, +void x86_cpu_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void x86_cpu_unplug_cb (HotplugHandler *hotplug_dev, +void x86_cpu_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory,
include/hw/mem/nvdimm.h +1 -1
@@ -157,5 +157,5 @@ void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, uint32_t ram_slots, const char *oem_id, const char *oem_table_id);void nvdimm_plug (NVDIMMState *state); -void nvdimm_acpi_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev); +void nvdimm_acpi_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev);#endif
include/hw/pci/pci_bridge.h +3 -3
@@ -141,11 +141,11 @@ void pci_bridge_reset(DeviceState *qdev);void pci_bridge_initfn (PCIDevice *pci_dev,const char *typename);void pci_bridge_exitfn (PCIDevice *pci_dev); -void pci_bridge_dev_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void pci_bridge_dev_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void pci_bridge_dev_unplug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void pci_bridge_dev_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void pci_bridge_dev_unplug_request_cb (HotplugHandler *hotplug_dev, +void pci_bridge_dev_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp);/*
include/hw/pci/pcie.h +4 -4
@@ -146,13 +146,13 @@ void pcie_ats_init(PCIDevice *dev, uint16_t offset, bool aligned);void pcie_cap_fill_link_ep_usp (PCIDevice *dev,PCIExpLinkWidth width,PCIExpLinkSpeed speed,bool flitmode); -void pcie_cap_slot_pre_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void pcie_cap_slot_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void pcie_cap_slot_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void pcie_cap_slot_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void pcie_cap_slot_unplug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void pcie_cap_slot_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void pcie_cap_slot_unplug_request_cb (HotplugHandler *hotplug_dev, +void pcie_cap_slot_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); void pcie_pasid_common_init(PCIDevice *dev, uint16_t offset,
include/hw/pci/shpc.h +3 -3
@@ -45,11 +45,11 @@ void shpc_free(PCIDevice *dev);void shpc_cap_write_config (PCIDevice *d,uint32_t addr,uint32_t val,int len); -void shpc_device_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void shpc_device_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void shpc_device_unplug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void shpc_device_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp); -void shpc_device_unplug_request_cb (HotplugHandler *hotplug_dev, +void shpc_device_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp);extern const VMStateInfo shpc_vmstate_info;
include/hw/ppc/spapr_nvdimm.h +1 -1
@@ -18,7 +18,7 @@ typedef struct SpaprMachineState SpaprMachineState;int spapr_pmem_dt_populate (SpaprDrc *drc,SpaprMachineState *spapr,void *fdt,int *fdt_start_offset,Error **errp);void spapr_dt_persistent_memory (SpaprMachineState *spapr,void *fdt); -bool spapr_nvdimm_validate (HotplugHandler *hotplug_dev,NVDIMMDevice *nvdimm, +bool spapr_nvdimm_validate (const HotplugHandler *hotplug_dev,NVDIMMDevice *nvdimm,uint64_t size,Error **errp);void spapr_add_nvdimm (DeviceState *dev,uint64_t slot);void spapr_nvdimm_finish_flushes (void );
hw/acpi/acpi-cpu-hotplug-stub.c +2 -2
@@ -14,7 +14,7 @@ void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list) { } -void acpi_cpu_plug_cb (HotplugHandler *hotplug_dev, +void acpi_cpu_plug_cb (const HotplugHandler *hotplug_dev,CPUHotplugState *cpu_st,DeviceState *dev,Error **errp) { }
@@ -24,7 +24,7 @@ void acpi_cpu_unplug_cb(CPUHotplugState *cpu_st, { } -void acpi_cpu_unplug_request_cb (HotplugHandler *hotplug_dev, +void acpi_cpu_unplug_request_cb (const HotplugHandler *hotplug_dev,CPUHotplugState *cpu_st,DeviceState *dev,Error **errp) {
hw/acpi/acpi-mem-hotplug-stub.c +2 -2
@@ -13,7 +13,7 @@ void acpi_memory_ospm_status(MemHotplugState *mem_st, ACPIOSTInfoList ***list) { } -void acpi_memory_plug_cb (HotplugHandler *hotplug_dev,MemHotplugState *mem_st, +void acpi_memory_plug_cb (const HotplugHandler *hotplug_dev,MemHotplugState *mem_st,DeviceState *dev,Error **errp) { }
@@ -23,7 +23,7 @@ void acpi_memory_unplug_cb(MemHotplugState *mem_st, { } -void acpi_memory_unplug_request_cb (HotplugHandler *hotplug_dev, +void acpi_memory_unplug_request_cb (const HotplugHandler *hotplug_dev,MemHotplugState *mem_st,DeviceState *dev,Error **errp) {
hw/acpi/acpi-nvdimm-stub.c +1 -1
@@ -2,6 +2,6 @@#include "hw/mem/nvdimm.h" #include "hw/core/hotplug.h" -void nvdimm_acpi_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev) +void nvdimm_acpi_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev) { }
hw/acpi/acpi-pci-hotplug-stub.c +4 -4
@@ -9,22 +9,22 @@ void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, { } -void acpi_pcihp_device_plug_cb (HotplugHandler *hotplug_dev,AcpiPciHpState *s, +void acpi_pcihp_device_plug_cb (const HotplugHandler *hotplug_dev,AcpiPciHpState *s,DeviceState *dev,Error **errp) { } -void acpi_pcihp_device_pre_plug_cb (HotplugHandler *hotplug_dev, +void acpi_pcihp_device_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) { } -void acpi_pcihp_device_unplug_cb (HotplugHandler *hotplug_dev,AcpiPciHpState *s, +void acpi_pcihp_device_unplug_cb (const HotplugHandler *hotplug_dev,AcpiPciHpState *s,DeviceState *dev,Error **errp) { } -void acpi_pcihp_device_unplug_request_cb (HotplugHandler *hotplug_dev, +void acpi_pcihp_device_unplug_request_cb (const HotplugHandler *hotplug_dev,AcpiPciHpState *s,DeviceState *dev,Error **errp) {
hw/acpi/cpu.c +3 -3
@@ -132,7 +132,7 @@ static void cpu_hotplug_wr(void *opaque, hwaddr addr, uint64_t data,trace_cpuhp_acpi_clear_remove_evt (cpu_st->selector); }else if (data &8 ) {DeviceState *dev =NULL ; -HotplugHandler *hotplug_ctrl =NULL ; +const HotplugHandler *hotplug_ctrl;if (!cdev->cpu || cdev->cpu == first_cpu) {trace_cpuhp_acpi_ejecting_invalid_cpu (cpu_st->selector);
@@ -247,7 +247,7 @@ static AcpiCpuStatus *get_cpu_status(CPUHotplugState *cpu_st, DeviceState *dev)return NULL ; } -void acpi_cpu_plug_cb (HotplugHandler *hotplug_dev, +void acpi_cpu_plug_cb (const HotplugHandler *hotplug_dev,CPUHotplugState *cpu_st,DeviceState *dev,Error **errp) {AcpiCpuStatus *cdev;
@@ -264,7 +264,7 @@ void acpi_cpu_plug_cb(HotplugHandler *hotplug_dev, } } -void acpi_cpu_unplug_request_cb (HotplugHandler *hotplug_dev, +void acpi_cpu_unplug_request_cb (const HotplugHandler *hotplug_dev,CPUHotplugState *cpu_st,DeviceState *dev,Error **errp) {
hw/acpi/generic_event_device.c +6 -5
@@ -45,7 +45,8 @@ static const uint32_t ged_supported_events[] = {* affected by the interrupt. This way, we can support up to 32 events * with a unique interrupt. */ -void build_ged_aml (Aml *table,const char *name,HotplugHandler *hotplug_dev, +void build_ged_aml (Aml *table,const char *name, +const HotplugHandler *hotplug_dev,uint32_t ged_irq,AmlRegionSpace rs,hwaddr ged_base) {const AcpiGedState *s =ACPI_GED (hotplug_dev);
@@ -250,7 +251,7 @@ static const MemoryRegionOps ged_regs_ops = { }, }; -static void acpi_ged_device_pre_plug_cb (HotplugHandler *hotplug_dev, +static void acpi_ged_device_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {if (object_dynamic_cast (OBJECT (dev),TYPE_PCI_DEVICE )) {
@@ -258,7 +259,7 @@ static void acpi_ged_device_pre_plug_cb(HotplugHandler *hotplug_dev, } } -static void acpi_ged_device_plug_cb (HotplugHandler *hotplug_dev, +static void acpi_ged_device_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {AcpiGedState *s =ACPI_GED (hotplug_dev);
@@ -279,7 +280,7 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev, } } -static void acpi_ged_unplug_request_cb (HotplugHandler *hotplug_dev, +static void acpi_ged_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {AcpiGedState *s =ACPI_GED (hotplug_dev);
@@ -298,7 +299,7 @@ static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev, } } -static void acpi_ged_unplug_cb (HotplugHandler *hotplug_dev, +static void acpi_ged_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {AcpiGedState *s =ACPI_GED (hotplug_dev);
hw/acpi/ich9.c +5 -5
@@ -410,7 +410,7 @@ void ich9_pm_add_class_properties(ObjectClass *oc, ptrdiff_t pm_offset)#undef PM_REG_FIELD -void ich9_pm_device_pre_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void ich9_pm_device_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {ICH9LPCState *lpc =ICH9_LPC_DEVICE (hotplug_dev);
@@ -432,7 +432,7 @@ void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, } } -void ich9_pm_device_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void ich9_pm_device_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {ICH9LPCState *lpc =ICH9_LPC_DEVICE (hotplug_dev);
@@ -455,7 +455,7 @@ void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, } } -void ich9_pm_device_unplug_request_cb (HotplugHandler *hotplug_dev, +void ich9_pm_device_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {ICH9LPCState *lpc =ICH9_LPC_DEVICE (hotplug_dev);
@@ -489,7 +489,7 @@ void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, } } -void ich9_pm_device_unplug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void ich9_pm_device_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {ICH9LPCState *lpc =ICH9_LPC_DEVICE (hotplug_dev);
@@ -507,7 +507,7 @@ void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, } } -bool ich9_pm_is_hotpluggable_bus (HotplugHandler *hotplug_dev,BusState *bus) +bool ich9_pm_is_hotpluggable_bus (const HotplugHandler *hotplug_dev,BusState *bus) {ICH9LPCState *lpc =ICH9_LPC_DEVICE (hotplug_dev);return acpi_pcihp_is_hotpluggable_bus (&lpc->pm.acpi_pci_hotplug, bus);
hw/acpi/memory_hotplug.c +3 -3
@@ -166,7 +166,7 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, mdev->is_removing = false;trace_mhp_acpi_clear_remove_evt (mem_st->selector); }else if (data &8 ) { -HotplugHandler *hotplug_ctrl; +const HotplugHandler *hotplug_ctrl;if (!mdev->is_enabled) {trace_mhp_acpi_ejecting_invalid_slot (mem_st->selector);
@@ -254,7 +254,7 @@ acpi_memory_slot_status(MemHotplugState *mem_st,return &mem_st->devs[slot]; } -void acpi_memory_plug_cb (HotplugHandler *hotplug_dev,MemHotplugState *mem_st, +void acpi_memory_plug_cb (const HotplugHandler *hotplug_dev,MemHotplugState *mem_st,DeviceState *dev,Error **errp) {MemStatus *mdev;
@@ -277,7 +277,7 @@ void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, } } -void acpi_memory_unplug_request_cb (HotplugHandler *hotplug_dev, +void acpi_memory_unplug_request_cb (const HotplugHandler *hotplug_dev,MemHotplugState *mem_st,DeviceState *dev,Error **errp) {
hw/acpi/nvdimm.c +1 -1
@@ -887,7 +887,7 @@ static const MemoryRegionOps nvdimm_dsm_ops = { }, }; -void nvdimm_acpi_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev) +void nvdimm_acpi_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev) {if (dev->hotplugged) {acpi_send_event (DEVICE (hotplug_dev),ACPI_NVDIMM_HOTPLUG_STATUS );
hw/acpi/pcihp.c +5 -5
@@ -209,7 +209,7 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo*/ qdev->pending_deleted_event = false; }else { -HotplugHandler *hotplug_ctrl; +const HotplugHandler *hotplug_ctrl; hotplug_ctrl =qdev_get_hotplug_handler (qdev);hotplug_handler_unplug (hotplug_ctrl, qdev, &error_abort);
@@ -261,7 +261,7 @@ void acpi_pcihp_reset(AcpiPciHpState *s)acpi_pcihp_update (s); } -void acpi_pcihp_device_pre_plug_cb (HotplugHandler *hotplug_dev, +void acpi_pcihp_device_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PCIDevice *pdev =PCI_DEVICE (dev);
@@ -275,7 +275,7 @@ void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev, } } -void acpi_pcihp_device_plug_cb (HotplugHandler *hotplug_dev,AcpiPciHpState *s, +void acpi_pcihp_device_plug_cb (const HotplugHandler *hotplug_dev,AcpiPciHpState *s,DeviceState *dev,Error **errp) {PCIDevice *pdev =PCI_DEVICE (dev);
@@ -317,7 +317,7 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,acpi_send_event (DEVICE (hotplug_dev),ACPI_PCI_HOTPLUG_STATUS ); } -void acpi_pcihp_device_unplug_cb (HotplugHandler *hotplug_dev,AcpiPciHpState *s, +void acpi_pcihp_device_unplug_cb (const HotplugHandler *hotplug_dev,AcpiPciHpState *s,DeviceState *dev,Error **errp) {PCIDevice *pdev =PCI_DEVICE (dev);
@@ -328,7 +328,7 @@ void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,qdev_unrealize (dev); } -void acpi_pcihp_device_unplug_request_cb (HotplugHandler *hotplug_dev, +void acpi_pcihp_device_unplug_request_cb (const HotplugHandler *hotplug_dev,AcpiPciHpState *s,DeviceState *dev,Error **errp) {
hw/acpi/piix4.c +6 -6
@@ -303,8 +303,8 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque)acpi_pm1_evt_power_down (&s->ar); } -static void piix4_device_pre_plug_cb (HotplugHandler *hotplug_dev, -DeviceState *dev,Error **errp) +static void piix4_device_pre_plug_cb (const HotplugHandler *hotplug_dev, +DeviceState *dev,Error **errp) {PIIX4PMState *s =PIIX4_PM (hotplug_dev);
@@ -323,7 +323,7 @@ static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev, } } -static void piix4_device_plug_cb (HotplugHandler *hotplug_dev, +static void piix4_device_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PIIX4PMState *s =PIIX4_PM (hotplug_dev);
@@ -344,7 +344,7 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev, } } -static void piix4_device_unplug_request_cb (HotplugHandler *hotplug_dev, +static void piix4_device_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PIIX4PMState *s =PIIX4_PM (hotplug_dev);
@@ -364,7 +364,7 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev, } } -static void piix4_device_unplug_cb (HotplugHandler *hotplug_dev, +static void piix4_device_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PIIX4PMState *s =PIIX4_PM (hotplug_dev);
@@ -383,7 +383,7 @@ static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev, } } -static bool piix4_is_hotpluggable_bus (HotplugHandler *hotplug_dev, +static bool piix4_is_hotpluggable_bus (const HotplugHandler *hotplug_dev,BusState *bus) {PIIX4PMState *s =PIIX4_PM (hotplug_dev);
hw/arm/virt.c +12 -11
@@ -3753,7 +3753,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)return ms->possible_cpus; } -static void virt_memory_pre_plug (HotplugHandler *hotplug_dev,DeviceState *dev, +static void virt_memory_pre_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {VirtMachineState *vms =VIRT_MACHINE (hotplug_dev);
@@ -3779,7 +3779,7 @@ static void virt_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,pc_dimm_pre_plug (PC_DIMM (dev),MACHINE (hotplug_dev), errp); } -static void virt_memory_plug (HotplugHandler *hotplug_dev, +static void virt_memory_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {VirtMachineState *vms =VIRT_MACHINE (hotplug_dev);
@@ -3798,7 +3798,7 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev, } } -static void virt_machine_device_pre_plug_cb (HotplugHandler *hotplug_dev, +static void virt_machine_device_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {VirtMachineState *vms =VIRT_MACHINE (hotplug_dev);
@@ -3896,7 +3896,7 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, } } -static void virt_machine_device_plug_cb (HotplugHandler *hotplug_dev, +static void virt_machine_device_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {VirtMachineState *vms =VIRT_MACHINE (hotplug_dev);
@@ -3957,7 +3957,7 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev, } } -static void virt_dimm_unplug_request (HotplugHandler *hotplug_dev, +static void virt_dimm_unplug_request (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {VirtMachineState *vms =VIRT_MACHINE (hotplug_dev);
@@ -3977,7 +3977,7 @@ static void virt_dimm_unplug_request(HotplugHandler *hotplug_dev, errp); } -static void virt_dimm_unplug (HotplugHandler *hotplug_dev, +static void virt_dimm_unplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {VirtMachineState *vms =VIRT_MACHINE (hotplug_dev);
@@ -3995,8 +3995,9 @@ out:error_propagate (errp, local_err); } -static void virt_machine_device_unplug_request_cb (HotplugHandler *hotplug_dev, -DeviceState *dev,Error **errp) +static void +virt_machine_device_unplug_request_cb (const HotplugHandler *hotplug_dev, +DeviceState *dev,Error **errp) {if (object_dynamic_cast (OBJECT (dev),TYPE_PC_DIMM )) {virt_dimm_unplug_request (hotplug_dev, dev, errp);
@@ -4009,7 +4010,7 @@ static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, } } -static void virt_machine_device_unplug_cb (HotplugHandler *hotplug_dev, +static void virt_machine_device_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {if (object_dynamic_cast (OBJECT (dev),TYPE_PC_DIMM )) {
@@ -4022,8 +4023,8 @@ static void virt_machine_device_unplug_cb(HotplugHandler *hotplug_dev, } } -static HotplugHandler *virt_machine_get_hotplug_handler (MachineState *machine, -DeviceState *dev) +static const HotplugHandler * +virt_machine_get_hotplug_handler (MachineState *machine,DeviceState *dev) {MachineClass *mc =MACHINE_GET_CLASS (machine);
hw/char/virtio-serial-bus.c +1 -1
@@ -979,7 +979,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp) port->elem =NULL ; } -static void virtser_port_device_plug (HotplugHandler *hotplug_dev, +static void virtser_port_device_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {VirtIOSerialPort *port =VIRTIO_SERIAL_PORT (dev);
hw/core/hotplug.c +4 -4
@@ -13,7 +13,7 @@#include "hw/core/hotplug.h" #include "qemu/module.h" -void hotplug_handler_pre_plug (HotplugHandler *plug_handler, +void hotplug_handler_pre_plug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp) {
@@ -24,7 +24,7 @@ void hotplug_handler_pre_plug(HotplugHandler *plug_handler, } } -void hotplug_handler_plug (HotplugHandler *plug_handler, +void hotplug_handler_plug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp) {
@@ -35,7 +35,7 @@ void hotplug_handler_plug(HotplugHandler *plug_handler, } } -void hotplug_handler_unplug_request (HotplugHandler *plug_handler, +void hotplug_handler_unplug_request (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp) {
@@ -46,7 +46,7 @@ void hotplug_handler_unplug_request(HotplugHandler *plug_handler, } } -void hotplug_handler_unplug (HotplugHandler *plug_handler, +void hotplug_handler_unplug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp) {
hw/core/qdev-hotplug.c +5 -5
@@ -14,7 +14,7 @@#include "hw/core/boards.h" #include "qapi/error.h" -HotplugHandler *qdev_get_machine_hotplug_handler (DeviceState *dev) +const HotplugHandler *qdev_get_machine_hotplug_handler (DeviceState *dev) {MachineState *machine;MachineClass *mc;
@@ -90,7 +90,7 @@ bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp)qdev_hotplug_unplug_allowed_common (dev, dev->parent_bus, errp); } -HotplugHandler *qdev_get_bus_hotplug_handler (DeviceState *dev) +const HotplugHandler *qdev_get_bus_hotplug_handler (DeviceState *dev) {if (dev->parent_bus) {return dev->parent_bus->hotplug_handler;
@@ -98,9 +98,9 @@ HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev)return NULL ; } -HotplugHandler *qdev_get_hotplug_handler (DeviceState *dev) +const HotplugHandler *qdev_get_hotplug_handler (DeviceState *dev) { -HotplugHandler *hotplug_ctrl =qdev_get_machine_hotplug_handler (dev); +const HotplugHandler *hotplug_ctrl =qdev_get_machine_hotplug_handler (dev);if (hotplug_ctrl ==NULL && dev->parent_bus) { hotplug_ctrl =qdev_get_bus_hotplug_handler (dev);
@@ -109,7 +109,7 @@ HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev) }/* can be used as ->unplug() callback for the simple cases */ -void qdev_simple_device_unplug_cb (HotplugHandler *hotplug_dev, +void qdev_simple_device_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {qdev_unrealize (dev);
hw/core/qdev.c +1 -1
@@ -501,7 +501,7 @@ static void device_set_realized(Object *obj, bool value, Error **errp) {DeviceState *dev =DEVICE (obj);DeviceClass *dc =DEVICE_GET_CLASS (dev); -HotplugHandler *hotplug_ctrl; +const HotplugHandler *hotplug_ctrl;BusState *bus;NamedClockList *ncl;Error *local_err =NULL ;
hw/i386/microvm.c +6 -6
@@ -416,7 +416,7 @@ static void microvm_fix_kernel_cmdline(MachineState *machine)g_free (cmdline); } -static void microvm_device_pre_plug_cb (HotplugHandler *hotplug_dev, +static void microvm_device_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {X86CPU *cpu =X86_CPU (dev);
@@ -425,26 +425,26 @@ static void microvm_device_pre_plug_cb(HotplugHandler *hotplug_dev,x86_cpu_pre_plug (hotplug_dev, dev, errp); } -static void microvm_device_plug_cb (HotplugHandler *hotplug_dev, +static void microvm_device_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {x86_cpu_plug (hotplug_dev, dev, errp); } -static void microvm_device_unplug_request_cb (HotplugHandler *hotplug_dev, +static void microvm_device_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {error_setg (errp,"unplug not supported by microvm" ); } -static void microvm_device_unplug_cb (HotplugHandler *hotplug_dev, +static void microvm_device_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {error_setg (errp,"unplug not supported by microvm" ); } -static HotplugHandler *microvm_get_hotplug_handler (MachineState *machine, -DeviceState *dev) +static const HotplugHandler *microvm_get_hotplug_handler (MachineState *machine, +DeviceState *dev) {if (object_dynamic_cast (OBJECT (dev),TYPE_CPU )) {return HOTPLUG_HANDLER (machine);
hw/i386/pc.c +14 -14
@@ -1181,7 +1181,7 @@ void pc_i8259_create(ISABus *isa_bus, qemu_irq *i8259_irqs)g_free (i8259); } -static void pc_memory_pre_plug (HotplugHandler *hotplug_dev,DeviceState *dev, +static void pc_memory_pre_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {const X86MachineState *x86ms =X86_MACHINE (hotplug_dev);
@@ -1214,7 +1214,7 @@ static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,pc_dimm_pre_plug (PC_DIMM (dev),MACHINE (hotplug_dev), errp); } -static void pc_memory_plug (HotplugHandler *hotplug_dev, +static void pc_memory_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PCMachineState *pcms =PC_MACHINE (hotplug_dev);
@@ -1231,7 +1231,7 @@ static void pc_memory_plug(HotplugHandler *hotplug_dev,hotplug_handler_plug (x86ms->acpi_dev, dev, &error_abort); } -static void pc_memory_unplug_request (HotplugHandler *hotplug_dev, +static void pc_memory_unplug_request (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {X86MachineState *x86ms =X86_MACHINE (hotplug_dev);
@@ -1256,7 +1256,7 @@ static void pc_memory_unplug_request(HotplugHandler *hotplug_dev, errp); } -static void pc_memory_unplug (HotplugHandler *hotplug_dev, +static void pc_memory_unplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PCMachineState *pcms =PC_MACHINE (hotplug_dev);
@@ -1274,7 +1274,7 @@ static void pc_memory_unplug(HotplugHandler *hotplug_dev,error_propagate (errp, local_err); } -static void pc_hv_balloon_pre_plug (HotplugHandler *hotplug_dev, +static void pc_hv_balloon_pre_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {/* The vmbus handler has no hotplug handler; we should never end up here. */
@@ -1282,13 +1282,13 @@ static void pc_hv_balloon_pre_plug(HotplugHandler *hotplug_dev,memory_device_pre_plug (MEMORY_DEVICE (dev),MACHINE (hotplug_dev), errp); } -static void pc_hv_balloon_plug (HotplugHandler *hotplug_dev, +static void pc_hv_balloon_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {memory_device_plug (MEMORY_DEVICE (dev),MACHINE (hotplug_dev)); } -static void pc_sp_mem_pre_plug (HotplugHandler *hotplug_dev, +static void pc_sp_mem_pre_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {MachineState *ms =MACHINE (hotplug_dev);
@@ -1304,7 +1304,7 @@ static void pc_sp_mem_pre_plug(HotplugHandler *hotplug_dev,memory_device_pre_plug (MEMORY_DEVICE (dev), ms, errp); } -static void pc_sp_mem_plug (HotplugHandler *hotplug_dev, +static void pc_sp_mem_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {SpMemDevice *spm =SP_MEM (dev);
@@ -1318,7 +1318,7 @@ static void pc_sp_mem_plug(HotplugHandler *hotplug_dev,e820_add_entry (addr, size,E820_SOFT_RESERVED ); } -static void pc_machine_device_pre_plug_cb (HotplugHandler *hotplug_dev, +static void pc_machine_device_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {if (object_dynamic_cast (OBJECT (dev),TYPE_PC_DIMM )) {
@@ -1356,7 +1356,7 @@ static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, } } -static void pc_machine_device_plug_cb (HotplugHandler *hotplug_dev, +static void pc_machine_device_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {if (object_dynamic_cast (OBJECT (dev),TYPE_PC_DIMM )) {
@@ -1372,7 +1372,7 @@ static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev, } } -static void pc_machine_device_unplug_request_cb (HotplugHandler *hotplug_dev, +static void pc_machine_device_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {if (object_dynamic_cast (OBJECT (dev),TYPE_PC_DIMM )) {
@@ -1388,7 +1388,7 @@ static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, } } -static void pc_machine_device_unplug_cb (HotplugHandler *hotplug_dev, +static void pc_machine_device_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {if (object_dynamic_cast (OBJECT (dev),TYPE_PC_DIMM )) {
@@ -1403,8 +1403,8 @@ static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev, } } -static HotplugHandler *pc_get_hotplug_handler (MachineState *machine, -DeviceState *dev) +static const HotplugHandler *pc_get_hotplug_handler (MachineState *machine, +DeviceState *dev) { if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || object_dynamic_cast(OBJECT(dev), TYPE_SP_MEM) ||
hw/i386/x86-common.c +4 -4
@@ -158,7 +158,7 @@ static CPUArchId *x86_find_cpu_slot(MachineState *ms, uint32_t id, int *idx)return found_cpu; } -void x86_cpu_plug (HotplugHandler *hotplug_dev, +void x86_cpu_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {CPUArchId *found_cpu;
@@ -199,7 +199,7 @@ out:error_propagate (errp, local_err); } -void x86_cpu_unplug_request_cb (HotplugHandler *hotplug_dev, +void x86_cpu_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {int idx =-1 ;
@@ -222,7 +222,7 @@ void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, errp); } -void x86_cpu_unplug_cb (HotplugHandler *hotplug_dev, +void x86_cpu_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {CPUArchId *found_cpu;
@@ -248,7 +248,7 @@ void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev,error_propagate (errp, local_err); } -void x86_cpu_pre_plug (HotplugHandler *hotplug_dev, +void x86_cpu_pre_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {int idx;
hw/intc/loongarch_dintc.c +4 -4
@@ -168,8 +168,8 @@ static DINTCCore *loongarch_dintc_get_cpu(LoongArchDINTCState *s,return loongarch_dintc_cpu_by_arch_id (s, arch_id); } -static void loongarch_dintc_cpu_plug (HotplugHandler *hotplug_dev, -DeviceState *dev,Error **errp) +static void loongarch_dintc_cpu_plug (const HotplugHandler *hotplug_dev, +DeviceState *dev,Error **errp) {LoongArchDINTCState *s =LOONGARCH_DINTC (hotplug_dev);Object *obj =OBJECT (dev);
@@ -194,8 +194,8 @@ static void loongarch_dintc_cpu_plug(HotplugHandler *hotplug_dev,return ; } -static void loongarch_dintc_cpu_unplug (HotplugHandler *hotplug_dev, -DeviceState *dev,Error **errp) +static void loongarch_dintc_cpu_unplug (const HotplugHandler *hotplug_dev, +DeviceState *dev,Error **errp) {LoongArchDINTCState *s =LOONGARCH_DINTC (hotplug_dev);Object *obj =OBJECT (dev);
hw/intc/loongarch_extioi_common.c +2 -2
@@ -28,7 +28,7 @@ static ExtIOICore *loongarch_extioi_get_cpu(LoongArchExtIOICommonState *s,return NULL ; } -static void loongarch_extioi_cpu_plug (HotplugHandler *hotplug_dev, +static void loongarch_extioi_cpu_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {LoongArchExtIOICommonState *s =LOONGARCH_EXTIOI_COMMON (hotplug_dev);
@@ -60,7 +60,7 @@ static void loongarch_extioi_cpu_plug(HotplugHandler *hotplug_dev, } } -static void loongarch_extioi_cpu_unplug (HotplugHandler *hotplug_dev, +static void loongarch_extioi_cpu_unplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {LoongArchExtIOICommonState *s =LOONGARCH_EXTIOI_COMMON (hotplug_dev);
hw/intc/loongarch_ipi.c +2 -2
@@ -129,7 +129,7 @@ static void loongarch_ipi_reset_hold(Object *obj, ResetType type) } } -static void loongarch_ipi_cpu_plug (HotplugHandler *hotplug_dev, +static void loongarch_ipi_cpu_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {LoongsonIPICommonState *lics =LOONGSON_IPI_COMMON (hotplug_dev);
@@ -155,7 +155,7 @@ static void loongarch_ipi_cpu_plug(HotplugHandler *hotplug_dev,qdev_connect_gpio_out (DEVICE (lics), index,qdev_get_gpio_in (dev,IRQ_IPI )); } -static void loongarch_ipi_cpu_unplug (HotplugHandler *hotplug_dev, +static void loongarch_ipi_cpu_unplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {LoongsonIPICommonState *lics =LOONGSON_IPI_COMMON (hotplug_dev);
hw/loongarch/virt.c +22 -22
120 lines not on this page · raw message
hw/net/virtio-net.c +2 -2
@@ -3816,7 +3816,7 @@ void virtio_net_set_netclient_name(VirtIONet *n, const char *name,static bool failover_unplug_primary (VirtIONet *n,DeviceState *dev) { -HotplugHandler *hotplug_ctrl; +const HotplugHandler *hotplug_ctrl;PCIDevice *pci_dev;Error *err =NULL ;
@@ -3839,7 +3839,7 @@ static bool failover_replug_primary(VirtIONet *n, DeviceState *dev, Error **errp) {Error *err =NULL ; -HotplugHandler *hotplug_ctrl; +const HotplugHandler *hotplug_ctrl;PCIDevice *pdev =PCI_DEVICE (dev);BusState *primary_bus;
hw/nvme/ctrl.c +4 -4
@@ -10615,8 +10615,8 @@ static const TypeInfo nvme_info = { }, }; -static void nvme_ns_hot_plug (HotplugHandler *hotplug_dev,DeviceState *dev, -Error **errp) +static void nvme_ns_hot_plug (const HotplugHandler *hotplug_dev, +DeviceState *dev,Error **errp) {NvmeNamespace *ns =NVME_NS (dev);NvmeSubsystem *subsys = ns->subsys;
@@ -10647,8 +10647,8 @@ static void nvme_ns_hot_plug(HotplugHandler *hotplug_dev, DeviceState *dev, } } -static void nvme_ns_hot_unplug (HotplugHandler *hotplug_dev,DeviceState *dev, -Error **errp) +static void nvme_ns_hot_unplug (const HotplugHandler *hotplug_dev, +DeviceState *dev,Error **errp) {NvmeNamespace *ns =NVME_NS (dev);NvmeSubsystem *subsys = ns->subsys;
hw/pci-bridge/pci_bridge_dev.c +3 -3
@@ -205,7 +205,7 @@ static const VMStateDescription pci_bridge_dev_vmstate = { } }; -void pci_bridge_dev_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void pci_bridge_dev_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PCIDevice *pci_hotplug_dev =PCI_DEVICE (hotplug_dev);
@@ -218,7 +218,7 @@ void pci_bridge_dev_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,shpc_device_plug_cb (hotplug_dev, dev, errp); } -void pci_bridge_dev_unplug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void pci_bridge_dev_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PCIDevice *pci_hotplug_dev =PCI_DEVICE (hotplug_dev);
@@ -227,7 +227,7 @@ void pci_bridge_dev_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,shpc_device_unplug_cb (hotplug_dev, dev, errp); } -void pci_bridge_dev_unplug_request_cb (HotplugHandler *hotplug_dev, +void pci_bridge_dev_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PCIDevice *pci_hotplug_dev =PCI_DEVICE (hotplug_dev);
hw/pci/pcie.c +5 -5
@@ -508,7 +508,7 @@ static void pcie_cap_slot_plug_common(PCIDevice *hotplug_dev, DeviceState *dev, } } -void pcie_cap_slot_pre_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void pcie_cap_slot_pre_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PCIDevice *hotplug_pdev =PCI_DEVICE (hotplug_dev);
@@ -525,7 +525,7 @@ void pcie_cap_slot_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,pcie_cap_slot_plug_common (PCI_DEVICE (hotplug_dev), dev, errp); } -void pcie_cap_slot_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void pcie_cap_slot_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PCIDevice *hotplug_pdev =PCI_DEVICE (hotplug_dev);
@@ -571,7 +571,7 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, } } -void pcie_cap_slot_unplug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void pcie_cap_slot_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {qdev_unrealize (dev);
@@ -579,7 +579,7 @@ void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,static void pcie_unplug_device (PCIBus *bus,PCIDevice *dev,void *opaque) { -HotplugHandler *hotplug_ctrl =qdev_get_hotplug_handler (DEVICE (dev)); +const HotplugHandler *hotplug_ctrl =qdev_get_hotplug_handler (DEVICE (dev));if (dev->partially_hotplugged) { dev->qdev.pending_deleted_event = false;
@@ -608,7 +608,7 @@ static void pcie_cap_slot_do_unplug(PCIDevice *dev) PCI_EXP_SLTSTA_PDC); } -void pcie_cap_slot_unplug_request_cb (HotplugHandler *hotplug_dev, +void pcie_cap_slot_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {Error *local_err =NULL ;
hw/pci/pcie_port.c +1 -1
@@ -188,7 +188,7 @@ int pcie_count_ds_ports(PCIBus *bus)return dsp_count; } -static bool pcie_slot_is_hotpluggable_bus (HotplugHandler *plug_handler, +static bool pcie_slot_is_hotpluggable_bus (const HotplugHandler *plug_handler,BusState *bus) {PCIESlot *s =PCIE_SLOT (bus->parent);
hw/pci/shpc.c +5 -5
@@ -278,7 +278,7 @@ static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot) ++devfn) {PCIDevice *affected_dev = shpc->sec_bus->devices[devfn];if (affected_dev) { -HotplugHandler *hotplug_ctrl; +const HotplugHandler *hotplug_ctrl; hotplug_ctrl =qdev_get_hotplug_handler (DEVICE (affected_dev)); hotplug_handler_unplug(hotplug_ctrl, DEVICE(affected_dev),
@@ -561,8 +561,8 @@ static bool shpc_device_get_slot(PCIDevice *affected_dev, int *slot,return true; } -void shpc_device_plug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, -Error **errp) +void shpc_device_plug_cb (const HotplugHandler *hotplug_dev, +DeviceState *dev,Error **errp) {PCIDevice *pci_hotplug_dev =PCI_DEVICE (hotplug_dev);SHPCDevice *shpc = pci_hotplug_dev->shpc;
@@ -601,13 +601,13 @@ void shpc_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,shpc_interrupt_update (pci_hotplug_dev); } -void shpc_device_unplug_cb (HotplugHandler *hotplug_dev,DeviceState *dev, +void shpc_device_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {qdev_unrealize (dev); } -void shpc_device_unplug_request_cb (HotplugHandler *hotplug_dev, +void shpc_device_unplug_request_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PCIDevice *pci_hotplug_dev =PCI_DEVICE (hotplug_dev);
hw/ppc/e500plat.c +2 -2
@@ -42,7 +42,7 @@ static void e500plat_init(MachineState *machine)ppce500_init (machine); } -static void e500plat_machine_device_plug_cb (HotplugHandler *hotplug_dev, +static void e500plat_machine_device_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PPCE500MachineState *pms =PPCE500_MACHINE (hotplug_dev);
@@ -53,7 +53,7 @@ static void e500plat_machine_device_plug_cb(HotplugHandler *hotplug_dev, } } -static +static const HotplugHandler *e500plat_machine_get_hotpug_handler (MachineState *machine,DeviceState *dev) {
hw/ppc/spapr.c +24 -24
183 lines not on this page · raw message
hw/ppc/spapr_nvdimm.c +1 -1
@@ -64,7 +64,7 @@ struct SPAPRNVDIMMClass {void (*unrealize)(NVDIMMDevice *dimm,Error **errp); }; -bool spapr_nvdimm_validate (HotplugHandler *hotplug_dev,NVDIMMDevice *nvdimm, +bool spapr_nvdimm_validate (const HotplugHandler *hotplug_dev,NVDIMMDevice *nvdimm,uint64_t size,Error **errp) {const MachineClass *mc =MACHINE_GET_CLASS (hotplug_dev);
hw/ppc/spapr_pci.c +6 -6
@@ -1445,7 +1445,7 @@ static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,/* Callback to be called during DRC release. */ void spapr_phb_remove_pci_device_cb (DeviceState *dev) { -HotplugHandler *hotplug_ctrl =qdev_get_hotplug_handler (dev); +const HotplugHandler *hotplug_ctrl =qdev_get_hotplug_handler (dev);hotplug_handler_unplug (hotplug_ctrl, dev, &error_abort);object_unparent (OBJECT (dev));
@@ -1454,7 +1454,7 @@ void spapr_phb_remove_pci_device_cb(DeviceState *dev)int spapr_pci_dt_populate (SpaprDrc *drc,SpaprMachineState *spapr,void *fdt,int *fdt_start_offset,Error **errp) { -HotplugHandler *plug_handler =qdev_get_hotplug_handler (drc->dev); +const HotplugHandler *plug_handler =qdev_get_hotplug_handler (drc->dev);SpaprPhbState *sphb =SPAPR_PCI_HOST_BRIDGE (plug_handler);PCIDevice *pdev =PCI_DEVICE (drc->dev);
@@ -1521,7 +1521,7 @@ static bool bridge_has_valid_chassis_nr(Object *bridge, Error **errp)return true; } -static void spapr_pci_pre_plug (HotplugHandler *plug_handler, +static void spapr_pci_pre_plug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp) {SpaprPhbState *phb =SPAPR_PCI_HOST_BRIDGE (DEVICE (plug_handler));
@@ -1556,7 +1556,7 @@ static void spapr_pci_pre_plug(HotplugHandler *plug_handler, } } -static void spapr_pci_plug (HotplugHandler *plug_handler, +static void spapr_pci_plug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp) {SpaprPhbState *phb =SPAPR_PCI_HOST_BRIDGE (DEVICE (plug_handler));
@@ -1614,7 +1614,7 @@ static void spapr_pci_bridge_unplug(SpaprPhbState *phb,remove_drcs (phb, bus); } -static void spapr_pci_unplug (HotplugHandler *plug_handler, +static void spapr_pci_unplug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp) {SpaprPhbState *phb =SPAPR_PCI_HOST_BRIDGE (DEVICE (plug_handler));
@@ -1639,7 +1639,7 @@ static void spapr_pci_unplug(HotplugHandler *plug_handler,qdev_unrealize (plugged_dev); } -static void spapr_pci_unplug_request (HotplugHandler *plug_handler, +static void spapr_pci_unplug_request (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp) {SpaprPhbState *phb =SPAPR_PCI_HOST_BRIDGE (DEVICE (plug_handler));
hw/remote/machine.c +1 -1
@@ -111,7 +111,7 @@ static void remote_machine_instance_init(Object *obj) s->auto_shutdown = true; } -static void remote_machine_dev_unplug_cb (HotplugHandler *hotplug_dev, +static void remote_machine_dev_unplug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {qdev_unrealize (dev);
hw/riscv/virt.c +3 -3
@@ -1088,8 +1088,8 @@ static void virt_set_acpi(Object *obj, Visitor *v, const char *name,visit_type_OnOffAuto (v, name, &s->acpi, errp); } -static HotplugHandler *virt_machine_get_hotplug_handler (MachineState *machine, -DeviceState *dev) +static const HotplugHandler * +virt_machine_get_hotplug_handler (MachineState *machine,DeviceState *dev) {MachineClass *mc =MACHINE_GET_CLASS (machine);RISCVVirtState *s =RISCV_VIRT_MACHINE (machine);
@@ -1104,7 +1104,7 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,return NULL ; } -static void virt_machine_device_plug_cb (HotplugHandler *hotplug_dev, +static void virt_machine_device_plug_cb (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {RISCVVirtState *s =RISCV_VIRT_MACHINE (hotplug_dev);
hw/s390x/css-bridge.c +1 -1
@@ -26,7 +26,7 @@* (including sending a channel report to the guest) and remove the * device from the virtual css bus. */ -static void ccw_device_unplug (HotplugHandler *hotplug_dev, +static void ccw_device_unplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {CcwDevice *ccw_dev =CCW_DEVICE (dev);
hw/s390x/s390-pci-bus.c +6 -6
@@ -158,7 +158,7 @@ static void s390_pci_shutdown_notifier(Notifier *n, void *opaque)static void s390_pci_perform_unplug (S390PCIBusDevice *pbdev) { -HotplugHandler *hotplug_ctrl; +const HotplugHandler *hotplug_ctrl;if (pbdev->pft ==ZPCI_PFT_ISM ) {notifier_remove (&pbdev->shutdown_notifier);
@@ -1005,8 +1005,8 @@ static bool s390_pci_alloc_idx(S390pciState *s, S390PCIBusDevice *pbdev)return true; } -static void s390_pcihost_pre_plug (HotplugHandler *hotplug_dev,DeviceState *dev, -Error **errp) +static void s390_pcihost_pre_plug (const HotplugHandler *hotplug_dev, +DeviceState *dev,Error **errp) {S390pciState *s =S390_PCI_HOST_BRIDGE (hotplug_dev);
@@ -1079,7 +1079,7 @@ static int s390_pci_interp_plug(S390pciState *s, S390PCIBusDevice *pbdev)return 0 ; } -static void s390_pcihost_plug (HotplugHandler *hotplug_dev,DeviceState *dev, +static void s390_pcihost_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {S390pciState *s =S390_PCI_HOST_BRIDGE (hotplug_dev);
@@ -1216,7 +1216,7 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev, } } -static void s390_pcihost_unplug (HotplugHandler *hotplug_dev,DeviceState *dev, +static void s390_pcihost_unplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {S390pciState *s =S390_PCI_HOST_BRIDGE (hotplug_dev);
@@ -1255,7 +1255,7 @@ static void s390_pcihost_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, } } -static void s390_pcihost_unplug_request (HotplugHandler *hotplug_dev, +static void s390_pcihost_unplug_request (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {
hw/s390x/s390-virtio-ccw.c +8 -8
@@ -343,8 +343,8 @@ static void ccw_init(MachineState *machine) } -static void s390_cpu_plug (HotplugHandler *hotplug_dev, -DeviceState *dev,Error **errp) +static void s390_cpu_plug (const HotplugHandler *hotplug_dev, +DeviceState *dev,Error **errp) {ERRP_GUARD ();MachineState *ms =MACHINE (hotplug_dev);
@@ -608,7 +608,7 @@ out_lock:bql_lock (); } -static void s390_machine_device_pre_plug (HotplugHandler *hotplug_dev, +static void s390_machine_device_pre_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {if (object_dynamic_cast (OBJECT (dev),TYPE_VIRTIO_MD_CCW )) {
@@ -618,7 +618,7 @@ static void s390_machine_device_pre_plug(HotplugHandler *hotplug_dev, } } -static void s390_machine_device_plug (HotplugHandler *hotplug_dev, +static void s390_machine_device_plug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {S390CcwMachineState *s390ms =S390_CCW_MACHINE (hotplug_dev);
@@ -648,7 +648,7 @@ static void s390_machine_device_plug(HotplugHandler *hotplug_dev, } } -static void s390_machine_device_unplug_request (HotplugHandler *hotplug_dev, +static void s390_machine_device_unplug_request (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {if (object_dynamic_cast (OBJECT (dev),TYPE_CPU )) {
@@ -662,7 +662,7 @@ static void s390_machine_device_unplug_request(HotplugHandler *hotplug_dev, } } -static void s390_machine_device_unplug (HotplugHandler *hotplug_dev, +static void s390_machine_device_unplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {if (object_dynamic_cast (OBJECT (dev),TYPE_VIRTIO_MD_CCW )) {
@@ -715,8 +715,8 @@ static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)return ms->possible_cpus; } -static HotplugHandler *s390_get_hotplug_handler (MachineState *machine, -DeviceState *dev) +static const HotplugHandler *s390_get_hotplug_handler (MachineState *machine, +DeviceState *dev) { if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) || object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW) ||
hw/s390x/virtio-ccw-md.c +4 -4
@@ -19,7 +19,7 @@void virtio_ccw_md_pre_plug (VirtIOMDCcw *vmd,MachineState *ms,Error **errp) {DeviceState *dev =DEVICE (vmd); -HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev); +const HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev);MemoryDeviceState *md =MEMORY_DEVICE (vmd);Error *local_err =NULL ;
@@ -48,7 +48,7 @@ void virtio_ccw_md_pre_plug(VirtIOMDCcw *vmd, MachineState *ms, Error **errp)void virtio_ccw_md_plug (VirtIOMDCcw *vmd,MachineState *ms,Error **errp) {DeviceState *dev =DEVICE (vmd); -HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev); +const HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev);MemoryDeviceState *md =MEMORY_DEVICE (vmd);Error *local_err =NULL ;
@@ -72,7 +72,7 @@ void virtio_ccw_md_unplug_request(VirtIOMDCcw *vmd, MachineState *ms, {VirtIOMDCcwClass *vmdc =VIRTIO_MD_CCW_GET_CLASS (vmd);DeviceState *dev =DEVICE (vmd); -HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev); +const HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev);const HotplugHandlerClass *hdc;Error *local_err =NULL ;
@@ -112,7 +112,7 @@ void virtio_ccw_md_unplug_request(VirtIOMDCcw *vmd, MachineState *ms,void virtio_ccw_md_unplug (VirtIOMDCcw *vmd,MachineState *ms,Error **errp) {DeviceState *dev =DEVICE (vmd); -HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev); +const HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev);MemoryDeviceState *md =MEMORY_DEVICE (vmd);Error *local_err =NULL ;
hw/s390x/virtio-ccw.c +1 -1
@@ -1235,7 +1235,7 @@ static void virtio_ccw_busdev_unrealize(DeviceState *dev)virtio_ccw_device_unrealize (_dev); } -static void virtio_ccw_busdev_unplug (HotplugHandler *hotplug_dev, +static void virtio_ccw_busdev_unplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {VirtioCcwDevice *_dev =to_virtio_ccw_dev_fast (dev);
hw/scsi/virtio-scsi.c +3 -3
@@ -1144,14 +1144,14 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense) } } -static void virtio_scsi_pre_hotplug (HotplugHandler *hotplug_dev, +static void virtio_scsi_pre_hotplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {SCSIDevice *sd =SCSI_DEVICE (dev); sd->hba_supports_iothread = true; } -static void virtio_scsi_hotplug (HotplugHandler *hotplug_dev,DeviceState *dev, +static void virtio_scsi_hotplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {VirtIODevice *vdev =VIRTIO_DEVICE (hotplug_dev);
@@ -1183,7 +1183,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, } } -static void virtio_scsi_hotunplug (HotplugHandler *hotplug_dev,DeviceState *dev, +static void virtio_scsi_hotunplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {VirtIODevice *vdev =VIRTIO_DEVICE (hotplug_dev);
hw/scsi/vmw_pvscsi.c +2 -2
@@ -612,7 +612,7 @@ pvscsi_send_msg(PVSCSIState *s, SCSIDevice *dev, uint32_t msg_type) }static void -pvscsi_hotplug (HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) +pvscsi_hotplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PVSCSIState *s =PVSCSI (hotplug_dev);
@@ -620,7 +620,7 @@ pvscsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) }static void -pvscsi_hot_unplug (HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) +pvscsi_hot_unplug (const HotplugHandler *hotplug_dev,DeviceState *dev,Error **errp) {PVSCSIState *s =PVSCSI (hotplug_dev);
hw/virtio/virtio-md-pci.c +4 -4
@@ -19,7 +19,7 @@void virtio_md_pci_pre_plug (VirtIOMDPCI *vmd,MachineState *ms,Error **errp) {DeviceState *dev =DEVICE (vmd); -HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev); +const HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev);MemoryDeviceState *md =MEMORY_DEVICE (vmd);Error *local_err =NULL ;
@@ -47,7 +47,7 @@ void virtio_md_pci_pre_plug(VirtIOMDPCI *vmd, MachineState *ms, Error **errp)void virtio_md_pci_plug (VirtIOMDPCI *vmd,MachineState *ms,Error **errp) {DeviceState *dev =DEVICE (vmd); -HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev); +const HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev);MemoryDeviceState *md =MEMORY_DEVICE (vmd);Error *local_err =NULL ;
@@ -71,7 +71,7 @@ void virtio_md_pci_unplug_request(VirtIOMDPCI *vmd, MachineState *ms, {VirtIOMDPCIClass *vmdc =VIRTIO_MD_PCI_GET_CLASS (vmd);DeviceState *dev =DEVICE (vmd); -HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev); +const HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev);const HotplugHandlerClass *hdc;Error *local_err =NULL ;
@@ -110,7 +110,7 @@ void virtio_md_pci_unplug_request(VirtIOMDPCI *vmd, MachineState *ms,void virtio_md_pci_unplug (VirtIOMDPCI *vmd,MachineState *ms,Error **errp) {DeviceState *dev =DEVICE (vmd); -HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev); +const HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev);MemoryDeviceState *md =MEMORY_DEVICE (vmd);Error *local_err =NULL ;
hw/xen/xen-bus.c +1 -1
@@ -374,7 +374,7 @@ fail:g_free (key); } -static void xen_bus_unplug_request (HotplugHandler *hotplug, +static void xen_bus_unplug_request (const HotplugHandler *hotplug,DeviceState *dev,Error **errp) {
stubs/hotplug-stubs.c +3 -3
@@ -14,19 +14,19 @@#include "qemu/osdep.h" #include "hw/core/qdev.h" -HotplugHandler *qdev_get_hotplug_handler (DeviceState *dev) +const HotplugHandler *qdev_get_hotplug_handler (DeviceState *dev) {return NULL ; } -void hotplug_handler_pre_plug (HotplugHandler *plug_handler, +void hotplug_handler_pre_plug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp) {g_assert_not_reached (); } -void hotplug_handler_plug (HotplugHandler *plug_handler, +void hotplug_handler_plug (const HotplugHandler *plug_handler,DeviceState *plugged_dev,Error **errp) {
system/qdev-monitor.c +1 -1
@@ -917,7 +917,7 @@ static DeviceState *find_device_state(const char *id, bool use_generic_error,void qdev_unplug (DeviceState *dev,Error **errp) { -HotplugHandler *hotplug_ctrl; +const HotplugHandler *hotplug_ctrl;const HotplugHandlerClass *hdc;Error *local_err =NULL ;
Signature · 1 line
MST
[PULL v2 66/75] net/tap-solaris: Fix resource leaks on error paths
In reply to Michael S. Tsirkin--- net/tap-solaris.c | 69 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 21 deletions(-)
net/tap-solaris.c +48 -21
@@ -60,8 +60,6 @@ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)*/ static int tap_alloc (char *dev,size_t dev_size,Error **errp) { -/* FIXME leaks like a sieve on error paths */ -/* FIXME suspicious: many errors are reported, then ignored */ int tap_fd, if_fd, ppa =-1 ;static int ip_fd =0 ;char *ptr;
@@ -102,45 +100,61 @@ static int tap_alloc(char *dev, size_t dev_size, Error **errp) strioc_ppa.ic_timout =0 ; strioc_ppa.ic_len =sizeof (ppa); strioc_ppa.ic_dp = (char *)&ppa; -if ((ppa =ioctl (tap_fd,I_STR , &strioc_ppa)) <0 ) +if ((ppa =ioctl (tap_fd,I_STR , &strioc_ppa)) <0 ) {error_report ("Can't assign new interface" ); + goto fail_tap_fd; + } if_fd =RETRY_ON_EINTR (open ("/dev/tap" ,O_RDWR ,0 ));if (if_fd <0 ) {error_setg_file_open (errp, errno,"/dev/tap" ); -return -1 ; + goto fail_tap_fd; }if (ioctl (if_fd,I_PUSH ,"ip" ) <0 ){error_setg (errp,"Can't push IP module" ); -return -1 ; + goto fail_if_fd; } -if (ioctl (if_fd,SIOCGLIFFLAGS , &ifr) <0 ) +if (ioctl (if_fd,SIOCGLIFFLAGS , &ifr) <0 ) {error_report ("Can't get flags" ); + goto fail_if_fd; + } -snprintf (actual_name,32 ,"tap%d" , ppa); +snprintf (actual_name,32 ,"tap%d" , ppa);pstrcpy (ifr.lifr_name,sizeof (ifr.lifr_name), actual_name); ifr.lifr_ppa = ppa; -/* Assign ppa according to the unit number returned by tun device */ - -if (ioctl (if_fd,SIOCSLIFNAME , &ifr) <0 ) +if (ioctl (if_fd,SIOCSLIFNAME , &ifr) <0 ) {error_report ("Can't set PPA %d" , ppa); -if (ioctl (if_fd,SIOCGLIFFLAGS , &ifr) <0 ) + goto fail_if_fd; + } + +if (ioctl (if_fd,SIOCGLIFFLAGS , &ifr) <0 ) {error_report ("Can't get flags" ); + goto fail_if_fd; + } +/* Push arp module to if_fd */ -if (ioctl (if_fd,I_PUSH ,"arp" ) <0 ) +if (ioctl (if_fd,I_PUSH ,"arp" ) <0 ) {error_report ("Can't push ARP module (2)" ); + goto fail_if_fd; + }/* Push arp module to ip_fd */ -if (ioctl (ip_fd,I_POP ,NULL ) <0 ) +if (ioctl (ip_fd,I_POP ,NULL ) <0 ) {error_report ("I_POP failed" ); -if (ioctl (ip_fd,I_PUSH ,"arp" ) <0 ) + goto fail_if_fd; + } +if (ioctl (ip_fd,I_PUSH ,"arp" ) <0 ) {error_report ("Can't push ARP module (3)" ); + goto fail_if_fd; + }/* Open arp_fd */ arp_fd =RETRY_ON_EINTR (open ("/dev/tap" ,O_RDWR ,0 )); -if (arp_fd <0 ) +if (arp_fd <0 ) {error_report ("Can't open %s" ,"/dev/tap" ); + goto fail_if_fd; + }/* Set ifname to arp */ strioc_if.ic_cmd =SIOCSLIFNAME ;
@@ -149,32 +163,45 @@ static int tap_alloc(char *dev, size_t dev_size, Error **errp) strioc_if.ic_dp = (char *)𝔦if (ioctl (arp_fd,I_STR , &strioc_if) <0 ){error_report ("Can't set ifname to arp" ); + goto fail_arp_fd; }if ((ip_muxid =ioctl (ip_fd,I_LINK , if_fd)) <0 ){error_setg (errp,"Can't link TAP device to IP" ); -return -1 ; + goto fail_arp_fd; } -if ((arp_muxid =ioctl (ip_fd, link_type, arp_fd)) <0 ) +if ((arp_muxid =ioctl (ip_fd, link_type, arp_fd)) <0 ) {error_report ("Can't link TAP device to ARP" ); + goto fail_ip_muxid; + } -close (if_fd); +close (if_fd);memset (&ifr,0x0 ,sizeof (ifr));pstrcpy (ifr.lifr_name,sizeof (ifr.lifr_name), actual_name); ifr.lifr_ip_muxid = ip_muxid; ifr.lifr_arp_muxid = arp_muxid; -if (ioctl (ip_fd,SIOCSLIFMUXID , &ifr) <0 ) +if (ioctl (ip_fd,SIOCSLIFMUXID , &ifr) <0 ) { -ioctl (ip_fd,I_PUNLINK , arp_muxid); -ioctl (ip_fd,I_PUNLINK , ip_muxid); +ioctl (ip_fd,I_PUNLINK , arp_muxid); +ioctl (ip_fd,I_PUNLINK , ip_muxid);error_report ("Can't set multiplexor id" ); }snprintf (dev, dev_size,"tap%d" , ppa);return tap_fd; + +fail_ip_muxid: +ioctl (ip_fd,I_PUNLINK , ip_muxid); +fail_arp_fd: +close (arp_fd); +fail_if_fd: +close (if_fd); +fail_tap_fd: +close (tap_fd); +return -1 ; } int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
Signature · 1 line
MST
[PULL v2 42/75] vhost-user.rst: fix typo
In reply to Michael S. TsirkinFrom: Alyssa Ross <[email protected]>
The protocol feature is named SHMEM. SHMEM_MAP is one of the requests.
Message-ID: <[email protected]>
--- docs/interop/vhost-user.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
docs/interop/vhost-user.rst +1 -1
@@ -1158,7 +1158,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_DEVICE_STATE 19 #define VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT 20 #define VHOST_USER_PROTOCOL_F_GPA_ADDRESSES 21 - #define VHOST_USER_PROTOCOL_F_SHMEM_MAP 22 + #define VHOST_USER_PROTOCOL_F_SHMEM 22 Front-end message types -----------------------
Signature · 1 line
MST
[PULL v2 68/75] intel_iommu: Expose SMPWC when SVM is enabled
In reply to Michael S. TsirkinFrom: Clément MATHIEU--DRIF <[email protected]>
SVM in Linux requires SMPWC. This is free in the current implementation as it is already in line with the expected behaviour.
Message-ID: <[email protected]>
--- hw/i386/intel_iommu_internal.h | 1 + hw/i386/intel_iommu.c | 3 ++- hw/i386/intel_iommu_accel.c | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-)
hw/i386/intel_iommu_internal.h +1 -0
@@ -202,6 +202,7 @@#define VTD_ECAP_SMTS (1ULL << 43)#define VTD_ECAP_SSTS (1ULL << 46)#define VTD_ECAP_FSTS (1ULL << 47) +#define VTD_ECAP_SMPWCS (1ULL << 48)/* CAP_REG */ /* (offset >> 4) << 24 */
hw/i386/intel_iommu.c +2 -1
@@ -5121,7 +5121,8 @@ static void vtd_init(IntelIOMMUState *s) }if (s->svm) { - s->ecap |=VTD_ECAP_PRS |VTD_ECAP_PDS |VTD_ECAP_NWFS ; + s->ecap |=VTD_ECAP_PRS |VTD_ECAP_PDS |VTD_ECAP_NWFS | +VTD_ECAP_SMPWCS ; }vtd_reset_caches (s);
hw/i386/intel_iommu_accel.c +6 -0
@@ -37,6 +37,12 @@ bool vtd_check_hiod_accel(IntelIOMMUState *s, VTDHostIOMMUDevice *vtd_hiod,return false; } +if ((s->ecap &VTD_ECAP_SMPWCS ) && !(vtd->ecap_reg &VTD_ECAP_SMPWCS )) { +error_setg (errp, +"Scalable-mode coherent walk is unsupported by host IOMMU" ); +return false; + } +if (s->fs1gp && !(vtd->cap_reg &VTD_CAP_FS1GP )) {error_setg (errp,"First stage 1GB large page is unsupported by host IOMMU" );
Signature · 1 line
MST
[PULL v2 74/75] vhost-user-blk: use GET_VRING_BASE_SKIP_DRAIN when inflight-migration is on
In reply to Michael S. TsirkinFrom: Alexandr Moshkov <[email protected]>
Currently during live migration vhost-user-blk sends GET_VRING_BASE to stop vrings, which causes the back-end to drain all in-flight I/O before returning. This blocks the migration source until all I/O completes, adding significant downtime proportional to the I/O load.
When inflight-migration is enabled, send GET_VRING_BASE_SKIP_DRAIN instead. This instructs the back-end to immediately suspend in-flight I/O and record it in the shared inflight region, which is then migrated to the destination host along with the rest of the device state.
Since inflight-migration can only be toggled while the VM is running, i2ts value at stop time reliably reflects the intent set on a live VM. There is no need to check migration runstate to decide whether to skip draining. Using GET_VRING_BASE_SKIP_DRAIN on a regular VM stop is safe - the back-end records any in-flight requests in the shared inflight region, and they will be resubmitted when the VM starts again via SET_INFLIGHT_FD.
If the back-end does not support VHOST_USER_PROTOCOL_F_GET_VRING_BASE_SKIP_DRAIN,
migration is aborted with an error in pre_save rather than hitting an assert at runtime.
Message-ID: <[email protected]>
--- include/hw/virtio/vhost-user.h | 1 - hw/block/vhost-user-blk.c | 29 +++++++++++++++++++++++------ hw/virtio/vhost-user.c | 3 +-- 3 files changed, 24 insertions(+), 9 deletions(-)
include/hw/virtio/vhost-user.h +0 -1
@@ -73,7 +73,6 @@ typedef struct VhostUserState {GPtrArray *notifiers;int memory_slots;bool supports_config; -bool supports_inflight_migration; } VhostUserState;/**
hw/block/vhost-user-blk.c +23 -6
@@ -141,10 +141,7 @@ static bool vhost_user_blk_inflight_needed(void *opaque) {struct VHostUserBlk *s = opaque; -bool inflight_migration =virtio_has_feature (s->dev.protocol_features, -VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT ); - -return inflight_migration; +return s->inflight_migration; }
@@ -245,11 +242,13 @@ static int vhost_user_blk_stop(VirtIODevice *vdev)return 0 ; } +bool skip_drain =vhost_user_blk_inflight_needed (s); + force_stop = s->skip_get_vring_base_on_force_shutdown &&qemu_force_shutdown_requested (); ret = force_stop ?vhost_dev_force_stop (&s->dev, vdev, true) : -vhost_dev_stop (&s->dev, vdev, true, false); +vhost_dev_stop (&s->dev, vdev, true, skip_drain); err = k->set_guest_notifiers (qbus->parent, s->dev.nvqs, false);if (err <0 ) {
@@ -381,7 +380,6 @@ static int vhost_user_blk_connect(DeviceState *dev, Error **errp)vhost_dev_set_config_notifier (&s->dev, &blk_ops); s->vhost_user.supports_config = true; - s->vhost_user.supports_inflight_migration = s->inflight_migration; ret =vhost_dev_init (&s->dev, &s->vhost_user,VHOST_BACKEND_TYPE_USER ,0 , errp);if (ret <0 ) {
@@ -608,10 +606,29 @@ static struct vhost_dev *vhost_user_blk_get_vhost(VirtIODevice *vdev)return &s->dev; } +static bool vhost_user_blk_pre_save (void *opaque,Error **errp) +{ +VHostUserBlk *s =VHOST_USER_BLK (opaque); + +bool inflight_migration_enabled =vhost_user_has_protocol_feature (&s->dev, +VHOST_USER_PROTOCOL_F_GET_VRING_BASE_SKIP_DRAIN ); + +if (vhost_user_blk_inflight_needed (s) && !inflight_migration_enabled) { +error_setg (errp,"can't migrate vhost-user-blk device: " +"backend doesn't support " +"VHOST_USER_PROTOCOL_F_GET_VRING_BASE_SKIP_DRAIN " +"protocol feature" ); +return false; + } + +return true; +} +static const VMStateDescription vmstate_vhost_user_blk_inflight = { .name ="vhost-user-blk/inflight" , .version_id =1 , .needed = vhost_user_blk_inflight_needed, + .pre_save_errp = vhost_user_blk_pre_save, .fields = (const VMStateField []) {VMSTATE_VHOST_INFLIGHT_REGION (inflight, VHostUserBlk),VMSTATE_END_OF_LIST ()
hw/virtio/vhost-user.c +1 -2
@@ -2596,8 +2596,7 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque, } } -if (!u->user->supports_inflight_migration || - !virtio_has_feature (protocol_features, +if (!virtio_has_feature (protocol_features,VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD )) { protocol_features &= ~(1ULL <<VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT );
Signature · 1 line
MST
[PULL v2 41/75] virtio-balloon: fix free-page BH teardown on unrealize
In reply to Michael S. TsirkinWhen a guest triggers PCIe hot-unplug while the free-page-hint BH is running on an IOThread, the BH will keep accessing vq->used_elems array when running it. Note that qemu_bh_delete merely prevents new BHs from running, it does not wait for already running ones to finish.
We need to wait for it to finish - do it like virtio scsi and run a dummy oneshot AIO in the same context, and wait for it.
But there's a twist: BH could be blocked in qemu_cond_wait, then AIO won't run.
Add a special reporting state FREE_PAGE_HINT_S_UNREALIZE to make BH exit immediately.
Cc: David Hildenbrand <[email protected]>
Fixes: CVE-2026-66899
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4079
Message-ID: <0967d574d9ffe469edf5fc16da86237e54a69c34.1785327742.git.mst@redhat.com>
--- include/hw/virtio/virtio-balloon.h | 1 + hw/virtio/virtio-balloon.c | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
include/hw/virtio/virtio-balloon.h +1 -0
@@ -39,6 +39,7 @@ enum virtio_balloon_free_page_hint_status {FREE_PAGE_HINT_S_REQUESTED =1 ,FREE_PAGE_HINT_S_START =2 ,FREE_PAGE_HINT_S_DONE =3 , + FREE_PAGE_HINT_S_UNREALIZE = 4, }; struct VirtIOBalloon {
hw/virtio/virtio-balloon.c +18 -1
@@ -35,6 +35,7 @@#include "system/reset.h" #include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio-access.h" +#include "qemu/aio-wait.h" #define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT)
@@ -519,6 +520,9 @@ static bool get_free_page_hints(VirtIOBalloon *dev)int i;while (dev->block_iothread) { +if (dev->free_page_hint_status ==FREE_PAGE_HINT_S_UNREALIZE ) { +return false; + }qemu_cond_wait (&dev->free_page_cond, &dev->free_page_lock); }
@@ -912,6 +916,11 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)qemu_register_resettable (OBJECT (dev)); } +static void dummy_bh (void *opaque) +{ +/* Do nothing */ +} +static void virtio_balloon_device_unrealize (DeviceState *dev) {VirtIODevice *vdev =VIRTIO_DEVICE (dev);
@@ -919,9 +928,17 @@ static void virtio_balloon_device_unrealize(DeviceState *dev)qemu_unregister_resettable (OBJECT (dev));if (s->free_page_bh) { +AioContext *ctx =iothread_get_aio_context (s->iothread); +qemu_bh_delete (s->free_page_bh); + +qemu_mutex_lock (&s->free_page_lock); + s->free_page_hint_status =FREE_PAGE_HINT_S_UNREALIZE ; +qemu_cond_signal (&s->free_page_cond); +qemu_mutex_unlock (&s->free_page_lock); +aio_wait_bh_oneshot (ctx, dummy_bh,NULL ); +object_unref (OBJECT (s->iothread)); -virtio_balloon_free_page_stop (s);precopy_remove_notifier (&s->free_page_hint_notify); }balloon_stats_destroy_timer (s);
Signature · 1 line
MST
[PULL v2 56/75] virtio-rtc: Report smeared UTC clock type
In reply to Michael S. TsirkinFrom: Kuan-Wei Chiu <[email protected]>
The Linux virtio_rtc driver only registers an RTC class device when the clock type is VIRTIO_RTC_CLOCK_UTC_SMEARED to avoid leap second steps on pure UTC clocks.
Report VIRTIO_RTC_CLOCK_UTC_SMEARED in clock capabilities so the guest can expose the device as an RTC device.
Message-ID: <[email protected]>
--- hw/virtio/virtio-rtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
hw/virtio/virtio-rtc.c +2 -1
@@ -62,7 +62,8 @@ static void virtio_rtc_handle_request(VirtIODevice *vdev, VirtQueue *vq) resp.head.status =VIRTIO_RTC_S_ENODEV ; }else { resp.head.status =VIRTIO_RTC_S_OK ; - resp.type =VIRTIO_RTC_CLOCK_UTC ; + resp.type =VIRTIO_RTC_CLOCK_UTC_SMEARED ; + resp.leap_second_smearing =VIRTIO_RTC_SMEAR_UNSPECIFIED ; } written =iov_from_buf (elem->in_sg, elem->in_num,0 , &resp,sizeof (resp));
Signature · 1 line
MST
[PULL v2 21/75] virtio-net: support local migration of backend
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
Next commit will introduce live-migration (with fd-passing) for TAP net backend. So, now we prepare virtio-net for it
Add virtio-net option local-migration, which is true by default, but false for older machine types, which doesn't support the feature.
We introduce interface for live-migrating backends:
1. ->is_wait_incoming() handler, so that virtio-net knows, that backend is not fully intialized, as it waits for incoming migration stream.
2. MIG_PRI_BACKEND priority: backends should migrate with higher priority than virtio-net, so that we can do final preparations here in post-load handlers and be sure, that backends are already prepared.
Message-ID: <[email protected]>
--- include/hw/virtio/virtio-net.h | 1 + include/migration/vmstate.h | 2 + include/net/net.h | 2 + hw/net/virtio-net.c | 89 +++++++++++++++++++++++++++++++++- 4 files changed, 93 insertions(+), 1 deletion(-)
include/hw/virtio/virtio-net.h +1 -0
@@ -230,6 +230,7 @@ struct VirtIONet {struct EBPFRSSContext ebpf_rss;uint32_t nr_ebpf_rss_fds;char **ebpf_rss_fds; +bool peers_wait_incoming; }; size_t virtio_net_handle_ctrl_iov(VirtIODevice *vdev,
include/migration/vmstate.h +2 -0
@@ -169,6 +169,8 @@ typedef enum {MIG_PRI_LOW ,/* Must happen after default */ MIG_PRI_DEFAULT , +MIG_PRI_BACKEND ,/* Must happen before emulated devices, */ +/* e.g. virtio-net */ MIG_PRI_IOMMU ,/* Must happen before PCI devices */ MIG_PRI_PCI_BUS ,/* Must happen before IOMMU */ MIG_PRI_VIRTIO_MEM, /* Must happen before IOMMU */
include/net/net.h +2 -0
@@ -82,6 +82,7 @@ typedef void (SocketReadStateFinalize)(SocketReadState *rs);typedef void (NetAnnounce )(NetClientState *);typedef bool (SetSteeringEBPF )(NetClientState *,int );typedef bool (NetCheckPeerType )(NetClientState *,ObjectClass *,Error **); +typedef bool (IsWaitIncoming )(NetClientState *);typedef struct vhost_net *(GetVHostNet )(NetClientState *nc); typedef struct NetClientInfo {
@@ -110,6 +111,7 @@ typedef struct NetClientInfo {NetAnnounce *announce;SetSteeringEBPF *set_steering_ebpf;NetCheckPeerType *check_peer_type; +IsWaitIncoming *is_wait_incoming;GetVHostNet *get_vhost_net; } NetClientInfo;
hw/net/virtio-net.c +88 -1
137 lines not on this page · raw message
Signature · 1 line
MST
[PULL v2 46/75] amd_iommu: acpi-build: update PA, GVA and VA size macros
In reply to Michael S. TsirkinFrom: Sairaj Kodilkar <[email protected]>
Current implementation supports up to 64 bit IOVA and up to 52 bit PA. Modify related macros so that guest can see right size.
Also, use these macros to build the IVINFO field in the IVRS.
Message-ID: <[email protected]>
--- hw/i386/amd_iommu.h | 11 ++++++++--- hw/i386/acpi-build.c | 4 +++- hw/i386/amd_iommu.c | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-)
hw/i386/amd_iommu.h +8 -3
@@ -243,9 +243,14 @@#define AMDVI_PAGE_SHIFT_4K 12#define AMDVI_PAGE_MASK_4K GENMASK64(63, 12) -#define AMDVI_MAX_GVA_ADDR (2UL << 5) -#define AMDVI_MAX_PH_ADDR (40UL << 8) -#define AMDVI_MAX_VA_ADDR (48UL << 15) +/* +* IOMMU Capability Offset 10h: Miscellaneous Information Register 0. +* VAsize[21:15], PAsize[14:8], and GVAsize[7:5]. +* These fields use the same layout in the IVRS IVinfo Field. +*/ +#define AMDVI_VA_SIZE_64 (64UL << 15) +#define AMDVI_PA_SIZE_52 (52UL << 8) +#define AMDVI_GVA_SIZE_48 (2UL << 5)/* Completion Wait data size */ #define AMDVI_COMPLETION_DATA_SIZE 8
hw/i386/acpi-build.c +3 -1
@@ -1858,7 +1858,9 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id,*/ build_append_int_noprefix (table_data, (1UL <<0 ) |/* EFRSup */ - (40UL <<8 ),/* PASize */ +AMDVI_GVA_SIZE_48 |/* GVASize: 010b = 48 bits */ +AMDVI_PA_SIZE_52 |/* PASize: 011_0100b = 52 bits */ +AMDVI_VA_SIZE_64 ,/* VASize: 100_0000b = 64 bits */ 4 );/* reserved */ build_append_int_noprefix (table_data,0 ,8 );
hw/i386/amd_iommu.c +1 -1
@@ -2595,7 +2595,7 @@ static void amdvi_pci_realize(PCIDevice *pdev, Error **errp) 0xff000000);pci_set_long (pdev->config + s->capab_offset +AMDVI_CAPAB_MISC ,0 );pci_set_long (pdev->config + s->capab_offset +AMDVI_CAPAB_MISC , -AMDVI_MAX_PH_ADDR |AMDVI_MAX_GVA_ADDR |AMDVI_MAX_VA_ADDR ); +AMDVI_PA_SIZE_52 |AMDVI_GVA_SIZE_48 |AMDVI_VA_SIZE_64 ); }static void amdvi_sysbus_reset (DeviceState *dev)
Signature · 1 line
MST
[PULL v2 73/75] vhost-user-blk: move inflight_needed higher
In reply to Michael S. TsirkinFrom: Alexandr Moshkov <[email protected]>
Move vhost_user_blk_inflight_needed() earlier in the file so it can be called from vhost_user_blk_stop(), which is defined before the VMState section. No functional change.
Message-ID: <[email protected]>
--- hw/block/vhost-user-blk.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
hw/block/vhost-user-blk.c +11 -8
@@ -137,6 +137,17 @@ const VhostDevConfigOps blk_ops = { .vhost_dev_config_notifier = vhost_user_blk_handle_config_change, }; +static bool vhost_user_blk_inflight_needed (void *opaque) +{ +struct VHostUserBlk *s = opaque; + +bool inflight_migration =virtio_has_feature (s->dev.protocol_features, +VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT ); + +return inflight_migration; +} + +static int vhost_user_blk_start (VirtIODevice *vdev,Error **errp) {VHostUserBlk *s =VHOST_USER_BLK (vdev);
@@ -597,14 +608,6 @@ static struct vhost_dev *vhost_user_blk_get_vhost(VirtIODevice *vdev)return &s->dev; } -static bool vhost_user_blk_inflight_needed (void *opaque) -{ -struct VHostUserBlk *s = opaque; - -return vhost_user_has_protocol_feature ( - &s->dev,VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT ); -} -static const VMStateDescription vmstate_vhost_user_blk_inflight = { .name ="vhost-user-blk/inflight" , .version_id =1 ,
Signature · 1 line
MST
[PULL v2 34/75] hw/nvme: Fix block accounting for compare
In reply to Michael S. TsirkinFrom: Hanna Czenczek <[email protected]>
nvme_compare() starts block accounting for the operation, but nvme_compare_data_cb() (and nvme_compare_mdata_cb()) do not always finalize the cookie. Specifically, there are a lot of error paths that do not call block_acct_failed().
Fix this by putting block_acct_done()/block_acct_failed() under the out labels of nvme_compare_data_cb() and nvme_compare_mdata_cb().
Message-ID: <[email protected]>
--- hw/nvme/ctrl.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
hw/nvme/ctrl.c +12 -5
@@ -2389,7 +2389,6 @@ static void nvme_compare_mdata_cb(void *opaque, int ret)trace_pci_nvme_compare_mdata_cb (nvme_cid (req));if (ret) { -block_acct_failed (stats, acct); req->status =NVME_UNRECOVERED_READ ;trace_pci_nvme_err_aio (nvme_cid (req),strerror (-ret), req->status);
@@ -2444,9 +2443,14 @@ static void nvme_compare_mdata_cb(void *opaque, int ret) goto out; } -block_acct_done (stats, acct); out: +if (req->status ==NVME_SUCCESS ) { +block_acct_done (stats, acct); + }else { +block_acct_failed (stats, acct); + } +qemu_iovec_destroy (&ctx->data.iov);g_free (ctx->data.bounce);
@@ -2474,7 +2478,6 @@ static void nvme_compare_data_cb(void *opaque, int ret)trace_pci_nvme_compare_data_cb (nvme_cid (req));if (ret) { -block_acct_failed (stats, acct); req->status =NVME_UNRECOVERED_READ ;trace_pci_nvme_err_aio (nvme_cid (req),strerror (-ret), req->status);
@@ -2513,9 +2516,13 @@ static void nvme_compare_data_cb(void *opaque, int ret)return ; } -block_acct_done (stats, acct); - out: +if (req->status ==NVME_SUCCESS ) { +block_acct_done (stats, acct); + }else { +block_acct_failed (stats, acct); + } +qemu_iovec_destroy (&ctx->data.iov);g_free (ctx->data.bounce);g_free (ctx);
Signature · 1 line
MST
[PULL v2 67/75] virtio-net: validate IHL in virtio_net_rsc_extract_unit4 before use
In reply to Michael S. Tsirkinvirtio_net_rsc_extract_unit4() uses the IPv4 IHL nibble from the wire to compute the TCP header offset, but the caller's length check only guarantees space for a minimum 20-byte IP header. A crafted IHL of 15 causes a read 32 bytes past a 66-byte buffer when the frame was parked in net/queue.c's exact-size allocation.
virtio_net_rsc_sanity_check4() rejects IHL != 5 on the next line, but runs after the OOB read already happened.
Validate IHL before using it as an offset. Since virtio_net_rsc_sanity_check4() only accepts IHL == 5 anyway, reject anything else early and let the caller fall through to the bypass path.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4166
--- hw/net/virtio-net.c | 8 ++++++++ 1 file changed, 8 insertions(+)
hw/net/virtio-net.c +8 -0
@@ -2104,6 +2104,14 @@ static void virtio_net_rsc_extract_unit4(VirtioNetRscChain *chain, unit->ip = (void *)ip; ip_hdrlen = (ip->ip_ver_len &0xF ) <<2 ; unit->ip_plen = &ip->ip_len; + +if (ip_hdrlen !=sizeof (struct ip_header )) { + unit->tcp =NULL ; + unit->tcp_hdrlen =0 ; + unit->payload =0 ; +return ; + } + unit->tcp = (struct tcp_header *)(((uint8_t *)unit->ip) + ip_hdrlen); unit->tcp_hdrlen = (htons (unit->tcp->th_offset_flags) &0xF000 ) >>10 ; unit->payload =read_unit_ip_len (unit) - ip_hdrlen - unit->tcp_hdrlen;
Signature · 1 line
MST
[PULL v2 47/75] acpi_build: Use IOMMU pci device to build IOMMU DeviceID
In reply to Michael S. TsirkinFrom: Sairaj Kodilkar <[email protected]>
Currently, build_amd_iommu() uses "addr" property to build the DeviceID for IOMMU device and advertise it through IVRS. But this property does not encode IOMMU bus number, only the device and function number. This creates an incorrect DeviceID when the IOMMU is attached to a bus other than the default one with bus number 0.
Message-ID: <[email protected]>
--- hw/i386/acpi-build.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
hw/i386/acpi-build.c +4 -6
@@ -1851,6 +1851,7 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id,AcpiTable table = { .sig ="IVRS" , .rev =1 , .oem_id = oem_id, .oem_table_id = oem_table_id };uint64_t feature_report; +uint16_t iommu_devid =pci_get_bdf (&s->pci->dev);acpi_table_begin (&table, table_data);/* IVinfo - IO virtualization information common to all
@@ -1913,9 +1914,7 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id,/* IVHD length */ build_append_int_noprefix (table_data, ivhd_blob->len +24 ,2 );/* DeviceID */ -build_append_int_noprefix (table_data, -object_property_get_int (OBJECT (s->pci),"addr" , - &error_abort),2 ); +build_append_int_noprefix (table_data, iommu_devid,2 );/* Capability offset */ build_append_int_noprefix (table_data, s->pci->capab_offset,2 );/* IOMMU base address */
@@ -1947,10 +1946,9 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id,/* IVHD length */ build_append_int_noprefix (table_data, ivhd_blob->len +40 ,2 ); +/* DeviceID */ -build_append_int_noprefix (table_data, -object_property_get_int (OBJECT (s->pci),"addr" , - &error_abort),2 ); +build_append_int_noprefix (table_data, iommu_devid,2 );/* Capability offset */ build_append_int_noprefix (table_data, s->pci->capab_offset,2 );/* IOMMU base address */
Signature · 1 line
MST
[PULL v2 39/75] virtio-crypto: clean up every data queue
In reply to Michael S. TsirkinFrom: GuoHan Zhao <[email protected]>
realize() creates max_queues data queues and one BH for each of them. unrealize() decides how many to tear down from multiqueue, but nothing ever sets that field, so it only deletes the first queue and BH.
It does not matter how many queues the guest used here. unrealize() must undo all the allocations made by realize(), so loop over max_queues.
Message-ID: <[email protected]>
--- hw/virtio/virtio-crypto.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
hw/virtio/virtio-crypto.c +2 -3
@@ -1114,10 +1114,9 @@ static void virtio_crypto_device_unrealize(DeviceState *dev)VirtIODevice *vdev =VIRTIO_DEVICE (dev);VirtIOCrypto *vcrypto =VIRTIO_CRYPTO (dev);VirtIOCryptoQueue *q; -int i, max_queues; +int i; - max_queues = vcrypto->multiqueue ? vcrypto->max_queues :1 ; -for (i =0 ; i < max_queues; i++) { +for (i =0 ; i < vcrypto->max_queues; i++) {virtio_delete_queue (vcrypto->vqs[i].dataq); q = &vcrypto->vqs[i];qemu_bh_delete (q->dataq_bh);
Signature · 1 line
MST
[PULL v2 59/75] intel_iommu: Always write all the flags passed to vtd_set_flag_in_pte
In reply to Michael S. TsirkinFrom: Clément MATHIEU--DRIF <[email protected]>
This function was initially designed to write a single flag in a pte. The current implementation expects it to set several flags.
Message-ID: <[email protected]>
--- hw/i386/intel_iommu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
hw/i386/intel_iommu.c +5 -5
@@ -1964,13 +1964,13 @@ static bool vtd_iova_fs_check_canonical(IntelIOMMUState *s, uint64_t iova, } } -static MemTxResult vtd_set_flag_in_pte (dma_addr_t base_addr,uint32_t index, -uint64_t pte,uint64_t flag) +static MemTxResult vtd_set_flags_in_pte (dma_addr_t base_addr,uint32_t index, +uint64_t pte,uint64_t flags) { -if (pte & flag) { +if ((pte & flags) == flags) {return MEMTX_OK ; } - pte |= flag; + pte |= flags; pte =cpu_to_le64 (pte); return dma_memory_write(&address_space_memory, base_addr + index * sizeof(pte),
@@ -2043,7 +2043,7 @@ static int vtd_iova_to_fspte(IntelIOMMUState *s, VTDContextEntry *ce, flag_ad |=VTD_FS_D ; } -if (vtd_set_flag_in_pte (addr, offset, fspte, flag_ad) !=MEMTX_OK ) { +if (vtd_set_flags_in_pte (addr, offset, fspte, flag_ad) !=MEMTX_OK ) {return -VTD_FR_FS_BIT_UPDATE_FAILED ; }
Signature · 1 line
MST
[PULL v2 44/75] amd_iommu: Return empty efr for stub call
In reply to Michael S. TsirkinFrom: Sairaj Kodilkar <[email protected]>
The stub call should not return normal EFR as it is used as place holder when actual AMD IOMMU calls are not available. Hence return 0.
Message-ID: <[email protected]>
--- hw/i386/amd_iommu-stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
hw/i386/amd_iommu-stub.c +1 -1
@@ -22,5 +22,5 @@uint64_t amdvi_extended_feature_register (AMDVIState *s) { -return AMDVI_DEFAULT_EXT_FEATURES ; +return 0 ; }
Signature · 1 line
MST
[PULL v2 58/75] intel_iommu: Only set dirty bit when PTE exposes write permission
In reply to Michael S. TsirkinFrom: Clément MATHIEU--DRIF <[email protected]>
Setting the dirty bit without the write bit in vIOMMU creates a spoofed shadow stack PTE that misleads the guest OS. This results in infinite PRI requests from the device, as no actual write permission is ever granted - the guest OS treats the PTE as a legitimate shadow stack entry and considers the permissions already correct.
Message-ID: <[email protected]>
--- hw/i386/intel_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
hw/i386/intel_iommu.c +1 -1
@@ -2039,7 +2039,7 @@ static int vtd_iova_to_fspte(IntelIOMMUState *s, VTDContextEntry *ce,return -VTD_FR_FS_PAGING_ENTRY_RSVD ; } -if (vtd_is_last_pte (fspte, *fspte_level) && is_write) { +if (vtd_is_last_pte (fspte, *fspte_level) && *writes && is_write) { flag_ad |=VTD_FS_D ; }
Signature · 1 line
MST
[PULL v2 53/75] linux-headers: Update to Linux v7.3-rc1
In reply to Michael S. TsirkinFrom: Albert Esteve <[email protected]>
VIRTIO_ID_MEDIA was added previously, synchronize the rest of the headers to the same version.
Message-ID: <[email protected]>
--- include/standard-headers/linux/ethtool.h | 6 +++ linux-headers/linux/iommufd.h | 45 ++++++++++++++++++-- linux-headers/linux/userfaultfd.h | 54 ++++++++++++++++++++++-- linux-headers/linux/vduse.h | 28 ++++++++++++ linux-headers/linux/vfio.h | 21 +++++++++ linux-headers/linux/vfio_zdev.h | 2 + 6 files changed, 149 insertions(+), 7 deletions(-)
include/standard-headers/linux/ethtool.h +6 -0
@@ -2015,7 +2015,13 @@ enum ethtool_link_mode_bit_indices { ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT =39 , ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT =40 , ETHTOOL_LINK_MODE_1000baseX_Full_BIT =41 , + +/* Despite the "baseCR" in 10000baseCR, this is not an IEEE 802.3 baseCR +* It represents SFF-8431 Appendix-E SFP+ Direct Attach (10G-SFI-DA). +* The name is kept as-is for uAPI backward compatibility. +*/ ETHTOOL_LINK_MODE_10000baseCR_Full_BIT =42 , + ETHTOOL_LINK_MODE_10000baseSR_Full_BIT =43 , ETHTOOL_LINK_MODE_10000baseLR_Full_BIT =44 , ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT = 45,
linux-headers/linux/iommufd.h +42 -3
79 lines not on this page · raw message
linux-headers/linux/userfaultfd.h +50 -4
128 lines not on this page · raw message
linux-headers/linux/vduse.h +28 -0
@@ -14,6 +14,12 @@#define VDUSE_API_VERSION_1 1 +/* The VDUSE instance expects a request for vq ready */ +#define VDUSE_F_QUEUE_READY 0 + +/* The VDUSE instance expects a request for suspend */ +#define VDUSE_F_SUSPEND 1 +/* * Get the version of VDUSE API that kernel supported (VDUSE_API_VERSION). * This is used for future extension.
@@ -63,6 +69,12 @@ struct vduse_dev_config {*/ #define VDUSE_DESTROY_DEV _IOW(VDUSE_BASE, 0x03, char[VDUSE_NAME_MAX]) +/* Get the VDUSE supported features */ +#define VDUSE_GET_FEATURES _IOR(VDUSE_BASE, 0x04, __u64) + +/* Set the VDUSE features */ +#define VDUSE_SET_FEATURES _IOW(VDUSE_BASE, 0x05, __u64) +/* The ioctls for VDUSE device (/dev/vduse/$NAME) */ /**
@@ -325,6 +337,8 @@ enum vduse_req_type {VDUSE_SET_STATUS ,VDUSE_UPDATE_IOTLB ,VDUSE_SET_VQ_GROUP_ASID , +VDUSE_SET_VQ_READY , + VDUSE_SUSPEND, };/**
@@ -372,6 +386,15 @@ struct vduse_iova_range_v2 {__u32 padding; }; +/** +* struct vduse_vq_ready - Virtqueue ready request message +* @num: Virtqueue number +*/ +struct vduse_vq_ready { +__u32 num; +__u32 ready; +}; +/** * struct vduse_dev_request - control request * @type: request type
@@ -382,6 +405,7 @@ struct vduse_iova_range_v2 {* @iova: IOVA range for updating * @iova_v2: IOVA range for updating if API_VERSION >= 1 * @vq_group_asid: ASID of a virtqueue group +* @vq_ready: Virtqueue ready request * @padding: padding * * Structure used by read(2) on /dev/vduse/$NAME.
@@ -399,6 +423,10 @@ struct vduse_dev_request {*/ struct vduse_iova_range_v2 iova_v2;struct vduse_vq_group_asid vq_group_asid; + +/* Only if VDUSE_F_QUEUE_READY is negotiated */ +struct vduse_vq_ready vq_ready; +__u32 padding[32 ]; }; };
linux-headers/linux/vfio.h +21 -0
@@ -1534,6 +1534,27 @@ struct vfio_device_feature_dma_buf {*/ #define VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2 12 +/** +* VFIO_DEVICE_FEATURE_ZPCI_ERROR feature provides PCI error information to +* userspace for vfio-pci devices on s390. On s390, PCI error recovery +* involves platform firmware and notification to operating systems is done +* by architecture specific mechanism. Exposing this information to +* userspace allows it to take appropriate actions to handle an +* error on the device. +* +* Userspace provides an opaque buffer of fixed length, and the kernel +* fills it with the zpci_ccdf_err data structure. The length of +* zpci_ccdf_err is provided to userspace via the +* VFIO_DEVICE_INFO_CAP_ZPCI_BASE capability. +* +* The ioctl returns -ENOMSG if there are no pending PCI errors. +*/ +struct vfio_device_feature_zpci_err { +__aligned_u64 data; +}; + +#define VFIO_DEVICE_FEATURE_ZPCI_ERROR 13 +/* -------- API for Type1 VFIO IOMMU -------- */ /**
linux-headers/linux/vfio_zdev.h +2 -0
@@ -32,6 +32,8 @@ struct vfio_device_info_cap_zpci_base {/* End of version 1 */ __u32 fh;/* PCI function handle */ /* End of version 2 */ +__u32 ccdf_err_length;/* PCI CCDF length */ +/* End of version 3 */ };/**
Signature · 1 line
MST
[PULL v2 30/75] hw/net/virtio-net: check packet size before VLAN tag access in receive_filter()
In reply to Michael S. TsirkinFrom: Laurent Vivier <[email protected]>
receive_filter() reads ptr[14..15] to extract the VLAN ID without checking the packet is large enough. A short frame with VLAN TPID at bytes 12-13 but no VLAN TCI causes a 2-byte out-of-bounds read.
Add size checks before accessing the Ethernet header and the VLAN tag fields.
Cc: [email protected]
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3788
Message-ID: <[email protected]>
--- hw/net/virtio-net.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
hw/net/virtio-net.c +6 -2
@@ -1751,12 +1751,16 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size) } ptr += n->host_hdr_len; + size -= n->host_hdr_len; + +if (size <sizeof (struct eth_header )) { +return 0 ; + }if (!memcmp (&ptr[12 ], vlan,sizeof (vlan))) {int vid; -/* Truncated vlan packet */ -if (size < n->host_hdr_len +16 ) { +if (size <16 ) {return 0 ; } vid =lduw_be_p (ptr +14 ) &0xfff ;
Signature · 1 line
MST
[PULL v2 19/75] migration/fd: add errp parameter to migration_fd_valid()
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
Let migration_fd_valid() report the error itself, instead of duplicating the error message in both callers. This also prepares for adding one more check (with a different error message) to the function.
Message-ID: <[email protected]>
--- migration/fd.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-)
migration/fd.c +6 -12
@@ -37,16 +37,14 @@ static bool fd_is_pipe(int fd)return S_ISFIFO (statbuf.st_mode); } -static bool migration_fd_valid (int fd) +static bool migration_fd_valid (int fd,Error **errp) { -if (fd_is_socket (fd)) { -return true; - } - -if (fd_is_pipe (fd)) { +if (fd_is_socket (fd) ||fd_is_pipe (fd)) {return true; } +error_setg (errp,"fd: migration to a file is not supported." +" Use file: instead." );return false; }
@@ -59,9 +57,7 @@ QIOChannel *fd_connect_outgoing(MigrationState *s, const char *fdname, goto out; } -if (!migration_fd_valid (fd)) { -error_setg (errp,"fd: migration to a file is not supported." -" Use file: instead." ); +if (!migration_fd_valid (fd, errp)) {close (fd); goto out; }
@@ -95,9 +91,7 @@ void fd_connect_incoming(const char *fdname, Error **errp)return ; } -if (!migration_fd_valid (fd)) { -error_setg (errp,"fd: migration to a file is not supported." -" Use file: instead." ); +if (!migration_fd_valid (fd, errp)) {close (fd);return ; }
Signature · 1 line
MST
[PULL v2 40/75] hw/virtio: reject inverted virtio-iommu IOVA ranges
In reply to Michael S. TsirkinFrom: Jia Jia <[email protected]>
Guest MAP and UNMAP requests can set virt_end below virt_start. Since virt_end is inclusive, this is not a valid interval. MAP nevertheless stores it in domain->mappings, but interval_cmp() assumes low <= high. For an inverted key, interval_cmp(key, key) returns -1. A covering UNMAP can therefore find the key but fail to remove it and repeat forever while holding s->mutex.
Reject inverted request ranges with VIRTIO_IOMMU_S_INVAL and make the notifier range decomposition skip invalid ranges. Keep the existing notifier-before-remove ordering, but return VIRTIO_IOMMU_S_DEVERR if g_tree_remove() fails.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4104
Message-ID: <[email protected]>
--- hw/virtio/virtio-iommu.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
hw/virtio/virtio-iommu.c +16 -1
@@ -212,6 +212,10 @@ static void virtio_iommu_notify_map_unmap(IOMMUMemoryRegion *mr, {uint64_t delta = virt_end - virt_start; +if (virt_end < virt_start) { +return ; + } + event->entry.iova = virt_start; event->entry.addr_mask = delta;
@@ -807,6 +811,10 @@ static int virtio_iommu_map(VirtIOIOMMU *s,return VIRTIO_IOMMU_S_INVAL ; } +if (virt_end < virt_start) { +return VIRTIO_IOMMU_S_INVAL ; + } + domain =g_tree_lookup (s->domains,GUINT_TO_POINTER (domain_id));if (!domain) {return VIRTIO_IOMMU_S_NOENT ;
@@ -857,6 +865,10 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,trace_virtio_iommu_unmap (domain_id, virt_start, virt_end); +if (virt_end < virt_start) { +return VIRTIO_IOMMU_S_INVAL ; + } + domain =g_tree_lookup (s->domains,GUINT_TO_POINTER (domain_id));if (!domain) {return VIRTIO_IOMMU_S_NOENT ;
@@ -879,7 +891,10 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,virtio_iommu_notify_unmap (ep->iommu_mr, current_low, current_high); } -g_tree_remove (domain->mappings, iter_key); +if (!g_tree_remove (domain->mappings, iter_key)) { + ret =VIRTIO_IOMMU_S_DEVERR ; +break ; + }trace_virtio_iommu_unmap_done (domain_id, current_low, current_high); }else { ret =VIRTIO_IOMMU_S_RANGE ;
Signature · 1 line
MST
[PULL v2 43/75] hw/virtio: Propagate vhost_virtqueue_mask errors
In reply to Michael S. TsirkinFrom: Xiong Weimin <[email protected]>
vhost_virtqueue_mask() currently reports failures from vhost_set_vring_call() but always returns void, so callers cannot react. In particular, vhost_virtqueue_start() has a TODO next to the unmask call when !use_guest_notifier_mask.
Make vhost_virtqueue_mask() return the underlying errno, and on failure in vhost_virtqueue_start() jump to the existing fail path which unmaps the vring and propagates the error to the device start caller. Other call sites keep today's behavior by ignoring the return value.
Message-ID: <[email protected]>
--- include/hw/virtio/vhost.h | 9 ++++++--- hw/virtio/vhost.c | 10 +++++++--- 2 files changed, 13 insertions(+), 6 deletions(-)
include/hw/virtio/vhost.h +6 -3
@@ -310,10 +310,13 @@ void vhost_dev_set_config_notifier(struct vhost_dev *dev,*/ bool vhost_virtqueue_pending (struct vhost_dev *hdev,int n); -/* Mask/unmask events from this vq. +/** +* vhost_virtqueue_mask(): mask/unmask events from this vq. +* +* Returns: 0 on success, a negative errno on failure. */ -void vhost_virtqueue_mask (struct vhost_dev *hdev,VirtIODevice *vdev,int n, -bool mask); +int vhost_virtqueue_mask (struct vhost_dev *hdev,VirtIODevice *vdev,int n, +bool mask);/** * vhost_get_features_ex() - sanitize the extended features set
hw/virtio/vhost.c +7 -3
@@ -1471,8 +1471,10 @@ int vhost_virtqueue_start(struct vhost_dev *dev,* will do it later. */ if (!vdev->use_guest_notifier_mask) { -/* TODO: check and handle errors. */ -vhost_virtqueue_mask (dev, vdev, idx, false); + r =vhost_virtqueue_mask (dev, vdev, idx, false); +if (r <0 ) { + goto fail; + } } if (k->query_guest_notifiers &&
@@ -1919,7 +1921,7 @@ bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n) }/* Mask/unmask events from this vq. */ -void vhost_virtqueue_mask (struct vhost_dev *hdev,VirtIODevice *vdev,int n, +int vhost_virtqueue_mask (struct vhost_dev *hdev,VirtIODevice *vdev,int n,bool mask) {struct VirtQueue *vvq =virtio_get_queue (vdev, n);
@@ -1940,7 +1942,9 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, r = hdev->vhost_ops->vhost_set_vring_call (hdev, &file);if (r <0 ) {error_report ("vhost_set_vring_call failed %d" , -r); +return r; } +return 0 ; }bool vhost_config_pending (struct vhost_dev *hdev)
Signature · 1 line
MST
[PULL v2 48/75] acpi_build: Build IVRS feature report using extended feature register
In reply to Michael S. TsirkinFrom: Sairaj Kodilkar <[email protected]>
Currently IVRS feature report values are hardcoded, this is difficult to maintain as any updates to extended feature must be synced. Along with it, current feature report does not have GATS and HATS set. Hence use the extended feature registers to build the IVRS feature report.
Message-ID: <[email protected]>
--- hw/i386/amd_iommu.h | 11 ++++++++++ hw/i386/acpi-build.c | 48 +++++++++++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 12 deletions(-)
hw/i386/amd_iommu.h +11 -0
@@ -174,7 +174,11 @@#define AMDVI_DTE_QUAD3_RESERVED (GENMASK64(14, 0) | GENMASK64(53, 48))/* AMDVI paging mode */ +#define AMDVI_GATS_MODE_SHIFT (12) +#define AMDVI_GATS_MODE_MASK (3ULL << 12)#define AMDVI_GATS_MODE (2ULL << 12) +#define AMDVI_HATS_MODE_SHIFT (10) +#define AMDVI_HATS_MODE_MASK (3ULL << 10)#define AMDVI_HATS_MODE (2ULL << 10)#define AMDVI_HATS_MODE_RESERVED (3ULL << 10)
@@ -296,6 +300,13 @@#define AMDVI_DEV_LINT0_PASS_MASK (1ULL << 62)#define AMDVI_DEV_LINT1_PASS_MASK (1ULL << 63) +#define AMDVI_IVHD_FEATURE_REPORT_HATS_SHIFT (30) +#define AMDVI_IVHD_FEATURE_REPORT_GATS_SHIFT (28) +#define AMDVI_IVHD_FEATURE_REPORT_GA_SUP_SHIFT (6) +#define AMDVI_IVHD_FEATURE_REPORT_IA_SUP_SHIFT (5) +#define AMDVI_IVHD_FEATURE_REPORT_GT_SUP_SHIFT (2) +#define AMDVI_IVHD_FEATURE_REPORT_XT_SUP_SHIFT (0) +#define TYPE_AMD_IOMMU_DEVICE "amd-iommu"OBJECT_DECLARE_SIMPLE_TYPE (AMDVIState,AMD_IOMMU_DEVICE )
hw/i386/acpi-build.c +36 -12
73 lines not on this page · raw message
Signature · 1 line
MST
[PULL v2 72/75] vhost-user-blk: make inflight-migration prop mutable on running vm
In reply to Michael S. TsirkinFrom: Alexandr Moshkov <[email protected]>
The inflight-migration property currently can only be set before the device is realized. This makes it impossible to disable inflight migration at runtime without restarting the VM.
Make the property mutable, but only while the VM is running. Blocking changes when the VM is not running ensures that the value at stop time reliably reflects the intent set on a live VM, which allows vhost_user_blk_stop() to use skip_drain unconditionally based on the property value without inspecting migration runstate.
Message-ID: <[email protected]>
--- hw/block/vhost-user-blk.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-)
hw/block/vhost-user-blk.c +26 -2
@@ -629,6 +629,8 @@ static const VMStateDescription vmstate_vhost_user_blk = { } }; +static PropertyInfo vhost_user_blk_inflight_migration_prop; +static const Property vhost_user_blk_properties[] = {DEFINE_PROP_CHR ("chardev" , VHostUserBlk, chardev), DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues,
@@ -644,8 +646,9 @@ static const Property vhost_user_blk_properties[] = { VIRTIO_BLK_F_WRITE_ZEROES, true),DEFINE_PROP_BOOL ("skip-get-vring-base-on-force-shutdown" , VHostUserBlk, skip_get_vring_base_on_force_shutdown, false), - DEFINE_PROP_BOOL("inflight-migration", VHostUserBlk, - inflight_migration, false), +DEFINE_PROP ("inflight-migration" , VHostUserBlk, inflight_migration, + vhost_user_blk_inflight_migration_prop, bool, + .set_default = true, .defval.u = false), };static void vhost_user_blk_class_init (ObjectClass *klass,const void *data)
@@ -675,8 +678,29 @@ static const TypeInfo vhost_user_blk_info = { .class_init = vhost_user_blk_class_init, }; +static void vhost_user_blk_set_inflight_migration (Object *obj,Visitor *v, +const char *name, +void *opaque,Error **errp) +{ +DeviceState *dev =DEVICE (obj); + +if (dev->realized && !runstate_is_running ()) { +error_setg (errp,"Property '%s' cannot be changed " +"while VM is not running" , name); +return ; + } + + qdev_prop_bool.set (obj, v, name, opaque, errp); +} + +static void virtio_register_types (void ) { + vhost_user_blk_inflight_migration_prop = qdev_prop_bool; + vhost_user_blk_inflight_migration_prop.realized_set_allowed = true; + vhost_user_blk_inflight_migration_prop.set = + vhost_user_blk_set_inflight_migration; +type_register_static (&vhost_user_blk_info); }
Signature · 1 line
MST
[PULL v2 57/75] intel_iommu: Support concurrent page fault handling with PRI
In reply to Michael S. TsirkinFrom: Clément MATHIEU--DRIF <[email protected]>
PRQ slot allocation must be thread safe to avoid posting multiple commands in the same slot so we take a lock in vtd_pri_request_page.
This allows multiple devices to call the page request interface of the same iommu instance.
Message-ID: <[email protected]>
--- hw/i386/intel_iommu.c | 103 ++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 40 deletions(-)
hw/i386/intel_iommu.c +63 -40
@@ -3627,15 +3627,26 @@ static void vtd_handle_iectl_write(IntelIOMMUState *s)static void vtd_handle_prs_write (IntelIOMMUState *s) { -uint32_t prs =vtd_get_long_raw (s,DMAR_PRS_REG ); +uint32_t prs; + +vtd_iommu_lock (s); + + prs =vtd_get_long_raw (s,DMAR_PRS_REG );if (!(prs &VTD_PR_STATUS_PPR ) && !(prs &VTD_PR_STATUS_PRO )) {vtd_set_clear_mask_long (s,DMAR_PECTL_REG ,VTD_PR_PECTL_IP ,0 ); } + +vtd_iommu_unlock (s); }static void vtd_handle_pectl_write (IntelIOMMUState *s) { -uint32_t pectl =vtd_get_long_raw (s,DMAR_PECTL_REG ); +uint32_t pectl; + +vtd_iommu_lock (s); + + pectl =vtd_get_long_raw (s,DMAR_PECTL_REG ); +if ((pectl &VTD_PR_PECTL_IP ) && !(pectl &VTD_PR_PECTL_IM )) {/* * If IP field was 1 when software clears the IM field,
@@ -3644,6 +3655,8 @@ static void vtd_handle_pectl_write(IntelIOMMUState *s)vtd_set_clear_mask_long (s,DMAR_PECTL_REG ,VTD_PR_PECTL_IP ,0 );vtd_generate_interrupt (s,DMAR_PEADDR_REG ,DMAR_PEDATA_REG ); } + +vtd_iommu_unlock (s); }static uint64_t vtd_mem_read (void *opaque,hwaddr addr,unsigned size)
@@ -5377,19 +5390,18 @@ static int vtd_pri_request_page(PCIBus *bus, void *opaque, int devfn, {IntelIOMMUState *s = opaque;VTDAddressSpace *vtd_as; +uint64_t queue_addr_reg; +uint64_t queue_tail_offset_reg; +uint64_t new_queue_tail_offset; +uint64_t queue_head_offset_reg; +hwaddr queue_tail; +uint32_t old_pr_status; +uint16_t sid; +VTDPRDesc desc; +int ret =0 ; vtd_as =vtd_find_add_as (s, bus, devfn, pasid); - -uint64_t queue_addr_reg =vtd_get_quad (s,DMAR_PQA_REG ); -uint64_t queue_tail_offset_reg =vtd_get_quad (s,DMAR_PQT_REG ); -uint64_t new_queue_tail_offset = ( - (queue_tail_offset_reg +VTD_PQA_ENTRY_SIZE ) % - (vtd_prq_size (s) *VTD_PQA_ENTRY_SIZE )); -uint64_t queue_head_offset_reg =vtd_get_quad (s,DMAR_PQH_REG ); -hwaddr queue_tail = (queue_addr_reg &VTD_PQA_ADDR ) + queue_tail_offset_reg; -uint32_t old_pr_status =vtd_get_long (s,DMAR_PRS_REG ); -uint16_t sid =PCI_BUILD_BDF (pci_bus_num (vtd_as->bus), vtd_as->devfn); -VTDPRDesc desc; + sid =PCI_BUILD_BDF (pci_bus_num (vtd_as->bus), vtd_as->devfn);if (!(s->ecap &VTD_ECAP_PRS )) {return -EPERM ;
@@ -5413,25 +5425,7 @@ static int vtd_pri_request_page(PCIBus *bus, void *opaque, int devfn,return -EPERM ; } -if (old_pr_status &VTD_PR_STATUS_PRO ) { -/* -* No action is taken by hardware to report a fault -* or generate an event -*/ -return -ENOSPC ; - } - -/* Check for overflow */ -if (new_queue_tail_offset == queue_head_offset_reg) { -vtd_set_clear_mask_long (s,DMAR_PRS_REG ,0 ,VTD_PR_STATUS_PRO ); -vtd_generate_page_request_event (s, old_pr_status); -return -ENOSPC ; - } - -if (vtd_pri_perform_implicit_invalidation (vtd_as, addr)) { -return -EINVAL ; - } - +/* Prepare the descriptor */ desc.lo =VTD_PRD_TYPE |VTD_PRD_PP (true) |VTD_PRD_RID (sid) |VTD_PRD_PASID (vtd_as->pasid) |VTD_PRD_PMR (priv_req); desc.hi = VTD_PRD_RDR(is_read) | VTD_PRD_WRR(is_write) |
@@ -5439,26 +5433,55 @@ static int vtd_pri_request_page(PCIBus *bus, void *opaque, int devfn, desc.lo =cpu_to_le64 (desc.lo); desc.hi =cpu_to_le64 (desc.hi); + +if (vtd_pri_perform_implicit_invalidation (vtd_as, addr)) { +return -EINVAL ; + } + +vtd_iommu_lock (s); + + queue_addr_reg =vtd_get_quad (s,DMAR_PQA_REG ); + queue_tail_offset_reg =vtd_get_quad (s,DMAR_PQT_REG ); + new_queue_tail_offset = ((queue_tail_offset_reg +VTD_PQA_ENTRY_SIZE ) % + (vtd_prq_size (s) *VTD_PQA_ENTRY_SIZE )); + queue_head_offset_reg =vtd_get_quad (s,DMAR_PQH_REG ); + queue_tail = (queue_addr_reg &VTD_PQA_ADDR ) + queue_tail_offset_reg; + old_pr_status =vtd_get_long (s,DMAR_PRS_REG ); + +if (old_pr_status &VTD_PR_STATUS_PRO ) { +/* +* No action is taken by hardware to report a fault +* or generate an event +*/ + ret = -ENOSPC ; + goto out; + } + +/* Check for overflow */ +if (new_queue_tail_offset == queue_head_offset_reg) { +vtd_set_clear_mask_long (s,DMAR_PRS_REG ,0 ,VTD_PR_STATUS_PRO ); +vtd_generate_page_request_event (s, old_pr_status); + ret = -ENOSPC ; + goto out; + } +if (dma_memory_write (&address_space_memory, queue_tail, &desc,sizeof (desc),MEMTXATTRS_UNSPECIFIED )) {error_report_once ("IO error, the PQ tail cannot be updated" ); -return -EIO ; + ret = -EIO ; + goto out; }/* increment the tail register and set the pending request bit */ vtd_set_quad (s,DMAR_PQT_REG , new_queue_tail_offset); -/* -* read status again so that the kernel does not miss a request. -* in some cases, we can trigger an unecessary interrupt but this strategy -* drastically improves performance as we don't need to take a lock. -*/ - old_pr_status =vtd_get_long (s,DMAR_PRS_REG );if (!(old_pr_status &VTD_PR_STATUS_PPR )) {vtd_set_clear_mask_long (s,DMAR_PRS_REG ,0 ,VTD_PR_STATUS_PPR );vtd_generate_page_request_event (s, old_pr_status); } -return 0 ; +out: +vtd_iommu_unlock (s); +return ret; } static void vtd_init_iotlb_notifier(PCIBus *bus, void *opaque, int devfn,
Signature · 1 line
MST
[PULL v2 36/75] hw/scsi-disk: Fix accounting for IGNORE, ret > 0
In reply to Michael S. TsirkinFrom: Hanna Czenczek <[email protected]>
When encountering SCSI error status (ret > 0), accounting is left to scsi_handle_rw_error(), but the BLOCK_ERROR_ACTION_IGNORE path in turn leaves accounting (block_acct_done()) to the caller, so neither side does it. Fix this by unconditionally calling block_acct_done() in the IGNORE path. Yes, this will often result in it being called twice, but that is a no-op, as block_acct_done() resets the cookie type to BLOCK_ACCT_NONE, and will only do accounting if the type is not BLOCK_ACCT_NONE.
(And given that the conditions on who does what accounting are quite confusing in scsi-disk, for me at least, I prefer this unconditional call rather than guard it with a condition that has no obvious reason.)
Message-ID: <[email protected]>
--- hw/scsi/scsi-disk.c | 7 +++++++ 1 file changed, 7 insertions(+)
hw/scsi/scsi-disk.c +7 -0
@@ -318,6 +318,13 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed)return true;case BLOCK_ERROR_ACTION_IGNORE : +/* +* The caller may have already finalized the accounting cookie +* (e.g. scsi_dma_complete() for ret < 0), but calling +* block_acct_done() afterwards is fine (just a no-op). Just +* make sure all cookies are indeed accounted at some point. +*/ +block_acct_done (blk_get_stats (s->qdev.conf.blk), &r->acct);return false;case BLOCK_ERROR_ACTION_STOP :
Signature · 1 line
MST
[PULL v2 51/75] libvhost-user: accept the postcopy client base ack in vu_add_mem_reg()
In reply to Michael S. TsirkinFrom: Bin Guo <[email protected]>
In postcopy mode QEMU signals that it has collected all the postcopy client bases by sending a VHOST_USER_ADD_MEM_REG message with a u64 payload of 0 and no file descriptor (see vhost_user_add_remove_regions()). vu_add_mem_reg() has a case for that message, but only reaches it after validating the fd count of a regular region, so the ack is rejected first:
VHOST_USER_ADD_MEM_REG received 0 fds - only 1 fd should be sent for this message type
This kills the backend during memory table setup, making postcopy unusable for any libvhost-user backend that negotiates VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS.
Recognise the ack before validating the fd count.
Message-ID: <[email protected]>
--- subprojects/libvhost-user/libvhost-user.c | 26 ++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-)
subprojects/libvhost-user/libvhost-user.c +14 -12
@@ -948,6 +948,20 @@ static bool vu_add_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {VhostUserMemoryRegion m = vmsg->payload.memreg.region, *msg_region = &m; +/* +* If we are in postcopy mode and we receive a u64 payload with a 0 value +* we know all the postcopy client bases have been received, and we +* should start generating faults. This message carries no file +* descriptor, so it has to be recognised before the fd count of a real +* region is validated below. +*/ +if (dev->postcopy_listening && + vmsg->size ==sizeof (vmsg->payload.u64) && + vmsg->payload.u64 ==0 ) { + (void )generate_faults (dev); +return false; + } +if (vmsg->fd_num !=1 ) {vmsg_close_fds (vmsg); vu_panic(dev, "VHOST_USER_ADD_MEM_REG received %d fds - only 1 fd "
@@ -971,18 +985,6 @@ vu_add_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {return false; } -/* -* If we are in postcopy mode and we receive a u64 payload with a 0 value -* we know all the postcopy client bases have been received, and we -* should start generating faults. -*/ -if (dev->postcopy_listening && - vmsg->size ==sizeof (vmsg->payload.u64) && - vmsg->payload.u64 ==0 ) { - (void )generate_faults (dev); -return false; - } -_vu_add_mem_reg (dev, msg_region, vmsg->fds[0 ]);close (vmsg->fds[0 ]);
Signature · 1 line
MST
[PULL v2 75/75] MAINTAINERS: add Junjie Cao as CXL reviewer
In reply to Michael S. TsirkinFrom: Junjie Cao <[email protected]>
I have been reviewing, testing and contributing to hw/cxl for the past few months, and would like to be Cc'd on incoming CXL changes to help with review.
Message-ID: <[email protected]>
--- MAINTAINERS | 1 + 1 file changed, 1 insertion(+)
MAINTAINERS +1 -0
@@ -3334,6 +3334,7 @@ F: docs/devel/migration/CPR.rst Compute Express Link M: Jonathan Cameron <[email protected]> +R: Junjie Cao <[email protected]> L: [email protected] S: Supported F: hw/cxl/
Signature · 1 line
MST
[PULL v2 35/75] hw/ide: Have ide_dma_cb() complete accounting
In reply to Michael S. TsirkinFrom: Hanna Czenczek <[email protected]>
ide_sector_start_dma() starts accounting for reading and writing, and ide_dma_cb() is supposed to complete it, but currently does not always:
In one case, it just forgets it altogether, in the other, it uses block_acct_invalid(), which should not be used after a cookie has already been created.
Message-ID: <[email protected]>
--- hw/ide/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
hw/ide/core.c +2 -1
@@ -898,6 +898,7 @@ static void ide_dma_cb(void *opaque, int ret)if (ret == -EINVAL ) {ide_dma_error (s); +block_acct_failed (blk_get_stats (s->blk), &s->acct);return ; }
@@ -968,7 +969,7 @@ static void ide_dma_cb(void *opaque, int ret)if ((s->dma_cmd ==IDE_DMA_READ || s->dma_cmd ==IDE_DMA_WRITE ) && !ide_sect_range_ok (s, sector_num, n)) {ide_dma_error (s); -block_acct_invalid (blk_get_stats (s->blk), s->acct.type); +block_acct_failed (blk_get_stats (s->blk), &s->acct);return ; }
Signature · 1 line
MST
[PULL v2 62/75] hw/acpi: Make AcpiGedState const in build_ged_aml()
In reply to Michael S. TsirkinFrom: Philippe Mathieu-Daudé <[email protected]>
build_ged_aml() do not modify the AcpiGedState structure.
Message-ID: <[email protected]>
--- hw/acpi/generic_event_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
hw/acpi/generic_event_device.c +1 -1
@@ -48,7 +48,7 @@ static const uint32_t ged_supported_events[] = {void build_ged_aml (Aml *table,const char *name,HotplugHandler *hotplug_dev,uint32_t ged_irq,AmlRegionSpace rs,hwaddr ged_base) { -AcpiGedState *s =ACPI_GED (hotplug_dev); +const AcpiGedState *s =ACPI_GED (hotplug_dev);Aml *crs =aml_resource_template ();Aml *evt, *field;Aml *dev =aml_device ("%s" , name);
Signature · 1 line
MST
[PULL v2 33/75] hw/nvme: Fix block accounting in nvme_copy()
In reply to Michael S. TsirkinFrom: Hanna Czenczek <[email protected]>
In nvme_copy(), we start accounting for each of the copied ranges, but only end it once (in nvme_copy_done()). We should end it after each read/write operation is done instead, so they are properly accounted for.
We should also actually pass the number of bytes we are reading/writing (instead of 0), and probably account for the metadata operations also, as they are block operations we execute.
Message-ID: <[email protected]>
--- hw/nvme/ctrl.c | 53 +++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 20 deletions(-)
hw/nvme/ctrl.c +33 -20
@@ -2802,8 +2802,6 @@ static const AIOCBInfo nvme_copy_aiocb_info = {static void nvme_copy_done (NvmeCopyAIOCB *iocb) {NvmeRequest *req = iocb->req; -NvmeNamespace *ns = req->ns; -BlockAcctStats *stats =blk_get_stats (ns->blkconf.blk);if (iocb->idx != iocb->nr) { req->cqe.result =cpu_to_le32 (iocb->idx);
@@ -2813,14 +2811,6 @@ static void nvme_copy_done(NvmeCopyAIOCB *iocb)g_free (iocb->bounce);g_free (iocb->ranges); -if (iocb->ret <0 ) { -block_acct_failed (stats, &iocb->acct.read); -block_acct_failed (stats, &iocb->acct.write); - }else { -block_acct_done (stats, &iocb->acct.read); -block_acct_done (stats, &iocb->acct.write); - } - iocb->common.cb (iocb->common.opaque, iocb->ret);qemu_aio_unref (iocb); }
@@ -2951,6 +2941,7 @@ static void nvme_copy_out_completed_cb(void *opaque, int ret)NvmeCopyAIOCB *iocb = opaque;NvmeRequest *req = iocb->req;NvmeNamespace *dns = req->ns; +BlockAcctStats *stats =blk_get_stats (dns->blkconf.blk);uint32_t nlb; nvme_copy_source_range_parse(iocb->ranges, iocb->idx, iocb->format, NULL,
@@ -2959,10 +2950,12 @@ static void nvme_copy_out_completed_cb(void *opaque, int ret)if (ret <0 ) { iocb->ret = ret; req->status =NVME_WRITE_FAULT ; - goto out; - }else if (iocb->ret <0 ) { + } +if (iocb->ret <0 ) { +block_acct_failed (stats, &iocb->acct.write); goto out; } +block_acct_done (stats, &iocb->acct.write);if (dns->params.zoned) {nvme_advance_zone_wp (dns, iocb->zone, nlb);
@@ -2979,11 +2972,18 @@ static void nvme_copy_out_cb(void *opaque, int ret)NvmeCopyAIOCB *iocb = opaque;NvmeRequest *req = iocb->req;NvmeNamespace *dns = req->ns; +BlockAcctStats *stats =blk_get_stats (dns->blkconf.blk);uint32_t nlb;size_t mlen;uint8_t *mbounce; -if (ret <0 || iocb->ret <0 || !dns->lbaf.ms) { +if (ret <0 || iocb->ret <0 ) { +block_acct_failed (stats, &iocb->acct.write); + goto out; + } +block_acct_done (stats, &iocb->acct.write); + +if (!dns->lbaf.ms) { goto out; }
@@ -2996,6 +2996,7 @@ static void nvme_copy_out_cb(void *opaque, int ret)qemu_iovec_reset (&iocb->iov);qemu_iovec_add (&iocb->iov, mbounce, mlen); +block_acct_start (stats, &iocb->acct.write, mlen,BLOCK_ACCT_WRITE ); iocb->aiocb =blk_aio_pwritev (dns->blkconf.blk,nvme_moff (dns, iocb->slba), &iocb->iov,0 , nvme_copy_out_completed_cb, iocb);
@@ -3012,6 +3013,7 @@ static void nvme_copy_in_completed_cb(void *opaque, int ret)NvmeRequest *req = iocb->req;NvmeNamespace *sns = iocb->sns;NvmeNamespace *dns = req->ns; +BlockAcctStats *sstats =blk_get_stats (sns->blkconf.blk);NvmeCopyCmd *copy =NULL ;uint8_t *mbounce =NULL ;uint32_t nlb;
@@ -3024,10 +3026,12 @@ static void nvme_copy_in_completed_cb(void *opaque, int ret)if (ret <0 ) { iocb->ret = ret; req->status =NVME_UNRECOVERED_READ ; - goto out; - }else if (iocb->ret <0 ) { + } +if (iocb->ret <0 ) { +block_acct_failed (sstats, &iocb->acct.read); goto out; } +block_acct_done (sstats, &iocb->acct.read);nvme_copy_source_range_parse (iocb->ranges, iocb->idx, iocb->format, &slba, &nlb,NULL , &apptag, &appmask, &reftag);
@@ -3102,7 +3106,7 @@ static void nvme_copy_in_completed_cb(void *opaque, int ret)qemu_iovec_reset (&iocb->iov);qemu_iovec_add (&iocb->iov, iocb->bounce, len); -block_acct_start (blk_get_stats (dns->blkconf.blk), &iocb->acct.write,0 , +block_acct_start (blk_get_stats (dns->blkconf.blk), &iocb->acct.write, len,BLOCK_ACCT_WRITE ); iocb->aiocb = blk_aio_pwritev(dns->blkconf.blk, nvme_l2b(dns, iocb->slba),
@@ -3121,20 +3125,29 @@ static void nvme_copy_in_cb(void *opaque, int ret) {NvmeCopyAIOCB *iocb = opaque;NvmeNamespace *sns = iocb->sns; +BlockAcctStats *stats =blk_get_stats (sns->blkconf.blk);uint64_t slba;uint32_t nlb; +size_t mlen; -if (ret <0 || iocb->ret <0 || !sns->lbaf.ms) { +if (ret <0 || iocb->ret <0 ) { +block_acct_failed (stats, &iocb->acct.read); + goto out; + } +block_acct_done (stats, &iocb->acct.read); + +if (!sns->lbaf.ms) { goto out; }nvme_copy_source_range_parse (iocb->ranges, iocb->idx, iocb->format, &slba, &nlb,NULL ,NULL ,NULL ,NULL ); + mlen =nvme_m2b (sns, nlb);qemu_iovec_reset (&iocb->iov); -qemu_iovec_add (&iocb->iov, iocb->bounce +nvme_l2b (sns, nlb), -nvme_m2b (sns, nlb)); +qemu_iovec_add (&iocb->iov, iocb->bounce +nvme_l2b (sns, nlb), mlen); +block_acct_start (stats, &iocb->acct.read, mlen,BLOCK_ACCT_READ ); iocb->aiocb =blk_aio_preadv (sns->blkconf.blk,nvme_moff (sns, slba), &iocb->iov,0 , nvme_copy_in_completed_cb, iocb);
@@ -3342,7 +3355,7 @@ static void nvme_do_copy(NvmeCopyAIOCB *iocb)assert (len <= blen);qemu_iovec_add (&iocb->iov, iocb->bounce, len); -block_acct_start (blk_get_stats (sns->blkconf.blk), &iocb->acct.read,0 , +block_acct_start (blk_get_stats (sns->blkconf.blk), &iocb->acct.read, len,BLOCK_ACCT_READ ); iocb->aiocb = blk_aio_preadv(sns->blkconf.blk, nvme_l2b(sns, slba),
Signature · 1 line
MST
[PULL v2 52/75] libvhost-user: return the backend mapping address for added regions
In reply to Michael S. TsirkinFrom: Bin Guo <[email protected]>
In postcopy mode the backend must tell QEMU where it mapped a region, so that QEMU can translate the backend's fault addresses back into a RAMBlock and offset. vu_add_mem_reg() works on a copy of the region and lets _vu_add_mem_reg() fill the mapping address into that copy, but never writes it back into the reply payload. QEMU then stores its own address as the postcopy client base, so fault resolution fails:
vhost_user_postcopy_fault_handler: Failed to find region for fault ...
The VHOST_USER_SET_MEM_TABLE path is unaffected, it fills the payload directly. Put the updated region back into the payload before replying; a pointer into the payload cannot be used instead, as VhostUserMsg is packed.
Message-ID: <[email protected]>
--- subprojects/libvhost-user/libvhost-user.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
subprojects/libvhost-user/libvhost-user.c +7 -1
@@ -989,7 +989,13 @@ vu_add_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {close (vmsg->fds[0 ]);if (dev->postcopy_listening) { -/* Send the message back to qemu with the addresses filled in. */ +/* +* Send the message back to qemu with the addresses filled in. +* _vu_add_mem_reg() worked on our copy of the region, so it has to be +* put back into the message payload. A pointer into the payload +* cannot be handed out instead, VhostUserMsg is packed. +*/ + vmsg->payload.memreg.region = m; vmsg->fd_num =0 ;DPRINT ("Successfully added new region in postcopy\n" );return true;
Signature · 1 line
MST
[PULL v2 18/75] migration/fd: fix fd leak when fd is not valid for migration
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
Both fd_connect_outgoing() and fd_connect_incoming() own the file descriptor after resolving it from the monitor, but forget to close it when migration_fd_valid() check fails.
Message-ID: <[email protected]>
--- migration/fd.c | 2 ++ 1 file changed, 2 insertions(+)
migration/fd.c +2 -0
@@ -62,6 +62,7 @@ QIOChannel *fd_connect_outgoing(MigrationState *s, const char *fdname,if (!migration_fd_valid (fd)) {error_setg (errp,"fd: migration to a file is not supported." " Use file: instead." ); +close (fd); goto out; }
@@ -97,6 +98,7 @@ void fd_connect_incoming(const char *fdname, Error **errp)if (!migration_fd_valid (fd)) {error_setg (errp,"fd: migration to a file is not supported." " Use file: instead." ); +close (fd);return ; }
Signature · 1 line
MST
[PULL v2 54/75] virtio-scsi: set dataplane_started to false upon failure
In reply to Michael S. TsirkinFrom: Stefan Hajnoczi <[email protected]>
Commit e24a47c5b73e ("virtio-scsi: do not use vring in dataplane") set dataplane_started to true when virtio_scsi_dataplane_start() fails. This is likely a typo since dataplane is not functional after failure.
The non-ioeventfd fallback is broken because dataplane_started is true after virtio_scsi_dataplane_start() failure. As a result, the following assertion failure occurs when a virtio-scsi device exceeds the open file descriptor ulimit when setting up notifiers (eventfds):
$ ulimit -n 104 # exact number can vary based on QEMU version
$ qemu-system-x86_64 -M q35,accel=kvm -m 1G -cpu host -smp 14 \
--blockdev file,node-name=drive0,filename=test.img,cache.direct=on,aio=native \
--blockdev file,node-name=drive1,filename=data01.img,cache.direct=on,aio=native \
--device virtio-scsi-pci,id=virtio-scsi-pci0 \
--device scsi-hd,drive=drive0,bus=virtio-scsi-pci0.0 \
--device virtio-scsi-pci,id=virtio-scsi-pci1 \
--device scsi-hd,drive=drive1,bus=virtio-scsi-pci1.0
qemu: virtio-scsi: Failed to set guest notifiers (-24), ensure -accel kvm is set.
qemu: virtio_bus_start_ioeventfd: failed. Fallback to userspace (slower).
qemu-system-x86_64: ../hw/scsi/virtio-scsi.c:1017: virtio_scsi_reset: Assertion `!s->dataplane_started' failed.
Aborted (core dumped)Message-ID: <[email protected]>
--- hw/scsi/virtio-scsi-dataplane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
hw/scsi/virtio-scsi-dataplane.c +1 -1
@@ -230,7 +230,7 @@ fail_host_notifiers: fail_guest_notifiers: s->dataplane_fenced = true; s->dataplane_starting = false; - s->dataplane_started = true; + s->dataplane_started = false;return -ENOSYS ; }
Signature · 1 line
MST
[PULL v2 60/75] pci: batch BAR remapping into one memory transaction
In reply to Michael S. TsirkinFrom: "Denis V. Lunev" <[email protected]>
pci_update_mappings() deletes and re-adds a subregion for each BAR whose address changed, and both of those commit their own transaction, so one BAR move costs two full flatview rebuilds.
Nothing between the delete and the add touches an address space, so the walk can run inside a single transaction. pci_bridge_update_mappings() already does this for the bridge windows.
Message-ID: <[email protected]>
--- hw/pci/pci.c | 4 ++++ 1 file changed, 4 insertions(+)
hw/pci/pci.c +4 -0
@@ -1742,6 +1742,8 @@ static void pci_update_mappings(PCIDevice *d)int i;pcibus_t new_addr; +memory_region_transaction_begin (); +for (i =0 ; i <PCI_NUM_REGIONS ; i++) { r = &d->io_regions[i];
@@ -1778,6 +1780,8 @@ static void pci_update_mappings(PCIDevice *d) }pci_update_vga (d); + +memory_region_transaction_commit (); }int pci_irq_disabled (PCIDevice *d)
Signature · 1 line
MST
[PULL v2 23/75] net/tap: support local migration with virtio-net
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
Support transferring of TAP state (including open fd).
Add new property "x-permit-local-migration", which defines whether local migration is actually permitted for this TAP device.
Note that local-migration is enabled by global "local" migration parameter, but individual devices may have additional options to enable/disable it per device.
The tricky thing is that we need to know whether to call open/connect in TAP initialization code, i.e. we need to know the value of migration parameter "local" when creating the TAP device. For incoming migration, we can know only for TAP devices created with QMP after setting the migration parameter with QMP.
So the full picture is:
On source, to start outgoing "local" migration you need:
- migration parameter "local" set to true
- "x-permit-local-migration" TAP option set to true
If at least one of these options is not set, TAP backend doesn't participate in migration.
On target, things are more difficult:
Same, you need both "local" and "x-permit-local-migration" be set. And same, if one of them is not set, TAP backend is initialized as usual, and doesn't accept any incoming state.
Additionally, if you are going to set "local", it must be set before creating the TAP device. If TAP device created with "local" unset, it initializes as usual. If you enable "local" after it and start incoming migration, it will fail in .pre_load handler of TAP backend.
Moreover, there are interface restrictions: if you create TAP device when QEMU is in INCOMING state, and both "local" and "x-permit-local-migration" set, most of TAP options are not allowed, and script/downscript are required to be explicitly disabled.
Message-ID: <[email protected]>
--- qapi/net.json | 29 ++++++++- net/tap.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 189 insertions(+), 7 deletions(-)
qapi/net.json +28 -1
@@ -437,6 +437,31 @@ # @poll-us: maximum number of microseconds that could be spent on busy # polling for tap (since 2.7) # +# @x-permit-local-migration: permit local migration for this TAP +# backend. When set, local migration is enabled/disabled by +# migration parameter @local for this TAP backend. When unset, +# migration parameter @local is ignored for this TAP backend. +# +# To be able to do incoming local migration of a TAP backend, +# migration parameter @local must be set _before_ creating the +# TAP backend. Otherwise, TAP backend is initialized as usual, +# opening/creating TAP devices in kernel. In this case further +# local incoming migration (with migration parameter @local set +# after creating TAP backend with @x-permit-local-migration +# parameter set) will simply fail. +# +# Moreover, when QEMU is in incoming migration state, migration +# parameter @local is set and @x-permit-local-migration is set, +# the following options are not supported and must not be set: +# @fd, @fds, @helper, @br, @ifname, @sndbuf, @vnet_hdr. +# Additionally, @script and @downscript must be explicitly +# disabled then. +# (default: false, since 11.2) +# +# Features: +# +# @unstable: Member @x-permit-local-migration is experimental. +# # Since: 1.2 ## { 'struct': 'NetdevTapOptions',
@@ -455,7 +480,9 @@ '*vhostfds': 'str', '*vhostforce': 'bool', '*queues': 'uint32', - '*poll-us': 'uint32'} } + '*poll-us': 'uint32', + '*x-permit-local-migration': { + 'type': 'bool', 'features' : [ 'unstable'] } } } ## # @NetdevSocketOptions:
net/tap.c +161 -6
276 lines not on this page · raw message
Signature · 1 line
MST
[PULL v2 61/75] pci: load a device's config inside one memory transaction
In reply to Michael S. TsirkinFrom: "Denis V. Lunev" <[email protected]>
Restoring config space remaps the BARs, updates the bridge windows when the device is a bridge, and toggles the bus master region. Each of those commits a transaction of its own, so one device costs several flatview rebuilds where one would do, and the cost of a rebuild grows with the number of regions in the machine.
Nothing between them touches an address space, so the three can share a transaction. The saving scales with the number of PCI devices.
Message-ID: <[email protected]>
--- hw/pci/pci.c | 4 ++++ 1 file changed, 4 insertions(+)
hw/pci/pci.c +4 -0
@@ -840,6 +840,8 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size, }memcpy (s->config, config, size); +memory_region_transaction_begin (); +pci_update_mappings (s);if (IS_PCI_BRIDGE (s)) {pci_bridge_update_mappings (PCI_BRIDGE (s));
@@ -848,6 +850,8 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size,pci_set_master (s,pci_get_word (s->config +PCI_COMMAND ) &PCI_COMMAND_MASTER ); +memory_region_transaction_commit (); +g_free (config);return 0 ; }
Signature · 1 line
MST
[PULL v2 22/75] net/tap: disable read polling for stopped VM
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
Polling when VM is stopped doesn't make real sense, as stopped VM can't handle incoming traffic anyway.
And it's critical for introduction of local TAP migration feature in the next commit: the TAP device will be transferred to the target (open fd will be passed through migration channel), and if we continue polling on source, we may get a package, which we'll never handle on source (already stopped), it will be lost. Better is save this package for target VM to handle.
Message-ID: <[email protected]>
--- net/tap.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
net/tap.c +32 -0
@@ -36,6 +36,7 @@#include "net/net.h" #include "clients.h" #include "monitor/monitor.h" +#include "system/runstate.h" #include "system/system.h" #include "qapi/error.h" #include "qemu/cutils.h"
@@ -92,6 +93,8 @@ struct TAPState {Notifier exit;int queue_index; +bool enable_poll_on_resume; +VMChangeStateEntry *vmstate; }; static void launch_script(const char *setup_script, const char *ifname,
@@ -145,10 +148,31 @@ static void tap_update_fd_handler(TAPState *s)static void tap_read_poll (TAPState *s,bool enable) { +if (enable &&runstate_check (RUN_STATE_FINISH_MIGRATE )) { + s->enable_poll_on_resume = true; +return ; + } s->read_poll = enable;tap_update_fd_handler (s); } +static void tap_vm_state_change (void *opaque,bool running,RunState state) +{ +TAPState *s = opaque; + +if (running) { +if (s->enable_poll_on_resume) { +tap_read_poll (s, true); + s->enable_poll_on_resume = false; + } + }else if (state ==RUN_STATE_FINISH_MIGRATE ) { +if (s->read_poll) { + s->enable_poll_on_resume = true; +tap_read_poll (s, false); + } + } +} +static void tap_write_poll (TAPState *s,bool enable) { s->write_poll = enable;
@@ -379,6 +403,11 @@ static void tap_cleanup(NetClientState *nc) s->exit.notify =NULL ; } +if (s->vmstate) { +qemu_del_vm_change_state_handler (s->vmstate); + s->vmstate =NULL ; + } +tap_read_poll (s, false);tap_write_poll (s, false);close (s->fd);
@@ -818,6 +847,9 @@ static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,int sndbuf = (tap->has_sndbuf && tap->sndbuf) ?MIN (tap->sndbuf,INT_MAX ) :INT_MAX ; + s->enable_poll_on_resume = false; + s->vmstate =qemu_add_vm_change_state_handler (tap_vm_state_change, s); +if (!tap_set_sndbuf (fd, sndbuf, sndbuf_required ? errp :NULL ) && sndbuf_required) { goto failed;
Signature · 1 line
MST
[PULL v2 64/75] hw/hotplug: Reduce some HotplugHandler variables scope
In reply to Michael S. TsirkinFrom: Philippe Mathieu-Daudé <[email protected]>
Message-ID: <[email protected]>
--- hw/acpi/memory_hotplug.c | 3 ++- hw/acpi/pcihp.c | 3 ++- hw/pci/shpc.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-)
hw/acpi/memory_hotplug.c +2 -1
@@ -119,7 +119,6 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,MemStatus *mdev;ACPIOSTInfo *info;DeviceState *dev =NULL ; -HotplugHandler *hotplug_ctrl =NULL ;Error *local_err =NULL ;if (!mem_st->dev_count) {
@@ -167,6 +166,8 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data, mdev->is_removing = false;trace_mhp_acpi_clear_remove_evt (mem_st->selector); }else if (data &8 ) { +HotplugHandler *hotplug_ctrl; +if (!mdev->is_enabled) {trace_mhp_acpi_ejecting_invalid_slot (mem_st->selector);break ;
hw/acpi/pcihp.c +2 -1
@@ -173,7 +173,6 @@ static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev)static void acpi_pcihp_eject_slot (AcpiPciHpState *s,unsigned bsel,unsigned slots) { -HotplugHandler *hotplug_ctrl;BusChild *kid, *next;int slot =ctz32 (slots);PCIBus *bus =acpi_pcihp_find_hotplug_bus (s, bsel);
@@ -210,6 +209,8 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo*/ qdev->pending_deleted_event = false; }else { +HotplugHandler *hotplug_ctrl; + hotplug_ctrl =qdev_get_hotplug_handler (qdev);hotplug_handler_unplug (hotplug_ctrl, qdev, &error_abort);object_unparent (OBJECT (qdev));
hw/pci/shpc.c +2 -1
@@ -271,7 +271,6 @@ static void shpc_invalid_command(SHPCDevice *shpc)static void shpc_free_devices_in_slot (SHPCDevice *shpc,int slot) { -HotplugHandler *hotplug_ctrl;int devfn;int pci_slot =SHPC_IDX_TO_PCI (slot); for (devfn = PCI_DEVFN(pci_slot, 0);
@@ -279,6 +278,8 @@ static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot) ++devfn) {PCIDevice *affected_dev = shpc->sec_bus->devices[devfn];if (affected_dev) { +HotplugHandler *hotplug_ctrl; + hotplug_ctrl =qdev_get_hotplug_handler (DEVICE (affected_dev));hotplug_handler_unplug (hotplug_ctrl,DEVICE (affected_dev), &error_abort);
Signature · 1 line
MST
[PULL v2 12/75] net/tap: move vhost-net open() calls to tap_parse_vhost_fds()
In reply to Michael S. TsirkinFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
1. Simplify code path: get vhostfds for all cases in one function.
2. Prepare for further tap-fd-migraton feature, when we'll need to postpone vhost initialization up to post-load stage.
Based-on: <[email protected]>
Message-ID: <[email protected]>
--- net/tap.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-)
net/tap.c +22 -17
@@ -756,8 +756,7 @@ static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, } } -if (tap->has_vhost ? tap->vhost : - (vhostfd !=-1 ) || (tap->has_vhostforce && tap->vhostforce)) { +if (vhostfd !=-1 ) {VhostNetOptions options; options.backend_type =VHOST_BACKEND_TYPE_KERNEL ;
@@ -767,17 +766,6 @@ static bool net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, }else { options.busyloop_timeout =0 ; } - -if (vhostfd ==-1 ) { - vhostfd =open ("/dev/vhost-net" ,O_RDWR ); -if (vhostfd <0 ) { -error_setg_file_open (errp, errno,"/dev/vhost-net" ); - goto failed; - } -if (!qemu_set_blocking (vhostfd, false, errp)) { - goto failed; - } - } options.opaque = (void *)(uintptr_t )vhostfd; options.nvqs =2 ; options.feature_bits = kernel_feature_bits;
@@ -863,14 +851,31 @@ static int tap_parse_fds_and_queues(const NetdevTapOptions *tap, int **fds,static bool tap_parse_vhost_fds (const NetdevTapOptions *tap,int **vhost_fds,int queues,Error **errp) { -if (!(tap->vhostfd || tap->vhostfds)) { +bool need_vhost = tap->has_vhost ? tap->vhost : + ((tap->vhostfd || tap->vhostfds) || + (tap->has_vhostforce && tap->vhostforce)); + +if (!need_vhost) { *vhost_fds =NULL ;return true; } -if (net_parse_fds (tap->vhostfd ?: tap->vhostfds, - vhost_fds, queues, errp) <0 ) { -return false; +if (tap->vhostfd || tap->vhostfds) { +if (net_parse_fds (tap->vhostfd ?: tap->vhostfds, + vhost_fds, queues, errp) <0 ) { +return false; + } + }else { + *vhost_fds =g_new (int, queues); +for (int i =0 ; i < queues; i++) { +int vhostfd =open ("/dev/vhost-net" ,O_RDWR ); +if (vhostfd <0 ) { +error_setg_file_open (errp, errno,"/dev/vhost-net" ); +net_free_fds (*vhost_fds, i); +return false; + } + (*vhost_fds)[i] = vhostfd; + } }if (!unblock_fds (*vhost_fds, queues, errp)) {
Signature · 1 line
MST
[PULL v2 45/75] tests/acpi: x86: Allow IVRS acpi table changes
In reply to Michael S. TsirkinFrom: Sairaj Kodilkar <[email protected]>
Message-ID: <[email protected]>
--- tests/qtest/bios-tables-test-allowed-diff.h | 1 + 1 file changed, 1 insertion(+)
tests/qtest/bios-tables-test-allowed-diff.h +1 -0
@@ -1 +1,2 @@/* List of comma-separated changed AML files to ignore */ +tests/data/acpi/x86/q35/IVRS .ivrs
Signature · 1 line
MST
[PULL v2 63/75] hw/hotplug: Mark various HotplugHandlerClass variables as const
In reply to Michael S. TsirkinFrom: Philippe Mathieu-Daudé <[email protected]>
The HotplugHandlerClass pointers are only dereferenced, not updated.
Message-ID: <[email protected]>
--- include/hw/core/qdev.h | 2 +- hw/core/hotplug.c | 8 ++++---- hw/s390x/virtio-ccw-md.c | 2 +- hw/virtio/virtio-md-pci.c | 2 +- system/qdev-monitor.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-)
include/hw/core/qdev.h +1 -1
@@ -1069,7 +1069,7 @@ static inline bool qbus_is_hotpluggable(BusState *bus)bool ret = !!plug_handler;if (plug_handler) { -HotplugHandlerClass *hdc; +const HotplugHandlerClass *hdc; hdc =HOTPLUG_HANDLER_GET_CLASS (plug_handler);if (hdc->is_hotpluggable_bus) {
hw/core/hotplug.c +4 -4
@@ -17,7 +17,7 @@ void hotplug_handler_pre_plug(HotplugHandler *plug_handler, DeviceState *plugged_dev, Error **errp) { -HotplugHandlerClass *hdc =HOTPLUG_HANDLER_GET_CLASS (plug_handler); +const HotplugHandlerClass *hdc =HOTPLUG_HANDLER_GET_CLASS (plug_handler);if (hdc->pre_plug) { hdc->pre_plug (plug_handler, plugged_dev, errp);
@@ -28,7 +28,7 @@ void hotplug_handler_plug(HotplugHandler *plug_handler, DeviceState *plugged_dev, Error **errp) { -HotplugHandlerClass *hdc =HOTPLUG_HANDLER_GET_CLASS (plug_handler); +const HotplugHandlerClass *hdc =HOTPLUG_HANDLER_GET_CLASS (plug_handler);if (hdc->plug) { hdc->plug (plug_handler, plugged_dev, errp);
@@ -39,7 +39,7 @@ void hotplug_handler_unplug_request(HotplugHandler *plug_handler, DeviceState *plugged_dev, Error **errp) { -HotplugHandlerClass *hdc =HOTPLUG_HANDLER_GET_CLASS (plug_handler); +const HotplugHandlerClass *hdc =HOTPLUG_HANDLER_GET_CLASS (plug_handler);if (hdc->unplug_request) { hdc->unplug_request (plug_handler, plugged_dev, errp);
@@ -50,7 +50,7 @@ void hotplug_handler_unplug(HotplugHandler *plug_handler, DeviceState *plugged_dev, Error **errp) { -HotplugHandlerClass *hdc =HOTPLUG_HANDLER_GET_CLASS (plug_handler); +const HotplugHandlerClass *hdc =HOTPLUG_HANDLER_GET_CLASS (plug_handler);if (hdc->unplug) { hdc->unplug (plug_handler, plugged_dev, errp);
hw/s390x/virtio-ccw-md.c +1 -1
@@ -73,7 +73,7 @@ void virtio_ccw_md_unplug_request(VirtIOMDCcw *vmd, MachineState *ms,VirtIOMDCcwClass *vmdc =VIRTIO_MD_CCW_GET_CLASS (vmd);DeviceState *dev =DEVICE (vmd);HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev); -HotplugHandlerClass *hdc; +const HotplugHandlerClass *hdc;Error *local_err =NULL ;if (!vmdc->unplug_request_check) {
hw/virtio/virtio-md-pci.c +1 -1
@@ -72,7 +72,7 @@ void virtio_md_pci_unplug_request(VirtIOMDPCI *vmd, MachineState *ms,VirtIOMDPCIClass *vmdc =VIRTIO_MD_PCI_GET_CLASS (vmd);DeviceState *dev =DEVICE (vmd);HotplugHandler *bus_handler =qdev_get_bus_hotplug_handler (dev); -HotplugHandlerClass *hdc; +const HotplugHandlerClass *hdc;Error *local_err =NULL ;if (!vmdc->unplug_request_check) {
system/qdev-monitor.c +1 -1
@@ -918,7 +918,7 @@ static DeviceState *find_device_state(const char *id, bool use_generic_error,void qdev_unplug (DeviceState *dev,Error **errp) {HotplugHandler *hotplug_ctrl; -HotplugHandlerClass *hdc; +const HotplugHandlerClass *hdc;Error *local_err =NULL ;if (!qdev_hotunplug_allowed (dev, errp)) {
Signature · 1 line
MST
[PULL v2 71/75] vhost-user: use skip_drain with GET_VRING_BASE_SKIP_DRAIN message
In reply to Michael S. TsirkinFrom: Alexandr Moshkov <[email protected]>
Wire up the skip_drain parameter introduced in the previous commit to the new GET_VRING_BASE_SKIP_DRAIN message. When skip_drain is set, send GET_VRING_BASE_SKIP_DRAIN instead of GET_VRING_BASE, instructing the back-end to suspend in-flight I/O immediately.
Message-ID: <[email protected]>
--- hw/virtio/vhost.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
hw/virtio/vhost.c +5 -1
@@ -1521,7 +1521,11 @@ static int do_vhost_virtqueue_stop(struct vhost_dev *dev, }if (!force) { - r = dev->vhost_ops->vhost_get_vring_base (dev, &state); +if (!skip_drain) { + r = dev->vhost_ops->vhost_get_vring_base (dev, &state); + }else { + r = dev->vhost_ops->vhost_get_vring_base_skip_drain (dev, &state); + }if (r <0 ) {VHOST_OPS_DEBUG (r,"vhost VQ %u ring restore failed: %d" , idx, r); }
Signature · 1 line
MST
[PULL v2 70/75] vhost-user: add GET_VRING_BASE_SKIP_DRAIN message
In reply to Michael S. TsirkinFrom: Alexandr Moshkov <[email protected]>
VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT was introduced to allow the back-end to suspend in-flight I/O during GET_VRING_BASE instead of draining it, enabling live migration of in-flight requests. However, this behaviour is tied to the protocol feature itself - once negotiated, there is no way for the front-end to tell the back-end to fall back to the normal drain behaviour on a per-stop basis.
Introduce a separate message VHOST_USER_GET_VRING_BASE_SKIP_DRAIN (id=45) guarded by a new protocol feature VHOST_USER_PROTOCOL_F_GET_VRING_BASE_SKIP_DRAIN. The message is identical to GET_VRING_BASE except that the back-end must immediately suspend all in-flight I/O and record it in the inflight region. This way the front-end has explicit per-call control: send GET_VRING_BASE for normal drain, send GET_VRING_BASE_SKIP_DRAIN when immediate suspend is needed.
The new feature requires both VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT
and VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD to be negotiated.
Message-ID: <[email protected]>
--- docs/interop/vhost-user.rst | 42 ++++++++++++++++++++--------- include/hw/virtio/vhost-backend.h | 1 + include/hw/virtio/vhost-user.h | 1 + hw/virtio/vhost-user.c | 44 +++++++++++++++++++++++++++---- hw/virtio/vhost.c | 2 +- 5 files changed, 72 insertions(+), 18 deletions(-)
docs/interop/vhost-user.rst +30 -12
@@ -457,6 +457,7 @@ replies, except for the following requests: * ``VHOST_USER_GET_FEATURES`` * ``VHOST_USER_GET_PROTOCOL_FEATURES`` * ``VHOST_USER_GET_VRING_BASE`` +* ``VHOST_USER_GET_VRING_BASE_SKIP_DRAIN`` * ``VHOST_USER_SET_LOG_BASE`` (if ``VHOST_USER_PROTOCOL_F_LOG_SHMFD``) * ``VHOST_USER_GET_INFLIGHT_FD`` (if ``VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD``)
@@ -533,7 +534,7 @@ Rings have two independent states: started/stopped, and enabled/disabled. Each ring is initialized in a stopped and disabled state. Rings are started with ``VHOST_USER_SET_VRING_KICK`` (or ``VHOST_USER_VRING_KICK`` if ``VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS`` is negotiated) and stopped with -``VHOST_USER_GET_VRING_BASE``. A stopped ring enters the started state again +``VHOST_USER_GET_VRING_BASE`` or ``VHOST_USER_GET_VRING_BASE_SKIP_DRAIN``. A stopped ring enters the started state again with ``VHOST_USER_SET_VRING_KICK`` (or ``VHOST_USER_VRING_KICK`` if ``VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS`` is negotiated) and the back-end resumes processing requests.
@@ -1159,6 +1160,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT 20 #define VHOST_USER_PROTOCOL_F_GPA_ADDRESSES 21 #define VHOST_USER_PROTOCOL_F_SHMEM 22 + #define VHOST_USER_PROTOCOL_F_GET_VRING_BASE_SKIP_DRAIN 23 Front-end message types -----------------------
@@ -1355,17 +1357,11 @@ Front-end message types set to 0. By default, the back-end must complete all inflight I/O requests for the - specified vring before stopping it. - - If the ``VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT`` protocol - feature has been negotiated, the back-end may suspend in-flight I/O - requests and record them as described in :ref:`Inflight I/O tracking - <inflight_io_tracking>` instead of completing them before stopping the vring. - How to suspend an in-flight request depends on the implementation of the back-end - but it typically can be done by aborting or cancelling the underlying I/O - request. The ``VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT`` - protocol feature must only be negotiated if - ``VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD`` is also negotiated. + specified vring before stopping it. If the + ``VHOST_USER_PROTOCOL_F_GET_VRING_BASE_SKIP_DRAIN`` protocol feature has + been negotiated, the front-end may instead use + ``VHOST_USER_GET_VRING_BASE_SKIP_DRAIN`` to request the back-end to + suspend in-flight I/O immediately. ``VHOST_USER_SET_VRING_KICK`` :id: 12
@@ -1868,6 +1864,28 @@ Front-end message types * The size may be 0 if the region is unused. +``VHOST_USER_GET_VRING_BASE_SKIP_DRAIN`` + :id: 45 + :equivalent ioctl: N/A + :request payload: vring state description + :reply payload: vring descriptor index/indices + + This message requires the ``VHOST_USER_PROTOCOL_F_GET_VRING_BASE_SKIP_DRAIN`` + protocol feature to be negotiated. + + Identical to ``VHOST_USER_GET_VRING_BASE`` except that the back-end + must not wait for inflight I/O requests to complete before stopping + the vring. Instead, the back-end must immediately suspend all + in-flight I/O requests and record them as described in + :ref:`Inflight I/O tracking <inflight_io_tracking>`. How to suspend + an in-flight request depends on the implementation of the back-end, + but it typically can be done by aborting or cancelling the underlying + I/O request. + + The ``VHOST_USER_PROTOCOL_F_GET_VRING_BASE_SKIP_DRAIN`` protocol feature + must only be negotiated if both ``VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT`` + and ``VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD`` are also negotiated. + Back-end message types ----------------------
include/hw/virtio/vhost-backend.h +1 -0
@@ -190,6 +190,7 @@ typedef struct VhostOps {vhost_set_vring_num_op vhost_set_vring_num;vhost_set_vring_base_op vhost_set_vring_base;vhost_get_vring_base_op vhost_get_vring_base; +vhost_get_vring_base_op vhost_get_vring_base_skip_drain;vhost_set_vring_kick_op vhost_set_vring_kick;vhost_set_vring_call_op vhost_set_vring_call;vhost_set_vring_err_op vhost_set_vring_err;
include/hw/virtio/vhost-user.h +1 -0
@@ -36,6 +36,7 @@ enum VhostUserProtocolFeature {VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT =20 ,VHOST_USER_PROTOCOL_F_GPA_ADDRESSES =21 ,VHOST_USER_PROTOCOL_F_SHMEM =22 , +VHOST_USER_PROTOCOL_F_GET_VRING_BASE_SKIP_DRAIN =23 , VHOST_USER_PROTOCOL_F_MAX };
hw/virtio/vhost-user.c +39 -5
90 lines not on this page · raw message
hw/virtio/vhost.c +1 -1
@@ -1505,7 +1505,7 @@ static int do_vhost_virtqueue_stop(struct vhost_dev *dev, {if (skip_drain) {assert (vhost_user_has_protocol_feature (dev, -VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT )); +VHOST_USER_PROTOCOL_F_GET_VRING_BASE_SKIP_DRAIN )); }int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index (dev, idx);struct vhost_vring_state state = {
Signature · 1 line
MST
[PULL v2 49/75] amd_iommu: acpi-build: Remove unsupported PPR and HE feature
In reply to Michael S. TsirkinFrom: Sairaj Kodilkar <[email protected]>
AMD IOMMU does not support ppr and hardware error registers. Hence do not publish these features to guest through extended feature MMIO register and IVHD 10h flags field.
Message-ID: <[email protected]>
--- hw/i386/amd_iommu.h | 5 ++--- hw/i386/acpi-build.c | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-)
hw/i386/amd_iommu.h +2 -3
@@ -227,9 +227,8 @@/* default extended feature */ #define AMDVI_DEFAULT_EXT_FEATURES \ - (AMDVI_FEATURE_PREFETCH | AMDVI_FEATURE_PPR | \ - AMDVI_FEATURE_IA | AMDVI_FEATURE_GT | AMDVI_FEATURE_HE | \ - AMDVI_GATS_MODE | AMDVI_HATS_MODE | AMDVI_FEATURE_GA) + (AMDVI_FEATURE_PREFETCH | AMDVI_FEATURE_IA | AMDVI_FEATURE_GT | \ + AMDVI_GATS_MODE | AMDVI_HATS_MODE | AMDVI_FEATURE_GA)/* capabilities header */ #define AMDVI_CAPAB_FEATURES (AMDVI_CAPAB_FLAT_EXT | \
hw/i386/acpi-build.c +1 -2
@@ -1938,8 +1938,7 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id,build_append_int_noprefix (table_data, (1UL <<0 ) |/* HtTunEn */ (1UL <<4 ) |/* iotblSup */ - (1UL <<6 ) |/* PrefSup */ - (1UL <<7 ),/* PPRSup */ + (1UL <<6 ),/* PrefSup */ 1 );/* IVHD length */
Signature · 1 line
MST
Quoted 26 lines · Michael S. Tsirkin
The following changes since commit
1df256f5968e9f7c3c4533a1383b071c044a36d6:Merge tag 'qom-qapi-pr-pr-v1' of https://gitlab.com/marcandre.lureau/qemu into staging (2026-09-08 18:35:31 +0100)
are available in the Git repository at:
https://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
for you to fetch changes up to
2f8991c0b9c400f55897849a538580039b61865a:
MAINTAINERS: add Junjie Cao as CXL reviewer (2026-09-11 04:59:15 -0400)----------------------------------------------------------------
pci, vhost, virtio, iommu, apci: features, fixesnew vhost-user-media device
virtio-net now supports live-TAP local migration
cxl now supports CFMW restrictions and per-window optionsintel_iommunow supports concurrent page fault handling with PRI pci now batches memory transactions around mapping updates vhost-user-blk now allows toggling inflight-migration at runtime virtio-rtc now supports smeared UTC clock typeintel_iommunow exposes SMPWC when SVM is enabled
new reviewer for CXL patches
Quoted 3 lines
Fixes, cleanups all over the place
Signed-off-by Michael S. Tsirkin <[email protected]>
Hi Michael,
I see you dropped these patches from v1 to v2. Just checking if this was intended or if there is an issue/CI failure that needs addressing?
[...]
Dorinda Bassey (1):
vhost: Fix SHMEM_MAP transaction ordering and resulting deadlock
Feifan Qian (1):
vhost-user: Reject SHMEM_MAP when no KVM memory slot is left
[...]
Matej Hrica (2):
vhost-user-gpu: Add shared memory region support
vhost-user-gpu: Forward RESOURCE_BLOB and CONTEXT_INIT flags
[...]
Thanks!
Albert
Quoted 267 lines
----------------------------------------------------------------
Albert Esteve (4):
linux-headers: addVIRTIO_ID_MEDIA
hw/display: add vhost-user-media device hw/display/vhost-user-media: add shared memory region BAR
linux-headers: Update to Linux v7.3-rc1Alexandr Moshkov (6):
vhost-user: addskip_drainparam todo_vhost_virtqueue_stop
vhost-user: addGET_VRING_BASE_SKIP_DRAINmessage
vhost-user: useskip_drainwithGET_VRING_BASE_SKIP_DRAINmessage
vhost-user-blk: make inflight-migration prop mutable on running vm
vhost-user-blk: moveinflight_neededhigher
vhost-user-blk: useGET_VRING_BASE_SKIP_DRAINwhen inflight-migration is onAlyssa Ross (1):
vhost-user.rst: fix typoBin Guo (2):
libvhost-user: accept the postcopy client base ack invu_add_mem_reg()
libvhost-user: return the backend mapping address for added regionsClément MATHIEU--DRIF (4):
intel_iommu: Support concurrent page fault handling with PRI
intel_iommu: Only set dirty bit when PTE exposes write permission
intel_iommu: Always write all the flags passed tovtd_set_flag_in_pte
intel_iommu: Expose SMPWC when SVM is enabledDavidlohr Bueso (5):
tests/bios-tables-test: Exclude CEDT.cxl for the CFMW restriction change hw/cxl: Drop Back-Invalidate from default CFMW window restrictions tests/acpi/cxl: Update CEDT.cxl for the default CFMW restrictions hw/cxl: Add configurable CXL Fixed Memory Window restriction flags tests/qtest/cxl: Add CXL Fixed Memory Window restriction flag testsDenis V. Lunev (2):
pci: batch BAR remapping into one memory transaction
pci: load a device's config inside one memory transactionGuoHan Zhao (1):
virtio-crypto: clean up every data queueHanna Czenczek (6):
hw/virtio-blk: Account discard operations hw/virtio-blk: Complete zone-append cookies hw/nvme: Fix block accounting innvme_copy()hw/nvme: Fix block accounting for compare hw/ide: Haveide_dma_cb()complete accounting hw/scsi-disk: Fix accounting for IGNORE, ret > 0Jia Jia (2):
virtio: reduce code duplication for split ring hw/virtio: reject inverted virtio-iommu IOVA rangesJunjie Cao (3):
hw/cxl: Fix guest-triggerable QEMU exit on reserved interleave ways hw/cxl: fix the CDAT DOE overlapping the Flex Bus DVSEC when sn= is set
MAINTAINERS: add Junjie Cao as CXL reviewerKuan-Wei Chiu (1):
virtio-rtc: Report smeared UTC clock typeLaurent Vivier (2):
hw/net/virtio-net: check packet size before VLAN tag access inreceive_filter()hw/net/virtio-net: strip trailing padding when caching RSC segmentMichael S. Tsirkin (7):
virtio: fix exit(1) on DMA mapping failure during migration restore
virtio: fixconfig_lenDoS in migration restore path
virtio-pci: rejectQ_ENABLEwrite on already-enabled queue
meson: disable "maybe uninitilized" errors with -Og
virtio-balloon: fix free-page BH teardown on unrealizenet/tap-solaris: Fix resource leaks on error paths
virtio-net: validate IHL invirtio_net_rsc_extract_unit4before usePhilippe Mathieu-Daudé (4):
hw/acpi: Make AcpiGedState const inbuild_ged_aml()hw/hotplug: Mark various HotplugHandlerClass variables as const hw/hotplug: Reduce some HotplugHandler variables scope hw/hotplug: Constify HotplugHandlerSairaj Kodilkar (7):
amd_iommu: Return empty efr for stub call
tests/acpi: x86: Allow IVRS acpi table changes
amd_iommu: acpi-build: update PA, GVA and VA size macros
acpi_build: Use IOMMU pci device to build IOMMU DeviceID
acpi_build: Build IVRS feature report using extended feature register
amd_iommu: acpi-build: Remove unsupported PPR and HE feature tests/acpi: x86: update golden masters for IVRSStefan Hajnoczi (1):
virtio-scsi: setdataplane_startedto false upon failureVladimir Sementsov-Ogievskiy (16):
net/tap: reworktap_parse_script
net/tap: improve script/downscript options documentation net/tap: deprecate "no" as special value for script/downscript net/tap: move vhost-netopen()calls totap_parse_vhost_fds()net/tap: move vhost initialization totap_setup_vhost()net/tap: usecontainer_ofinstead ofDO_UPCASTnet/tap: QOMify tap backend
net/tap: addTYPE_VMSTATE_IFinterface
qapi: add local migration parameter
migration/fd: fix fd leak when fd is not valid for migration migration/fd: add errp parameter tomigration_fd_valid()
migration: check that transfer is UNIX socket when "local" set
virtio-net: support local migration of backend net/tap: disable read polling for stopped VM net/tap: support local migration with virtio-net tests/functional: addtest_tap_migrationXiong Weimin (1):
hw/virtio: Propagatevhost_virtqueue_maskerrorsMAINTAINERS | 7 + docs/about/deprecated.rst | 18 + docs/interop/vhost-user.rst | 44 ++- docs/system/devices/cxl.rst | 25 +- docs/system/i386/microvm.rst | 4 +- docs/system/i386/xenpvh.rst | 2 +- docs/system/ppc/ppce500.rst | 4 +- docs/system/riscv/microchip-icicle-kit.rst | 2 +- docs/system/riscv/sifive_u.rst | 2 +- meson.build | 4 + qapi/machine.json | 28 ++ qapi/migration.json | 21 +- qapi/net.json | 45 ++- hw/i386/amd_iommu.h | 27 +- hw/i386/intel_iommu_internal.h | 1 + hw/s390x/ccw-device.h | 2 +- include/hw/acpi/cpu.h | 4 +- include/hw/acpi/cpu_hotplug.h | 2 +- include/hw/acpi/generic_event_device.h | 3 +- include/hw/acpi/ich9.h | 10 +- include/hw/acpi/memory_hotplug.h | 4 +- include/hw/acpi/pcihp.h | 8 +- include/hw/core/boards.h | 4 +- include/hw/core/hotplug.h | 13 +- include/hw/core/qdev.h | 14 +- include/hw/cxl/cxl.h | 12 + include/hw/i386/microvm.h | 4 +- include/hw/i386/x86.h | 10 +- include/hw/mem/nvdimm.h | 2 +- include/hw/pci/pci_bridge.h | 6 +- include/hw/pci/pcie.h | 8 +- include/hw/pci/shpc.h | 6 +- include/hw/ppc/spapr_nvdimm.h | 2 +- include/hw/virtio/vhost-backend.h | 1 + include/hw/virtio/vhost-user-media.h | 46 +++ include/hw/virtio/vhost-user.h | 2 +- include/hw/virtio/vhost.h | 16 +- include/hw/virtio/virtio-balloon.h | 1 + include/hw/virtio/virtio-net.h | 1 + include/hw/virtio/virtio.h | 2 +- include/migration/misc.h | 2 + include/migration/vmstate.h | 2 + include/net/net.h | 9 + include/net/tap.h | 2 + include/standard-headers/linux/ethtool.h | 6 + include/standard-headers/linux/virtio_ids.h | 1 + linux-headers/linux/iommufd.h | 45 ++- linux-headers/linux/userfaultfd.h | 54 ++- linux-headers/linux/vduse.h | 28 ++ linux-headers/linux/vfio.h | 21 ++ linux-headers/linux/vfio_zdev.h | 2 + backends/cryptodev-vhost.c | 2 +- backends/vhost-user.c | 2 +- hw/acpi/acpi-cpu-hotplug-stub.c | 4 +- hw/acpi/acpi-mem-hotplug-stub.c | 4 +- hw/acpi/acpi-nvdimm-stub.c | 2 +- hw/acpi/acpi-pci-hotplug-stub.c | 8 +- hw/acpi/cpu.c | 6 +- hw/acpi/cxl.c | 2 +- hw/acpi/generic_event_device.c | 13 +- hw/acpi/ich9.c | 10 +- hw/acpi/memory_hotplug.c | 7 +- hw/acpi/nvdimm.c | 2 +- hw/acpi/pcihp.c | 11 +- hw/acpi/piix4.c | 12 +- hw/arm/virt.c | 23 +- hw/block/vhost-user-blk.c | 60 +++- hw/block/virtio-blk.c | 38 ++- hw/char/virtio-serial-bus.c | 6 +- hw/core/hotplug.c | 16 +- hw/core/qdev-hotplug.c | 10 +- hw/core/qdev.c | 2 +- hw/cxl/cxl-host.c | 48 ++- hw/display/vhost-user-media-pci.c | 115 +++++++ hw/display/vhost-user-media.c | 388 ++++++++++++++++++++++ hw/i386/acpi-build.c | 65 ++-- hw/i386/amd_iommu-stub.c | 2 +- hw/i386/amd_iommu.c | 2 +- hw/i386/intel_iommu.c | 118 ++++--- hw/i386/intel_iommu_accel.c | 6 + hw/i386/microvm.c | 12 +- hw/i386/pc.c | 28 +- hw/i386/x86-common.c | 8 +- hw/ide/core.c | 3 +- hw/intc/loongarch_dintc.c | 8 +- hw/intc/loongarch_extioi_common.c | 4 +- hw/intc/loongarch_ipi.c | 4 +- hw/loongarch/virt.c | 44 +-- hw/mem/cxl_type3.c | 6 +- hw/net/vhost_net.c | 9 +- hw/net/virtio-net.c | 131 +++++++- hw/nvme/ctrl.c | 78 +++-- hw/pci-bridge/pci_bridge_dev.c | 6 +- hw/pci/pci.c | 8 + hw/pci/pcie.c | 10 +- hw/pci/pcie_port.c | 2 +- hw/pci/shpc.c | 11 +- hw/ppc/e500plat.c | 4 +- hw/ppc/spapr.c | 48 +-- hw/ppc/spapr_nvdimm.c | 2 +- hw/ppc/spapr_pci.c | 12 +- hw/remote/machine.c | 2 +- hw/riscv/virt.c | 6 +- hw/s390x/css-bridge.c | 2 +- hw/s390x/s390-pci-bus.c | 12 +- hw/s390x/s390-virtio-ccw.c | 16 +- hw/s390x/virtio-ccw-md.c | 10 +- hw/s390x/virtio-ccw.c | 2 +- hw/scsi/scsi-disk.c | 7 + hw/scsi/vhost-scsi-common.c | 2 +- hw/scsi/virtio-scsi-dataplane.c | 2 +- hw/scsi/virtio-scsi.c | 10 +- hw/scsi/vmw_pvscsi.c | 4 +- hw/virtio/vdpa-dev.c | 2 +- hw/virtio/vhost-user-base.c | 2 +- hw/virtio/vhost-user-fs.c | 2 +- hw/virtio/vhost-user-scmi.c | 2 +- hw/virtio/vhost-user.c | 47 ++- hw/virtio/vhost-vsock-common.c | 2 +- hw/virtio/vhost.c | 44 ++- hw/virtio/virtio-balloon.c | 19 +- hw/virtio/virtio-crypto.c | 5 +- hw/virtio/virtio-iommu.c | 17 +- hw/virtio/virtio-md-pci.c | 10 +- hw/virtio/virtio-pci.c | 7 + hw/virtio/virtio-rtc.c | 3 +- hw/virtio/virtio.c | 85 ++--- hw/xen/xen-bus.c | 2 +- migration/fd.c | 28 +- migration/migration.c | 13 + migration/options.c | 18 +- net/net.c | 14 +- net/tap-solaris.c | 69 ++-- net/tap.c | 448 ++++++++++++++++++++----- stubs/hotplug-stubs.c | 6 +- subprojects/libvhost-user/libvhost-user.c | 34 +- system/qdev-monitor.c | 4 +- tests/qtest/cxl-test.c | 95 ++++++ hw/display/Kconfig | 5 + hw/display/meson.build | 3 + qemu-options.hx | 13 +- tests/data/acpi/x86/q35/CEDT.cxl | Bin 184 -> 184 bytes tests/data/acpi/x86/q35/IVRS.ivrs | Bin 176 -> 176 bytes tests/functional/x86_64/meson.build | 1 + tests/functional/x86_64/test_tap_migration.py | 461 ++++++++++++++++++++++++++ 145 files changed, 2884 insertions(+), 663 deletions(-) create mode 100644 include/hw/virtio/vhost-user-media.h create mode 100644 hw/display/vhost-user-media-pci.c create mode 100644 hw/display/vhost-user-media.c create mode 100755 tests/functional/x86_64/test_tap_migration.py
Quoted 43 lines · Albert Esteve
Quoted 26 lines · Michael S. Tsirkin
The following changes since commit
1df256f5968e9f7c3c4533a1383b071c044a36d6:Merge tag 'qom-qapi-pr-pr-v1' of https://gitlab.com/marcandre.lureau/qemu into staging (2026-09-08 18:35:31 +0100)
are available in the Git repository at:
https://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
for you to fetch changes up to
2f8991c0b9c400f55897849a538580039b61865a:
MAINTAINERS: add Junjie Cao as CXL reviewer (2026-09-11 04:59:15 -0400)----------------------------------------------------------------
pci, vhost, virtio, iommu, apci: features, fixesnew vhost-user-media device
virtio-net now supports live-TAP local migration
cxl now supports CFMW restrictions and per-window optionsintel_iommunow supports concurrent page fault handling with PRI pci now batches memory transactions around mapping updates vhost-user-blk now allows toggling inflight-migration at runtime virtio-rtc now supports smeared UTC clock typeintel_iommunow exposes SMPWC when SVM is enabled
new reviewer for CXL patchesQuoted 3 lines
Fixes, cleanups all over the place
Signed-off-by Michael S. Tsirkin <[email protected]>Hi Michael,
I see you dropped these patches from v1 to v2. Just checking if this was intended or if there is an issue/CI failure that needs addressing?
[...]
Dorinda Bassey (1):
vhost: FixSHMEM_MAPtransaction ordering and resulting deadlockFeifan Qian (1):
vhost-user: RejectSHMEM_MAPwhen no KVM memory slot is left
Quoted 8 lines
[...]
Matej Hrica (2):
vhost-user-gpu: Add shared memory region support
vhost-user-gpu: ForwardRESOURCE_BLOBandCONTEXT_INITflags
[...]Thanks!
Albert
No issue, I just don't normally merge gpu things. This one was needed originally to resolve some other issue so I picked it up but I guess the issue's gone because it now passed without. So I'm happy to have it go through the usual channels.
Quoted 267 lines
Quoted 267 lines
----------------------------------------------------------------
Albert Esteve (4):
linux-headers: addVIRTIO_ID_MEDIA
hw/display: add vhost-user-media device hw/display/vhost-user-media: add shared memory region BAR
linux-headers: Update to Linux v7.3-rc1Alexandr Moshkov (6):
vhost-user: addskip_drainparam todo_vhost_virtqueue_stop
vhost-user: addGET_VRING_BASE_SKIP_DRAINmessage
vhost-user: useskip_drainwithGET_VRING_BASE_SKIP_DRAINmessage
vhost-user-blk: make inflight-migration prop mutable on running vm
vhost-user-blk: moveinflight_neededhigher
vhost-user-blk: useGET_VRING_BASE_SKIP_DRAINwhen inflight-migration is onAlyssa Ross (1):
vhost-user.rst: fix typoBin Guo (2):
libvhost-user: accept the postcopy client base ack invu_add_mem_reg()
libvhost-user: return the backend mapping address for added regionsClément MATHIEU--DRIF (4):
intel_iommu: Support concurrent page fault handling with PRI
intel_iommu: Only set dirty bit when PTE exposes write permission
intel_iommu: Always write all the flags passed tovtd_set_flag_in_pte
intel_iommu: Expose SMPWC when SVM is enabledDavidlohr Bueso (5):
tests/bios-tables-test: Exclude CEDT.cxl for the CFMW restriction change hw/cxl: Drop Back-Invalidate from default CFMW window restrictions tests/acpi/cxl: Update CEDT.cxl for the default CFMW restrictions hw/cxl: Add configurable CXL Fixed Memory Window restriction flags tests/qtest/cxl: Add CXL Fixed Memory Window restriction flag testsDenis V. Lunev (2):
pci: batch BAR remapping into one memory transaction
pci: load a device's config inside one memory transactionGuoHan Zhao (1):
virtio-crypto: clean up every data queueHanna Czenczek (6):
hw/virtio-blk: Account discard operations hw/virtio-blk: Complete zone-append cookies hw/nvme: Fix block accounting innvme_copy()hw/nvme: Fix block accounting for compare hw/ide: Haveide_dma_cb()complete accounting hw/scsi-disk: Fix accounting for IGNORE, ret > 0Jia Jia (2):
virtio: reduce code duplication for split ring hw/virtio: reject inverted virtio-iommu IOVA rangesJunjie Cao (3):
hw/cxl: Fix guest-triggerable QEMU exit on reserved interleave ways hw/cxl: fix the CDAT DOE overlapping the Flex Bus DVSEC when sn= is set
MAINTAINERS: add Junjie Cao as CXL reviewerKuan-Wei Chiu (1):
virtio-rtc: Report smeared UTC clock typeLaurent Vivier (2):
hw/net/virtio-net: check packet size before VLAN tag access inreceive_filter()hw/net/virtio-net: strip trailing padding when caching RSC segmentMichael S. Tsirkin (7):
virtio: fix exit(1) on DMA mapping failure during migration restore
virtio: fixconfig_lenDoS in migration restore path
virtio-pci: rejectQ_ENABLEwrite on already-enabled queue
meson: disable "maybe uninitilized" errors with -Og
virtio-balloon: fix free-page BH teardown on unrealizenet/tap-solaris: Fix resource leaks on error paths
virtio-net: validate IHL invirtio_net_rsc_extract_unit4before usePhilippe Mathieu-Daudé (4):
hw/acpi: Make AcpiGedState const inbuild_ged_aml()hw/hotplug: Mark various HotplugHandlerClass variables as const hw/hotplug: Reduce some HotplugHandler variables scope hw/hotplug: Constify HotplugHandlerSairaj Kodilkar (7):
amd_iommu: Return empty efr for stub call
tests/acpi: x86: Allow IVRS acpi table changes
amd_iommu: acpi-build: update PA, GVA and VA size macros
acpi_build: Use IOMMU pci device to build IOMMU DeviceID
acpi_build: Build IVRS feature report using extended feature register
amd_iommu: acpi-build: Remove unsupported PPR and HE feature tests/acpi: x86: update golden masters for IVRSStefan Hajnoczi (1):
virtio-scsi: setdataplane_startedto false upon failureVladimir Sementsov-Ogievskiy (16):
net/tap: reworktap_parse_script
net/tap: improve script/downscript options documentation net/tap: deprecate "no" as special value for script/downscript net/tap: move vhost-netopen()calls totap_parse_vhost_fds()net/tap: move vhost initialization totap_setup_vhost()net/tap: usecontainer_ofinstead ofDO_UPCASTnet/tap: QOMify tap backend
net/tap: addTYPE_VMSTATE_IFinterface
qapi: add local migration parameter
migration/fd: fix fd leak when fd is not valid for migration migration/fd: add errp parameter tomigration_fd_valid()
migration: check that transfer is UNIX socket when "local" set
virtio-net: support local migration of backend net/tap: disable read polling for stopped VM net/tap: support local migration with virtio-net tests/functional: addtest_tap_migrationXiong Weimin (1):
hw/virtio: Propagatevhost_virtqueue_maskerrorsMAINTAINERS | 7 + docs/about/deprecated.rst | 18 + docs/interop/vhost-user.rst | 44 ++- docs/system/devices/cxl.rst | 25 +- docs/system/i386/microvm.rst | 4 +- docs/system/i386/xenpvh.rst | 2 +- docs/system/ppc/ppce500.rst | 4 +- docs/system/riscv/microchip-icicle-kit.rst | 2 +- docs/system/riscv/sifive_u.rst | 2 +- meson.build | 4 + qapi/machine.json | 28 ++ qapi/migration.json | 21 +- qapi/net.json | 45 ++- hw/i386/amd_iommu.h | 27 +- hw/i386/intel_iommu_internal.h | 1 + hw/s390x/ccw-device.h | 2 +- include/hw/acpi/cpu.h | 4 +- include/hw/acpi/cpu_hotplug.h | 2 +- include/hw/acpi/generic_event_device.h | 3 +- include/hw/acpi/ich9.h | 10 +- include/hw/acpi/memory_hotplug.h | 4 +- include/hw/acpi/pcihp.h | 8 +- include/hw/core/boards.h | 4 +- include/hw/core/hotplug.h | 13 +- include/hw/core/qdev.h | 14 +- include/hw/cxl/cxl.h | 12 + include/hw/i386/microvm.h | 4 +- include/hw/i386/x86.h | 10 +- include/hw/mem/nvdimm.h | 2 +- include/hw/pci/pci_bridge.h | 6 +- include/hw/pci/pcie.h | 8 +- include/hw/pci/shpc.h | 6 +- include/hw/ppc/spapr_nvdimm.h | 2 +- include/hw/virtio/vhost-backend.h | 1 + include/hw/virtio/vhost-user-media.h | 46 +++ include/hw/virtio/vhost-user.h | 2 +- include/hw/virtio/vhost.h | 16 +- include/hw/virtio/virtio-balloon.h | 1 + include/hw/virtio/virtio-net.h | 1 + include/hw/virtio/virtio.h | 2 +- include/migration/misc.h | 2 + include/migration/vmstate.h | 2 + include/net/net.h | 9 + include/net/tap.h | 2 + include/standard-headers/linux/ethtool.h | 6 + include/standard-headers/linux/virtio_ids.h | 1 + linux-headers/linux/iommufd.h | 45 ++- linux-headers/linux/userfaultfd.h | 54 ++- linux-headers/linux/vduse.h | 28 ++ linux-headers/linux/vfio.h | 21 ++ linux-headers/linux/vfio_zdev.h | 2 + backends/cryptodev-vhost.c | 2 +- backends/vhost-user.c | 2 +- hw/acpi/acpi-cpu-hotplug-stub.c | 4 +- hw/acpi/acpi-mem-hotplug-stub.c | 4 +- hw/acpi/acpi-nvdimm-stub.c | 2 +- hw/acpi/acpi-pci-hotplug-stub.c | 8 +- hw/acpi/cpu.c | 6 +- hw/acpi/cxl.c | 2 +- hw/acpi/generic_event_device.c | 13 +- hw/acpi/ich9.c | 10 +- hw/acpi/memory_hotplug.c | 7 +- hw/acpi/nvdimm.c | 2 +- hw/acpi/pcihp.c | 11 +- hw/acpi/piix4.c | 12 +- hw/arm/virt.c | 23 +- hw/block/vhost-user-blk.c | 60 +++- hw/block/virtio-blk.c | 38 ++- hw/char/virtio-serial-bus.c | 6 +- hw/core/hotplug.c | 16 +- hw/core/qdev-hotplug.c | 10 +- hw/core/qdev.c | 2 +- hw/cxl/cxl-host.c | 48 ++- hw/display/vhost-user-media-pci.c | 115 +++++++ hw/display/vhost-user-media.c | 388 ++++++++++++++++++++++ hw/i386/acpi-build.c | 65 ++-- hw/i386/amd_iommu-stub.c | 2 +- hw/i386/amd_iommu.c | 2 +- hw/i386/intel_iommu.c | 118 ++++--- hw/i386/intel_iommu_accel.c | 6 + hw/i386/microvm.c | 12 +- hw/i386/pc.c | 28 +- hw/i386/x86-common.c | 8 +- hw/ide/core.c | 3 +- hw/intc/loongarch_dintc.c | 8 +- hw/intc/loongarch_extioi_common.c | 4 +- hw/intc/loongarch_ipi.c | 4 +- hw/loongarch/virt.c | 44 +-- hw/mem/cxl_type3.c | 6 +- hw/net/vhost_net.c | 9 +- hw/net/virtio-net.c | 131 +++++++- hw/nvme/ctrl.c | 78 +++-- hw/pci-bridge/pci_bridge_dev.c | 6 +- hw/pci/pci.c | 8 + hw/pci/pcie.c | 10 +- hw/pci/pcie_port.c | 2 +- hw/pci/shpc.c | 11 +- hw/ppc/e500plat.c | 4 +- hw/ppc/spapr.c | 48 +-- hw/ppc/spapr_nvdimm.c | 2 +- hw/ppc/spapr_pci.c | 12 +- hw/remote/machine.c | 2 +- hw/riscv/virt.c | 6 +- hw/s390x/css-bridge.c | 2 +- hw/s390x/s390-pci-bus.c | 12 +- hw/s390x/s390-virtio-ccw.c | 16 +- hw/s390x/virtio-ccw-md.c | 10 +- hw/s390x/virtio-ccw.c | 2 +- hw/scsi/scsi-disk.c | 7 + hw/scsi/vhost-scsi-common.c | 2 +- hw/scsi/virtio-scsi-dataplane.c | 2 +- hw/scsi/virtio-scsi.c | 10 +- hw/scsi/vmw_pvscsi.c | 4 +- hw/virtio/vdpa-dev.c | 2 +- hw/virtio/vhost-user-base.c | 2 +- hw/virtio/vhost-user-fs.c | 2 +- hw/virtio/vhost-user-scmi.c | 2 +- hw/virtio/vhost-user.c | 47 ++- hw/virtio/vhost-vsock-common.c | 2 +- hw/virtio/vhost.c | 44 ++- hw/virtio/virtio-balloon.c | 19 +- hw/virtio/virtio-crypto.c | 5 +- hw/virtio/virtio-iommu.c | 17 +- hw/virtio/virtio-md-pci.c | 10 +- hw/virtio/virtio-pci.c | 7 + hw/virtio/virtio-rtc.c | 3 +- hw/virtio/virtio.c | 85 ++--- hw/xen/xen-bus.c | 2 +- migration/fd.c | 28 +- migration/migration.c | 13 + migration/options.c | 18 +- net/net.c | 14 +- net/tap-solaris.c | 69 ++-- net/tap.c | 448 ++++++++++++++++++++----- stubs/hotplug-stubs.c | 6 +- subprojects/libvhost-user/libvhost-user.c | 34 +- system/qdev-monitor.c | 4 +- tests/qtest/cxl-test.c | 95 ++++++ hw/display/Kconfig | 5 + hw/display/meson.build | 3 + qemu-options.hx | 13 +- tests/data/acpi/x86/q35/CEDT.cxl | Bin 184 -> 184 bytes tests/data/acpi/x86/q35/IVRS.ivrs | Bin 176 -> 176 bytes tests/functional/x86_64/meson.build | 1 + tests/functional/x86_64/test_tap_migration.py | 461 ++++++++++++++++++++++++++ 145 files changed, 2884 insertions(+), 663 deletions(-) create mode 100644 include/hw/virtio/vhost-user-media.h create mode 100644 hw/display/vhost-user-media-pci.c create mode 100644 hw/display/vhost-user-media.c create mode 100755 tests/functional/x86_64/test_tap_migration.py
Quoted 25 lines · Michael S. Tsirkin
The following changes since commit
1df256f5968e9f7c3c4533a1383b071c044a36d6:Merge tag 'qom-qapi-pr-pr-v1' ofhttps://gitlab.com/marcandre.lureau/qemu into staging (2026-09-08 18:35:31 +0100)are available in the Git repository at:
https://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
for you to fetch changes up to
2f8991c0b9c400f55897849a538580039b61865a:
MAINTAINERS: add Junjie Cao as CXL reviewer (2026-09-11 04:59:15 -0400)----------------------------------------------------------------
pci, vhost, virtio, iommu, apci: features, fixesnew vhost-user-media device
virtio-net now supports live-TAP local migration
cxl now supports CFMW restrictions and per-window optionsintel_iommunow supports concurrent page fault handling with PRI pci now batches memory transactions around mapping updates vhost-user-blk now allows toggling inflight-migration at runtime virtio-rtc now supports smeared UTC clock typeintel_iommunow exposes SMPWC when SVM is enabled
new reviewer for CXL patches
Quoted 1 line
Fixes, cleanups all over the place
https://gitlab.com/qemu-project/qemu/-/pipelines/2840522620
Between the 6 failing jobs, I think there are 2 failures replicated:
https://gitlab.com/qemu-project/qemu/-/jobs/16454091774#L800
18/34 func-quick+func-x86_64 - qemu:func-x86_64-linters
FAIL 6.00s exit status 1
34/34 func-thorough+func-x86_64-thorough+thorough - qemu:func-x86_64-tap_migration ERROR 0.19s 0 subtests passed
r~
Quoted 34 lines · Richard Henderson
Quoted 25 lines · Michael S. Tsirkin
The following changes since commit
1df256f5968e9f7c3c4533a1383b071c044a36d6:Merge tag 'qom-qapi-pr-pr-v1' ofhttps://gitlab.com/marcandre.lureau/qemu into staging (2026-09-08 18:35:31 +0100)are available in the Git repository at:
https://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
for you to fetch changes up to
2f8991c0b9c400f55897849a538580039b61865a:
MAINTAINERS: add Junjie Cao as CXL reviewer (2026-09-11 04:59:15 -0400)----------------------------------------------------------------
pci, vhost, virtio, iommu, apci: features, fixesnew vhost-user-media device
virtio-net now supports live-TAP local migration
cxl now supports CFMW restrictions and per-window optionsintel_iommunow supports concurrent page fault handling with PRI pci now batches memory transactions around mapping updates vhost-user-blk now allows toggling inflight-migration at runtime virtio-rtc now supports smeared UTC clock typeintel_iommunow exposes SMPWC when SVM is enabled
new reviewer for CXL patchesQuoted 1 line
Fixes, cleanups all over the place
https://gitlab.com/qemu-project/qemu/-/pipelines/2840522620
Between the 6 failing jobs, I think there are 2 failures replicated:
https://gitlab.com/qemu-project/qemu/-/jobs/16454091774#L800
Quoted 8 lines
18/34 func-quick+func-x86_64 - qemu:func-x86_64-linters FAIL
6.00s exit status 1
34/34 func-thorough+func-x86_64-thorough+thorough -
qemu:func-x86_64-tap_migration ERROR 0.19s 0 subtests
passedr~
That's the new test. I dropped that.
The func-rx-vnc is due to the test using a fixed port which is always a bad idea, making the test flaky.
Pushed to same tag, could you try again pls?
Vladimir FYI tests/functional: add test_tap_migration is dropped due to linter issues and missing iproute2 dependency.
Signature · 1 line
MST
Richard Henderson
AppliedQuoted 13 lines · Michael S. Tsirkin
Quoted 12 lines · Richard Henderson
Quoted 11 lines · Michael S. Tsirkin
The following changes since commit
1df256f5968e9f7c3c4533a1383b071c044a36d6:Merge tag 'qom-qapi-pr-pr-v1' ofhttps://gitlab.com/marcandre.lureau/qemu into staging (2026-09-08 18:35:31 +0100)are available in the Git repository at:
https://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
for you to fetch changes up to
2f8991c0b9c400f55897849a538580039b61865a:MAINTAINERS: add Junjie Cao as CXL reviewer (2026-09-11 04:59:15 -0400)
...
Quoted 7 lines
That's the new test. I dropped that.
The func-rx-vnc is due to the test using a fixed port which is always a bad idea, making the test flaky.
Pushed to same tag, could you try again pls?
Applied, thanks.
r~
Quoted 47 lines · Michael S. Tsirkin
Quoted 34 lines · Richard Henderson
Quoted 25 lines · Michael S. Tsirkin
The following changes since commit
1df256f5968e9f7c3c4533a1383b071c044a36d6:Merge tag 'qom-qapi-pr-pr-v1' ofhttps://gitlab.com/marcandre.lureau/qemu into staging (2026-09-08 18:35:31 +0100)are available in the Git repository at:
https://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
for you to fetch changes up to
2f8991c0b9c400f55897849a538580039b61865a:MAINTAINERS: add Junjie Cao as CXL reviewer (2026-09-11 04:59:15 -0400)----------------------------------------------------------------
pci, vhost, virtio, iommu, apci: features, fixesnew vhost-user-media device
virtio-net now supports live-TAP local migration
cxl now supports CFMW restrictions and per-window optionsintel_iommunow supports concurrent page fault handling with PRI pci now batches memory transactions around mapping updates vhost-user-blk now allows toggling inflight-migration at runtime virtio-rtc now supports smeared UTC clock typeintel_iommunow exposes SMPWC when SVM is enabled
new reviewer for CXL patchesQuoted 1 line
Fixes, cleanups all over the place
https://gitlab.com/qemu-project/qemu/-/pipelines/2840522620
Between the 6 failing jobs, I think there are 2 failures replicated:
https://gitlab.com/qemu-project/qemu/-/jobs/16454091774#L800
Quoted 8 lines
18/34 func-quick+func-x86_64 - qemu:func-x86_64-linters FAIL
6.00s exit status 1
34/34 func-thorough+func-x86_64-thorough+thorough -
qemu:func-x86_64-tap_migration ERROR 0.19s 0 subtests
passedr~
That's the new test. I dropped that.
Quoted 8 lines
The func-rx-vnc is due to the test using a fixed port which is always a bad idea, making the test flaky.
Pushed to same tag, could you try again pls?
Vladimir FYI tests/functional: add
test_tap_migrationis dropped due to linter issues and missing iproute2 dependency.
OK, no problem, I'll resend it
Signature · 2 lines
Best regards, Vladimir