Skip to contentSkip to conversation

virtio,pci,pc: features,fixes

GIT PULL Michael S. Tsirkin 4 participants 73 messages Jul 22, 2024 – Jul 23, 2024

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

A couple of fixes are outstanding, will merge later.

The following changes since commit a87a7c449e532130d4fa8faa391ff7e1f04ed660:

Merge tag 'pull-loongarch-20240719' of https://gitlab.com/gaosong/qemu into staging (2024-07-19 16:28:28 +1000)

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 67d834362c55d6fca6504975bc34755606f17cf2:

virtio: Always reset vhost devices (2024-07-21 14:45:56 -0400)

----------------------------------------------------------------
virtio,pci,pc: features,fixes

pci: Initial support for SPDM Responders
cxl: Add support for scan media, feature commands, device patrol scrub
control, DDR5 ECS control, firmware updates
virtio: in-order support
virtio-net: support for SR-IOV emulation (note: known issues on s390,
might get reverted if not fixed)
smbios: memory device size is now configurable per Machine
cpu: architecture agnostic code to support vCPU Hotplug

Fixes, cleanups all over the place.

----------------------------------------------------------------
Akihiko Odaki (8):
hw/pci: Do not add ROM BAR for SR-IOV VF hw/pci: Fix SR-IOV VF number calculation
pcie_sriov: Ensure PF and VF are mutually exclusive
pcie_sriov: Check PCI Express for SR-IOV PF
pcie_sriov: Allow user to create SR-IOV device
virtio-pci: Implement SR-IOV PF
virtio-net: Implement SR-IOV VF
docs: Document composable SR-IOV device

Alistair Francis (1):
hw/pci: Add all Data Object Types defined in PCIe r6.0

Clément Mathieu--Drif (4):
intel_iommu: fix FRCD construction macro
intel_iommu: move VTD_FRCD_PV and VTD_FRCD_PP declarations
intel_iommu: fix type of the mask field in VTDIOTLBPageInvInfo
intel_iommu: make type match

Davidlohr Bueso (3):
hw/cxl: Add get scan media capabilities cmd support hw/cxl: Add get scan media results cmd support hw/cxl: Support firmware updates

Eric Auger (6):
Revert "virtio-iommu: Clear IOMMUDevice when VFIO device is unplugged"
virtio-iommu: Remove probe_done
virtio-iommu: Free [host_]resv_ranges on unset_iommu_devices
virtio-iommu: Remove the end point on detach
hw/vfio/common: Add vfio_listener_region_del_iommu trace event
virtio-iommu: Add trace point on virtio_iommu_detach_endpoint_from_domain

Fan Ni (1):
hw/cxl/cxl-mailbox-utils: remove unneeded mailbox output payload space zeroing

Gregory Price (1):
cxl/mailbox: move mailbox effect definitions to a header

Hanna Czenczek (1):
virtio: Always reset vhost devices

Huai-Cheng Kuo (1):
backends: Initial support for SPDM socket support

Hyeonggon Yoo (2):
hw/cxl/mbox: replace sanitize_running() with cxl_dev_media_disabled() hw/cxl/events: discard all event records during sanitation

Igor Mammedov (1):
smbios: make memory device size configurable per Machine

Jonah Palmer (6):
virtio: Add bool to VirtQueueElement
virtio: virtqueue_pop - VIRTIO_F_IN_ORDER support
virtio: virtqueue_ordered_fill - VIRTIO_F_IN_ORDER support
virtio: virtqueue_ordered_flush - VIRTIO_F_IN_ORDER support vhost,vhost-user: Add VIRTIO_F_IN_ORDER to vhost feature bits
virtio: Add VIRTIO_F_IN_ORDER property definition

Jonathan Cameron (1):
hw/cxl: Check for multiple mappings of memory backends.

Manos Pitsidianakis (2):
virtio-snd: add max size bounds check in input cb
virtio-snd: check for invalid param shift operands

Salil Mehta (7):
accel/kvm: Extract common KVM vCPU {creation,parking} code hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file hw/acpi: Update ACPI GED framework to support vCPU Hotplug hw/acpi: Update GED _EVT method AML with CPU scan
hw/acpi: Update CPUs AML with cpu-(ctrl)dev change
physmem: Add helper function to destroy CPU AddressSpace
gdbstub: Add helper function to unregister GDB register space

Shiju Jose (3):
hw/cxl/cxl-mailbox-utils: Add support for feature commands (8.2.9.6) hw/cxl/cxl-mailbox-utils: Add device patrol scrub control feature hw/cxl/cxl-mailbox-utils: Add device DDR5 ECS control feature

Stefano Garzarella (2):
MAINTAINERS: add Stefano Garzarella as vhost/vhost-user reviewer contrib/vhost-user-blk: fix overflowing expression

Sunil V L (9):
hw/riscv/virt-acpi-build.c: Add namespace devices for PLIC and APLIC hw/riscv/virt-acpi-build.c: Update the HID of RISC-V UART tests/acpi: Allow DSDT acpi table changes for aarch64 acpi/gpex: Create PCI link devices outside PCI root bridge tests/acpi: update expected DSDT blob for aarch64 and microvm tests/qtest/bios-tables-test.c: Remove the fall back path tests/acpi: Add empty ACPI data files for RISC-V tests/qtest/bios-tables-test.c: Enable basic testing for RISC-V tests/acpi: Add expected ACPI AML files for RISC-V

Wilfred Mallawa (1):
hw/nvme: Add SPDM over DOE support

Yi Liu (1):
MAINTAINERS: Add myself as a VT-d reviewer

Zhao Liu (1):
hw/cxl/cxl-host: Fix segmentation fault when getting cxl-fmw property

Zheyu Ma (1):
hw/virtio/virtio-crypto: Fix op_code assignment in virtio_crypto_create_asym_session

 accel/kvm/kvm-cpus.h                           |   1 -
 hw/i386/intel_iommu_internal.h                 |   6 +-
 include/exec/cpu-common.h                      |   8 +
 include/exec/gdbstub.h                         |   6 +
 include/hw/acpi/cpu.h                          |   7 +-
 include/hw/acpi/generic_event_device.h         |   5 +
 include/hw/boards.h                            |   4 +
 include/hw/core/cpu.h                          |   1 +
 include/hw/cxl/cxl_device.h                    |  88 ++-
 include/hw/cxl/cxl_mailbox.h                   |  18 +
 include/hw/pci/pci_device.h                    |  13 +-
 include/hw/pci/pcie_doe.h                      |   5 +
 include/hw/pci/pcie_sriov.h                    |  18 +
 include/hw/virtio/virtio-iommu.h               |   1 -
 include/hw/virtio/virtio-pci.h                 |   1 +
 include/hw/virtio/virtio.h                     |   6 +-
 include/sysemu/kvm.h                           |  25 +
 include/sysemu/spdm-socket.h                   |  74 ++
 accel/kvm/kvm-all.c                            |  95 ++-
 backends/spdm-socket.c                         | 216 ++++++
 contrib/vhost-user-blk/vhost-user-blk.c        |   2 +-
 gdbstub/gdbstub.c                              |  13 +
 hw/acpi/acpi-cpu-hotplug-stub.c                |   6 +
 hw/acpi/cpu.c                                  |  18 +-
 hw/acpi/generic_event_device.c                 |  50 ++
 hw/arm/virt.c                                  |   1 +
 hw/audio/virtio-snd.c                          |  13 +-
 hw/block/vhost-user-blk.c                      |   1 +
 hw/core/cpu-common.c                           |   5 +-
 hw/core/machine.c                              |   6 +
 hw/cxl/cxl-events.c                            |  13 +
 hw/cxl/cxl-host.c                              |   3 +-
 hw/cxl/cxl-mailbox-utils.c                     | 966 +++++++++++++++++++++++--
 hw/i386/acpi-build.c                           |   3 +-
 hw/i386/intel_iommu.c                          |   2 +-
 hw/i386/pc_piix.c                              |   1 +
 hw/i386/pc_q35.c                               |   1 +
 hw/mem/cxl_type3.c                             |  64 +-
 hw/net/vhost_net.c                             |   2 +
 hw/nvme/ctrl.c                                 |  62 ++
 hw/pci-host/gpex-acpi.c                        |  13 +-
 hw/pci/pci.c                                   |  76 +-
 hw/pci/pcie_sriov.c                            | 300 ++++++--
 hw/riscv/virt-acpi-build.c                     |  34 +-
 hw/scsi/vhost-scsi.c                           |   1 +
 hw/scsi/vhost-user-scsi.c                      |   1 +
 hw/smbios/smbios.c                             |  11 +-
 hw/vfio/common.c                               |   3 +-
 hw/virtio/vhost-user-fs.c                      |   1 +
 hw/virtio/vhost-user-vsock.c                   |   1 +
 hw/virtio/virtio-crypto.c                      |   2 +-
 hw/virtio/virtio-iommu.c                       |  88 +--
 hw/virtio/virtio-net-pci.c                     |   1 +
 hw/virtio/virtio-pci.c                         |  20 +-
 hw/virtio/virtio.c                             | 139 +++-
 net/vhost-vdpa.c                               |   1 +
 system/physmem.c                               |  29 +
 tests/qtest/bios-tables-test.c                 |  40 +-
 MAINTAINERS                                    |   9 +
 accel/kvm/trace-events                         |   5 +-
 backends/Kconfig                               |   4 +
 backends/meson.build                           |   2 +
 docs/specs/acpi_hw_reduced_hotplug.rst         |   3 +-
 docs/specs/index.rst                           |   1 +
 docs/specs/spdm.rst                            | 134 ++++
 docs/system/index.rst                          |   1 +
 docs/system/sriov.rst                          |  36 +
 hw/vfio/trace-events                           |   3 +-
 hw/virtio/trace-events                         |   1 +
 tests/data/acpi/aarch64/virt/DSDT              | Bin 5196 -> 5196 bytes
 tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt | Bin 5282 -> 5282 bytes
 tests/data/acpi/aarch64/virt/DSDT.memhp        | Bin 6557 -> 6557 bytes
 tests/data/acpi/aarch64/virt/DSDT.pxb          | Bin 7679 -> 7679 bytes
 tests/data/acpi/aarch64/virt/DSDT.topology     | Bin 5398 -> 5398 bytes
 tests/data/acpi/riscv64/virt/APIC              | Bin 0 -> 116 bytes
 tests/data/acpi/riscv64/virt/DSDT              | Bin 0 -> 3576 bytes
 tests/data/acpi/riscv64/virt/FACP              | Bin 0 -> 276 bytes
 tests/data/acpi/riscv64/virt/MCFG              | Bin 0 -> 60 bytes
 tests/data/acpi/riscv64/virt/RHCT              | Bin 0 -> 332 bytes
 tests/data/acpi/riscv64/virt/SPCR              | Bin 0 -> 80 bytes
 tests/data/acpi/x86/microvm/DSDT.pcie          | Bin 3023 -> 3023 bytes
 81 files changed, 2500 insertions(+), 290 deletions(-)
 create mode 100644 include/hw/cxl/cxl_mailbox.h
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c
 create mode 100644 docs/specs/spdm.rst
 create mode 100644 docs/system/sriov.rst
 create mode 100644 tests/data/acpi/riscv64/virt/APIC
 create mode 100644 tests/data/acpi/riscv64/virt/DSDT
 create mode 100644 tests/data/acpi/riscv64/virt/FACP
 create mode 100644 tests/data/acpi/riscv64/virt/MCFG
 create mode 100644 tests/data/acpi/riscv64/virt/RHCT
 create mode 100644 tests/data/acpi/riscv64/virt/SPCR
#1 lore raw

[PULL 26/63] vhost,vhost-user: Add VIRTIO_F_IN_ORDER to vhost feature bits

From: Jonah Palmer <[email protected]>

Add support for the VIRTIO_F_IN_ORDER feature across a variety of vhost devices.

The inclusion of VIRTIO_F_IN_ORDER in the feature bits arrays for these devices ensures that the backend is capable of offering and providing support for this feature, and that it can be disabled if the backend does not support it.

Message-Id: <[email protected]>

---
 hw/block/vhost-user-blk.c    | 1 +
 hw/net/vhost_net.c           | 2 ++
 hw/scsi/vhost-scsi.c         | 1 +
 hw/scsi/vhost-user-scsi.c    | 1 +
 hw/virtio/vhost-user-fs.c    | 1 +
 hw/virtio/vhost-user-vsock.c | 1 +
 net/vhost-vdpa.c             | 1 +
 7 files changed, 8 insertions(+)
hw/block/vhost-user-blk.c +1 -0
index fdbc30b9ce..5b7f46bbb0 100644
@@ -51,6 +51,7 @@ static const int user_feature_bits[] = {
     VIRTIO_F_RING_PACKED,
     VIRTIO_F_IOMMU_PLATFORM,
     VIRTIO_F_RING_RESET,
+    VIRTIO_F_IN_ORDER,
     VIRTIO_F_NOTIFICATION_DATA,
     VHOST_INVALID_FEATURE_BIT
 };
hw/net/vhost_net.c +2 -0
index 18898afe81..a788e6937e 100644
@@ -48,6 +48,7 @@ static const int kernel_feature_bits[] = {
     VIRTIO_F_IOMMU_PLATFORM,
     VIRTIO_F_RING_PACKED,
     VIRTIO_F_RING_RESET,
+    VIRTIO_F_IN_ORDER,
     VIRTIO_F_NOTIFICATION_DATA,
     VIRTIO_NET_F_HASH_REPORT,
     VHOST_INVALID_FEATURE_BIT
@@ -78,6 +79,7 @@ static const int user_feature_bits[] = {
     VIRTIO_F_IOMMU_PLATFORM,
     VIRTIO_F_RING_PACKED,
     VIRTIO_F_RING_RESET,
+    VIRTIO_F_IN_ORDER,
     VIRTIO_NET_F_RSS,
     VIRTIO_NET_F_HASH_REPORT,
     VIRTIO_NET_F_GUEST_USO4,
hw/scsi/vhost-scsi.c +1 -0
index 3d5fe0994d..49cff2a0cb 100644
@@ -38,6 +38,7 @@ static const int kernel_feature_bits[] = {
     VIRTIO_RING_F_EVENT_IDX,
     VIRTIO_SCSI_F_HOTPLUG,
     VIRTIO_F_RING_RESET,
+    VIRTIO_F_IN_ORDER,
     VIRTIO_F_NOTIFICATION_DATA,
     VHOST_INVALID_FEATURE_BIT
 };
hw/scsi/vhost-user-scsi.c +1 -0
index cc91ade525..55e4be5b34 100644
@@ -36,6 +36,7 @@ static const int user_feature_bits[] = {
     VIRTIO_RING_F_EVENT_IDX,
     VIRTIO_SCSI_F_HOTPLUG,
     VIRTIO_F_RING_RESET,
+    VIRTIO_F_IN_ORDER,
     VIRTIO_F_NOTIFICATION_DATA,
     VHOST_INVALID_FEATURE_BIT
 };
hw/virtio/vhost-user-fs.c +1 -0
index ae48cc1c96..32ee7f496d 100644
@@ -33,6 +33,7 @@ static const int user_feature_bits[] = {
     VIRTIO_F_RING_PACKED,
     VIRTIO_F_IOMMU_PLATFORM,
     VIRTIO_F_RING_RESET,
+    VIRTIO_F_IN_ORDER,
     VIRTIO_F_NOTIFICATION_DATA,
     VHOST_INVALID_FEATURE_BIT
 };
hw/virtio/vhost-user-vsock.c +1 -0
index 802b44a07d..da3b0e0229 100644
@@ -21,6 +21,7 @@ static const int user_feature_bits[] = {
     VIRTIO_RING_F_INDIRECT_DESC,
     VIRTIO_RING_F_EVENT_IDX,
     VIRTIO_F_NOTIFY_ON_EMPTY,
+    VIRTIO_F_IN_ORDER,
     VIRTIO_F_NOTIFICATION_DATA,
     VHOST_INVALID_FEATURE_BIT
 };
net/vhost-vdpa.c +1 -0
index daa38428c5..03457ead66 100644
@@ -62,6 +62,7 @@ const int vdpa_feature_bits[] = {
     VIRTIO_F_RING_PACKED,
     VIRTIO_F_RING_RESET,
     VIRTIO_F_VERSION_1,
+    VIRTIO_F_IN_ORDER,
     VIRTIO_F_NOTIFICATION_DATA,
     VIRTIO_NET_F_CSUM,
     VIRTIO_NET_F_CTRL_GUEST_OFFLOADS,
Signature · 1 line
MST
#2 lore raw

[PULL 02/63] MAINTAINERS: add Stefano Garzarella as vhost/vhost-user reviewer

In reply to Michael S. Tsirkin

From: Stefano Garzarella <[email protected]>

I have recently been working on supporting vhost-user on any POSIX, so I want to help maintain it.

Cc Michael S. Tsirkin <[email protected]>

Message-Id: <[email protected]>

---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)
MAINTAINERS +1 -0
index 7d9811458c..b7e9ced3e8 100644
@@ -2209,6 +2209,7 @@ F: docs/devel/vfio-iommufd.rst
 
 vhost
 M: Michael S. Tsirkin <[email protected]>
+R: Stefano Garzarella <[email protected]>
 S: Supported
 F: hw/*/*vhost*
 F: docs/interop/vhost-user.json
Signature · 1 line
MST
#3 lore raw

[PULL 01/63] hw/virtio/virtio-crypto: Fix op_code assignment in virtio_crypto_create_asym_session

In reply to Michael S. Tsirkin

From: Zheyu Ma <[email protected]>

Currently, if the function fails during the key_len check, the op_code does not have a proper value, causing virtio_crypto_free_create_session_req not to free the memory correctly, leading to a memory leak.

By setting the op_code before performing any checks, we ensure that virtio_crypto_free_create_session_req has the correct context to perform cleanup operations properly, thus preventing memory leaks.

ASAN log:
==3055068==ERROR: LeakSanitizer: detected memory leaks Direct leak of 512 byte(s) in 1 object(s) allocated from:

    #0 0x5586a75e6ddd in malloc llvm/compiler-rt/lib/asan/asan_malloc_linux.cpp:129:3
    #1 0x7fb6b63b6738 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5e738)
    #2 0x5586a864bbde in virtio_crypto_handle_ctrl hw/virtio/virtio-crypto.c:407:19
    #3 0x5586a94fc84c in virtio_queue_notify_vq hw/virtio/virtio.c:2277:9
    #4 0x5586a94fc0a2 in virtio_queue_host_notifier_read hw/virtio/virtio.c:3641:9

Message-Id: <[email protected]>

---
 hw/virtio/virtio-crypto.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
hw/virtio/virtio-crypto.c +1 -1
index bbe8aa4b99..5034768bff 100644
@@ -205,6 +205,7 @@ virtio_crypto_create_asym_session(VirtIOCrypto *vcrypto,
     int queue_index;
     uint32_t algo, keytype, keylen;
 
+    sreq->info.op_code = opcode;
     algo = ldl_le_p(&sess_req->para.algo);
     keytype = ldl_le_p(&sess_req->para.keytype);
     keylen = ldl_le_p(&sess_req->para.keylen);
@@ -224,7 +225,6 @@ virtio_crypto_create_asym_session(VirtIOCrypto *vcrypto,
         iov_discard_front(&iov, &out_num, keylen);
     }
 
-    sreq->info.op_code = opcode;
     asym_info = &sreq->info.u.asym_sess_info;
     asym_info->algo = algo;
     asym_info->keytype = keytype;
Signature · 1 line
MST
#4 lore raw

[PULL 09/63] hw/cxl: Add get scan media results cmd support

In reply to Michael S. Tsirkin

From: Davidlohr Bueso <[email protected]>

Iterate over the list keeping the output payload size into account, returning the results from a previous scan media operation. The scan media operation does not fail prematurely due to device being out of storage, so this implementation does not deal with the retry/restart functionality.

Message-Id: <[email protected]>

---
 include/hw/cxl/cxl_device.h |  1 +
 hw/cxl/cxl-mailbox-utils.c  | 85 +++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+)
include/hw/cxl/cxl_device.h +1 -0
index 0509d961c3..cc98553583 100644
@@ -499,6 +499,7 @@ struct CXLType3Dev {
     /* Poison Injection - backup */
     CXLPoisonList poison_list_bkp;
     CXLPoisonList scan_media_results;
+    bool scan_media_hasrun;
 
     struct dynamic_capacity {
         HostMemoryBackend *host_dc;
hw/cxl/cxl-mailbox-utils.c +85 -0

109 lines not on this page · raw message

Signature · 1 line
MST
#5 lore raw

[PULL 15/63] MAINTAINERS: Add myself as a VT-d reviewer

In reply to Michael S. Tsirkin

From: Yi Liu <[email protected]>

Message-Id: <[email protected]>

---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)
MAINTAINERS +1 -0
index b7e9ced3e8..8ad64ff76b 100644
@@ -3659,6 +3659,7 @@ F: tests/uefi-test-tools/
 VT-d Emulation
 M: Michael S. Tsirkin <[email protected]>
 R: Jason Wang <[email protected]>
+R: Yi Liu <[email protected]>
 S: Supported
 F: hw/i386/intel_iommu.c
 F: hw/i386/intel_iommu_internal.h
Signature · 1 line
MST
#6 lore raw

[PULL 38/63] accel/kvm: Extract common KVM vCPU {creation,parking} code

In reply to Michael S. Tsirkin

From: Salil Mehta <[email protected]>

KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread is spawned. This is common to all the architectures as of now.

Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't support vCPU removal. Therefore, its representative KVM vCPU object/context in Qemu is parked.

Refactor architecture common logic so that some APIs could be reused by vCPU Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs with trace events. New APIs qemu_{create,park,unpark}_vcpu() can be externally called. No functional change is intended here.

Message-Id: <[email protected]>

---
 accel/kvm/kvm-cpus.h   |  1 -
 include/sysemu/kvm.h   | 25 +++++++++++
 accel/kvm/kvm-all.c    | 95 ++++++++++++++++++++++++++++--------------
 accel/kvm/trace-events |  5 ++-
 4 files changed, 92 insertions(+), 34 deletions(-)
accel/kvm/kvm-cpus.h +0 -1
index ca40add32c..171b22fd29 100644
@@ -22,5 +22,4 @@ bool kvm_supports_guest_debug(void);
 int kvm_insert_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len);
 int kvm_remove_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len);
 void kvm_remove_all_breakpoints(CPUState *cpu);
-
 #endif /* KVM_CPUS_H */
include/sysemu/kvm.h +25 -0
index c31d9c7356..c4a914b3d8 100644
@@ -313,6 +313,31 @@ int kvm_create_device(KVMState *s, uint64_t type, bool test);
  */
 bool kvm_device_supported(int vmfd, uint64_t type);
 
+/**
+ * kvm_create_vcpu - Gets a parked KVM vCPU or creates a KVM vCPU
+ * @cpu: QOM CPUState object for which KVM vCPU has to be fetched/created.
+ *
+ * @returns: 0 when success, errno (<0) when failed.
+ */
+int kvm_create_vcpu(CPUState *cpu);
+
+/**
+ * kvm_park_vcpu - Park QEMU KVM vCPU context
+ * @cpu: QOM CPUState object for which QEMU KVM vCPU context has to be parked.
+ *
+ * @returns: none
+ */
+void kvm_park_vcpu(CPUState *cpu);
+
+/**
+ * kvm_unpark_vcpu - unpark QEMU KVM vCPU context
+ * @s: KVM State
+ * @vcpu_id: Architecture vCPU ID of the parked vCPU
+ *
+ * @returns: KVM fd
+ */
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id);
+
 /* Arch specific hooks */
 
 extern const KVMCapabilityInfo kvm_arch_required_capabilities[];
accel/kvm/kvm-all.c +63 -32

130 lines not on this page · raw message

accel/kvm/trace-events +4 -1
index 681ccb667d..37626c1ac5 100644
@@ -9,6 +9,10 @@ kvm_device_ioctl(int fd, int type, void *arg) "dev fd %d, type 0x%x, arg %p"
 kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s"
 kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s"
 kvm_init_vcpu(int cpu_index, unsigned long arch_cpu_id) "index: %d id: %lu"
+kvm_create_vcpu(int cpu_index, unsigned long arch_cpu_id, int kvm_fd) "index: %d, id: %lu, kvm fd: %d"
+kvm_destroy_vcpu(int cpu_index, unsigned long arch_cpu_id) "index: %d id: %lu"
+kvm_park_vcpu(int cpu_index, unsigned long arch_cpu_id) "index: %d id: %lu"
+kvm_unpark_vcpu(unsigned long arch_cpu_id, const char *msg) "id: %lu %s"
 kvm_irqchip_commit_routes(void) ""
 kvm_irqchip_add_msi_route(char *name, int vector, int virq) "dev %s vector %d virq %d"
 kvm_irqchip_update_msi_route(int virq) "Updating MSI route virq=%d"
@@ -25,7 +29,6 @@ kvm_dirty_ring_reaper(const char *s) "%s"
 kvm_dirty_ring_reap(uint64_t count, int64_t t) "reaped %"PRIu64" pages (took %"PRIi64" us)"
 kvm_dirty_ring_reaper_kick(const char *reason) "%s"
 kvm_dirty_ring_flush(int finished) "%d"
-kvm_destroy_vcpu(void) ""
 kvm_failed_get_vcpu_mmap_size(void) ""
 kvm_cpu_exec(void) ""
 kvm_interrupt_exit_request(void) ""
Signature · 1 line
MST
#7 lore raw

[PULL 17/63] virtio-snd: check for invalid param shift operands

In reply to Michael S. Tsirkin

From: Manos Pitsidianakis <[email protected]>

When setting the parameters of a PCM stream, we compute the bit flag with the format and rate values as shift operand to check if they are set in supported_formats and supported_rates.

If the guest provides a format/rate value which when shifting 1 results in a value bigger than the number of bits in supported_formats/supported_rates, we must report an error.

Previously, this ended up triggering the not reached assertions later when converting to internal QEMU values.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2416

Message-Id: <[email protected]>

---
 hw/audio/virtio-snd.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
hw/audio/virtio-snd.c +4 -2
index e6432ac959..e5196aa4bb 100644
@@ -282,11 +282,13 @@ uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
         error_report("Number of channels is not supported.");
         return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP);
     }
-    if (!(supported_formats & BIT(params->format))) {
+    if (BIT(params->format) > sizeof(supported_formats) ||
+        !(supported_formats & BIT(params->format))) {
         error_report("Stream format is not supported.");
         return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP);
     }
-    if (!(supported_rates & BIT(params->rate))) {
+    if (BIT(params->rate) > sizeof(supported_rates) ||
+        !(supported_rates & BIT(params->rate))) {
         error_report("Stream rate is not supported.");
         return cpu_to_le32(VIRTIO_SND_S_NOT_SUPP);
     }
Signature · 1 line
MST
#8 lore raw

[PULL 34/63] virtio-pci: Implement SR-IOV PF

In reply to Michael S. Tsirkin

From: Akihiko Odaki <[email protected]>

Allow user to attach SR-IOV VF to a virtio-pci PF.

Message-Id: <[email protected]>

---
 include/hw/virtio/virtio-pci.h |  1 +
 hw/virtio/virtio-pci.c         | 20 +++++++++++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)
include/hw/virtio/virtio-pci.h +1 -0
index 9e67ba38c7..34539f2f67 100644
@@ -152,6 +152,7 @@ struct VirtIOPCIProxy {
     uint32_t modern_io_bar_idx;
     uint32_t modern_mem_bar_idx;
     int config_cap;
+    uint16_t last_pcie_cap_offset;
     uint32_t flags;
     bool disable_modern;
     bool ignore_backend_features;
hw/virtio/virtio-pci.c +15 -5
index 9534730bba..0c8fcc5627 100644
@@ -1955,6 +1955,7 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
     uint8_t *config;
     uint32_t size;
     VirtIODevice *vdev = virtio_bus_get_device(bus);
+    int16_t res;
 
     /*
      * Virtio capabilities present without
@@ -2100,6 +2101,14 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
         pci_register_bar(&proxy->pci_dev, proxy->legacy_io_bar_idx,
                          PCI_BASE_ADDRESS_SPACE_IO, &proxy->bar);
     }
+
+    res = pcie_sriov_pf_init_from_user_created_vfs(&proxy->pci_dev,
+                                                   proxy->last_pcie_cap_offset,
+                                                   errp);
+    if (res > 0) {
+        proxy->last_pcie_cap_offset += res;
+        virtio_add_feature(&vdev->host_features, VIRTIO_F_SR_IOV);
+    }
 }
 
 static void virtio_pci_device_unplugged(DeviceState *d)
@@ -2187,7 +2196,7 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
 
     if (pcie_port && pci_is_express(pci_dev)) {
         int pos;
-        uint16_t last_pcie_cap_offset = PCI_CONFIG_SPACE_SIZE;
+        proxy->last_pcie_cap_offset = PCI_CONFIG_SPACE_SIZE;
 
         pos = pcie_endpoint_cap_init(pci_dev, 0);
         assert(pos > 0);
@@ -2207,9 +2216,9 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
         pci_set_word(pci_dev->config + pos + PCI_PM_PMC, 0x3);
 
         if (proxy->flags & VIRTIO_PCI_FLAG_AER) {
-            pcie_aer_init(pci_dev, PCI_ERR_VER, last_pcie_cap_offset,
+            pcie_aer_init(pci_dev, PCI_ERR_VER, proxy->last_pcie_cap_offset,
                           PCI_ERR_SIZEOF, NULL);
-            last_pcie_cap_offset += PCI_ERR_SIZEOF;
+            proxy->last_pcie_cap_offset += PCI_ERR_SIZEOF;
         }
 
         if (proxy->flags & VIRTIO_PCI_FLAG_INIT_DEVERR) {
@@ -2234,9 +2243,9 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
         }
 
         if (proxy->flags & VIRTIO_PCI_FLAG_ATS) {
-            pcie_ats_init(pci_dev, last_pcie_cap_offset,
+            pcie_ats_init(pci_dev, proxy->last_pcie_cap_offset,
                           proxy->flags & VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED);
-            last_pcie_cap_offset += PCI_EXT_CAP_ATS_SIZEOF;
+            proxy->last_pcie_cap_offset += PCI_EXT_CAP_ATS_SIZEOF;
         }
 
         if (proxy->flags & VIRTIO_PCI_FLAG_INIT_FLR) {
@@ -2263,6 +2272,7 @@ static void virtio_pci_exit(PCIDevice *pci_dev)
     bool pcie_port = pci_bus_is_express(pci_get_bus(pci_dev)) &&
                      !pci_bus_is_root(pci_get_bus(pci_dev));
 
+    pcie_sriov_pf_exit(&proxy->pci_dev);
     msix_uninit_exclusive_bar(pci_dev);
     if (proxy->flags & VIRTIO_PCI_FLAG_AER && pcie_port &&
         pci_is_express(pci_dev)) {
Signature · 1 line
MST
#9 lore raw

[PULL 18/63] intel_iommu: fix FRCD construction macro

In reply to Michael S. Tsirkin

From: Clément Mathieu--Drif <[email protected]>

The constant must be unsigned, otherwise the two's complement overrides the other fields when a PASID is present.

Fixes 1b2b12376c8a ("intel-iommu: PASID support")

Message-Id: <[email protected]>

---
 hw/i386/intel_iommu_internal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
hw/i386/intel_iommu_internal.h +1 -1
index f8cf99bddf..cbc4030031 100644
@@ -267,7 +267,7 @@
 /* For the low 64-bit of 128-bit */
 #define VTD_FRCD_FI(val)        ((val) & ~0xfffULL)
 #define VTD_FRCD_PV(val)        (((val) & 0xffffULL) << 40)
-#define VTD_FRCD_PP(val)        (((val) & 0x1) << 31)
+#define VTD_FRCD_PP(val)        (((val) & 0x1ULL) << 31)
 #define VTD_FRCD_IR_IDX(val)    (((val) & 0xffffULL) << 48)
 
 /* DMA Remapping Fault Conditions */
Signature · 1 line
MST
#10 lore raw

[PULL 39/63] hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file

In reply to Michael S. Tsirkin

From: Salil Mehta <[email protected]>

CPU ctrl-dev MMIO region length could be used in ACPI GED and various other architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more appropriate common header file.

Message-Id: <[email protected]>

---
 include/hw/acpi/cpu.h | 2 ++
 hw/acpi/cpu.c         | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)
include/hw/acpi/cpu.h +2 -0
index e6e1a9ef59..df87b15997 100644
@@ -19,6 +19,8 @@
 #include "hw/boards.h"
 #include "hw/hotplug.h"
 
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
+
 typedef struct AcpiCpuStatus {
     CPUState *cpu;
     uint64_t arch_id;
hw/acpi/cpu.c +0 -1
index 2d81c1e790..cf5e9183e4 100644
@@ -7,7 +7,6 @@
 #include "trace.h"
 #include "sysemu/numa.h"
 
-#define ACPI_CPU_HOTPLUG_REG_LEN 12
 #define ACPI_CPU_SELECTOR_OFFSET_WR 0
 #define ACPI_CPU_FLAGS_OFFSET_RW 4
 #define ACPI_CPU_CMD_OFFSET_WR 5
Signature · 1 line
MST
#11 lore raw

[PULL 25/63] virtio: virtqueue_ordered_flush - VIRTIO_F_IN_ORDER support

In reply to Michael S. Tsirkin

From: Jonah Palmer <[email protected]>

Add VIRTIO_F_IN_ORDER feature support for the virtqueue_flush operation.

The goal of the virtqueue_ordered_flush operation when the VIRTIO_F_IN_ORDER feature has been negotiated is to write elements to the used/descriptor ring in-order and then update used_idx.

The function iterates through the VirtQueueElement used_elems array in-order starting at vq->used_idx. If the element is valid (filled), the element is written to the used/descriptor ring. This process continues until we find an invalid (not filled) element.

For packed VQs, the first entry (at vq->used_idx) is written to the descriptor ring last so the guest doesn't see any invalid descriptors.

If any elements were written, the used_idx is updated.

Message-Id: <[email protected]>

---
 hw/virtio/virtio.c | 71 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 70 insertions(+), 1 deletion(-)
hw/virtio/virtio.c +70 -1
index 0000a7b41c..397c261c3c 100644
@@ -1023,6 +1023,73 @@ static void virtqueue_packed_flush(VirtQueue *vq, unsigned int count)
     }
 }
 
+static void virtqueue_ordered_flush(VirtQueue *vq)
+{
+    unsigned int i = vq->used_idx % vq->vring.num;
+    unsigned int ndescs = 0;
+    uint16_t old = vq->used_idx;
+    uint16_t new;
+    bool packed;
+    VRingUsedElem uelem;
+
+    packed = virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED);
+
+    if (packed) {
+        if (unlikely(!vq->vring.desc)) {
+            return;
+        }
+    } else if (unlikely(!vq->vring.used)) {
+        return;
+    }
+
+    /* First expected in-order element isn't ready, nothing to do */
+    if (!vq->used_elems[i].in_order_filled) {
+        return;
+    }
+
+    /* Search for filled elements in-order */
+    while (vq->used_elems[i].in_order_filled) {
+        /*
+         * First entry for packed VQs is written last so the guest
+         * doesn't see invalid descriptors.
+         */
+        if (packed && i != vq->used_idx) {
+            virtqueue_packed_fill_desc(vq, &vq->used_elems[i], ndescs, false);
+        } else if (!packed) {
+            uelem.id = vq->used_elems[i].index;
+            uelem.len = vq->used_elems[i].len;
+            vring_used_write(vq, &uelem, i);
+        }
+
+        vq->used_elems[i].in_order_filled = false;
+        ndescs += vq->used_elems[i].ndescs;
+        i += vq->used_elems[i].ndescs;
+        if (i >= vq->vring.num) {
+            i -= vq->vring.num;
+        }
+    }
+
+    if (packed) {
+        virtqueue_packed_fill_desc(vq, &vq->used_elems[vq->used_idx], 0, true);
+        vq->used_idx += ndescs;
+        if (vq->used_idx >= vq->vring.num) {
+            vq->used_idx -= vq->vring.num;
+            vq->used_wrap_counter ^= 1;
+            vq->signalled_used_valid = false;
+        }
+    } else {
+        /* Make sure buffer is written before we update index. */
+        smp_wmb();
+        new = old + ndescs;
+        vring_used_idx_set(vq, new);
+        if (unlikely((int16_t)(new - vq->signalled_used) <
+                     (uint16_t)(new - old))) {
+            vq->signalled_used_valid = false;
+        }
+    }
+    vq->inuse -= ndescs;
+}
+
 void virtqueue_flush(VirtQueue *vq, unsigned int count)
 {
     if (virtio_device_disabled(vq->vdev)) {
@@ -1030,7 +1097,9 @@ void virtqueue_flush(VirtQueue *vq, unsigned int count)
         return;
     }
 
-    if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) {
+    if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_IN_ORDER)) {
+        virtqueue_ordered_flush(vq);
+    } else if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) {
         virtqueue_packed_flush(vq, count);
     } else {
         virtqueue_split_flush(vq, count);
Signature · 1 line
MST
#12 lore raw

[PULL 51/63] hw/riscv/virt-acpi-build.c: Add namespace devices for PLIC and APLIC

In reply to Michael S. Tsirkin

From: Sunil V L <[email protected]>

As per the requirement ACPI_080 in the RISC-V Boot and Runtime Services (BRS) specification [1], PLIC and APLIC should be in namespace as well. So, add them using the defined HID.

[1] - https://github.com/riscv-non-isa/riscv-brs/releases/download/v0.0.2/riscv-brs-spec.pdf

      (Chapter 6)

Message-Id: <[email protected]>

---
 hw/riscv/virt-acpi-build.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
hw/riscv/virt-acpi-build.c +32 -0
index 0925528160..5f5082a35b 100644
@@ -141,6 +141,30 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)
     }
 }
 
+static void acpi_dsdt_add_plic_aplic(Aml *scope, uint8_t socket_count,
+                                     uint64_t mmio_base, uint64_t mmio_size,
+                                     const char *hid)
+{
+    uint64_t plic_aplic_addr;
+    uint32_t gsi_base;
+    uint8_t  socket;
+
+    for (socket = 0; socket < socket_count; socket++) {
+        plic_aplic_addr = mmio_base + mmio_size * socket;
+        gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
+        Aml *dev = aml_device("IC%.02X", socket);
+        aml_append(dev, aml_name_decl("_HID", aml_string("%s", hid)));
+        aml_append(dev, aml_name_decl("_UID", aml_int(socket)));
+        aml_append(dev, aml_name_decl("_GSB", aml_int(gsi_base)));
+
+        Aml *crs = aml_resource_template();
+        aml_append(crs, aml_memory32_fixed(plic_aplic_addr, mmio_size,
+                                           AML_READ_WRITE));
+        aml_append(dev, aml_name_decl("_CRS", crs));
+        aml_append(scope, dev);
+    }
+}
+
 static void
 acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
                     uint32_t uart_irq)
@@ -411,6 +435,14 @@ static void build_dsdt(GArray *table_data,
 
     socket_count = riscv_socket_count(ms);
 
+    if (s->aia_type == VIRT_AIA_TYPE_NONE) {
+        acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_PLIC].base,
+                                 memmap[VIRT_PLIC].size, "RSCV0001");
+    } else {
+        acpi_dsdt_add_plic_aplic(scope, socket_count, memmap[VIRT_APLIC_S].base,
+                                 memmap[VIRT_APLIC_S].size, "RSCV0002");
+    }
+
     acpi_dsdt_add_uart(scope, &memmap[VIRT_UART0], UART0_IRQ);
 
     if (socket_count == 1) {
Signature · 1 line
MST
#13 lore raw

[PULL 28/63] contrib/vhost-user-blk: fix overflowing expression

In reply to Michael S. Tsirkin

From: Stefano Garzarella <[email protected]>

Coverity reported:

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

CID 1549454: Integer handling issues (OVERFLOW_BEFORE_WIDEN) Potentially overflowing expression

"le32_to_cpu(desc->num_sectors) << 9" with type "uint32_t" (32 bits, unsigned) is evaluated using 32-bit arithmetic, and then used in a context that expects an expression of type "uint64_t" (64 bits, unsigned).
199 le32_to_cpu(desc->num_sectors) << 9 };

Coverity noticed this issue after commit ab04420c3 ("contrib/vhost-user-*:
use QEMU bswap helper functions"), but it was pre-existing and introduced from the beginning by commit caa1ee4313 ("vhost-user-blk: add discard/write zeroes features support").

Explicitly cast the 32-bit value before the shift to fix this issue.

Fixes Coverity CID 1549454
Fixes 5ab04420c3 ("contrib/vhost-user-*: use QEMU bswap helper functions")
Fixes caa1ee4313 ("vhost-user-blk: add discard/write zeroes features support")

Message-Id: <[email protected]>

---
 contrib/vhost-user-blk/vhost-user-blk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/vhost-user-blk/vhost-user-blk.c +1 -1
index 9492146855..6cc18a1c04 100644
@@ -196,7 +196,7 @@ vub_discard_write_zeroes(VubReq *req, struct iovec *iov, uint32_t iovcnt,
     VubDev *vdev_blk = req->vdev_blk;
     desc = buf;
     uint64_t range[2] = { le64_to_cpu(desc->sector) << 9,
-                          le32_to_cpu(desc->num_sectors) << 9 };
+                          (uint64_t)le32_to_cpu(desc->num_sectors) << 9 };
     if (type == VIRTIO_BLK_T_DISCARD) {
         if (ioctl(vdev_blk->blk_fd, BLKDISCARD, range) == 0) {
             g_free(buf);
Signature · 1 line
MST
#14 lore raw

[PULL 41/63] hw/acpi: Update GED _EVT method AML with CPU scan

In reply to Michael S. Tsirkin

From: Salil Mehta <[email protected]>

OSPM evaluates _EVT method to map the event. The CPU hotplug event eventually results in start of the CPU scan. Scan figures out the CPU and the kind of event(plug/unplug) and notifies it back to the guest. Update the GED AML _EVT method with the call to method \\_SB.CPUS.CSCN (via \\_SB.GED.CSCN)

Architecture specific code [1] might initialize its CPUs AML code by calling common function build_cpus_aml() like below for ARM:

build_cpus_aml(scope, ms, opts, xx_madt_cpu_entry, memmap[VIRT_CPUHP_ACPI].base,

               "\\_SB", "\\_SB.GED.CSCN", AML_SYSTEM_MEMORY);

[1] https://lore.kernel.org/qemu-devel/[email protected]/

Message-Id: <[email protected]>

---
 include/hw/acpi/generic_event_device.h | 1 +
 hw/acpi/generic_event_device.c         | 3 +++
 2 files changed, 4 insertions(+)
include/hw/acpi/generic_event_device.h +1 -0
index e091ac2108..40af3550b5 100644
@@ -87,6 +87,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
 #define GED_DEVICE      "GED"
 #define AML_GED_EVT_REG "EREG"
 #define AML_GED_EVT_SEL "ESEL"
+#define AML_GED_EVT_CPU_SCAN_METHOD "\\_SB.GED.CSCN"
 
 /*
  * Platforms need to specify the GED event bitmap
hw/acpi/generic_event_device.c +3 -0
index 4641933a0f..15b4c3ebbf 100644
@@ -108,6 +108,9 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
                 aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
                                              MEMORY_SLOT_SCAN_METHOD));
                 break;
+            case ACPI_GED_CPU_HOTPLUG_EVT:
+                aml_append(if_ctx, aml_call0(AML_GED_EVT_CPU_SCAN_METHOD));
+                break;
             case ACPI_GED_PWR_DOWN_EVT:
                 aml_append(if_ctx,
                            aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
Signature · 1 line
MST
#15 lore raw

[PULL 45/63] Revert "virtio-iommu: Clear IOMMUDevice when VFIO device is unplugged"

In reply to Michael S. Tsirkin

From: Eric Auger <[email protected]>

This reverts commit 1b889d6e39c32d709f1114699a014b381bcf1cb1. There are different problems with that tentative fix:
- Some resources are left dangling (resv_regions, host_resv_ranges) and memory subregions are left attached to the root MR although freed as embedded in the sdev IOMMUDevice. Finally the sdev->as is not destroyed and associated listeners are left.
- Even when fixing the above we observe a memory corruption associated with the deallocation of the IOMMUDevice. This can be observed when a VFIO device is hotplugged, hot-unplugged and a system reset is issued. At this stage we have not been able to identify the root cause (IOMMU MR or as structs beeing overwritten and used later on?).
- Another issue is HostIOMMUDevice are indexed by non aliased BDF whereas the IOMMUDevice is indexed by aliased BDF - yes the current naming is really misleading -. Given the state of the code I don't think the virtio-iommu device works in non singleton group case though.

So let's revert the patch for now. This means the IOMMU MR/as survive the hotunplug. This is what is done in the intel_iommu for instance. It does not sound very logical to keep those but currently there is no symetric function to pci_device_iommu_address_space().

probe_done issue will be handled in a subsequent patch. Also resv_regions and host_resv_regions will be deallocated separately.

Message-Id: <[email protected]>

---
 hw/virtio/virtio-iommu.c | 21 ---------------------
 1 file changed, 21 deletions(-)
hw/virtio/virtio-iommu.c +0 -21
index 33ae61c4a6..4e34dacd6e 100644
@@ -467,26 +467,6 @@ static AddressSpace *virtio_iommu_find_add_as(PCIBus *bus, void *opaque,
     return &sdev->as;
 }
 
-static void virtio_iommu_device_clear(VirtIOIOMMU *s, PCIBus *bus, int devfn)
-{
-    IOMMUPciBus *sbus = g_hash_table_lookup(s->as_by_busptr, bus);
-    IOMMUDevice *sdev;
-
-    if (!sbus) {
-        return;
-    }
-
-    sdev = sbus->pbdev[devfn];
-    if (!sdev) {
-        return;
-    }
-
-    g_list_free_full(sdev->resv_regions, g_free);
-    sdev->resv_regions = NULL;
-    g_free(sdev);
-    sbus->pbdev[devfn] = NULL;
-}
-
 static gboolean hiod_equal(gconstpointer v1, gconstpointer v2)
 {
     const struct hiod_key *key1 = v1;
@@ -728,7 +708,6 @@ virtio_iommu_unset_iommu_device(PCIBus *bus, void *opaque, int devfn)
     }
 
     g_hash_table_remove(viommu->host_iommu_devices, &key);
-    virtio_iommu_device_clear(viommu, bus, devfn);
 }
 
 static const PCIIOMMUOps virtio_iommu_ops = {
Signature · 1 line
MST
#16 lore raw

[PULL 21/63] intel_iommu: make type match

In reply to Michael S. Tsirkin

From: Clément Mathieu--Drif <[email protected]>

The 'level' field in vtd_iotlb_key is an unsigned integer. We don't need to store level as an int in vtd_lookup_iotlb.

This is not an issue by itself, but using unsigned here seems cleaner.

Message-Id: <[email protected]>

---
 hw/i386/intel_iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
hw/i386/intel_iommu.c +1 -1
index 37c21a0aec..be0cb39b5c 100644
@@ -358,7 +358,7 @@ static VTDIOTLBEntry *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id,
 {
     struct vtd_iotlb_key key;
     VTDIOTLBEntry *entry;
-    int level;
+    unsigned level;
 
     for (level = VTD_SL_PT_LEVEL; level < VTD_SL_PML4_LEVEL; level++) {
         key.gfn = vtd_get_iotlb_gfn(addr, level);
Signature · 1 line
MST
#17 lore raw

[PULL 14/63] hw/cxl: Support firmware updates

In reply to Michael S. Tsirkin

From: Davidlohr Bueso <[email protected]>

Implement transfer and activate functionality per 3.1 spec for supporting update metadata (no actual buffers). Transfer times are arbitrarily set to ten and two seconds for full and part transfers, respectively.

cxl update-firmware mem0 -F fw.img

<on-going fw update>

cxl update-firmware mem0
"memdev":"mem0",
"pmem_size":"1024.00 MiB (1073.74 MB)",
"serial":"0",
"host":"0000:0d:00.0",

  "firmware":{
    "num_slots":2,
    "active_slot":1,
    "online_activate_capable":true,
    "slot_1_version":"BWFW VERSION 0",
    "fw_update_in_progress":true,
    "remaining_size":22400

}
}

<completed fw update>

cxl update-firmware mem0
{
"memdev":"mem0",
"pmem_size":"1024.00 MiB (1073.74 MB)",
"serial":"0",
"host":"0000:0d:00.0",

  "firmware":{
    "num_slots":2,
    "active_slot":1,
    "staged_slot":2,
    "online_activate_capable":true,
    "slot_1_version":"BWFW VERSION 0",
    "slot_2_version":"BWFW VERSION 1",
    "fw_update_in_progress":false

}
}

Message-Id: <[email protected]>

---
 include/hw/cxl/cxl_device.h |  15 +++
 hw/cxl/cxl-mailbox-utils.c  | 205 +++++++++++++++++++++++++++++++++++-
 2 files changed, 215 insertions(+), 5 deletions(-)
include/hw/cxl/cxl_device.h +15 -0
index 5cae7159e6..fdd0f4e62b 100644
@@ -181,6 +181,21 @@ typedef struct CXLCCI {
         uint64_t runtime;
         QEMUTimer *timer;
     } bg;
+
+    /* firmware update */
+    struct {
+        uint8_t active_slot;
+        uint8_t staged_slot;
+        bool slot[4];
+        uint8_t curr_action;
+        uint8_t curr_slot;
+        /* handle partial transfers */
+        bool transferring;
+        size_t prev_offset;
+        size_t prev_len;
+        time_t last_partxfer;
+    } fw;
+
     size_t payload_max;
     /* Pointer to device hosting the CCI */
     DeviceState *d;
hw/cxl/cxl-mailbox-utils.c +200 -5

252 lines not on this page · raw message

Signature · 1 line
MST
#18 lore raw

[PULL 33/63] pcie_sriov: Allow user to create SR-IOV device

In reply to Michael S. Tsirkin

From: Akihiko Odaki <[email protected]>

A user can create a SR-IOV device by specifying the PF with the sriov-pf property of the VFs. The VFs must be added before the PF.

A user-creatable VF must have PCIDeviceClass::sriov_vf_user_creatable set. Such a VF cannot refer to the PF because it is created before the PF.

A PF that user-creatable VFs can be attached calls pcie_sriov_pf_init_from_user_created_vfs() during realization and pcie_sriov_pf_exit() when exiting.

Message-Id: <[email protected]>

---
 include/hw/pci/pci_device.h |   6 +-
 include/hw/pci/pcie_sriov.h |  18 +++
 hw/pci/pci.c                |  62 +++++---
 hw/pci/pcie_sriov.c         | 290 ++++++++++++++++++++++++++++--------
 4 files changed, 293 insertions(+), 83 deletions(-)
include/hw/pci/pci_device.h +5 -1
index ca15132508..cefd6f7640 100644
@@ -37,6 +37,8 @@ struct PCIDeviceClass {
     uint16_t subsystem_id;              /* only for header type = 0 */
 
     const char *romfile;                /* rom bar */
+
+    bool sriov_vf_user_creatable;
 };
 
 enum PCIReqIDType {
@@ -160,6 +162,8 @@ struct PCIDevice {
     /* ID of standby device in net_failover pair */
     char *failover_pair_id;
     uint32_t acpi_index;
+
+    char *sriov_pf;
 };
 
 static inline int pci_intx(PCIDevice *pci_dev)
@@ -192,7 +196,7 @@ static inline int pci_is_express_downstream_port(const PCIDevice *d)
 
 static inline int pci_is_vf(const PCIDevice *d)
 {
-    return d->exp.sriov_vf.pf != NULL;
+    return d->sriov_pf || d->exp.sriov_vf.pf != NULL;
 }
 
 static inline uint32_t pci_config_size(const PCIDevice *d)
include/hw/pci/pcie_sriov.h +18 -0
index c5d2d318d3..f75b8f22ee 100644
@@ -18,6 +18,7 @@
 typedef struct PCIESriovPF {
     uint8_t vf_bar_type[PCI_NUM_REGIONS];   /* Store type for each VF bar */
     PCIDevice **vf;     /* Pointer to an array of num_vfs VF devices */
+    bool vf_user_created; /* If VFs are created by user */
 } PCIESriovPF;
 
 typedef struct PCIESriovVF {
@@ -40,6 +41,23 @@ void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
 void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
                                 MemoryRegion *memory);
 
+/**
+ * pcie_sriov_pf_init_from_user_created_vfs() - Initialize PF with user-created
+ *                                              VFs.
+ * @dev: A PCIe device being realized.
+ * @offset: The offset of the SR-IOV capability.
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Return: The size of added capability. 0 if the user did not create VFs.
+ *         -1 if failed.
+ */
+int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev,
+                                                 uint16_t offset,
+                                                 Error **errp);
+
+bool pcie_sriov_register_device(PCIDevice *dev, Error **errp);
+void pcie_sriov_unregister_device(PCIDevice *dev);
+
 /*
  * Default (minimal) page size support values
  * as required by the SR/IOV standard:
hw/pci/pci.c +38 -24

112 lines not on this page · raw message

hw/pci/pcie_sriov.c +232 -58

346 lines not on this page · raw message

Signature · 1 line
MST
#19 lore raw

[PULL 36/63] docs: Document composable SR-IOV device

In reply to Michael S. Tsirkin

From: Akihiko Odaki <[email protected]>

Message-Id: <[email protected]>

---
 MAINTAINERS           |  1 +
 docs/system/index.rst |  1 +
 docs/system/sriov.rst | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+)
 create mode 100644 docs/system/sriov.rst
MAINTAINERS +1 -0
index 8ad64ff76b..93546cfb14 100644
@@ -2010,6 +2010,7 @@ F: hw/pci-bridge/*
 F: qapi/pci.json
 F: docs/pci*
 F: docs/specs/*pci*
+F: docs/system/sriov.rst
 
 PCIE DOE
 M: Huai-Cheng Kuo <[email protected]>
docs/system/index.rst +1 -0
index c21065e519..718e9d3c56 100644
@@ -39,3 +39,4 @@ or Hypervisor.Framework.
    multi-process
    confidential-guest-support
    vm-templating
+   sriov
docs/system/sriov.rst new file +36 -0
new file mode 100644
index 0000000000..a851a66a4b
@@ -0,0 +1,36 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Compsable SR-IOV device
+=======================
+
+SR-IOV (Single Root I/O Virtualization) is an optional extended capability of a
+PCI Express device. It allows a single physical function (PF) to appear as
+multiple virtual functions (VFs) for the main purpose of eliminating software
+overhead in I/O from virtual machines.
+
+There are devices with predefined SR-IOV configurations, but it is also possible
+to compose an SR-IOV device yourself. Composing an SR-IOV device is currently
+only supported by virtio-net-pci.
+
+Users can configure an SR-IOV-capable virtio-net device by adding
+virtio-net-pci functions to a bus. Below is a command line example:
+
+.. code-block:: shell
+
+    -netdev user,id=n -netdev user,id=o
+    -netdev user,id=p -netdev user,id=q
+    -device pcie-root-port,id=b
+    -device virtio-net-pci,bus=b,addr=0x0.0x3,netdev=q,sriov-pf=f
+    -device virtio-net-pci,bus=b,addr=0x0.0x2,netdev=p,sriov-pf=f
+    -device virtio-net-pci,bus=b,addr=0x0.0x1,netdev=o,sriov-pf=f
+    -device virtio-net-pci,bus=b,addr=0x0.0x0,netdev=n,id=f
+
+The VFs specify the paired PF with ``sriov-pf`` property. The PF must be
+added after all VFs. It is the user's responsibility to ensure that VFs have
+function numbers larger than one of the PF, and that the function numbers
+have a consistent stride.
+
+You may also need to perform additional steps to activate the SR-IOV feature on
+your guest. For Linux, refer to [1]_.
+
+.. [1] https://docs.kernel.org/PCI/pci-iov-howto.html
Signature · 1 line
MST
#20 lore raw

[PULL 11/63] hw/cxl/cxl-mailbox-utils: Add support for feature commands (8.2.9.6)

In reply to Michael S. Tsirkin

From: Shiju Jose <[email protected]>

CXL spec 3.1 section 8.2.9.6 describes optional device specific features. CXL devices supports features with changeable attributes.
Get Supported Features retrieves the list of supported device specific features. The settings of a feature can be retrieved using Get Feature and optionally modified using Set Feature.

Message-Id: <[email protected]>

---
 include/hw/cxl/cxl_device.h |  10 ++
 hw/cxl/cxl-mailbox-utils.c  | 258 ++++++++++++++++++++++++++++++++++++
 2 files changed, 268 insertions(+)
include/hw/cxl/cxl_device.h +10 -0
index cc98553583..48ed0d9240 100644
@@ -464,6 +464,14 @@ typedef struct CXLDCRegion {
     unsigned long *blk_bitmap;
 } CXLDCRegion;
 
+typedef struct CXLSetFeatureInfo {
+    QemuUUID uuid;
+    uint8_t data_transfer_flag;
+    bool data_saved_across_reset;
+    uint16_t data_offset;
+    size_t data_size;
+} CXLSetFeatureInfo;
+
 struct CXLType3Dev {
     /* Private */
     PCIDevice parent_obj;
@@ -501,6 +509,8 @@ struct CXLType3Dev {
     CXLPoisonList scan_media_results;
     bool scan_media_hasrun;
 
+    CXLSetFeatureInfo set_feat_info;
+
     struct dynamic_capacity {
         HostMemoryBackend *host_dc;
         AddressSpace host_dc_as;
hw/cxl/cxl-mailbox-utils.c +258 -0

276 lines not on this page · raw message

Signature · 1 line
MST
#21 lore raw

[PULL 43/63] physmem: Add helper function to destroy CPU AddressSpace

In reply to Michael S. Tsirkin

From: Salil Mehta <[email protected]>

Virtual CPU Hot-unplug leads to unrealization of a CPU object. This also involves destruction of the CPU AddressSpace. Add common function to help destroy the CPU AddressSpace.

Message-Id: <[email protected]>

---
 include/exec/cpu-common.h |  8 ++++++++
 include/hw/core/cpu.h     |  1 +
 system/physmem.c          | 29 +++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+)
include/exec/cpu-common.h +8 -0
index 815342d043..240ee04369 100644
@@ -129,6 +129,14 @@ size_t qemu_ram_pagesize_largest(void);
  */
 void cpu_address_space_init(CPUState *cpu, int asidx,
                             const char *prefix, MemoryRegion *mr);
+/**
+ * cpu_address_space_destroy:
+ * @cpu: CPU for which address space needs to be destroyed
+ * @asidx: integer index of this address space
+ *
+ * Note that with KVM only one address space is supported.
+ */
+void cpu_address_space_destroy(CPUState *cpu, int asidx);
 
 void cpu_physical_memory_rw(hwaddr addr, void *buf,
                             hwaddr len, bool is_write);
include/hw/core/cpu.h +1 -0
index d946161717..1c9c775df6 100644
@@ -496,6 +496,7 @@ struct CPUState {
     QSIMPLEQ_HEAD(, qemu_work_item) work_list;
 
     struct CPUAddressSpace *cpu_ases;
+    int cpu_ases_count;
     int num_ases;
     AddressSpace *as;
     MemoryRegion *memory;
system/physmem.c +29 -0
index 9a3b3a7636..0e19186e1b 100644
@@ -763,6 +763,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
 
     if (!cpu->cpu_ases) {
         cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
+        cpu->cpu_ases_count = cpu->num_ases;
     }
 
     newas = &cpu->cpu_ases[asidx];
@@ -776,6 +777,34 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
     }
 }
 
+void cpu_address_space_destroy(CPUState *cpu, int asidx)
+{
+    CPUAddressSpace *cpuas;
+
+    assert(cpu->cpu_ases);
+    assert(asidx >= 0 && asidx < cpu->num_ases);
+    /* KVM cannot currently support multiple address spaces. */
+    assert(asidx == 0 || !kvm_enabled());
+
+    cpuas = &cpu->cpu_ases[asidx];
+    if (tcg_enabled()) {
+        memory_listener_unregister(&cpuas->tcg_as_listener);
+    }
+
+    address_space_destroy(cpuas->as);
+    g_free_rcu(cpuas->as, rcu);
+
+    if (asidx == 0) {
+        /* reset the convenience alias for address space 0 */
+        cpu->as = NULL;
+    }
+
+    if (--cpu->cpu_ases_count == 0) {
+        g_free(cpu->cpu_ases);
+        cpu->cpu_ases = NULL;
+    }
+}
+
 AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
 {
     /* Return the AddressSpace corresponding to the specified index */
Signature · 1 line
MST
#22 lore raw

[PULL 04/63] hw/cxl: Check for multiple mappings of memory backends.

In reply to Michael S. Tsirkin

From: Jonathan Cameron <[email protected]>

Similar protection to that provided for -numa memdev=x
to make sure that memory used to back a type3 device is not also mapped as normal RAM, or for multiple type3 devices.

This is an easy footgun to remove and seems multiple people have run into it.

Message-Id: <[email protected]>

---
 hw/mem/cxl_type3.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
hw/mem/cxl_type3.c +15 -0
index 35ac59883a..e7fbbb4d51 100644
@@ -737,6 +737,11 @@ static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp)
             error_setg(errp, "volatile memdev must have backing device");
             return false;
         }
+        if (host_memory_backend_is_mapped(ct3d->hostvmem)) {
+            error_setg(errp, "memory backend %s can't be used multiple times.",
+               object_get_canonical_path_component(OBJECT(ct3d->hostvmem)));
+            return false;
+        }
         memory_region_set_nonvolatile(vmr, false);
         memory_region_set_enabled(vmr, true);
         host_memory_backend_set_mapped(ct3d->hostvmem, true);
@@ -760,6 +765,11 @@ static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp)
             error_setg(errp, "persistent memdev must have backing device");
             return false;
         }
+        if (host_memory_backend_is_mapped(ct3d->hostpmem)) {
+            error_setg(errp, "memory backend %s can't be used multiple times.",
+               object_get_canonical_path_component(OBJECT(ct3d->hostpmem)));
+            return false;
+        }
         memory_region_set_nonvolatile(pmr, true);
         memory_region_set_enabled(pmr, true);
         host_memory_backend_set_mapped(ct3d->hostpmem, true);
@@ -790,6 +800,11 @@ static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp)
             return false;
         }
 
+        if (host_memory_backend_is_mapped(ct3d->dc.host_dc)) {
+            error_setg(errp, "memory backend %s can't be used multiple times.",
+               object_get_canonical_path_component(OBJECT(ct3d->dc.host_dc)));
+            return false;
+        }
         /*
          * Set DC regions as volatile for now, non-volatile support can
          * be added in the future if needed.
Signature · 1 line
MST
#23 lore raw

[PULL 37/63] smbios: make memory device size configurable per Machine

In reply to Michael S. Tsirkin

From: Igor Mammedov <[email protected]>

Currently QEMU describes initial[1] RAM* in SMBIOS as a series of virtual DIMMs (capped at 16Gb max) using type 17 structure entries.

Which is fine for the most cases. However when starting guest with terabytes of RAM this leads to too many memory device structures, which eventually upsets linux kernel as it reserves only 64K for these entries and when that border is crossed out it runs out of reserved memory.

Instead of partitioning initial RAM on 16Gb DIMMs, use maximum possible chunk size that SMBIOS spec allows[2]. Which lets encode RAM in lower 31 bits of 32bit field (which amounts upto 2047Tb per DIMM).
As result initial RAM will generate only one type 17 structure until host/guest reach ability to use more RAM in the future.

Compat changes:
We can't unconditionally change chunk size as it will break QEMU<->guest ABI (and migration). Thus introduce a new machine class field that would let older versioned machines to use legacy 16Gb chunks, while new(er) machine type[s] use maximum possible chunk size.

PS:
While it might seem to be risky to rise max entry size this large (much beyond of what current physical RAM modules support), I'd not expect it causing much issues, modulo uncovering bugs in software running within guest. And those should be fixed on guest side to handle SMBIOS spec properly, especially if guest is expected to support so huge RAM configs.

In worst case, QEMU can reduce chunk size later if we would care enough about introducing a workaround for some 'unfixable' guest OS, either by fixing up the next machine type or giving users a CLI option to customize it.

1) Initial RAM - is RAM configured with help '-m SIZE' CLI option/ implicitly defined by machine. It doesn't include memory configured with help of '-device' option[s] (pcdimm,nvdimm,...)
2) SMBIOS 3.1.0 7.18.5 Memory Device — Extended Size

PS:
* tested on 8Tb host with RHEL6 guest, which seems to parse type 17 SMBIOS table entries correctly (according to 'dmidecode').

Message-Id: <[email protected]>

---
 include/hw/boards.h |  4 ++++
 hw/arm/virt.c       |  1 +
 hw/core/machine.c   |  6 ++++++
 hw/i386/pc_piix.c   |  1 +
 hw/i386/pc_q35.c    |  1 +
 hw/smbios/smbios.c  | 11 ++++++-----
 6 files changed, 19 insertions(+), 5 deletions(-)
include/hw/boards.h +4 -0
index ef6f18f2c1..48ff6d8b93 100644
@@ -237,6 +237,9 @@ typedef struct {
  *    purposes only.
  *    Applies only to default memory backend, i.e., explicit memory backend
  *    wasn't used.
+ * @smbios_memory_device_size:
+ *    Default size of memory device,
+ *    SMBIOS 3.1.0 "7.18 Memory Device (Type 17)"
  */
 struct MachineClass {
     /*< private >*/
@@ -304,6 +307,7 @@ struct MachineClass {
     const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
     int64_t (*get_default_cpu_node_id)(const MachineState *ms, int idx);
     ram_addr_t (*fixup_ram_size)(ram_addr_t size);
+    uint64_t smbios_memory_device_size;
 };
 
 /**
hw/arm/virt.c +1 -0
index b0c68d66a3..719e83e6a1 100644
@@ -3308,6 +3308,7 @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 1)
 static void virt_machine_9_0_options(MachineClass *mc)
 {
     virt_machine_9_1_options(mc);
+    mc->smbios_memory_device_size = 16 * GiB;
     compat_props_add(mc->compat_props, hw_compat_9_0, hw_compat_9_0_len);
 }
 DEFINE_VIRT_MACHINE(9, 0)
hw/core/machine.c +6 -0
index bc38cad7f2..ac30544e7f 100644
@@ -1004,6 +1004,12 @@ static void machine_class_init(ObjectClass *oc, void *data)
     /* Default 128 MB as guest ram size */
     mc->default_ram_size = 128 * MiB;
     mc->rom_file_has_mr = true;
+    /*
+     * SMBIOS 3.1.0 7.18.5 Memory Device — Extended Size
+     * use max possible value that could be encoded into
+     * 'Extended Size' field (2047Tb).
+     */
+    mc->smbios_memory_device_size = 2047 * TiB;
 
     /* numa node memory size aligned on 8MB by default.
      * On Linux, each node's border has to be 8MB aligned
hw/i386/pc_piix.c +1 -0
index 9445b07b4f..d9e69243b4 100644
@@ -495,6 +495,7 @@ static void pc_i440fx_machine_9_0_options(MachineClass *m)
     pc_i440fx_machine_9_1_options(m);
     m->alias = NULL;
     m->is_default = false;
+    m->smbios_memory_device_size = 16 * GiB;
 
     compat_props_add(m->compat_props, hw_compat_9_0, hw_compat_9_0_len);
     compat_props_add(m->compat_props, pc_compat_9_0, pc_compat_9_0_len);
hw/i386/pc_q35.c +1 -0
index 71d3c6d122..9d108b194e 100644
@@ -374,6 +374,7 @@ static void pc_q35_machine_9_0_options(MachineClass *m)
     PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
     pc_q35_machine_9_1_options(m);
     m->alias = NULL;
+    m->smbios_memory_device_size = 16 * GiB;
     compat_props_add(m->compat_props, hw_compat_9_0, hw_compat_9_0_len);
     compat_props_add(m->compat_props, pc_compat_9_0, pc_compat_9_0_len);
     pcmc->isa_bios_alias = false;
hw/smbios/smbios.c +6 -5
index 3b7703489d..a394514264 100644
@@ -1093,6 +1093,7 @@ static bool smbios_get_tables_ep(MachineState *ms,
                        Error **errp)
 {
     unsigned i, dimm_cnt, offset;
+    MachineClass *mc = MACHINE_GET_CLASS(ms);
     ERRP_GUARD();
 
     assert(ep_type == SMBIOS_ENTRY_POINT_TYPE_32 ||
@@ -1123,12 +1124,12 @@ static bool smbios_get_tables_ep(MachineState *ms,
     smbios_build_type_9_table(errp);
     smbios_build_type_11_table();
 
-#define MAX_DIMM_SZ (16 * GiB)
-#define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
-                                        : ((current_machine->ram_size - 1) % MAX_DIMM_SZ) + 1)
+#define GET_DIMM_SZ ((i < dimm_cnt - 1) ? mc->smbios_memory_device_size \
+    : ((current_machine->ram_size - 1) % mc->smbios_memory_device_size) + 1)
 
-    dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size, MAX_DIMM_SZ) /
-               MAX_DIMM_SZ;
+    dimm_cnt = QEMU_ALIGN_UP(current_machine->ram_size,
+                             mc->smbios_memory_device_size) /
+               mc->smbios_memory_device_size;
 
     /*
      * The offset determines if we need to keep additional space between
Signature · 1 line
MST
#24 lore raw

[PULL 24/63] virtio: virtqueue_ordered_fill - VIRTIO_F_IN_ORDER support

In reply to Michael S. Tsirkin

From: Jonah Palmer <[email protected]>

Add VIRTIO_F_IN_ORDER feature support for the virtqueue_fill operation.

The goal of the virtqueue_ordered_fill operation when the VIRTIO_F_IN_ORDER feature has been negotiated is to search for this now-used element, set its length, and mark the element as filled in the VirtQueue's used_elems array.

By marking the element as filled, it will indicate that this element has been processed and is ready to be flushed, so long as the element is in-order.

Message-Id: <[email protected]>

---
 hw/virtio/virtio.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)
hw/virtio/virtio.c +43 -1
index 98eb601b09..0000a7b41c 100644
@@ -872,6 +872,46 @@ static void virtqueue_packed_fill(VirtQueue *vq, const VirtQueueElement *elem,
     vq->used_elems[idx].ndescs = elem->ndescs;
 }
 
+static void virtqueue_ordered_fill(VirtQueue *vq, const VirtQueueElement *elem,
+                                   unsigned int len)
+{
+    unsigned int i, steps, max_steps;
+
+    i = vq->used_idx % vq->vring.num;
+    steps = 0;
+    /*
+     * We shouldn't need to increase 'i' by more than the distance
+     * between used_idx and last_avail_idx.
+     */
+    max_steps = (vq->last_avail_idx - vq->used_idx) % vq->vring.num;
+
+    /* Search for element in vq->used_elems */
+    while (steps <= max_steps) {
+        /* Found element, set length and mark as filled */
+        if (vq->used_elems[i].index == elem->index) {
+            vq->used_elems[i].len = len;
+            vq->used_elems[i].in_order_filled = true;
+            break;
+        }
+
+        i += vq->used_elems[i].ndescs;
+        steps += vq->used_elems[i].ndescs;
+
+        if (i >= vq->vring.num) {
+            i -= vq->vring.num;
+        }
+    }
+
+    /*
+     * We should be able to find a matching VirtQueueElement in
+     * used_elems. If we don't, this is an error.
+     */
+    if (steps >= max_steps) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: %s cannot fill buffer id %u\n",
+                      __func__, vq->vdev->name, elem->index);
+    }
+}
+
 static void virtqueue_packed_fill_desc(VirtQueue *vq,
                                        const VirtQueueElement *elem,
                                        unsigned int idx,
@@ -922,7 +962,9 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
         return;
     }
 
-    if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) {
+    if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_IN_ORDER)) {
+        virtqueue_ordered_fill(vq, elem, len);
+    } else if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) {
         virtqueue_packed_fill(vq, elem, len, idx);
     } else {
         virtqueue_split_fill(vq, elem, len, idx);
Signature · 1 line
MST
#25 lore raw

[PULL 52/63] hw/riscv/virt-acpi-build.c: Update the HID of RISC-V UART

In reply to Michael S. Tsirkin

From: Sunil V L <[email protected]>

The requirement ACPI_060 in the RISC-V BRS specification [1], requires NS16550 compatible UART to have the HID RSCV0003. So, update the HID for the UART.

[1] - https://github.com/riscv-non-isa/riscv-brs/releases/download/v0.0.2/riscv-brs-spec.pdf

       (Chapter 6)

Message-Id: <[email protected]>

---
 hw/riscv/virt-acpi-build.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
hw/riscv/virt-acpi-build.c +1 -1
index 5f5082a35b..36d6a3a412 100644
@@ -170,7 +170,7 @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
                     uint32_t uart_irq)
 {
     Aml *dev = aml_device("COM0");
-    aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501")));
+    aml_append(dev, aml_name_decl("_HID", aml_string("RSCV0003")));
     aml_append(dev, aml_name_decl("_UID", aml_int(0)));
 
     Aml *crs = aml_resource_template();
Signature · 1 line
MST
#26 lore raw

[PULL 54/63] acpi/gpex: Create PCI link devices outside PCI root bridge

In reply to Michael S. Tsirkin

From: Sunil V L <[email protected]>

Currently, PCI link devices (PNP0C0F) are always created within the scope of the PCI root bridge. However, RISC-V needs these link devices to be created outside to ensure the probing order in the OS. This matches the example given in the ACPI specification [1] as well. Hence, create these link devices directly under _SB instead of under the PCI root bridge.

To keep these link device names unique for multiple PCI bridges, change the device name from GSIx to LXXY format where XX is the PCI bus number and Y is the INTx.

GPEX is currently used by riscv, aarch64/virt and x86/microvm machines. So, this change will alter the DSDT for those systems.

[1] - ACPI 5.1: 6.2.13.1 Example: Using _PRT to Describe PCI IRQ Routing

Message-Id: <[email protected]>

---
 hw/pci-host/gpex-acpi.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
hw/pci-host/gpex-acpi.c +7 -6
index f69413ea2c..391fabb8a8 100644
@@ -7,7 +7,8 @@
 #include "hw/pci/pcie_host.h"
 #include "hw/acpi/cxl.h"
 
-static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq)
+static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq,
+                                          Aml *scope, uint8_t bus_num)
 {
     Aml *method, *crs;
     int i, slot_no;
@@ -20,7 +21,7 @@ static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq)
             Aml *pkg = aml_package(4);
             aml_append(pkg, aml_int((slot_no << 16) | 0xFFFF));
             aml_append(pkg, aml_int(i));
-            aml_append(pkg, aml_name("GSI%d", gsi));
+            aml_append(pkg, aml_name("L%.02X%X", bus_num, gsi));
             aml_append(pkg, aml_int(0));
             aml_append(rt_pkg, pkg);
         }
@@ -30,7 +31,7 @@ static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq)
     /* Create GSI link device */
     for (i = 0; i < PCI_NUM_PINS; i++) {
         uint32_t irqs = irq + i;
-        Aml *dev_gsi = aml_device("GSI%d", i);
+        Aml *dev_gsi = aml_device("L%.02X%X", bus_num, i);
         aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F")));
         aml_append(dev_gsi, aml_name_decl("_UID", aml_int(i)));
         crs = aml_resource_template();
@@ -45,7 +46,7 @@ static void acpi_dsdt_add_pci_route_table(Aml *dev, uint32_t irq)
         aml_append(dev_gsi, aml_name_decl("_CRS", crs));
         method = aml_method("_SRS", 1, AML_NOTSERIALIZED);
         aml_append(dev_gsi, method);
-        aml_append(dev, dev_gsi);
+        aml_append(scope, dev_gsi);
     }
 }
 
@@ -174,7 +175,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
                 aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node)));
             }
 
-            acpi_dsdt_add_pci_route_table(dev, cfg->irq);
+            acpi_dsdt_add_pci_route_table(dev, cfg->irq, scope, bus_num);
 
             /*
              * Resources defined for PXBs are composed of the following parts:
@@ -205,7 +206,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg)
     aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device")));
     aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
 
-    acpi_dsdt_add_pci_route_table(dev, cfg->irq);
+    acpi_dsdt_add_pci_route_table(dev, cfg->irq, scope, 0);
 
     method = aml_method("_CBA", 0, AML_NOTSERIALIZED);
     aml_append(method, aml_return(aml_int(cfg->ecam.base)));
Signature · 1 line
MST
#27 lore raw

[PULL 61/63] backends: Initial support for SPDM socket support

In reply to Michael S. Tsirkin

From: Huai-Cheng Kuo <[email protected]>

SPDM enables authentication, attestation and key exchange to assist in providing infrastructure security enablement. It's a standard published by the DMTF [1].

SPDM supports multiple transports, including PCIe DOE and MCTP. This patch adds support to QEMU to connect to an external SPDM instance.

SPDM support can be added to any QEMU device by exposing a TCP socket to a SPDM server. The server can then implement the SPDM decoding/encoding support, generally using libspdm [2].

This is similar to how the current TPM implementation works and means that the heavy lifting of setting up certificate chains, capabilities, measurements and complex crypto can be done outside QEMU by a well supported and tested library.

1: https://www.dmtf.org/standards/SPDM
2: https://github.com/DMTF/libspdm

[ Changes by WM
- Bug fixes from testing
]

[ Changes by AF:
- Convert to be more QEMU-ified
- Move to backends as it isn't PCIe specific
]

Message-Id: <[email protected]>

---
 include/sysemu/spdm-socket.h |  74 ++++++++++++
 backends/spdm-socket.c       | 216 +++++++++++++++++++++++++++++++++++
 MAINTAINERS                  |   6 +
 backends/Kconfig             |   4 +
 backends/meson.build         |   2 +
 5 files changed, 302 insertions(+)
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c
include/sysemu/spdm-socket.h new file +74 -0
new file mode 100644
index 0000000000..5d8bd9aa4e
@@ -0,0 +1,74 @@
+/*
+ * QEMU SPDM socket support
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+/**
+ * spdm_socket_connect: connect to an external SPDM socket
+ * @port: port to connect to
+ * @errp: error object handle
+ *
+ * This will connect to an external SPDM socket server. On error
+ * it will return -1 and errp will be set. On success this function
+ * will return the socket number.
+ */
+int spdm_socket_connect(uint16_t port, Error **errp);
+
+/**
+ * spdm_socket_rsp: send and receive a message to a SPDM server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ * @req: request buffer
+ * @req_len: request buffer length
+ * @rsp: response buffer
+ * @rsp_len: response buffer length
+ *
+ * Send platform data to a SPDM server on socket and then receive
+ * a response.
+ */
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+                         void *req, uint32_t req_len,
+                         void *rsp, uint32_t rsp_len);
+
+/**
+ * spdm_socket_close: send a shutdown command to the server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ *
+ * This will issue a shutdown command to the server.
+ */
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL                0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE  0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE              0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN              0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN                0xFFFF
+#define SPDM_SOCKET_COMMAND_TEST                  0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP           0x01
+#define SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE        0x02
+
+#define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE       0x1200
+
+#endif
backends/spdm-socket.c new file +216 -0

216 lines not on this page · raw message

MAINTAINERS +6 -0
index 93546cfb14..d76b49a597 100644
@@ -3401,6 +3401,12 @@ F: tests/qtest/*tpm*
 F: docs/specs/tpm.rst
 T: git https://github.com/stefanberger/qemu-tpm.git tpm-next
 
+SPDM
+M: Alistair Francis <[email protected]>
+S: Maintained
+F: backends/spdm-socket.c
+F: include/sysemu/spdm-socket.h
+
 Checkpatch
 S: Odd Fixes
 F: scripts/checkpatch.pl
backends/Kconfig +4 -0
index 2cb23f62fa..d3dbe19868 100644
@@ -3,3 +3,7 @@ source tpm/Kconfig
 config IOMMUFD
     bool
     depends on VFIO
+
+config SPDM_SOCKET
+    bool
+    default y
backends/meson.build +2 -0
index 749b491f12..da714b93d1 100644
@@ -33,4 +33,6 @@ endif
 system_ss.add(when: gio, if_true: files('dbus-vmstate.c'))
 system_ss.add(when: 'CONFIG_SGX', if_true: files('hostmem-epc.c'))
 
+system_ss.add(when: 'CONFIG_SPDM_SOCKET', if_true: files('spdm-socket.c'))
+
 subdir('tpm')
Signature · 1 line
MST
#28 lore raw

[PULL 07/63] hw/cxl/mbox: replace sanitize_running() with cxl_dev_media_disabled()

In reply to Michael S. Tsirkin

From: Hyeonggon Yoo <[email protected]>

The spec states that reads/writes should have no effect and a part of commands should be ignored when the media is disabled, not when the sanitize command is running.

Introduce cxl_dev_media_disabled() to check if the media is disabled and replace sanitize_running() with it.

Make sure that the media has been correctly disabled during sanitation by adding an assert to __toggle_media(). Now, enabling when already enabled or vice versa results in an assert() failure.

Message-Id: <[email protected]>

---
 include/hw/cxl/cxl_device.h | 10 +++++-----
 hw/cxl/cxl-mailbox-utils.c  | 29 +++++++++++++++++------------
 hw/mem/cxl_type3.c          |  4 ++--
 3 files changed, 24 insertions(+), 19 deletions(-)
include/hw/cxl/cxl_device.h +5 -5
index b5beb7f90e..42a622197e 100644
@@ -397,16 +397,16 @@ static inline void __toggle_media(CXLDeviceState *cxl_dstate, int val)
 #define cxl_dev_enable_media(cxlds)                     \
         do { __toggle_media((cxlds), 0x1); } while (0)
 
+static inline bool cxl_dev_media_disabled(CXLDeviceState *cxl_dstate)
+{
+    uint64_t dev_status_reg = cxl_dstate->mbox_reg_state64[R_CXL_MEM_DEV_STS];
+    return FIELD_EX64(dev_status_reg, CXL_MEM_DEV_STS, MEDIA_STATUS) == 0x3;
+}
 static inline bool scan_media_running(CXLCCI *cci)
 {
     return !!cci->bg.runtime && cci->bg.opcode == 0x4304;
 }
 
-static inline bool sanitize_running(CXLCCI *cci)
-{
-    return !!cci->bg.runtime && cci->bg.opcode == 0x4400;
-}
-
 typedef struct CXLError {
     QTAILQ_ENTRY(CXLError) node;
     int type; /* Error code as per FE definition */
hw/cxl/cxl-mailbox-utils.c +17 -12
index 8ae9c6a699..522d9aa589 100644
@@ -2108,6 +2108,7 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
     int ret;
     const struct cxl_cmd *cxl_cmd;
     opcode_handler h;
+    CXLDeviceState *cxl_dstate;
 
     *len_out = 0;
     cxl_cmd = &cci->cxl_cmd_set[set][cmd];
@@ -2128,18 +2129,22 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
         return CXL_MBOX_BUSY;
     }
 
-    /* forbid any selected commands while overwriting */
-    if (sanitize_running(cci)) {
-        if (h == cmd_events_get_records ||
-            h == cmd_ccls_get_partition_info ||
-            h == cmd_ccls_set_lsa ||
-            h == cmd_ccls_get_lsa ||
-            h == cmd_logs_get_log ||
-            h == cmd_media_get_poison_list ||
-            h == cmd_media_inject_poison ||
-            h == cmd_media_clear_poison ||
-            h == cmd_sanitize_overwrite) {
-            return CXL_MBOX_MEDIA_DISABLED;
+    /* forbid any selected commands while the media is disabled */
+    if (object_dynamic_cast(OBJECT(cci->d), TYPE_CXL_TYPE3)) {
+        cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
+
+        if (cxl_dev_media_disabled(cxl_dstate)) {
+            if (h == cmd_events_get_records ||
+                h == cmd_ccls_get_partition_info ||
+                h == cmd_ccls_set_lsa ||
+                h == cmd_ccls_get_lsa ||
+                h == cmd_logs_get_log ||
+                h == cmd_media_get_poison_list ||
+                h == cmd_media_inject_poison ||
+                h == cmd_media_clear_poison ||
+                h == cmd_sanitize_overwrite) {
+                return CXL_MBOX_MEDIA_DISABLED;
+            }
         }
     }
 
hw/mem/cxl_type3.c +2 -2
index e763b9bff0..c7910687ae 100644
@@ -1142,7 +1142,7 @@ MemTxResult cxl_type3_read(PCIDevice *d, hwaddr host_addr, uint64_t *data,
         return MEMTX_ERROR;
     }
 
-    if (sanitize_running(&ct3d->cci)) {
+    if (cxl_dev_media_disabled(&ct3d->cxl_dstate)) {
         qemu_guest_getrandom_nofail(data, size);
         return MEMTX_OK;
     }
@@ -1164,7 +1164,7 @@ MemTxResult cxl_type3_write(PCIDevice *d, hwaddr host_addr, uint64_t data,
         return MEMTX_ERROR;
     }
 
-    if (sanitize_running(&ct3d->cci)) {
+    if (cxl_dev_media_disabled(&ct3d->cxl_dstate)) {
         return MEMTX_OK;
     }
 
Signature · 1 line
MST
#29 lore raw

[PULL 13/63] hw/cxl/cxl-mailbox-utils: Add device DDR5 ECS control feature

In reply to Michael S. Tsirkin

From: Shiju Jose <[email protected]>

CXL spec 3.1 section 8.2.9.9.11.2 describes the DDR5 Error Check Scrub (ECS) control feature.

The Error Check Scrub (ECS) is a feature defined in JEDEC DDR5 SDRAM Specification (JESD79-5) and allows the DRAM to internally read, correct single-bit errors, and write back corrected data bits to the DRAM array while providing transparency to error counts. The ECS control feature allows the request to configure ECS input configurations during system boot or at run-time.

The ECS control allows the requester to change the log entry type, the ECS threshold count provided that the request is within the definition specified in DDR5 mode registers, change mode between codeword mode and row count mode, and reset the ECS counter.

Message-Id: <[email protected]>

---
 include/hw/cxl/cxl_device.h | 24 +++++++++++++
 hw/cxl/cxl-mailbox-utils.c  | 71 +++++++++++++++++++++++++++++++++++++
 hw/mem/cxl_type3.c          | 14 ++++++++
 3 files changed, 109 insertions(+)
include/hw/cxl/cxl_device.h +24 -0
index 2c1df25453..5cae7159e6 100644
@@ -447,6 +447,27 @@ typedef struct CXLMemPatrolScrubWriteAttrs {
 #define CXL_MEMDEV_PS_MIN_SCRUB_CYCLE_DEFAULT    1
 #define CXL_MEMDEV_PS_ENABLE_DEFAULT    0
 
+/* CXL memory device DDR5 ECS control attributes */
+typedef struct CXLMemECSReadAttrs {
+        uint8_t ecs_log_cap;
+        uint8_t ecs_cap;
+        uint16_t ecs_config;
+        uint8_t ecs_flags;
+} QEMU_PACKED CXLMemECSReadAttrs;
+
+typedef struct CXLMemECSWriteAttrs {
+   uint8_t ecs_log_cap;
+    uint16_t ecs_config;
+} QEMU_PACKED CXLMemECSWriteAttrs;
+
+#define CXL_ECS_GET_FEATURE_VERSION    0x01
+#define CXL_ECS_SET_FEATURE_VERSION    0x01
+#define CXL_ECS_LOG_ENTRY_TYPE_DEFAULT    0x01
+#define CXL_ECS_REALTIME_REPORT_CAP_DEFAULT    1
+#define CXL_ECS_THRESHOLD_COUNT_DEFAULT    3 /* 3: 256, 4: 1024, 5: 4096 */
+#define CXL_ECS_MODE_DEFAULT    0
+#define CXL_ECS_NUM_MEDIA_FRUS   3 /* Default */
+
 #define DCD_MAX_NUM_REGION 8
 
 typedef struct CXLDCExtentRaw {
@@ -534,6 +555,9 @@ struct CXLType3Dev {
     /* Patrol scrub control attributes */
     CXLMemPatrolScrubReadAttrs patrol_scrub_attrs;
     CXLMemPatrolScrubWriteAttrs patrol_scrub_wr_attrs;
+    /* ECS control attributes */
+    CXLMemECSReadAttrs ecs_attrs[CXL_ECS_NUM_MEDIA_FRUS];
+    CXLMemECSWriteAttrs ecs_wr_attrs[CXL_ECS_NUM_MEDIA_FRUS];
 
     struct dynamic_capacity {
         HostMemoryBackend *host_dc;
hw/cxl/cxl-mailbox-utils.c +71 -0

117 lines not on this page · raw message

hw/mem/cxl_type3.c +14 -0
index 7c583d80f5..d648192ab9 100644
@@ -844,6 +844,7 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
     uint8_t *pci_conf = pci_dev->config;
     unsigned short msix_num = 6;
     int i, rc;
+    uint16_t count;
 
     QTAILQ_INIT(&ct3d->error_list);
 
@@ -917,6 +918,19 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
                            (CXL_MEMDEV_PS_MIN_SCRUB_CYCLE_DEFAULT << 8);
     ct3d->patrol_scrub_attrs.scrub_flags = CXL_MEMDEV_PS_ENABLE_DEFAULT;
 
+    /* Set default value for DDR5 ECS read attributes */
+    for (count = 0; count < CXL_ECS_NUM_MEDIA_FRUS; count++) {
+        ct3d->ecs_attrs[count].ecs_log_cap =
+                            CXL_ECS_LOG_ENTRY_TYPE_DEFAULT;
+        ct3d->ecs_attrs[count].ecs_cap =
+                            CXL_ECS_REALTIME_REPORT_CAP_DEFAULT;
+        ct3d->ecs_attrs[count].ecs_config =
+                            CXL_ECS_THRESHOLD_COUNT_DEFAULT |
+                            (CXL_ECS_MODE_DEFAULT << 3);
+        /* Reserved */
+        ct3d->ecs_attrs[count].ecs_flags = 0;
+    }
+
     return;
 
 err_release_cdat:
Signature · 1 line
MST
#30 lore raw

[PULL 19/63] intel_iommu: move VTD_FRCD_PV and VTD_FRCD_PP declarations

In reply to Michael S. Tsirkin

From: Clément Mathieu--Drif <[email protected]>

These 2 macros are for high 64-bit of the FRCD registers. Declarations have to be moved accordingly.

Message-Id: <[email protected]>

---
 hw/i386/intel_iommu_internal.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
hw/i386/intel_iommu_internal.h +2 -2
index cbc4030031..faea23e8d6 100644
@@ -264,10 +264,10 @@
 #define VTD_FRCD_FR(val)        (((val) & 0xffULL) << 32)
 #define VTD_FRCD_SID_MASK       0xffffULL
 #define VTD_FRCD_SID(val)       ((val) & VTD_FRCD_SID_MASK)
-/* For the low 64-bit of 128-bit */
-#define VTD_FRCD_FI(val)        ((val) & ~0xfffULL)
 #define VTD_FRCD_PV(val)        (((val) & 0xffffULL) << 40)
 #define VTD_FRCD_PP(val)        (((val) & 0x1ULL) << 31)
+/* For the low 64-bit of 128-bit */
+#define VTD_FRCD_FI(val)        ((val) & ~0xfffULL)
 #define VTD_FRCD_IR_IDX(val)    (((val) & 0xffffULL) << 48)
 
 /* DMA Remapping Fault Conditions */
Signature · 1 line
MST
#31 lore raw

[PULL 47/63] virtio-iommu: Free [host_]resv_ranges on unset_iommu_devices

In reply to Michael S. Tsirkin

From: Eric Auger <[email protected]>

We are currently missing the deallocation of the [host_]resv_regions in case of hot unplug. Also to make things more simple let's rule out the case where multiple HostIOMMUDevices would be aliased and attached to the same IOMMUDevice. This allows to remove the handling of conflicting Host reserved regions. Anyway this is not properly supported at guest kernel level. On hotunplug the reserved regions are reset to the ones set by virtio-iommu property.

Message-Id: <[email protected]>

---
 hw/virtio/virtio-iommu.c | 62 ++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 34 deletions(-)
hw/virtio/virtio-iommu.c +28 -34
index 2c54c0d976..2de41ab412 100644
@@ -538,8 +538,6 @@ static int virtio_iommu_set_host_iova_ranges(VirtIOIOMMU *s, PCIBus *bus,
 {
     IOMMUPciBus *sbus = g_hash_table_lookup(s->as_by_busptr, bus);
     IOMMUDevice *sdev;
-    GList *current_ranges;
-    GList *l, *tmp, *new_ranges = NULL;
     int ret = -EINVAL;
 
     if (!sbus) {
@@ -553,33 +551,10 @@ static int virtio_iommu_set_host_iova_ranges(VirtIOIOMMU *s, PCIBus *bus,
         return ret;
     }
 
-    current_ranges = sdev->host_resv_ranges;
-
-    /* check that each new resv region is included in an existing one */
     if (sdev->host_resv_ranges) {
-        range_inverse_array(iova_ranges,
-                            &new_ranges,
-                            0, UINT64_MAX);
-
-        for (tmp = new_ranges; tmp; tmp = tmp->next) {
-            Range *newr = (Range *)tmp->data;
-            bool included = false;
-
-            for (l = current_ranges; l; l = l->next) {
-                Range * r = (Range *)l->data;
-
-                if (range_contains_range(r, newr)) {
-                    included = true;
-                    break;
-                }
-            }
-            if (!included) {
-                goto error;
-            }
-        }
-        /* all new reserved ranges are included in existing ones */
-        ret = 0;
-        goto out;
+        error_setg(errp, "%s virtio-iommu does not support aliased BDF",
+                   __func__);
+        return ret;
     }
 
     range_inverse_array(iova_ranges,
@@ -588,14 +563,31 @@ static int virtio_iommu_set_host_iova_ranges(VirtIOIOMMU *s, PCIBus *bus,
     rebuild_resv_regions(sdev);
 
     return 0;
-error:
-    error_setg(errp, "%s Conflicting host reserved ranges set!",
-               __func__);
-out:
-    g_list_free_full(new_ranges, g_free);
-    return ret;
 }
 
+static void virtio_iommu_unset_host_iova_ranges(VirtIOIOMMU *s, PCIBus *bus,
+                                                int devfn)
+{
+    IOMMUPciBus *sbus = g_hash_table_lookup(s->as_by_busptr, bus);
+    IOMMUDevice *sdev;
+
+    if (!sbus) {
+        return;
+    }
+
+    sdev = sbus->pbdev[devfn];
+    if (!sdev) {
+        return;
+    }
+
+    g_list_free_full(g_steal_pointer(&sdev->host_resv_ranges), g_free);
+    g_list_free_full(sdev->resv_regions, g_free);
+    sdev->host_resv_ranges = NULL;
+    sdev->resv_regions = NULL;
+    add_prop_resv_regions(sdev);
+}
+
+
 static bool check_page_size_mask(VirtIOIOMMU *viommu, uint64_t new_mask,
                                  Error **errp)
 {
@@ -704,6 +696,8 @@ virtio_iommu_unset_iommu_device(PCIBus *bus, void *opaque, int devfn)
     if (!hiod) {
         return;
     }
+    virtio_iommu_unset_host_iova_ranges(viommu, hiod->aliased_bus,
+                                        hiod->aliased_devfn);
 
     g_hash_table_remove(viommu->host_iommu_devices, &key);
 }
Signature · 1 line
MST
#32 lore raw

[PULL 46/63] virtio-iommu: Remove probe_done

In reply to Michael S. Tsirkin

From: Eric Auger <[email protected]>

Now we have switched to PCIIOMMUOps to convey host IOMMU information, the host reserved regions are transmitted when the PCIe topology is built. This happens way before the virtio-iommu driver calls the probe request. So let's remove the probe_done flag that allowed to check the probe was not done before the IOMMU MR got enabled. Besides this probe_done flag had a flaw wrt migration since it was not saved/restored.

The only case at risk is if 2 devices were plugged to a PCIe to PCI bridge and thus aliased. First of all we discovered in the past this case was not properly supported for neither SMMU nor virtio-iommu on guest kernel side: see

[RFC] virtio-iommu: Take into account possible aliasing in virtio_iommu_mr()
https://lore.kernel.org/all/[email protected]/

If this were supported by the guest kernel, it is unclear what the call sequence would be from a virtio-iommu driver point of view.

Message-Id: <[email protected]>

---
 include/hw/virtio/virtio-iommu.h | 1 -
 hw/virtio/virtio-iommu.c         | 3 ---
 2 files changed, 4 deletions(-)
include/hw/virtio/virtio-iommu.h +0 -1
index bdb3da72d0..7db4210b16 100644
@@ -43,7 +43,6 @@ typedef struct IOMMUDevice {
     MemoryRegion bypass_mr;     /* The alias of shared memory MR */
     GList *resv_regions;
     GList *host_resv_ranges;
-    bool probe_done;
 } IOMMUDevice;
 
 typedef struct IOMMUPciBus {
hw/virtio/virtio-iommu.c +0 -3
index 4e34dacd6e..2c54c0d976 100644
@@ -555,8 +555,6 @@ static int virtio_iommu_set_host_iova_ranges(VirtIOIOMMU *s, PCIBus *bus,
 
     current_ranges = sdev->host_resv_ranges;
 
-    g_assert(!sdev->probe_done);
-
     /* check that each new resv region is included in an existing one */
     if (sdev->host_resv_ranges) {
         range_inverse_array(iova_ranges,
@@ -956,7 +954,6 @@ static int virtio_iommu_probe(VirtIOIOMMU *s,
     }
     buf += count;
     free -= count;
-    sdev->probe_done = true;
 
     return VIRTIO_IOMMU_S_OK;
 }
Signature · 1 line
MST
#33 lore raw

[PULL 60/63] hw/pci: Add all Data Object Types defined in PCIe r6.0

In reply to Michael S. Tsirkin

From: Alistair Francis <[email protected]>

Add all of the defined protocols/features from the PCIe-SIG r6.0 "Table 6-32 PCI-SIG defined Data Object Types (Vendor ID = 0001h)" table.

Message-Id: <[email protected]>

---
 include/hw/pci/pcie_doe.h | 2 ++
 1 file changed, 2 insertions(+)
include/hw/pci/pcie_doe.h +2 -0
index 87dc17dcef..15d94661f9 100644
@@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0)
 
 /* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */
 #define PCI_SIG_DOE_DISCOVERY       0x00
+#define PCI_SIG_DOE_CMA             0x01
+#define PCI_SIG_DOE_SECURED_CMA     0x02
 
 #define PCI_DOE_DW_SIZE_MAX         (1 << 18)
 #define PCI_DOE_PROTOCOL_NUM_MAX    256
Signature · 1 line
MST
#34 lore raw

[PULL 48/63] virtio-iommu: Remove the end point on detach

In reply to Michael S. Tsirkin

From: Eric Auger <[email protected]>

We currently miss the removal of the endpoint in case of detach.

Message-Id: <[email protected]>

---
 hw/virtio/virtio-iommu.c | 1 +
 1 file changed, 1 insertion(+)
hw/virtio/virtio-iommu.c +1 -0
index 2de41ab412..440dfa6e92 100644
@@ -786,6 +786,7 @@ static int virtio_iommu_detach(VirtIOIOMMU *s,
     if (QLIST_EMPTY(&domain->endpoint_list)) {
         g_tree_remove(s->domains, GUINT_TO_POINTER(domain->id));
     }
+    g_tree_remove(s->endpoints, GUINT_TO_POINTER(ep_id));
     return VIRTIO_IOMMU_S_OK;
 }
 
Signature · 1 line
MST
#35 lore raw

[PULL 63/63] virtio: Always reset vhost devices

In reply to Michael S. Tsirkin

From: Hanna Czenczek <[email protected]>

Requiring vhost_started to be true for resetting vhost devices in virtio_reset() seems like the wrong condition: Most importantly, the preceding virtio_set_status(vdev, 0) call will (for vhost devices) end up in vhost_dev_stop() (through vhost devices' .set_status implementations), setting vdev->vhost_started = false. Therefore, the gated vhost_reset_device() call is unreachable.

vhost_started is not documented, so it is hard to say what exactly it is supposed to mean, but judging from the fact that vhost_dev_start() sets it and vhost_dev_stop() clears it, it seems like it indicates whether there is a vhost back-end, and whether that back-end is currently running and processing virtio requests.

Making a reset conditional on whether the vhost back-end is processing virtio requests seems wrong; in fact, it is probably better to reset it only when it is not currently processing requests, which is exactly the current order of operations in virtio_reset(): First, the back-end is stopped through virtio_set_status(vdev, 0), then we want to send a reset.

Therefore, we should drop the vhost_started condition, but in its stead we then have to verify that we can indeed send a reset to this vhost device, by not just checking k->get_vhost != NULL (introduced by commit 95e1019a4a9), but also that the vhost back-end is connected (hdev = k->get_vhost(); hdev != NULL && hdev->vhost_ops != NULL).

Message-Id: <[email protected]>

---
 hw/virtio/virtio.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
hw/virtio/virtio.c +6 -2
index 397c261c3c..624fdcae91 100644
@@ -2275,8 +2275,12 @@ void virtio_reset(void *opaque)
         vdev->device_endian = virtio_default_endian();
     }
 
-    if (vdev->vhost_started && k->get_vhost) {
-        vhost_reset_device(k->get_vhost(vdev));
+    if (k->get_vhost) {
+        struct vhost_dev *hdev = k->get_vhost(vdev);
+        /* Only reset when vhost back-end is connected */
+        if (hdev && hdev->vhost_ops) {
+            vhost_reset_device(hdev);
+        }
     }
 
     if (k->reset) {
Signature · 1 line
MST
#36 lore raw

[PULL 03/63] hw/cxl/cxl-mailbox-utils: remove unneeded mailbox output payload space zeroing

In reply to Michael S. Tsirkin

From: Fan Ni <[email protected]>

The whole mailbox output payload space is already zeroed after copying out the input payload, which happens before processing the specific mailbox command:
https://elixir.bootlin.com/qemu/v8.2.1/source/hw/cxl/cxl-device-utils.c#L204

Message-Id: <[email protected]>

---
 hw/cxl/cxl-mailbox-utils.c | 7 -------
 1 file changed, 7 deletions(-)
hw/cxl/cxl-mailbox-utils.c +0 -7
index 74eeb6fde7..facec42dc8 100644
@@ -235,7 +235,6 @@ static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
     log_type = payload_in[0];
 
     pl = (CXLGetEventPayload *)payload_out;
-    memset(pl, 0, sizeof(*pl));
 
     max_recs = (cxlds->payload_size - CXL_EVENT_PAYLOAD_HDR_SIZE) /
                 CXL_EVENT_RECORD_SIZE;
@@ -273,7 +272,6 @@ static CXLRetCode cmd_events_get_interrupt_policy(const struct cxl_cmd *cmd,
     CXLEventLog *log;
 
     policy = (CXLEventInterruptPolicy *)payload_out;
-    memset(policy, 0, sizeof(*policy));
 
     log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
     if (log->irq_enabled) {
@@ -372,7 +370,6 @@ static CXLRetCode cmd_infostat_identify(const struct cxl_cmd *cmd,
     QEMU_BUILD_BUG_ON(sizeof(*is_identify) != 18);
 
     is_identify = (void *)payload_out;
-    memset(is_identify, 0, sizeof(*is_identify));
     is_identify->pcie_vid = class->vendor_id;
     is_identify->pcie_did = class->device_id;
     if (object_dynamic_cast(OBJECT(cci->d), TYPE_CXL_USP)) {
@@ -606,7 +603,6 @@ static CXLRetCode cmd_infostat_bg_op_sts(const struct cxl_cmd *cmd,
     QEMU_BUILD_BUG_ON(sizeof(*bg_op_status) != 8);
 
     bg_op_status = (void *)payload_out;
-    memset(bg_op_status, 0, sizeof(*bg_op_status));
     bg_op_status->status = cci->bg.complete_pct << 1;
     if (cci->bg.runtime > 0) {
         bg_op_status->status |= 1U << 0;
@@ -647,7 +643,6 @@ static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
     }
 
     fw_info = (void *)payload_out;
-    memset(fw_info, 0, sizeof(*fw_info));
 
     fw_info->slots_supported = 2;
     fw_info->slot_info = BIT(0) | BIT(3);
@@ -805,7 +800,6 @@ static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
     }
 
     id = (void *)payload_out;
-    memset(id, 0, sizeof(*id));
 
     snprintf(id->fw_revision, 0x10, "BWFW VERSION %02d", 0);
 
@@ -1095,7 +1089,6 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
     out_pl_len = sizeof(*out) + record_count * sizeof(out->records[0]);
     assert(out_pl_len <= CXL_MAILBOX_MAX_PAYLOAD_SIZE);
 
-    memset(out, 0, out_pl_len);
     QLIST_FOREACH(ent, poison_list, node) {
         uint64_t start, stop;
 
Signature · 1 line
MST
#37 lore raw

[PULL 50/63] virtio-iommu: Add trace point on virtio_iommu_detach_endpoint_from_domain

In reply to Michael S. Tsirkin

From: Eric Auger <[email protected]>

Add a trace point on virtio_iommu_detach_endpoint_from_domain().

Message-Id: <[email protected]>

---
 hw/virtio/virtio-iommu.c | 1 +
 hw/virtio/trace-events   | 1 +
 2 files changed, 2 insertions(+)
hw/virtio/virtio-iommu.c +1 -0
index 440dfa6e92..59ef4fb217 100644
@@ -308,6 +308,7 @@ static void virtio_iommu_detach_endpoint_from_domain(VirtIOIOMMUEndpoint *ep)
     if (!ep->domain) {
         return;
     }
+    trace_virtio_iommu_detach_endpoint_from_domain(domain->id, ep->id);
     g_tree_foreach(domain->mappings, virtio_iommu_notify_unmap_cb,
                    ep->iommu_mr);
     QLIST_REMOVE(ep, next);
hw/virtio/trace-events +1 -0
index b7c04f0856..04e36ae047 100644
@@ -116,6 +116,7 @@ virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t end, u
 virtio_iommu_set_config(uint8_t bypass) "bypass=0x%x"
 virtio_iommu_attach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
 virtio_iommu_detach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
+virtio_iommu_detach_endpoint_from_domain(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
 virtio_iommu_map(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end, uint64_t phys_start, uint32_t flags) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64 " phys_start=0x%"PRIx64" flags=%d"
 virtio_iommu_unmap(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64
 virtio_iommu_unmap_done(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64
Signature · 1 line
MST
#38 lore raw

[PULL 55/63] tests/acpi: update expected DSDT blob for aarch64 and microvm

In reply to Michael S. Tsirkin

From: Sunil V L <[email protected]>

After PCI link devices are moved out of the scope of PCI root complex, the DSDT files of machines which use GPEX, will change. So, update the expected AML files with these changes for these machines.

Mainly, there are 2 changes.

1) Since the link devices are created now directly under _SB for all PCI root bridges in the system, they should have unique names. So, instead of GSIx, named those devices as LXXY where L means link, XX will have PCI bus number and Y will have the INTx number (ex: L000 or L001). The _PRT entries will also be updated to reflect this name change.

2) PCI link devices are moved from the scope of each PCI root bridge to directly under _SB.

Below is the sample iASL difference for one such link device.

Scope (\_SB)

{
    Name (_HID, "LNRO0005")  // _HID: Hardware ID
    Name (_UID, 0x1F)  // _UID: Unique ID
    Name (_CCA, One)  // _CCA: Cache Coherency Attribute
    Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
    {
        Memory32Fixed (ReadWrite,
            0x0A003E00,         // Address Base
            0x00000200,         // Address Length
            )
        Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
        {
            0x0000004F,
        }
    })

+ Device (L000)
+ {

+       Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */)
+       Name (_UID, Zero)  // _UID: Unique ID
+       Name (_PRS, ResourceTemplate ()
+       {

+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
+ {
+ 0x00000023,
+ }

+       })
+       Name (_CRS, ResourceTemplate ()
+       {

+ Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
+ {
+ 0x00000023,
+ }

+       })
+       Method (_SRS, 1, NotSerialized)  // _SRS: Set Resource Settings
+       {
+       }
+   }
+
      Device (PCI0)
      {
          Name (_HID, "PNP0A08" /* PCI Express Bus */)  // _HID: Hardware ID
          Name (_CID, "PNP0A03" /* PCI Bus */)  // _CID: Compatible ID
          Name (_SEG, Zero)  // _SEG: PCI Segment
          Name (_BBN, Zero)  // _BBN: BIOS Bus Number
          Name (_UID, Zero)  // _UID: Unique ID
          Name (_STR, Unicode ("PCIe 0 Device"))  // _STR: Description String
          Name (_CCA, One)  // _CCA: Cache Coherency Attribute
          Name (_PRT, Package (0x80)  // _PRT: PCI Routing Table
          {

              Package (0x04)
              {
                  0xFFFF,
                  Zero,
-                 GSI0,
+                 L000,
                  Zero
              },

               .....

          })

          Device (GSI0)
          {
              Name (_HID, "PNP0C0F" /* PCI Interrupt Link Device */)
              Name (_UID, Zero)  // _UID: Unique ID
              Name (_PRS, ResourceTemplate ()
              {
                 Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
                 {
                     0x00000023,
                 }
              })
              Name (_CRS, ResourceTemplate ()
              {
                 Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, )
                 {
                     0x00000023,
                 }
              })
              Method (_SRS, 1, NotSerialized)  // _SRS: Set Resource Settings
              {
              }
          }
      }
}

Message-Id: <[email protected]>

---
 tests/qtest/bios-tables-test-allowed-diff.h   |   6 ------
 tests/data/acpi/aarch64/virt/DSDT             | Bin 5196 -> 5196 bytes
 .../data/acpi/aarch64/virt/DSDT.acpihmatvirt  | Bin 5282 -> 5282 bytes
 tests/data/acpi/aarch64/virt/DSDT.memhp       | Bin 6557 -> 6557 bytes
 tests/data/acpi/aarch64/virt/DSDT.pxb         | Bin 7679 -> 7679 bytes
 tests/data/acpi/aarch64/virt/DSDT.topology    | Bin 5398 -> 5398 bytes
 tests/data/acpi/x86/microvm/DSDT.pcie         | Bin 3023 -> 3023 bytes
 7 files changed, 6 deletions(-)
tests/qtest/bios-tables-test-allowed-diff.h +0 -6
index 9282ea0fb2..dfb8523c8b 100644
@@ -1,7 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/aarch64/virt/DSDT",
-"tests/data/acpi/aarch64/virt/DSDT.memhp",
-"tests/data/acpi/aarch64/virt/DSDT.topology",
-"tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt",
-"tests/data/acpi/aarch64/virt/DSDT.pxb",
-"tests/data/acpi/x86/microvm/DSDT.pcie",
tests/data/acpi/aarch64/virt/DSDT binary +0 -0
index c47503990715d389914fdf9c8bccb510761741ac..36d3e5d5a5e47359b6dcb3706f98b4f225677591 100644
GIT binary patch
tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt binary +0 -0
index aee6ba017cd730948bfa93e91551eb10a6809293..e6154d0355f84fdcc51387b4db8f9ee63acae4e9 100644
GIT binary patch
tests/data/acpi/aarch64/virt/DSDT.memhp binary +0 -0
index bae36cdd397473afe3923c52f030641a5ab19d5d..33f011d6b635035a04c0b39ce9b4e219f7ae74b7 100644
GIT binary patch
tests/data/acpi/aarch64/virt/DSDT.pxb binary +0 -0
index fbd78f44c4785d19759daea909fe6d6f9a6e6b01..c0fdc6e9c1396cc2259dc4bc665ba023adcf4c9b 100644
GIT binary patch
tests/data/acpi/aarch64/virt/DSDT.topology binary +0 -0
index 501314c91be01d927fd125e0c72e919fdd85592e..029d03eecc4efddc001e5377e85ac8e831294362 100644
GIT binary patch
tests/data/acpi/x86/microvm/DSDT.pcie binary +0 -0
index 765f14ef3d1e54d3cadccbf0a880f8adb73b3f1f..8eacd21d6ecdf9a3cd3e4f03cf1b40748dcbf53e 100644
GIT binary patch
Signature · 1 line
MST
#39 lore raw

[PULL 56/63] tests/qtest/bios-tables-test.c: Remove the fall back path

In reply to Michael S. Tsirkin

From: Sunil V L <[email protected]>

The expected ACPI AML files are moved now under ${arch}/{machine} path. Hence, there is no need to search in old path which didn't have ${arch}. Remove the code which searches for the expected AML files under old path as well.

Message-Id: <[email protected]>

---
 tests/qtest/bios-tables-test.c | 14 --------------
 1 file changed, 14 deletions(-)
tests/qtest/bios-tables-test.c +0 -14
index f4c4704bab..498e0e35d9 100644
@@ -267,15 +267,6 @@ static void dump_aml_files(test_data *data, bool rebuild)
                                        data->arch, data->machine,
                                        sdt->aml, ext);
 
-            /*
-             * To keep test cases not failing before the DATA files are moved to
-             * ${arch}/${machine} folder, add this check as well.
-             */
-            if (!g_file_test(aml_file, G_FILE_TEST_EXISTS)) {
-                aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir,
-                                           data->machine, sdt->aml, ext);
-            }
-
             if (!g_file_test(aml_file, G_FILE_TEST_EXISTS) &&
                 sdt->aml_len == exp_sdt->aml_len &&
                 !memcmp(sdt->aml, exp_sdt->aml, sdt->aml_len)) {
@@ -412,11 +403,6 @@ static GArray *load_expected_aml(test_data *data)
 try_again:
         aml_file = g_strdup_printf("%s/%s/%s/%.4s%s", data_dir, data->arch,
                                    data->machine, sdt->aml, ext);
-        if (!g_file_test(aml_file, G_FILE_TEST_EXISTS)) {
-            aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
-                                       sdt->aml, ext);
-        }
-
         if (verbosity_level >= 2) {
             fprintf(stderr, "Looking for expected file '%s'\n", aml_file);
         }
Signature · 1 line
MST
#40 lore raw

[PULL 42/63] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change

In reply to Michael S. Tsirkin

From: Salil Mehta <[email protected]>

CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is IO port based and existing CPUs AML code assumes _CRS objects would evaluate to a system resource which describes IO Port address. But on ARM arch CPUs control device(\\_SB.PRES) register interface is memory-mapped hence _CRS object should evaluate to system resource which describes memory-mapped base address. Update build CPUs AML function to accept both IO/MEMORY region spaces and accordingly update the _CRS object.

Message-Id: <[email protected]>

---
 include/hw/acpi/cpu.h |  5 +++--
 hw/acpi/cpu.c         | 17 +++++++++++++----
 hw/i386/acpi-build.c  |  3 ++-
 3 files changed, 18 insertions(+), 7 deletions(-)
include/hw/acpi/cpu.h +3 -2
index df87b15997..32654dc274 100644
@@ -63,9 +63,10 @@ typedef void (*build_madt_cpu_fn)(int uid, const CPUArchIdList *apic_ids,
                                   GArray *entry, bool force_enabled);
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-                    build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+                    build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
                     const char *res_root,
-                    const char *event_handler_method);
+                    const char *event_handler_method,
+                    AmlRegionSpace rs);
 
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
 
hw/acpi/cpu.c +13 -4
index cf5e9183e4..5cb60ca8bc 100644
@@ -338,9 +338,10 @@ const VMStateDescription vmstate_cpu_hotplug = {
 #define CPU_FW_EJECT_EVENT "CEJF"
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
-                    build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+                    build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
                     const char *res_root,
-                    const char *event_handler_method)
+                    const char *event_handler_method,
+                    AmlRegionSpace rs)
 {
     Aml *ifctx;
     Aml *field;
@@ -364,14 +365,22 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
             aml_name_decl("_UID", aml_string("CPU Hotplug resources")));
         aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
 
+        assert((rs == AML_SYSTEM_IO) || (rs == AML_SYSTEM_MEMORY));
+
         crs = aml_resource_template();
-        aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1,
+        if (rs == AML_SYSTEM_IO) {
+            aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr, 1,
                                ACPI_CPU_HOTPLUG_REG_LEN));
+        } else if (rs == AML_SYSTEM_MEMORY) {
+            aml_append(crs, aml_memory32_fixed(base_addr,
+                               ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
+        }
+
         aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs));
 
         /* declare CPU hotplug MMIO region with related access fields */
         aml_append(cpu_ctrl_dev,
-            aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base),
+            aml_operation_region("PRST", rs, aml_int(base_addr),
                                  ACPI_CPU_HOTPLUG_REG_LEN));
 
         field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK,
hw/i386/acpi-build.c +2 -1
index f4e366f64f..5d4bd2b710 100644
@@ -1536,7 +1536,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
             .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
         };
         build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
-                       pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02");
+                       pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02",
+                       AML_SYSTEM_IO);
     }
 
     if (pcms->memhp_io_base && nr_mem) {
Signature · 1 line
MST
#41 lore raw

[PULL 16/63] virtio-snd: add max size bounds check in input cb

In reply to Michael S. Tsirkin

From: Manos Pitsidianakis <[email protected]>

When reading input audio in the virtio-snd input callback, virtio_snd_pcm_in_cb(), we do not check whether the iov can actually fit the data buffer. This is because we use the buffer->size field as a total-so-far accumulator instead of byte-size-left like in TX buffers.

This triggers an out of bounds write if the size of the virtio queue element is equal to virtio_snd_pcm_status, which makes the available space for audio data zero. This commit adds a check for reaching the maximum buffer size before attempting any writes.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2427

Message-Id: <[email protected]>

---
 hw/audio/virtio-snd.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
hw/audio/virtio-snd.c +6 -1
index 5993f4f040..e6432ac959 100644
@@ -1261,7 +1261,7 @@ static void virtio_snd_pcm_in_cb(void *data, int available)
 {
     VirtIOSoundPCMStream *stream = data;
     VirtIOSoundPCMBuffer *buffer;
-    size_t size;
+    size_t size, max_size;
 
     WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
         while (!QSIMPLEQ_EMPTY(&stream->queue)) {
@@ -1275,7 +1275,12 @@ static void virtio_snd_pcm_in_cb(void *data, int available)
                 continue;
             }
 
+            max_size = iov_size(buffer->elem->in_sg, buffer->elem->in_num);
             for (;;) {
+                if (buffer->size >= max_size) {
+                    return_rx_buffer(stream, buffer);
+                    break;
+                }
                 size = AUD_read(stream->voice.in,
                         buffer->data + buffer->size,
                         MIN(available, (stream->params.period_bytes -
Signature · 1 line
MST
#42 lore raw

[PULL 06/63] hw/cxl: Add get scan media capabilities cmd support

In reply to Michael S. Tsirkin

From: Davidlohr Bueso <[email protected]>

Use simple heuristics to determine the cost of scanning any given chunk, assuming cost is equal across the whole device, without differentiating between volatile or persistent partitions. This is aligned to the fact that these constraints are not enforced in respective poison query commands.

Message-Id: <[email protected]>

---
 include/hw/cxl/cxl_device.h |   9 ++
 hw/cxl/cxl-mailbox-utils.c  | 211 +++++++++++++++++++++++++++++++++++-
 hw/mem/cxl_type3.c          |  22 ++--
 3 files changed, 233 insertions(+), 9 deletions(-)
include/hw/cxl/cxl_device.h +9 -0
index 0a4fcb2800..b5beb7f90e 100644
@@ -397,6 +397,11 @@ static inline void __toggle_media(CXLDeviceState *cxl_dstate, int val)
 #define cxl_dev_enable_media(cxlds)                     \
         do { __toggle_media((cxlds), 0x1); } while (0)
 
+static inline bool scan_media_running(CXLCCI *cci)
+{
+    return !!cci->bg.runtime && cci->bg.opcode == 0x4304;
+}
+
 static inline bool sanitize_running(CXLCCI *cci)
 {
     return !!cci->bg.runtime && cci->bg.opcode == 0x4400;
@@ -491,6 +496,9 @@ struct CXLType3Dev {
     unsigned int poison_list_cnt;
     bool poison_list_overflowed;
     uint64_t poison_list_overflow_ts;
+    /* Poison Injection - backup */
+    CXLPoisonList poison_list_bkp;
+    CXLPoisonList scan_media_results;
 
     struct dynamic_capacity {
         HostMemoryBackend *host_dc;
@@ -558,6 +566,7 @@ CXLRetCode cxl_event_clear_records(CXLDeviceState *cxlds,
 void cxl_event_irq_assert(CXLType3Dev *ct3d);
 
 void cxl_set_poison_list_overflowed(CXLType3Dev *ct3d);
+void cxl_clear_poison_list_overflowed(CXLType3Dev *ct3d);
 
 CXLDCRegion *cxl_find_dc_region(CXLType3Dev *ct3d, uint64_t dpa, uint64_t len);
 
hw/cxl/cxl-mailbox-utils.c +209 -2

271 lines not on this page · raw message

hw/mem/cxl_type3.c +15 -7
index e7fbbb4d51..e763b9bff0 100644
@@ -1319,6 +1319,12 @@ void cxl_set_poison_list_overflowed(CXLType3Dev *ct3d)
             cxl_device_get_timestamp(&ct3d->cxl_dstate);
 }
 
+void cxl_clear_poison_list_overflowed(CXLType3Dev *ct3d)
+{
+    ct3d->poison_list_overflowed = false;
+    ct3d->poison_list_overflow_ts = 0;
+}
+
 void qmp_cxl_inject_poison(const char *path, uint64_t start, uint64_t length,
                            Error **errp)
 {
@@ -1355,19 +1361,21 @@ void qmp_cxl_inject_poison(const char *path, uint64_t start, uint64_t length,
         }
     }
 
-    if (ct3d->poison_list_cnt == CXL_POISON_LIST_LIMIT) {
-        cxl_set_poison_list_overflowed(ct3d);
-        return;
-    }
-
     p = g_new0(CXLPoison, 1);
     p->length = length;
     p->start = start;
     /* Different from injected via the mbox */
     p->type = CXL_POISON_TYPE_INTERNAL;
 
-    QLIST_INSERT_HEAD(&ct3d->poison_list, p, node);
-    ct3d->poison_list_cnt++;
+    if (ct3d->poison_list_cnt < CXL_POISON_LIST_LIMIT) {
+        QLIST_INSERT_HEAD(&ct3d->poison_list, p, node);
+        ct3d->poison_list_cnt++;
+    } else {
+        if (!ct3d->poison_list_overflowed) {
+            cxl_set_poison_list_overflowed(ct3d);
+        }
+        QLIST_INSERT_HEAD(&ct3d->poison_list_bkp, p, node);
+    }
 }
 
 /* For uncorrectable errors include support for multiple header recording */
Signature · 1 line
MST
#43 lore raw

[PULL 20/63] intel_iommu: fix type of the mask field in VTDIOTLBPageInvInfo

In reply to Michael S. Tsirkin

From: Clément Mathieu--Drif <[email protected]>

Per the below code, it can overflow as am can be larger than 8 according to the CH 6.5.2.3 IOTLB Invalidate. Use uint64_t to avoid overflows.

Fixes b5a280c00840 ("intel-iommu: add IOTLB using hash table")

Message-Id: <[email protected]>

---
 hw/i386/intel_iommu_internal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
hw/i386/intel_iommu_internal.h +1 -1
index faea23e8d6..5f32c36943 100644
@@ -436,7 +436,7 @@ struct VTDIOTLBPageInvInfo {
     uint16_t domain_id;
     uint32_t pasid;
     uint64_t addr;
-    uint8_t mask;
+    uint64_t mask;
 };
 typedef struct VTDIOTLBPageInvInfo VTDIOTLBPageInvInfo;
 
Signature · 1 line
MST
#44 lore raw

[PULL 31/63] pcie_sriov: Ensure PF and VF are mutually exclusive

In reply to Michael S. Tsirkin

From: Akihiko Odaki <[email protected]>

A device cannot be a SR-IOV PF and a VF at the same time.

Message-Id: <[email protected]>

---
 hw/pci/pcie_sriov.c | 5 +++++
 1 file changed, 5 insertions(+)
hw/pci/pcie_sriov.c +5 -0
index 56523ab4e8..6c79658b4c 100644
@@ -42,6 +42,11 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
     uint8_t *cfg = dev->config + offset;
     uint8_t *wmask;
 
+    if (pci_is_vf(dev)) {
+        error_setg(errp, "a device cannot be both an SR-IOV PF and a VF");
+        return false;
+    }
+
     if (total_vfs) {
         uint16_t ari_cap = pcie_find_capability(dev, PCI_EXT_CAP_ID_ARI);
         uint16_t first_vf_devfn = dev->devfn + vf_offset;
Signature · 1 line
MST
#45 lore raw

[PULL 44/63] gdbstub: Add helper function to unregister GDB register space

In reply to Michael S. Tsirkin

From: Salil Mehta <[email protected]>

Add common function to help unregister the GDB register space. This shall be done in context to the CPU unrealization.

Note: These are common functions exported to arch specific code. For example, for ARM this code is being referred in associated arch specific patch-set:

Message-Id: <[email protected]>

---
 include/exec/gdbstub.h |  6 ++++++
 gdbstub/gdbstub.c      | 13 +++++++++++++
 hw/core/cpu-common.c   |  5 ++++-
 3 files changed, 23 insertions(+), 1 deletion(-)
include/exec/gdbstub.h +6 -0
index 1bd2c4ec2a..d73f424f56 100644
@@ -40,6 +40,12 @@ void gdb_register_coprocessor(CPUState *cpu,
                               gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
                               const GDBFeature *feature, int g_pos);
 
+/**
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
+ * @cpu - the CPU associated with registers
+ */
+void gdb_unregister_coprocessor_all(CPUState *cpu);
+
 /**
  * gdbserver_start: start the gdb server
  * @port_or_device: connection spec for gdb
gdbstub/gdbstub.c +13 -0
index b9ad0a063e..5da17d6530 100644
@@ -618,6 +618,19 @@ void gdb_register_coprocessor(CPUState *cpu,
     }
 }
 
+void gdb_unregister_coprocessor_all(CPUState *cpu)
+{
+    /*
+     * Safe to nuke everything. GDBRegisterState::xml is static const char so
+     * it won't be freed
+     */
+    g_array_free(cpu->gdb_regs, true);
+
+    cpu->gdb_regs = NULL;
+    cpu->gdb_num_regs = 0;
+    cpu->gdb_num_g_regs = 0;
+}
+
 static void gdb_process_breakpoint_remove_all(GDBProcess *p)
 {
     CPUState *cpu = gdb_get_first_cpu_in_process(p);
hw/core/cpu-common.c +4 -1
index d2e3e4570a..7982ecd39a 100644
@@ -282,7 +282,10 @@ static void cpu_common_finalize(Object *obj)
     }
 #endif
     free_queued_cpu_work(cpu);
-    g_array_free(cpu->gdb_regs, TRUE);
+    /* If cleanup didn't happen in context to gdb_unregister_coprocessor_all */
+    if (cpu->gdb_regs) {
+        g_array_free(cpu->gdb_regs, TRUE);
+    }
     qemu_lockcnt_destroy(&cpu->in_ioctl_lock);
     qemu_mutex_destroy(&cpu->work_mutex);
     qemu_cond_destroy(cpu->halt_cond);
Signature · 1 line
MST
#46 lore raw

[PULL 23/63] virtio: virtqueue_pop - VIRTIO_F_IN_ORDER support

In reply to Michael S. Tsirkin

From: Jonah Palmer <[email protected]>

Add VIRTIO_F_IN_ORDER feature support in virtqueue_split_pop and virtqueue_packed_pop.

VirtQueueElements popped from the available/descritpor ring are added to the VirtQueue's used_elems array in-order and in the same fashion as they would be added the used and descriptor rings, respectively.

This will allow us to keep track of the current order, what elements have been written, as well as an element's essential data after being processed.

Message-Id: <[email protected]>

---
 hw/virtio/virtio.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
hw/virtio/virtio.c +15 -1
index 583a224163..98eb601b09 100644
@@ -1505,7 +1505,7 @@ static void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_nu
 
 static void *virtqueue_split_pop(VirtQueue *vq, size_t sz)
 {
-    unsigned int i, head, max;
+    unsigned int i, head, max, idx;
     VRingMemoryRegionCaches *caches;
     MemoryRegionCache indirect_desc_cache;
     MemoryRegionCache *desc_cache;
@@ -1629,6 +1629,13 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz)
         elem->in_sg[i] = iov[out_num + i];
     }
 
+    if (virtio_vdev_has_feature(vdev, VIRTIO_F_IN_ORDER)) {
+        idx = (vq->last_avail_idx - 1) % vq->vring.num;
+        vq->used_elems[idx].index = elem->index;
+        vq->used_elems[idx].len = elem->len;
+        vq->used_elems[idx].ndescs = elem->ndescs;
+    }
+
     vq->inuse++;
 
     trace_virtqueue_pop(vq, elem, elem->in_num, elem->out_num);
@@ -1762,6 +1769,13 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz)
 
     elem->index = id;
     elem->ndescs = (desc_cache == &indirect_desc_cache) ? 1 : elem_entries;
+
+    if (virtio_vdev_has_feature(vdev, VIRTIO_F_IN_ORDER)) {
+        vq->used_elems[vq->last_avail_idx].index = elem->index;
+        vq->used_elems[vq->last_avail_idx].len = elem->len;
+        vq->used_elems[vq->last_avail_idx].ndescs = elem->ndescs;
+    }
+
     vq->last_avail_idx += elem->ndescs;
     vq->inuse += elem->ndescs;
 
Signature · 1 line
MST
#47 lore raw

[PULL 30/63] hw/pci: Fix SR-IOV VF number calculation

In reply to Michael S. Tsirkin

From: Akihiko Odaki <[email protected]>

pci_config_get_bar_addr() had a division by vf_stride. vf_stride needs to be non-zero when there are multiple VFs, but the specification does not prohibit to make it zero when there is only one VF.

Do not perform the division for the first VF to avoid division by zero.

Message-Id: <[email protected]>

---
 hw/pci/pci.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
hw/pci/pci.c +5 -1
index bd956637bc..dbd954f1fe 100644
@@ -1437,7 +1437,11 @@ static pcibus_t pci_config_get_bar_addr(PCIDevice *d, int reg,
             pci_get_word(pf->config + sriov_cap + PCI_SRIOV_VF_OFFSET);
         uint16_t vf_stride =
             pci_get_word(pf->config + sriov_cap + PCI_SRIOV_VF_STRIDE);
-        uint32_t vf_num = (d->devfn - (pf->devfn + vf_offset)) / vf_stride;
+        uint32_t vf_num = d->devfn - (pf->devfn + vf_offset);
+
+        if (vf_num) {
+            vf_num /= vf_stride;
+        }
 
         if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
             new_addr = pci_get_quad(pf->config + bar);
Signature · 1 line
MST
#48 lore raw

[PULL 49/63] hw/vfio/common: Add vfio_listener_region_del_iommu trace event

In reply to Michael S. Tsirkin

From: Eric Auger <[email protected]>

Trace when VFIO gets notified about the deletion of an IOMMU MR. Also trace the name of the region in the add_iommu trace message.

Message-Id: <[email protected]>

---
 hw/vfio/common.c     | 3 ++-
 hw/vfio/trace-events | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)
hw/vfio/common.c +2 -1
index 6d15b36e0b..cfc44a4569 100644
@@ -599,7 +599,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
         IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
         int iommu_idx;
 
-        trace_vfio_listener_region_add_iommu(iova, end);
+        trace_vfio_listener_region_add_iommu(section->mr->name, iova, end);
         /*
          * FIXME: For VFIO iommu types which have KVM acceleration to
          * avoid bouncing all map/unmaps through qemu this way, this
@@ -725,6 +725,7 @@ static void vfio_listener_region_del(MemoryListener *listener,
     if (memory_region_is_iommu(section->mr)) {
         VFIOGuestIOMMU *giommu;
 
+        trace_vfio_listener_region_del_iommu(section->mr->name);
         QLIST_FOREACH(giommu, &bcontainer->giommu_list, giommu_next) {
             if (MEMORY_REGION(giommu->iommu_mr) == section->mr &&
                 giommu->n.start == section->offset_within_region) {
hw/vfio/trace-events +2 -1
index e16179b507..98bd4dccea 100644
@@ -95,7 +95,8 @@ vfio_region_read(char *name, int index, uint64_t addr, unsigned size, uint64_t d
 vfio_iommu_map_notify(const char *op, uint64_t iova_start, uint64_t iova_end) "iommu %s @ 0x%"PRIx64" - 0x%"PRIx64
 vfio_listener_region_skip(const char *name, uint64_t start, uint64_t end) "SKIPPING %s 0x%"PRIx64" - 0x%"PRIx64
 vfio_spapr_group_attach(int groupfd, int tablefd) "Attached groupfd %d to liobn fd %d"
-vfio_listener_region_add_iommu(uint64_t start, uint64_t end) "region_add [iommu] 0x%"PRIx64" - 0x%"PRIx64
+vfio_listener_region_add_iommu(const char* name, uint64_t start, uint64_t end) "region_add [iommu] %s 0x%"PRIx64" - 0x%"PRIx64
+vfio_listener_region_del_iommu(const char *name) "region_del [iommu] %s"
 vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]"
 vfio_known_safe_misalignment(const char *name, uint64_t iova, uint64_t offset_within_region, uintptr_t page_size) "Region \"%s\" iova=0x%"PRIx64" offset_within_region=0x%"PRIx64" qemu_real_host_page_size=0x%"PRIxPTR
 vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint64_t size, uint64_t page_size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" is not aligned to 0x%"PRIx64" and cannot be mapped for DMA"
Signature · 1 line
MST
#49 lore raw

[PULL 32/63] pcie_sriov: Check PCI Express for SR-IOV PF

In reply to Michael S. Tsirkin

From: Akihiko Odaki <[email protected]>

SR-IOV requires PCI Express.

Message-Id: <[email protected]>

---
 hw/pci/pcie_sriov.c | 5 +++++
 1 file changed, 5 insertions(+)
hw/pci/pcie_sriov.c +5 -0
index 6c79658b4c..15a4aac1f4 100644
@@ -42,6 +42,11 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
     uint8_t *cfg = dev->config + offset;
     uint8_t *wmask;
 
+    if (!pci_is_express(dev)) {
+        error_setg(errp, "PCI Express is required for SR-IOV PF");
+        return false;
+    }
+
     if (pci_is_vf(dev)) {
         error_setg(errp, "a device cannot be both an SR-IOV PF and a VF");
         return false;
Signature · 1 line
MST
#50 lore raw

[PULL 29/63] hw/pci: Do not add ROM BAR for SR-IOV VF

In reply to Michael S. Tsirkin

From: Akihiko Odaki <[email protected]>

A SR-IOV VF cannot have a ROM BAR.

Message-Id: <[email protected]>

---
 hw/pci/pci.c | 8 ++++++++
 1 file changed, 8 insertions(+)
hw/pci/pci.c +8 -0
index 4c7be52951..bd956637bc 100644
@@ -2359,6 +2359,14 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
         return;
     }
 
+    if (pci_is_vf(pdev)) {
+        if (pdev->rom_bar == ON_OFF_AUTO_ON) {
+            error_setg(errp, "ROM BAR cannot be enabled for SR-IOV VF");
+        }
+
+        return;
+    }
+
     if (load_file || pdev->romsize == UINT32_MAX) {
         path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
         if (path == NULL) {
Signature · 1 line
MST
#51 lore raw

Re: [PULL 29/63] hw/pci: Do not add ROM BAR for SR-IOV VF

Quoted 18 lines · Michael S. Tsirkin

From: Akihiko Odaki <[email protected]>

A SR-IOV VF cannot have a ROM BAR.

Message-Id: <[email protected]>

---
  hw/pci/pci.c | 8 ++++++++
  1 file changed, 8 insertions(+)
hw/pci/pci.c +0 -0
index 4c7be52951..bd956637bc 100644

hw/pci/pci.c static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, · line 2363

Quoted 5 lines
hw/pci/pci.c +2 -0
@@ -2359,6 +2359,14 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
          return;
      }
 
+    if (pci_is_vf(pdev)) {
+        if (pdev->rom_bar == ON_OFF_AUTO_ON) {

This requires:
https://lore.kernel.org/r/[email protected]
("[PATCH v2 0/4] hw/pci: Convert rom_bar into OnOffAuto")

However it does not seem included in this pull request.

Regards,
Akihiko Odaki

#52 lore raw

Re: [PULL 29/63] hw/pci: Do not add ROM BAR for SR-IOV VF

Quoted 28 lines · Akihiko Odaki
Quoted 18 lines · Michael S. Tsirkin

From: Akihiko Odaki <[email protected]>

A SR-IOV VF cannot have a ROM BAR.

Message-Id: <[email protected]>

---
  hw/pci/pci.c | 8 ++++++++
  1 file changed, 8 insertions(+)
hw/pci/pci.c +0 -0
index 4c7be52951..bd956637bc 100644

hw/pci/pci.c static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, · line 2362

Quoted 4 lines
hw/pci/pci.c +2 -0
@@ -2359,6 +2359,14 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
          return;
      }
+    if (pci_is_vf(pdev)) {
+        if (pdev->rom_bar == ON_OFF_AUTO_ON) {

This requires:
https://lore.kernel.org/r/[email protected]
("[PATCH v2 0/4] hw/pci: Convert rom_bar into OnOffAuto")

Quoted 4 lines

However it does not seem included in this pull request.

Regards,
Akihiko Odaki

good point, dropped for now.

#53 lore raw

[PULL 12/63] hw/cxl/cxl-mailbox-utils: Add device patrol scrub control feature

In reply to Michael S. Tsirkin

From: Shiju Jose <[email protected]>

CXL spec 3.1 section 8.2.9.9.11.1 describes the device patrol scrub control feature. The device patrol scrub proactively locates and makes corrections to errors in regular cycle. The patrol scrub control allows the request to configure patrol scrub input configurations.

The patrol scrub control allows the requester to specify the number of hours for which the patrol scrub cycles must be completed, provided that the requested number is not less than the minimum number of hours for the patrol scrub cycle that the device is capable of. In addition, the patrol scrub controls allow the host to disable and enable the feature in case disabling of the feature is needed for other purposes such as performance-aware operations which require the background operations to be turned off.

Message-Id: <[email protected]>

---
 include/hw/cxl/cxl_device.h | 24 +++++++++++
 hw/cxl/cxl-mailbox-utils.c  | 79 ++++++++++++++++++++++++++++++++++---
 hw/mem/cxl_type3.c          |  9 +++++
 3 files changed, 107 insertions(+), 5 deletions(-)
include/hw/cxl/cxl_device.h +24 -0
index 48ed0d9240..2c1df25453 100644
@@ -427,6 +427,26 @@ typedef struct CXLPoison {
 typedef QLIST_HEAD(, CXLPoison) CXLPoisonList;
 #define CXL_POISON_LIST_LIMIT 256
 
+/* CXL memory device patrol scrub control attributes */
+typedef struct CXLMemPatrolScrubReadAttrs {
+        uint8_t scrub_cycle_cap;
+        uint16_t scrub_cycle;
+        uint8_t scrub_flags;
+} QEMU_PACKED CXLMemPatrolScrubReadAttrs;
+
+typedef struct CXLMemPatrolScrubWriteAttrs {
+    uint8_t scrub_cycle_hr;
+    uint8_t scrub_flags;
+} QEMU_PACKED CXLMemPatrolScrubWriteAttrs;
+
+#define CXL_MEMDEV_PS_GET_FEATURE_VERSION    0x01
+#define CXL_MEMDEV_PS_SET_FEATURE_VERSION    0x01
+#define CXL_MEMDEV_PS_SCRUB_CYCLE_CHANGE_CAP_DEFAULT    BIT(0)
+#define CXL_MEMDEV_PS_SCRUB_REALTIME_REPORT_CAP_DEFAULT    BIT(1)
+#define CXL_MEMDEV_PS_CUR_SCRUB_CYCLE_DEFAULT    12
+#define CXL_MEMDEV_PS_MIN_SCRUB_CYCLE_DEFAULT    1
+#define CXL_MEMDEV_PS_ENABLE_DEFAULT    0
+
 #define DCD_MAX_NUM_REGION 8
 
 typedef struct CXLDCExtentRaw {
@@ -511,6 +531,10 @@ struct CXLType3Dev {
 
     CXLSetFeatureInfo set_feat_info;
 
+    /* Patrol scrub control attributes */
+    CXLMemPatrolScrubReadAttrs patrol_scrub_attrs;
+    CXLMemPatrolScrubWriteAttrs patrol_scrub_wr_attrs;
+
     struct dynamic_capacity {
         HostMemoryBackend *host_dc;
         AddressSpace host_dc_as;
hw/cxl/cxl-mailbox-utils.c +74 -5

127 lines not on this page · raw message

hw/mem/cxl_type3.c +9 -0
index c7910687ae..7c583d80f5 100644
@@ -908,6 +908,15 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
     }
     cxl_event_init(&ct3d->cxl_dstate, 2);
 
+    /* Set default value for patrol scrub attributes */
+    ct3d->patrol_scrub_attrs.scrub_cycle_cap =
+                           CXL_MEMDEV_PS_SCRUB_CYCLE_CHANGE_CAP_DEFAULT |
+                           CXL_MEMDEV_PS_SCRUB_REALTIME_REPORT_CAP_DEFAULT;
+    ct3d->patrol_scrub_attrs.scrub_cycle =
+                           CXL_MEMDEV_PS_CUR_SCRUB_CYCLE_DEFAULT |
+                           (CXL_MEMDEV_PS_MIN_SCRUB_CYCLE_DEFAULT << 8);
+    ct3d->patrol_scrub_attrs.scrub_flags = CXL_MEMDEV_PS_ENABLE_DEFAULT;
+
     return;
 
 err_release_cdat:
Signature · 1 line
MST
#54 lore raw

[PULL 59/63] tests/acpi: Add expected ACPI AML files for RISC-V

In reply to Michael S. Tsirkin

From: Sunil V L <[email protected]>

As per the step 5 in the process documented in bios-tables-test.c, generate the expected ACPI AML data files for RISC-V using the rebuild-expected-aml.sh script and update the bios-tables-test-allowed-diff.h.

These are all new files being added for the first time. Hence, iASL diff output is not added.

Message-Id: <[email protected]>

---
 tests/qtest/bios-tables-test-allowed-diff.h |   6 ------
 tests/data/acpi/riscv64/virt/APIC           | Bin 0 -> 116 bytes
 tests/data/acpi/riscv64/virt/DSDT           | Bin 0 -> 3576 bytes
 tests/data/acpi/riscv64/virt/FACP           | Bin 0 -> 276 bytes
 tests/data/acpi/riscv64/virt/MCFG           | Bin 0 -> 60 bytes
 tests/data/acpi/riscv64/virt/RHCT           | Bin 0 -> 332 bytes
 tests/data/acpi/riscv64/virt/SPCR           | Bin 0 -> 80 bytes
 7 files changed, 6 deletions(-)
tests/qtest/bios-tables-test-allowed-diff.h +0 -6
index 70474a097f..dfb8523c8b 100644
@@ -1,7 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/riscv64/virt/APIC",
-"tests/data/acpi/riscv64/virt/DSDT",
-"tests/data/acpi/riscv64/virt/FACP",
-"tests/data/acpi/riscv64/virt/MCFG",
-"tests/data/acpi/riscv64/virt/RHCT",
-"tests/data/acpi/riscv64/virt/SPCR",
tests/data/acpi/riscv64/virt/APIC binary +0 -0
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..66a25dfd2d6ea2b607c024722b2eab95873a01e9 100644
GIT binary patch
tests/data/acpi/riscv64/virt/DSDT binary +0 -0
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6a33f5647ddd6de3a0f000f718b58f6fff44f0fd 100644
GIT binary patch
tests/data/acpi/riscv64/virt/FACP binary +0 -0
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a5276b65ea8ce46cc9b40d96d98f0669c9089ed4 100644
GIT binary patch
tests/data/acpi/riscv64/virt/MCFG binary +0 -0
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..37eb923a9320f5573c0c2cdb90bd98409cc7eb6f 100644
GIT binary patch
tests/data/acpi/riscv64/virt/RHCT binary +0 -0
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4f231735abad925435c3cd052e6641b1b4187278 100644
GIT binary patch
tests/data/acpi/riscv64/virt/SPCR binary +0 -0
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4da9daf65f71a13ac2b488d4e9728f194b569a43 100644
GIT binary patch
Signature · 1 line
MST
#55 lore raw

[PULL 58/63] tests/qtest/bios-tables-test.c: Enable basic testing for RISC-V

In reply to Michael S. Tsirkin

From: Sunil V L <[email protected]>

Add basic ACPI table test case for RISC-V.

Message-Id: <[email protected]>

---
 tests/qtest/bios-tables-test.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
tests/qtest/bios-tables-test.c +26 -0
index 498e0e35d9..36e5c0adde 100644
@@ -1963,6 +1963,28 @@ static void test_acpi_microvm_acpi_erst(void)
 }
 #endif /* CONFIG_POSIX */
 
+static void test_acpi_riscv64_virt_tcg(void)
+{
+    test_data data = {
+        .machine = "virt",
+        .arch = "riscv64",
+        .tcg_only = true,
+        .uefi_fl1 = "pc-bios/edk2-riscv-code.fd",
+        .uefi_fl2 = "pc-bios/edk2-riscv-vars.fd",
+        .cd = "tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2",
+        .ram_start = 0x80000000ULL,
+        .scan_len = 128ULL * 1024 * 1024,
+    };
+
+    /*
+     * RHCT will have ISA string encoded. To reduce the effort
+     * of updating expected AML file for any new default ISA extension,
+     * use the profile rva22s64.
+     */
+    test_acpi_one("-cpu rva22s64 ", &data);
+    free_test_data(&data);
+}
+
 static void test_acpi_aarch64_virt_tcg(void)
 {
     test_data data = {
@@ -2441,6 +2463,10 @@ int main(int argc, char *argv[])
                 qtest_add_func("acpi/virt/viot", test_acpi_aarch64_virt_viot);
             }
         }
+    } else if (strcmp(arch, "riscv64") == 0) {
+        if (has_tcg && qtest_has_device("virtio-blk-pci")) {
+            qtest_add_func("acpi/virt", test_acpi_riscv64_virt_tcg);
+        }
     }
     ret = g_test_run();
     boot_sector_cleanup(disk);
Signature · 1 line
MST
#56 lore raw

[PULL 35/63] virtio-net: Implement SR-IOV VF

In reply to Michael S. Tsirkin

From: Akihiko Odaki <[email protected]>

A virtio-net device can be added as a SR-IOV VF to another virtio-pci device that will be the PF.

Message-Id: <[email protected]>

---
 hw/virtio/virtio-net-pci.c | 1 +
 1 file changed, 1 insertion(+)
hw/virtio/virtio-net-pci.c +1 -0
index e03543a70a..dba4987d6e 100644
@@ -75,6 +75,7 @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+    k->sriov_vf_user_creatable = true;
     set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
     device_class_set_props(dc, virtio_net_properties);
     vpciklass->realize = virtio_net_pci_realize;
Signature · 1 line
MST
#57 lore raw

[PULL 57/63] tests/acpi: Add empty ACPI data files for RISC-V

In reply to Michael S. Tsirkin

From: Sunil V L <[email protected]>

As per process documented (steps 1-3) in bios-tables-test.c, add empty AML data files for RISC-V ACPI tables and add the entries in bios-tables-test-allowed-diff.h.

Message-Id: <[email protected]>

---
 tests/qtest/bios-tables-test-allowed-diff.h | 6 ++++++
 tests/data/acpi/riscv64/virt/APIC           | 0
 tests/data/acpi/riscv64/virt/DSDT           | 0
 tests/data/acpi/riscv64/virt/FACP           | 0
 tests/data/acpi/riscv64/virt/MCFG           | 0
 tests/data/acpi/riscv64/virt/RHCT           | 0
 tests/data/acpi/riscv64/virt/SPCR           | 0
 7 files changed, 6 insertions(+)
 create mode 100644 tests/data/acpi/riscv64/virt/APIC
 create mode 100644 tests/data/acpi/riscv64/virt/DSDT
 create mode 100644 tests/data/acpi/riscv64/virt/FACP
 create mode 100644 tests/data/acpi/riscv64/virt/MCFG
 create mode 100644 tests/data/acpi/riscv64/virt/RHCT
 create mode 100644 tests/data/acpi/riscv64/virt/SPCR
tests/qtest/bios-tables-test-allowed-diff.h +6 -0
index dfb8523c8b..70474a097f 100644
@@ -1 +1,7 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/riscv64/virt/APIC",
+"tests/data/acpi/riscv64/virt/DSDT",
+"tests/data/acpi/riscv64/virt/FACP",
+"tests/data/acpi/riscv64/virt/MCFG",
+"tests/data/acpi/riscv64/virt/RHCT",
+"tests/data/acpi/riscv64/virt/SPCR",
tests/data/acpi/riscv64/virt/APIC new file +0 -0
new file mode 100644
index 0000000000..e69de29bb2
tests/data/acpi/riscv64/virt/DSDT new file +0 -0
new file mode 100644
index 0000000000..e69de29bb2
tests/data/acpi/riscv64/virt/FACP new file +0 -0
new file mode 100644
index 0000000000..e69de29bb2
tests/data/acpi/riscv64/virt/MCFG new file +0 -0
new file mode 100644
index 0000000000..e69de29bb2
tests/data/acpi/riscv64/virt/RHCT new file +0 -0
new file mode 100644
index 0000000000..e69de29bb2
tests/data/acpi/riscv64/virt/SPCR new file +0 -0
new file mode 100644
index 0000000000..e69de29bb2
Signature · 1 line
MST
#58 lore raw

[PULL 27/63] virtio: Add VIRTIO_F_IN_ORDER property definition

In reply to Michael S. Tsirkin

From: Jonah Palmer <[email protected]>

Extend the virtio device property definitions to include the VIRTIO_F_IN_ORDER feature.

The default state of this feature is disabled, allowing it to be explicitly enabled where it's supported.

Message-Id: <[email protected]>

---
 include/hw/virtio/virtio.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
include/hw/virtio/virtio.h +3 -1
index fdc827f82e..d2a1938757 100644
@@ -373,7 +373,9 @@ typedef struct VirtIORNGConf VirtIORNGConf;
     DEFINE_PROP_BIT64("packed", _state, _field, \
                       VIRTIO_F_RING_PACKED, false), \
     DEFINE_PROP_BIT64("queue_reset", _state, _field, \
-                      VIRTIO_F_RING_RESET, true)
+                      VIRTIO_F_RING_RESET, true), \
+    DEFINE_PROP_BIT64("in_order", _state, _field, \
+                      VIRTIO_F_IN_ORDER, false)
 
 hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
 bool virtio_queue_enabled_legacy(VirtIODevice *vdev, int n);
Signature · 1 line
MST
#59 lore raw

[PULL 05/63] hw/cxl/cxl-host: Fix segmentation fault when getting cxl-fmw property

In reply to Michael S. Tsirkin

From: Zhao Liu <[email protected]>

QEMU crashes (Segmentation fault) when getting cxl-fmw property via qmp:

(QEMU) qom-get path=machine property=cxl-fmw

This issue is caused by accessing wrong callback (opaque) type in machine_get_cfmw().

cxl_machine_init() sets the callback as CXLState * type but machine_get_cfmw() treats the callback as CXLFixedMemoryWindowOptionsList **.

Fix this error by casting opaque to CXLState * type in machine_get_cfmw().

Fixes 03b39fcf64bc ("hw/cxl: Make the CXL fixed memory window setup a machine parameter.")

Message-Id: <[email protected]>

---
 hw/cxl/cxl-host.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
hw/cxl/cxl-host.c +2 -1
index c5f5fcfd64..e9f2543c43 100644
@@ -315,7 +315,8 @@ static void machine_set_cxl(Object *obj, Visitor *v, const char *name,
 static void machine_get_cfmw(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp)
 {
-    CXLFixedMemoryWindowOptionsList **list = opaque;
+    CXLState *state = opaque;
+    CXLFixedMemoryWindowOptionsList **list = &state->cfmw_list;
 
     visit_type_CXLFixedMemoryWindowOptionsList(v, name, list, errp);
 }
Signature · 1 line
MST
#60 lore raw

[PULL 40/63] hw/acpi: Update ACPI GED framework to support vCPU Hotplug

In reply to Michael S. Tsirkin

From: Salil Mehta <[email protected]>

ACPI GED (as described in the ACPI 6.4 spec) uses an interrupt listed in the _CRS object of GED to intimate OSPM about an event. Later then demultiplexes the notified event by evaluating ACPI _EVT method to know the type of event. Use ACPI GED to also notify the guest kernel about any CPU hot(un)plug events.

Note, GED interface is used by many hotplug events like memory hotplug, NVDIMM hotplug and non-hotplug events like system power down event. Each of these can be selected using a bit in the 32 bit GED IO interface. A bit has been reserved for the CPU hotplug event.

ACPI CPU hotplug related initialization should only happen if ACPI_CPU_HOTPLUG support has been enabled for particular architecture. Add cpu_hotplug_hw_init() stub to avoid compilation break.

Message-Id: <[email protected]>

---
 include/hw/acpi/generic_event_device.h |  4 +++
 hw/acpi/acpi-cpu-hotplug-stub.c        |  6 ++++
 hw/acpi/generic_event_device.c         | 47 ++++++++++++++++++++++++++
 docs/specs/acpi_hw_reduced_hotplug.rst |  3 +-
 4 files changed, 59 insertions(+), 1 deletion(-)
include/hw/acpi/generic_event_device.h +4 -0
index ba84ce0214..e091ac2108 100644
@@ -62,6 +62,7 @@
 #include "hw/sysbus.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/ghes.h"
+#include "hw/acpi/cpu.h"
 #include "qom/object.h"
 
 #define ACPI_POWER_BUTTON_DEVICE "PWRB"
@@ -95,6 +96,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
 #define ACPI_GED_MEM_HOTPLUG_EVT   0x1
 #define ACPI_GED_PWR_DOWN_EVT      0x2
 #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4
+#define ACPI_GED_CPU_HOTPLUG_EVT    0x8
 
 typedef struct GEDState {
     MemoryRegion evt;
@@ -106,6 +108,8 @@ struct AcpiGedState {
     SysBusDevice parent_obj;
     MemHotplugState memhp_state;
     MemoryRegion container_memhp;
+    CPUHotplugState cpuhp_state;
+    MemoryRegion container_cpuhp;
     GEDState ged_state;
     uint32_t ged_event_bitmap;
     qemu_irq irq;
hw/acpi/acpi-cpu-hotplug-stub.c +6 -0
index 3fc4b14c26..c6c61bb9cd 100644
@@ -19,6 +19,12 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
     return;
 }
 
+void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
+                         CPUHotplugState *state, hwaddr base_addr)
+{
+    return;
+}
+
 void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
 {
     return;
hw/acpi/generic_event_device.c +47 -0

95 lines not on this page · raw message

docs/specs/acpi_hw_reduced_hotplug.rst +2 -1
index 0bd3f9399f..3acd6fcd8b 100644
@@ -64,7 +64,8 @@ GED IO interface (4 byte access)
        0: Memory hotplug event
        1: System power down event
        2: NVDIMM hotplug event
-    3-31: Reserved
+       3: CPU hotplug event
+    4-31: Reserved
 
 **write_access:**
 
Signature · 1 line
MST
#61 lore raw

[PULL 62/63] hw/nvme: Add SPDM over DOE support

In reply to Michael S. Tsirkin

From: Wilfred Mallawa <[email protected]>

Setup Data Object Exchange (DOE) as an extended capability for the NVME controller and connect SPDM to it (CMA) to it.

Message-Id: <[email protected]>

---
 include/hw/pci/pci_device.h |   7 ++
 include/hw/pci/pcie_doe.h   |   3 +
 hw/nvme/ctrl.c              |  62 +++++++++++++++++
 docs/specs/index.rst        |   1 +
 docs/specs/spdm.rst         | 134 ++++++++++++++++++++++++++++++++++++
 5 files changed, 207 insertions(+)
 create mode 100644 docs/specs/spdm.rst
include/hw/pci/pci_device.h +7 -0
index cefd6f7640..e7e41cb939 100644
@@ -3,6 +3,7 @@
 
 #include "hw/pci/pci.h"
 #include "hw/pci/pcie.h"
+#include "hw/pci/pcie_doe.h"
 
 #define TYPE_PCI_DEVICE "pci-device"
 typedef struct PCIDeviceClass PCIDeviceClass;
@@ -159,6 +160,12 @@ struct PCIDevice {
     MSIVectorReleaseNotifier msix_vector_release_notifier;
     MSIVectorPollNotifier msix_vector_poll_notifier;
 
+    /* SPDM */
+    uint16_t spdm_port;
+
+    /* DOE */
+    DOECap doe_spdm;
+
     /* ID of standby device in net_failover pair */
     char *failover_pair_id;
     uint32_t acpi_index;
include/hw/pci/pcie_doe.h +3 -0
index 15d94661f9..9e1275db8a 100644
@@ -108,6 +108,9 @@ struct DOECap {
     /* Protocols and its callback response */
     DOEProtocol *protocols;
     uint16_t protocol_num;
+
+    /* Used for spdm-socket */
+    int spdm_socket;
 };
 
 void pcie_doe_init(PCIDevice *pdev, DOECap *doe_cap, uint16_t offset,
hw/nvme/ctrl.c +62 -0

109 lines not on this page · raw message

docs/specs/index.rst +1 -0
index 1484e3e760..e2d907959a 100644
@@ -29,6 +29,7 @@ guest hardware that is specific to QEMU.
    edu
    ivshmem-spec
    pvpanic
+   spdm
    standard-vga
    virt-ctlr
    vmcoreinfo
docs/specs/spdm.rst new file +134 -0

134 lines not on this page · raw message

Signature · 1 line
MST
#62 lore raw

[PULL 53/63] tests/acpi: Allow DSDT acpi table changes for aarch64

In reply to Michael S. Tsirkin

From: Sunil V L <[email protected]>

so that CI tests don't fail when those ACPI tables are updated in the next patch. This is as per the documentation in bios-tables-tests.c.

Message-Id: <[email protected]>

---
 tests/qtest/bios-tables-test-allowed-diff.h | 6 ++++++
 1 file changed, 6 insertions(+)
tests/qtest/bios-tables-test-allowed-diff.h +6 -0
index dfb8523c8b..9282ea0fb2 100644
@@ -1 +1,7 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/aarch64/virt/DSDT",
+"tests/data/acpi/aarch64/virt/DSDT.memhp",
+"tests/data/acpi/aarch64/virt/DSDT.topology",
+"tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt",
+"tests/data/acpi/aarch64/virt/DSDT.pxb",
+"tests/data/acpi/x86/microvm/DSDT.pcie",
Signature · 1 line
MST
#63 lore raw

[PULL 08/63] hw/cxl/events: discard all event records during sanitation

In reply to Michael S. Tsirkin

From: Hyeonggon Yoo <[email protected]>

Per CXL r3.1 Section 8.2.9.9.5.1: Sanitize (Opcode 4400h), the sanitize command should delete all event logs. Introduce cxl_discard_all_event_logs() and call
this in __do_sanitization().

Message-Id: <[email protected]>

---
 include/hw/cxl/cxl_device.h |  1 +
 hw/cxl/cxl-events.c         | 13 +++++++++++++
 hw/cxl/cxl-mailbox-utils.c  |  1 +
 3 files changed, 15 insertions(+)
include/hw/cxl/cxl_device.h +1 -0
index 42a622197e..0509d961c3 100644
@@ -562,6 +562,7 @@ CXLRetCode cxl_event_get_records(CXLDeviceState *cxlds, CXLGetEventPayload *pl,
                                  size_t *len);
 CXLRetCode cxl_event_clear_records(CXLDeviceState *cxlds,
                                    CXLClearEventPayload *pl);
+void cxl_discard_all_event_records(CXLDeviceState *cxlds);
 
 void cxl_event_irq_assert(CXLType3Dev *ct3d);
 
hw/cxl/cxl-events.c +13 -0
index d397718b1b..12dee2e467 100644
@@ -139,6 +139,19 @@ bool cxl_event_insert(CXLDeviceState *cxlds, CXLEventLogType log_type,
     return cxl_event_count(log) == 1;
 }
 
+void cxl_discard_all_event_records(CXLDeviceState *cxlds)
+{
+    CXLEventLogType log_type;
+    CXLEventLog *log;
+
+    for (log_type = 0; log_type < CXL_EVENT_TYPE_MAX; log_type++) {
+        log = &cxlds->event_logs[log_type];
+        while (!cxl_event_empty(log)) {
+            cxl_event_delete_head(cxlds, log_type, log);
+        }
+    }
+}
+
 CXLRetCode cxl_event_get_records(CXLDeviceState *cxlds, CXLGetEventPayload *pl,
                                  uint8_t log_type, int max_recs,
                                  size_t *len)
hw/cxl/cxl-mailbox-utils.c +1 -0
index 522d9aa589..3c9600c39c 100644
@@ -949,6 +949,7 @@ static void __do_sanitization(CXLType3Dev *ct3d)
             memset(lsa, 0, memory_region_size(mr));
         }
     }
+    cxl_discard_all_event_records(&ct3d->cxl_dstate);
 }
 
 /*
Signature · 1 line
MST
#64 lore raw

[PULL 22/63] virtio: Add bool to VirtQueueElement

In reply to Michael S. Tsirkin

From: Jonah Palmer <[email protected]>

Add the boolean 'in_order_filled' member to the VirtQueueElement structure. The use of this boolean will signify whether the element has been processed and is ready to be flushed (so long as the element is in-order). This boolean is used to support the VIRTIO_F_IN_ORDER feature.

Message-Id: <[email protected]>

---
 include/hw/virtio/virtio.h | 2 ++
 1 file changed, 2 insertions(+)
include/hw/virtio/virtio.h +2 -0
index 7512afbc84..fdc827f82e 100644
@@ -69,6 +69,8 @@ typedef struct VirtQueueElement
     unsigned int ndescs;
     unsigned int out_num;
     unsigned int in_num;
+    /* Element has been processed (VIRTIO_F_IN_ORDER) */
+    bool in_order_filled;
     hwaddr *in_addr;
     hwaddr *out_addr;
     struct iovec *in_sg;
Signature · 1 line
MST
#65 lore raw

[PULL 10/63] cxl/mailbox: move mailbox effect definitions to a header

In reply to Michael S. Tsirkin

From: Gregory Price <[email protected]>

Preparation for allowing devices to define their own CCI commands

Message-Id: <[email protected]>

---
 include/hw/cxl/cxl_mailbox.h | 18 ++++++++++++++++++
 hw/cxl/cxl-mailbox-utils.c   | 34 +++++++++++++++-------------------
 2 files changed, 33 insertions(+), 19 deletions(-)
 create mode 100644 include/hw/cxl/cxl_mailbox.h
include/hw/cxl/cxl_mailbox.h new file +18 -0
new file mode 100644
index 0000000000..beb048052e
@@ -0,0 +1,18 @@
+/*
+ * QEMU CXL Mailbox
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See the
+ * COPYING file in the top-level directory.
+ */
+
+#ifndef CXL_MAILBOX_H
+#define CXL_MAILBOX_H
+
+#define CXL_MBOX_IMMEDIATE_CONFIG_CHANGE (1 << 1)
+#define CXL_MBOX_IMMEDIATE_DATA_CHANGE (1 << 2)
+#define CXL_MBOX_IMMEDIATE_POLICY_CHANGE (1 << 3)
+#define CXL_MBOX_IMMEDIATE_LOG_CHANGE (1 << 4)
+#define CXL_MBOX_SECURITY_STATE_CHANGE (1 << 5)
+#define CXL_MBOX_BACKGROUND_OPERATION (1 << 6)
+
+#endif
hw/cxl/cxl-mailbox-utils.c +15 -19
index 82120a6e7b..dbaa83a110 100644
@@ -12,6 +12,7 @@
 #include "hw/pci/msix.h"
 #include "hw/cxl/cxl.h"
 #include "hw/cxl/cxl_events.h"
+#include "hw/cxl/cxl_mailbox.h"
 #include "hw/pci/pci.h"
 #include "hw/pci-bridge/cxl_upstream_port.h"
 #include "qemu/cutils.h"
@@ -2095,28 +2096,21 @@ static CXLRetCode cmd_dcd_release_dyn_cap(const struct cxl_cmd *cmd,
     return CXL_MBOX_SUCCESS;
 }
 
-#define IMMEDIATE_CONFIG_CHANGE (1 << 1)
-#define IMMEDIATE_DATA_CHANGE (1 << 2)
-#define IMMEDIATE_POLICY_CHANGE (1 << 3)
-#define IMMEDIATE_LOG_CHANGE (1 << 4)
-#define SECURITY_STATE_CHANGE (1 << 5)
-#define BACKGROUND_OPERATION (1 << 6)
-
 static const struct cxl_cmd cxl_cmd_set[256][256] = {
     [EVENTS][GET_RECORDS] = { "EVENTS_GET_RECORDS",
         cmd_events_get_records, 1, 0 },
     [EVENTS][CLEAR_RECORDS] = { "EVENTS_CLEAR_RECORDS",
-        cmd_events_clear_records, ~0, IMMEDIATE_LOG_CHANGE },
+        cmd_events_clear_records, ~0, CXL_MBOX_IMMEDIATE_LOG_CHANGE },
     [EVENTS][GET_INTERRUPT_POLICY] = { "EVENTS_GET_INTERRUPT_POLICY",
                                       cmd_events_get_interrupt_policy, 0, 0 },
     [EVENTS][SET_INTERRUPT_POLICY] = { "EVENTS_SET_INTERRUPT_POLICY",
                                       cmd_events_set_interrupt_policy,
-                                      ~0, IMMEDIATE_CONFIG_CHANGE },
+                                      ~0, CXL_MBOX_IMMEDIATE_CONFIG_CHANGE },
     [FIRMWARE_UPDATE][GET_INFO] = { "FIRMWARE_UPDATE_GET_INFO",
         cmd_firmware_update_get_info, 0, 0 },
     [TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 },
     [TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set,
-                         8, IMMEDIATE_POLICY_CHANGE },
+                         8, CXL_MBOX_IMMEDIATE_POLICY_CHANGE },
     [LOGS][GET_SUPPORTED] = { "LOGS_GET_SUPPORTED", cmd_logs_get_supported,
                               0, 0 },
     [LOGS][GET_LOG] = { "LOGS_GET_LOG", cmd_logs_get_log, 0x18, 0 },
@@ -2126,9 +2120,11 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
         cmd_ccls_get_partition_info, 0, 0 },
     [CCLS][GET_LSA] = { "CCLS_GET_LSA", cmd_ccls_get_lsa, 8, 0 },
     [CCLS][SET_LSA] = { "CCLS_SET_LSA", cmd_ccls_set_lsa,
-        ~0, IMMEDIATE_CONFIG_CHANGE | IMMEDIATE_DATA_CHANGE },
+        ~0, CXL_MBOX_IMMEDIATE_CONFIG_CHANGE | CXL_MBOX_IMMEDIATE_DATA_CHANGE },
     [SANITIZE][OVERWRITE] = { "SANITIZE_OVERWRITE", cmd_sanitize_overwrite, 0,
-        IMMEDIATE_DATA_CHANGE | SECURITY_STATE_CHANGE | BACKGROUND_OPERATION },
+        (CXL_MBOX_IMMEDIATE_DATA_CHANGE |
+         CXL_MBOX_SECURITY_STATE_CHANGE |
+         CXL_MBOX_BACKGROUND_OPERATION)},
     [PERSISTENT_MEM][GET_SECURITY_STATE] = { "GET_SECURITY_STATE",
         cmd_get_security_state, 0, 0 },
     [MEDIA_AND_POISON][GET_POISON_LIST] = { "MEDIA_AND_POISON_GET_POISON_LIST",
@@ -2141,7 +2137,7 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
         "MEDIA_AND_POISON_GET_SCAN_MEDIA_CAPABILITIES",
         cmd_media_get_scan_media_capabilities, 16, 0 },
     [MEDIA_AND_POISON][SCAN_MEDIA] = { "MEDIA_AND_POISON_SCAN_MEDIA",
-        cmd_media_scan_media, 17, BACKGROUND_OPERATION },
+        cmd_media_scan_media, 17, CXL_MBOX_BACKGROUND_OPERATION },
     [MEDIA_AND_POISON][GET_SCAN_MEDIA_RESULTS] = {
         "MEDIA_AND_POISON_GET_SCAN_MEDIA_RESULTS",
         cmd_media_get_scan_media_results, 0, 0 },
@@ -2155,10 +2151,10 @@ static const struct cxl_cmd cxl_cmd_set_dcd[256][256] = {
         8, 0 },
     [DCD_CONFIG][ADD_DYN_CAP_RSP] = {
         "DCD_ADD_DYNAMIC_CAPACITY_RESPONSE", cmd_dcd_add_dyn_cap_rsp,
-        ~0, IMMEDIATE_DATA_CHANGE },
+        ~0, CXL_MBOX_IMMEDIATE_DATA_CHANGE },
     [DCD_CONFIG][RELEASE_DYN_CAP] = {
         "DCD_RELEASE_DYNAMIC_CAPACITY", cmd_dcd_release_dyn_cap,
-        ~0, IMMEDIATE_DATA_CHANGE },
+        ~0, CXL_MBOX_IMMEDIATE_DATA_CHANGE },
 };
 
 static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
@@ -2166,8 +2162,8 @@ static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
     [INFOSTAT][BACKGROUND_OPERATION_STATUS] = { "BACKGROUND_OPERATION_STATUS",
         cmd_infostat_bg_op_sts, 0, 0 },
     [TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 },
-    [TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set, 0,
-                         IMMEDIATE_POLICY_CHANGE },
+    [TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set, 8,
+                         CXL_MBOX_IMMEDIATE_POLICY_CHANGE },
     [LOGS][GET_SUPPORTED] = { "LOGS_GET_SUPPORTED", cmd_logs_get_supported, 0,
                               0 },
     [LOGS][GET_LOG] = { "LOGS_GET_LOG", cmd_logs_get_log, 0x18, 0 },
@@ -2210,7 +2206,7 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
     }
 
     /* Only one bg command at a time */
-    if ((cxl_cmd->effect & BACKGROUND_OPERATION) &&
+    if ((cxl_cmd->effect & CXL_MBOX_BACKGROUND_OPERATION) &&
         cci->bg.runtime > 0) {
         return CXL_MBOX_BUSY;
     }
@@ -2235,7 +2231,7 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
     }
 
     ret = (*h)(cxl_cmd, pl_in, len_in, pl_out, len_out, cci);
-    if ((cxl_cmd->effect & BACKGROUND_OPERATION) &&
+    if ((cxl_cmd->effect & CXL_MBOX_BACKGROUND_OPERATION) &&
         ret == CXL_MBOX_BG_STARTED) {
         *bg_started = true;
     } else {
Signature · 1 line
MST
#66 lore raw
In reply to Michael S. Tsirkin
Quoted 27 lines · Michael S. Tsirkin

A couple of fixes are outstanding, will merge later.

The following changes since commit a87a7c449e532130d4fa8faa391ff7e1f04ed660:

   Merge tag 'pull-loongarch-20240719' ofhttps://gitlab.com/gaosong/qemu into staging (2024-07-19 16:28:28 +1000)

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 67d834362c55d6fca6504975bc34755606f17cf2:

virtio: Always reset vhost devices (2024-07-21 14:45:56 -0400)

----------------------------------------------------------------
virtio,pci,pc: features,fixes

pci: Initial support for SPDM Responders
cxl: Add support for scan media, feature commands, device patrol scrub
control, DDR5 ECS control, firmware updates
virtio: in-order support
virtio-net: support for SR-IOV emulation (note: known issues on s390,
might get reverted if not fixed)
smbios: memory device size is now configurable per Machine
cpu: architecture agnostic code to support vCPU Hotplug

Quoted 3 lines

Fixes, cleanups all over the place.

Fails ubsan testing:

https://gitlab.com/qemu-project/qemu/-/jobs/7397450714

../publish/hw/net/virtio-net.c:3895:18: runtime error: member access within null pointer of type 'struct vhost_net'

r~

#67 lore raw
Quoted 34 lines · Richard Henderson
Quoted 27 lines · Michael S. Tsirkin

A couple of fixes are outstanding, will merge later.

The following changes since commit a87a7c449e532130d4fa8faa391ff7e1f04ed660:

   Merge tag 'pull-loongarch-20240719' ofhttps://gitlab.com/gaosong/qemu into staging (2024-07-19 16:28:28 +1000)

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 67d834362c55d6fca6504975bc34755606f17cf2:

virtio: Always reset vhost devices (2024-07-21 14:45:56 -0400)

----------------------------------------------------------------
virtio,pci,pc: features,fixes

pci: Initial support for SPDM Responders
cxl: Add support for scan media, feature commands, device patrol scrub
control, DDR5 ECS control, firmware updates
virtio: in-order support
virtio-net: support for SR-IOV emulation (note: known issues on s390,
might get reverted if not fixed)
smbios: memory device size is now configurable per Machine
cpu: architecture agnostic code to support vCPU Hotplug

Quoted 3 lines

Fixes, cleanups all over the place.

Fails ubsan testing:

Quoted 7 lines

https://gitlab.com/qemu-project/qemu/-/jobs/7397450714

../publish/hw/net/virtio-net.c:3895:18: runtime error: member access within null pointer of type 'struct vhost_net'

r~

Thanks! this is just make check under ubsan build, right?

#68 lore raw
Quoted 11 lines · Michael S. Tsirkin
Quoted 9 lines

Fails ubsan testing:

https://gitlab.com/qemu-project/qemu/-/jobs/7397450714

../publish/hw/net/virtio-net.c:3895:18: runtime error: member access within null pointer of type 'struct vhost_net'

r~

Thanks! this is just make check under ubsan build, right?

Yep. For avoidance of doubt, the configure line is at the top of the log.

r~

#69 lore raw
Quoted 9 lines · Richard Henderson
Quoted 8 lines · Michael S. Tsirkin
Quoted 8 lines

Fails ubsan testing:

https://gitlab.com/qemu-project/qemu/-/jobs/7397450714

../publish/hw/net/virtio-net.c:3895:18: runtime error: member access within null pointer of type 'struct vhost_net'

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

r~

Thanks! this is just make check under ubsan build, right?

Yep. For avoidance of doubt, the configure line is at the top of the log.

r~

I wonder why I see a ton of other ubsan errors btw. But anyway, sent v2 with a couple of patches dropped.

#70 lore raw
In reply to Richard Henderson
Quoted 31 lines · Richard Henderson
Quoted 30 lines · Michael S. Tsirkin

A couple of fixes are outstanding, will merge later.

The following changes since commit a87a7c449e532130d4fa8faa391ff7e1f04ed660:

   Merge tag 'pull-loongarch-20240719' ofhttps://gitlab.com/gaosong/qemu into staging (2024-07-19 16:28:28 +1000)

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 67d834362c55d6fca6504975bc34755606f17cf2:

   virtio: Always reset vhost devices (2024-07-21 14:45:56 -0400)

----------------------------------------------------------------
virtio,pci,pc: features,fixes

pci: Initial support for SPDM Responders
cxl: Add support for scan media, feature commands, device patrol scrub control, DDR5 ECS control, firmware updates
virtio: in-order support
virtio-net: support for SR-IOV emulation (note: known issues on s390, might get reverted if not fixed)
smbios: memory device size is now configurable per Machine
cpu: architecture agnostic code to support vCPU Hotplug

Fixes, cleanups all over the place.

Quoted 7 lines
Quoted 1 line

Fails ubsan testing:

https://gitlab.com/qemu-project/qemu/-/jobs/7397450714

../publish/hw/net/virtio-net.c:3895:18: runtime error: member access within null pointer of type 'struct vhost_net'

Honestly, I saw this piece of code, but concluded it already doesn’t make sense, so I assumed someone™ who wrote this would know why it’s been written this way, and I should rather not touch it.

Specifically, the problem is that get_vhost_net() can return a NULL pointer[1], which is fine, but virtio_net_get_vhost() never checks this.  I assumed this was written with intent (i.e. (uintptr_t)&net->dev == (uintptr_t)net, so that NULL remains NULL), because it’s so obvious that get_vhost_net() can happily return NULL under many circumstances, but maybe not.

The same theoretically applies to virtio_crypto_get_vhost(), although I don’t think that can ever be NULL in practice.

I’ll re-send the reset patch in a series with two patches that fix those two functions to check for NULL and explicitly return NULL if necessary.  In the meantime, it probably makes sense to drop it from this pull request.

Hanna

[1] For some reason, it uses integer 0 throughout to signify NULL. That was another reason that put me off touching this.

#71 lore raw
Quoted 59 lines · Hanna Czenczek
Quoted 35 lines · Richard Henderson
Quoted 34 lines · Michael S. Tsirkin

A couple of fixes are outstanding, will merge later.

The following changes since commit
a87a7c449e532130d4fa8faa391ff7e1f04ed660:

   Merge tag 'pull-loongarch-20240719' ofhttps://gitlab.com/gaosong/qemu into staging (2024-07-19 16:28:28 +1000)

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 67d834362c55d6fca6504975bc34755606f17cf2:

   virtio: Always reset vhost devices (2024-07-21 14:45:56 -0400)

----------------------------------------------------------------
virtio,pci,pc: features,fixes

pci: Initial support for SPDM Responders
cxl: Add support for scan media, feature commands, device patrol scrub control, DDR5 ECS control, firmware updates
virtio: in-order support
virtio-net: support for SR-IOV emulation (note: known issues on s390, might get reverted if not fixed)
smbios: memory device size is now configurable per Machine
cpu: architecture agnostic code to support vCPU Hotplug

Fixes, cleanups all over the place.

Quoted 8 lines
Quoted 1 line

Fails ubsan testing:

https://gitlab.com/qemu-project/qemu/-/jobs/7397450714

../publish/hw/net/virtio-net.c:3895:18: runtime error: member access within null pointer of type 'struct vhost_net'

Honestly, I saw this piece of code, but concluded it already doesn’t make sense, so I assumed someone™ who wrote this would know why it’s been written this way, and I should rather not touch it.

Specifically, the problem is that get_vhost_net() can return a NULL pointer[1], which is fine, but virtio_net_get_vhost() never checks this.  I assumed this was written with intent (i.e. (uintptr_t)&net->dev == (uintptr_t)net, so that NULL remains NULL), because it’s so obvious that get_vhost_net() can happily return NULL under many circumstances, but maybe not.

The same theoretically applies to virtio_crypto_get_vhost(), although I don’t think that can ever be NULL in practice.

Quoted 8 lines

I’ll re-send the reset patch in a series with two patches that fix those two functions to check for NULL and explicitly return NULL if necessary.  In the meantime, it probably makes sense to drop it from this pull request.

Hanna

[1] For some reason, it uses integer 0 throughout to signify NULL. That was another reason that put me off touching this.

drop what specifically?

#72 lore raw
Quoted 62 lines · Michael S. Tsirkin
Quoted 61 lines · Hanna Czenczek
Quoted 35 lines · Richard Henderson
Quoted 34 lines · Michael S. Tsirkin

A couple of fixes are outstanding, will merge later.

The following changes since commit
a87a7c449e532130d4fa8faa391ff7e1f04ed660:

   Merge tag 'pull-loongarch-20240719'
ofhttps://gitlab.com/gaosong/qemu into staging (2024-07-19 16:28:28 +1000)

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 67d834362c55d6fca6504975bc34755606f17cf2:

   virtio: Always reset vhost devices (2024-07-21 14:45:56 -0400)

----------------------------------------------------------------
virtio,pci,pc: features,fixes

pci: Initial support for SPDM Responders
cxl: Add support for scan media, feature commands, device patrol scrub
     control, DDR5 ECS control, firmware updates
virtio: in-order support
virtio-net: support for SR-IOV emulation (note: known issues on s390,
                                           might get reverted if not
fixed)
smbios: memory device size is now configurable per Machine
cpu: architecture agnostic code to support vCPU Hotplug

Fixes, cleanups all over the place.

Quoted 7 lines
Quoted 1 line

Fails ubsan testing:

https://gitlab.com/qemu-project/qemu/-/jobs/7397450714

../publish/hw/net/virtio-net.c:3895:18: runtime error: member access within null pointer of type 'struct vhost_net'

Honestly, I saw this piece of code, but concluded it already doesn’t make sense, so I assumed someone™ who wrote this would know why it’s been written this way, and I should rather not touch it.

Specifically, the problem is that get_vhost_net() can return a NULL pointer[1], which is fine, but virtio_net_get_vhost() never checks this.  I assumed this was written with intent (i.e. (uintptr_t)&net->dev == (uintptr_t)net, so that NULL remains NULL), because it’s so obvious that get_vhost_net() can happily return NULL under many circumstances, but maybe not.

The same theoretically applies to virtio_crypto_get_vhost(), although I don’t think that can ever be NULL in practice.

I’ll re-send the reset patch in a series with two patches that fix those two functions to check for NULL and explicitly return NULL if necessary.  In the meantime, it probably makes sense to drop it from this pull request.

Quoted 5 lines
Quoted 4 lines

Hanna

[1] For some reason, it uses integer 0 throughout to signify NULL. That was another reason that put me off touching this.

drop what specifically?

My patch, "virtio: Always reset vhost devices".

Judging from the CI trace, the problem to me appears to be that not making get_vhost() depend on vhost_started lets ubsan find a way to have get_vhost_net() return NULL (which I don’t find surprising, that’s why we check get_vhost()’s return value for whether it’s NULL).  It then complains about the &net->dev in virtio_net_get_vhost(), because net is NULL, and it’s not entirely clear that &net->dev == NULL, too (it is, which is why I decided to leave that piece of code be, originally).

So dropping my patch should make CI succeed again.

Hanna