* [PULL 01/51] vhost-user: ancilliary -> ancillary
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
@ 2026-02-04 19:02 ` Michael S. Tsirkin
2026-02-04 19:02 ` [PULL 02/51] hw/cxl/cxl-mailbox-utils: Move declaration of scrub and ECS feature attributes in cmd_features_set_feature() Michael S. Tsirkin
` (52 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:02 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Philippe Mathieu-Daudé, Gustavo Romero,
Stefano Garzarella, Pierrick Bouvier
My dictionary says the former spelling is incorrect.
Message-ID: <52339e58-4366-4b7c-872f-b28e05370a5d@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Gustavo Romero <gustavo.romero@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
docs/interop/vhost-user.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
index 93a9c8df2b..93f756d3f4 100644
--- a/docs/interop/vhost-user.rst
+++ b/docs/interop/vhost-user.rst
@@ -411,8 +411,8 @@ in the ancillary data:
* ``VHOST_USER_SET_INFLIGHT_FD`` (if ``VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD``)
* ``VHOST_USER_SET_DEVICE_STATE_FD``
-When sending file descriptors in ancilliary data, *front-end* should
-associate the ancilliary data with a ``sendmsg`` operation (or
+When sending file descriptors in ancillary data, *front-end* should
+associate the ancillary data with a ``sendmsg`` operation (or
equivalent) that sends bytes starting with the first byte of the
message header. *back-end* can therefore expect that file descriptors
will only be received in the first ``recvmsg`` operation for a message
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 02/51] hw/cxl/cxl-mailbox-utils: Move declaration of scrub and ECS feature attributes in cmd_features_set_feature()
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
2026-02-04 19:02 ` [PULL 01/51] vhost-user: ancilliary -> ancillary Michael S. Tsirkin
@ 2026-02-04 19:02 ` Michael S. Tsirkin
2026-02-04 19:02 ` [PULL 03/51] hw/cxl: Add support for Maintenance command and Post Package Repair (PPR) Michael S. Tsirkin
` (51 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Shiju Jose, Jonathan Cameron, Fan Ni
From: Shiju Jose <shiju.jose@huawei.com>
Move the declaration of scrub and ECS feature attributes in
cmd_features_set_feature() to the local scope where they are used.
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20250917143330.294698-2-Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-mailbox-utils.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 6cfdd98168..65b599f7aa 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -1351,10 +1351,6 @@ static CXLRetCode cmd_features_set_feature(const struct cxl_cmd *cmd,
CXLCCI *cci)
{
CXLSetFeatureInHeader *hdr = (void *)payload_in;
- CXLMemPatrolScrubWriteAttrs *ps_write_attrs;
- CXLMemPatrolScrubSetFeature *ps_set_feature;
- CXLMemECSWriteAttrs *ecs_write_attrs;
- CXLMemECSSetFeature *ecs_set_feature;
CXLSetFeatureInfo *set_feat_info;
uint16_t bytes_to_copy = 0;
uint8_t data_transfer_flag;
@@ -1396,13 +1392,14 @@ static CXLRetCode cmd_features_set_feature(const struct cxl_cmd *cmd,
}
if (qemu_uuid_is_equal(&hdr->uuid, &patrol_scrub_uuid)) {
+ CXLMemPatrolScrubSetFeature *ps_set_feature = (void *)payload_in;
+ CXLMemPatrolScrubWriteAttrs *ps_write_attrs =
+ &ps_set_feature->feat_data;
+
if (hdr->version != CXL_MEMDEV_PS_SET_FEATURE_VERSION) {
return CXL_MBOX_UNSUPPORTED;
}
- ps_set_feature = (void *)payload_in;
- ps_write_attrs = &ps_set_feature->feat_data;
-
if ((uint32_t)hdr->offset + bytes_to_copy >
sizeof(ct3d->patrol_scrub_wr_attrs)) {
return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
@@ -1423,13 +1420,13 @@ static CXLRetCode cmd_features_set_feature(const struct cxl_cmd *cmd,
}
} else if (qemu_uuid_is_equal(&hdr->uuid,
&ecs_uuid)) {
+ CXLMemECSSetFeature *ecs_set_feature = (void *)payload_in;
+ CXLMemECSWriteAttrs *ecs_write_attrs = ecs_set_feature->feat_data;
+
if (hdr->version != CXL_ECS_SET_FEATURE_VERSION) {
return CXL_MBOX_UNSUPPORTED;
}
- ecs_set_feature = (void *)payload_in;
- ecs_write_attrs = ecs_set_feature->feat_data;
-
if ((uint32_t)hdr->offset + bytes_to_copy >
sizeof(ct3d->ecs_wr_attrs)) {
return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 03/51] hw/cxl: Add support for Maintenance command and Post Package Repair (PPR)
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
2026-02-04 19:02 ` [PULL 01/51] vhost-user: ancilliary -> ancillary Michael S. Tsirkin
2026-02-04 19:02 ` [PULL 02/51] hw/cxl/cxl-mailbox-utils: Move declaration of scrub and ECS feature attributes in cmd_features_set_feature() Michael S. Tsirkin
@ 2026-02-04 19:02 ` Michael S. Tsirkin
2026-02-04 19:02 ` [PULL 04/51] hw/cxl: Add emulation for memory sparing control feature Michael S. Tsirkin
` (50 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:02 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Davidlohr Bueso, Shiju Jose, Jonathan Cameron,
Fan Ni
From: Davidlohr Bueso <dave@stgolabs.net>
This adds initial support for the Maintenance command, specifically
the soft and hard PPR operations on a dpa. The implementation allows
to be executed at runtime, therefore semantically, data is retained
and CXL.mem requests are correctly processed.
Keep track of the requests upon a general media or DRAM event.
Post Package Repair (PPR) maintenance operations may be supported by CXL
devices that implement CXL.mem protocol. A PPR maintenance operation
requests the CXL device to perform a repair operation on its media.
For example, a CXL device with DRAM components that support PPR features
may implement PPR Maintenance operations. DRAM components may support two
types of PPR, hard PPR (hPPR), for a permanent row repair, and Soft PPR
(sPPR), for a temporary row repair. Soft PPR is much faster than hPPR,
but the repair is lost with a power cycle.
CXL spec 3.2 section 8.2.10.7.1.2 describes the device's sPPR (soft PPR)
maintenance operation and section 8.2.10.7.1.3 describes the device's
hPPR (hard PPR) maintenance operation feature.
CXL spec 3.2 section 8.2.10.7.2.1 describes the sPPR feature discovery and
configuration.
CXL spec 3.2 section 8.2.10.7.2.2 describes the hPPR feature discovery and
configuration.
CXL spec 3.2 section 8.2.10.2.1.4 Table 8-60 describes the Memory Sparing
Event Record.
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Co-developed-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20250917143330.294698-3-Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-mailbox-utils.c | 240 +++++++++++++++++++++++++++++++++++-
hw/mem/cxl_type3.c | 125 +++++++++++++++++++
include/hw/cxl/cxl_device.h | 112 +++++++++++++++++
include/hw/cxl/cxl_events.h | 42 +++++++
4 files changed, 517 insertions(+), 2 deletions(-)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 65b599f7aa..8c38b88ad4 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -86,6 +86,8 @@ enum {
#define GET_SUPPORTED 0x0
#define GET_FEATURE 0x1
#define SET_FEATURE 0x2
+ MAINTENANCE = 0x06,
+ #define PERFORM 0x0
IDENTIFY = 0x40,
#define MEMORY_DEVICE 0x0
CCLS = 0x41,
@@ -1111,8 +1113,8 @@ typedef struct CXLSupportedFeatureEntry {
#define CXL_FEAT_ENTRY_ATTR_FLAG_CHANGABLE BIT(0)
#define CXL_FEAT_ENTRY_ATTR_FLAG_DEEPEST_RESET_PERSISTENCE_MASK GENMASK(3, 1)
#define CXL_FEAT_ENTRY_ATTR_FLAG_PERSIST_ACROSS_FIRMWARE_UPDATE BIT(4)
-#define CXL_FEAT_ENTRY_ATTR_FLAG_SUPPORT_DEFAULT_SELECTION BIT(5)
-#define CXL_FEAT_ENTRY_ATTR_FLAG_SUPPORT_SAVED_SELECTION BIT(6)
+#define CXL_FEAT_ENTRY_ATTR_FLAG_SUPPORT_DEFAULT_SEL BIT(5)
+#define CXL_FEAT_ENTRY_ATTR_FLAG_SUPPORT_SAVED_SEL BIT(6)
/* Supported Feature Entry : set feature effects */
#define CXL_FEAT_ENTRY_SFE_CONFIG_CHANGE_COLD_RESET BIT(0)
@@ -1131,6 +1133,8 @@ typedef struct CXLSupportedFeatureEntry {
enum CXL_SUPPORTED_FEATURES_LIST {
CXL_FEATURE_PATROL_SCRUB = 0,
CXL_FEATURE_ECS,
+ CXL_FEATURE_SPPR,
+ CXL_FEATURE_HPPR,
CXL_FEATURE_MAX
};
@@ -1172,6 +1176,28 @@ enum CXL_SET_FEATURE_FLAG_DATA_TRANSFER {
};
#define CXL_SET_FEAT_DATA_SAVED_ACROSS_RESET BIT(3)
+/* CXL r3.2 section 8.2.10.7.2.1: sPPR Feature Discovery and Configuration */
+static const QemuUUID soft_ppr_uuid = {
+ .data = UUID(0x892ba475, 0xfad8, 0x474e, 0x9d, 0x3e,
+ 0x69, 0x2c, 0x91, 0x75, 0x68, 0xbb)
+};
+
+typedef struct CXLMemSoftPPRSetFeature {
+ CXLSetFeatureInHeader hdr;
+ CXLMemSoftPPRWriteAttrs feat_data;
+} QEMU_PACKED QEMU_ALIGNED(16) CXLMemSoftPPRSetFeature;
+
+/* CXL r3.2 section 8.2.10.7.2.2: hPPR Feature Discovery and Configuration */
+static const QemuUUID hard_ppr_uuid = {
+ .data = UUID(0x80ea4521, 0x786f, 0x4127, 0xaf, 0xb1,
+ 0xec, 0x74, 0x59, 0xfb, 0x0e, 0x24)
+};
+
+typedef struct CXLMemHardPPRSetFeature {
+ CXLSetFeatureInHeader hdr;
+ CXLMemHardPPRWriteAttrs feat_data;
+} QEMU_PACKED QEMU_ALIGNED(16) CXLMemHardPPRSetFeature;
+
/* CXL r3.1 section 8.2.9.9.11.1: Device Patrol Scrub Control Feature */
static const QemuUUID patrol_scrub_uuid = {
.data = UUID(0x96dad7d6, 0xfde8, 0x482b, 0xa7, 0x33,
@@ -1235,6 +1261,38 @@ static CXLRetCode cmd_features_get_supported(const struct cxl_cmd *cmd,
for (entry = 0, index = get_feats_in->start_index;
entry < req_entries; index++) {
switch (index) {
+ case CXL_FEATURE_SPPR:
+ /* Fill supported feature entry for soft-PPR */
+ get_feats_out->feat_entries[entry++] =
+ (struct CXLSupportedFeatureEntry) {
+ .uuid = soft_ppr_uuid,
+ .feat_index = index,
+ .get_feat_size = sizeof(CXLMemSoftPPRReadAttrs),
+ .set_feat_size = sizeof(CXLMemSoftPPRWriteAttrs),
+ .attr_flags = CXL_FEAT_ENTRY_ATTR_FLAG_CHANGABLE |
+ CXL_FEAT_ENTRY_ATTR_FLAG_SUPPORT_DEFAULT_SEL,
+ .get_feat_version = CXL_MEMDEV_SPPR_GET_FEATURE_VERSION,
+ .set_feat_version = CXL_MEMDEV_SPPR_SET_FEATURE_VERSION,
+ .set_feat_effects = CXL_FEAT_ENTRY_SFE_IMMEDIATE_CONFIG_CHANGE |
+ CXL_FEAT_ENTRY_SFE_CEL_VALID,
+ };
+ break;
+ case CXL_FEATURE_HPPR:
+ /* Fill supported feature entry for hard-PPR */
+ get_feats_out->feat_entries[entry++] =
+ (struct CXLSupportedFeatureEntry) {
+ .uuid = hard_ppr_uuid,
+ .feat_index = index,
+ .get_feat_size = sizeof(CXLMemHardPPRReadAttrs),
+ .set_feat_size = sizeof(CXLMemHardPPRWriteAttrs),
+ .attr_flags = CXL_FEAT_ENTRY_ATTR_FLAG_CHANGABLE |
+ CXL_FEAT_ENTRY_ATTR_FLAG_SUPPORT_DEFAULT_SEL,
+ .get_feat_version = CXL_MEMDEV_HPPR_GET_FEATURE_VERSION,
+ .set_feat_version = CXL_MEMDEV_HPPR_SET_FEATURE_VERSION,
+ .set_feat_effects = CXL_FEAT_ENTRY_SFE_IMMEDIATE_CONFIG_CHANGE |
+ CXL_FEAT_ENTRY_SFE_CEL_VALID,
+ };
+ break;
case CXL_FEATURE_PATROL_SCRUB:
/* Fill supported feature entry for device patrol scrub control */
get_feats_out->feat_entries[entry++] =
@@ -1333,6 +1391,26 @@ static CXLRetCode cmd_features_get_feature(const struct cxl_cmd *cmd,
memcpy(payload_out,
(uint8_t *)&ct3d->ecs_attrs + get_feature->offset,
bytes_to_copy);
+ } else if (qemu_uuid_is_equal(&get_feature->uuid, &soft_ppr_uuid)) {
+ if (get_feature->offset >= sizeof(CXLMemSoftPPRReadAttrs)) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ bytes_to_copy = sizeof(CXLMemSoftPPRReadAttrs) -
+ get_feature->offset;
+ bytes_to_copy = MIN(bytes_to_copy, get_feature->count);
+ memcpy(payload_out,
+ (uint8_t *)&ct3d->soft_ppr_attrs + get_feature->offset,
+ bytes_to_copy);
+ } else if (qemu_uuid_is_equal(&get_feature->uuid, &hard_ppr_uuid)) {
+ if (get_feature->offset >= sizeof(CXLMemHardPPRReadAttrs)) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ bytes_to_copy = sizeof(CXLMemHardPPRReadAttrs) -
+ get_feature->offset;
+ bytes_to_copy = MIN(bytes_to_copy, get_feature->count);
+ memcpy(payload_out,
+ (uint8_t *)&ct3d->hard_ppr_attrs + get_feature->offset,
+ bytes_to_copy);
} else {
return CXL_MBOX_UNSUPPORTED;
}
@@ -1444,6 +1522,44 @@ static CXLRetCode cmd_features_set_feature(const struct cxl_cmd *cmd,
ct3d->ecs_wr_attrs.fru_attrs[count].ecs_config & 0x1F;
}
}
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &soft_ppr_uuid)) {
+ CXLMemSoftPPRSetFeature *sppr_set_feature = (void *)payload_in;
+ CXLMemSoftPPRWriteAttrs *sppr_write_attrs =
+ &sppr_set_feature->feat_data;
+
+ if (hdr->version != CXL_MEMDEV_SPPR_SET_FEATURE_VERSION) {
+ return CXL_MBOX_UNSUPPORTED;
+ }
+
+ memcpy((uint8_t *)&ct3d->soft_ppr_wr_attrs + hdr->offset,
+ sppr_write_attrs, bytes_to_copy);
+ set_feat_info->data_size += bytes_to_copy;
+
+ if (data_transfer_flag == CXL_SET_FEATURE_FLAG_FULL_DATA_TRANSFER ||
+ data_transfer_flag == CXL_SET_FEATURE_FLAG_FINISH_DATA_TRANSFER) {
+ ct3d->soft_ppr_attrs.op_mode = ct3d->soft_ppr_wr_attrs.op_mode;
+ ct3d->soft_ppr_attrs.sppr_op_mode =
+ ct3d->soft_ppr_wr_attrs.sppr_op_mode;
+ }
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &hard_ppr_uuid)) {
+ CXLMemHardPPRSetFeature *hppr_set_feature = (void *)payload_in;
+ CXLMemHardPPRWriteAttrs *hppr_write_attrs =
+ &hppr_set_feature->feat_data;
+
+ if (hdr->version != CXL_MEMDEV_HPPR_SET_FEATURE_VERSION) {
+ return CXL_MBOX_UNSUPPORTED;
+ }
+
+ memcpy((uint8_t *)&ct3d->hard_ppr_wr_attrs + hdr->offset,
+ hppr_write_attrs, bytes_to_copy);
+ set_feat_info->data_size += bytes_to_copy;
+
+ if (data_transfer_flag == CXL_SET_FEATURE_FLAG_FULL_DATA_TRANSFER ||
+ data_transfer_flag == CXL_SET_FEATURE_FLAG_FINISH_DATA_TRANSFER) {
+ ct3d->hard_ppr_attrs.op_mode = ct3d->hard_ppr_wr_attrs.op_mode;
+ ct3d->hard_ppr_attrs.hppr_op_mode =
+ ct3d->hard_ppr_wr_attrs.hppr_op_mode;
+ }
} else {
return CXL_MBOX_UNSUPPORTED;
}
@@ -1456,6 +1572,10 @@ static CXLRetCode cmd_features_set_feature(const struct cxl_cmd *cmd,
memset(&ct3d->patrol_scrub_wr_attrs, 0, set_feat_info->data_size);
} else if (qemu_uuid_is_equal(&hdr->uuid, &ecs_uuid)) {
memset(&ct3d->ecs_wr_attrs, 0, set_feat_info->data_size);
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &soft_ppr_uuid)) {
+ memset(&ct3d->soft_ppr_wr_attrs, 0, set_feat_info->data_size);
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &hard_ppr_uuid)) {
+ memset(&ct3d->hard_ppr_wr_attrs, 0, set_feat_info->data_size);
}
set_feat_info->data_transfer_flag = 0;
set_feat_info->data_saved_across_reset = false;
@@ -1466,6 +1586,116 @@ static CXLRetCode cmd_features_set_feature(const struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
+static void cxl_mbox_create_mem_sparing_event_records(CXLType3Dev *ct3d,
+ uint8_t maint_op_class, uint8_t maint_op_sub_class,
+ CXLMaintenance *ent)
+{
+ CXLEventSparing event_rec = {};
+
+ cxl_assign_event_header(&event_rec.hdr,
+ &sparing_uuid,
+ (1 << CXL_EVENT_TYPE_INFO),
+ sizeof(event_rec),
+ cxl_device_get_timestamp(&ct3d->cxl_dstate),
+ 1, maint_op_class, 1, maint_op_sub_class,
+ 0, 0, 0, 0);
+ if (ent) {
+ event_rec.flags = 0;
+ event_rec.result = 0;
+ stw_le_p(&event_rec.res_avail, 2);
+ stw_le_p(&event_rec.validity_flags, ent->validity_flags);
+ event_rec.channel = ent->channel;
+ event_rec.rank = ent->rank;
+ st24_le_p(event_rec.nibble_mask, ent->nibble_mask);
+ event_rec.bank_group = ent->bank_group;
+ event_rec.bank = ent->bank;
+ st24_le_p(event_rec.row, ent->row);
+ stw_le_p(&event_rec.column, ent->column);
+ event_rec.sub_channel = ent->sub_channel;
+ if (ent->validity_flags & CXL_MSER_VALID_COMP_ID) {
+ strncpy((char *)event_rec.component_id, (char *)ent->component_id,
+ sizeof(event_rec.component_id));
+ }
+ } else {
+ return;
+ }
+
+ if (cxl_event_insert(&ct3d->cxl_dstate,
+ CXL_EVENT_TYPE_INFO,
+ (CXLEventRecordRaw *)&event_rec)) {
+ cxl_event_irq_assert(ct3d);
+ }
+}
+
+
+static void cxl_perform_ppr(CXLType3Dev *ct3d, uint64_t dpa)
+{
+ CXLMaintenance *ent, *next;
+
+ QLIST_FOREACH_SAFE(ent, &ct3d->maint_list, node, next) {
+ if (dpa == ent->dpa) {
+ /* Produce a Memory Sparing Event Record */
+ if (ct3d->soft_ppr_attrs.sppr_op_mode &
+ CXL_MEMDEV_SPPR_OP_MODE_MEM_SPARING_EV_REC_EN) {
+ cxl_mbox_create_mem_sparing_event_records(ct3d,
+ CXL_MEMDEV_MAINT_CLASS_SPARING,
+ CXL_MEMDEV_MAINT_SUBCLASS_CACHELINE_SPARING,
+ ent);
+ }
+ break;
+ }
+ }
+}
+
+/* CXL r3.2 section 8.2.10.7.1 - Perform Maintenance (Opcode 0600h) */
+#define MAINTENANCE_PPR_QUERY_RESOURCES BIT(0)
+
+static CXLRetCode cmd_media_perform_maintenance(const struct cxl_cmd *cmd,
+ uint8_t *payload_in, size_t len_in,
+ uint8_t *payload_out, size_t *len_out,
+ CXLCCI *cci)
+{
+ struct {
+ uint8_t class;
+ uint8_t subclass;
+ union {
+ struct {
+ uint8_t flags;
+ uint64_t dpa;
+ uint8_t nibble_mask[3];
+ } QEMU_PACKED ppr;
+ };
+ } QEMU_PACKED *maint_in = (void *)payload_in;
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
+
+ if (maintenance_running(cci)) {
+ return CXL_MBOX_BUSY;
+ }
+
+ switch (maint_in->class) {
+ case CXL_MEMDEV_MAINT_CLASS_NO_OP:
+ return CXL_MBOX_SUCCESS; /* nop */
+ case CXL_MEMDEV_MAINT_CLASS_PPR:
+ if (maint_in->ppr.flags & MAINTENANCE_PPR_QUERY_RESOURCES) {
+ return CXL_MBOX_SUCCESS;
+ }
+
+ switch (maint_in->subclass) {
+ case CXL_MEMDEV_MAINT_SUBCLASS_SPPR:
+ case CXL_MEMDEV_MAINT_SUBCLASS_HPPR:
+ cxl_perform_ppr(ct3d, ldq_le_p(&maint_in->ppr.dpa));
+ return CXL_MBOX_SUCCESS;
+ default:
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ break;
+ default:
+ return CXL_MBOX_INVALID_INPUT;
+ }
+
+ return CXL_MBOX_SUCCESS;
+}
+
/* CXL r3.1 Section 8.2.9.9.1.1: Identify Memory Device (Opcode 4000h) */
static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
uint8_t *payload_in,
@@ -3761,6 +3991,12 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
CXL_MBOX_IMMEDIATE_POLICY_CHANGE |
CXL_MBOX_IMMEDIATE_LOG_CHANGE |
CXL_MBOX_SECURITY_STATE_CHANGE)},
+ [MAINTENANCE][PERFORM] = { "MAINTENANCE_PERFORM",
+ cmd_media_perform_maintenance, ~0,
+ CXL_MBOX_IMMEDIATE_CONFIG_CHANGE |
+ CXL_MBOX_IMMEDIATE_DATA_CHANGE |
+ CXL_MBOX_IMMEDIATE_LOG_CHANGE |
+ CXL_MBOX_BACKGROUND_OPERATION },
[IDENTIFY][MEMORY_DEVICE] = { "IDENTIFY_MEMORY_DEVICE",
cmd_identify_memory_device, 0, 0 },
[CCLS][GET_PARTITION_INFO] = { "CCLS_GET_PARTITION_INFO",
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 6eb20137a0..b02dc31f11 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -964,6 +964,32 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
ct3d->ecs_attrs.fru_attrs[count].ecs_flags = 0;
}
+ /* Set default values for soft-PPR attributes */
+ ct3d->soft_ppr_attrs = (CXLMemSoftPPRReadAttrs) {
+ .max_maint_latency = 0x5, /* 100 ms */
+ .op_caps = 0, /* require host involvement */
+ .op_mode = 0,
+ .maint_op_class = CXL_MEMDEV_MAINT_CLASS_PPR,
+ .maint_op_subclass = CXL_MEMDEV_MAINT_SUBCLASS_SPPR,
+ .sppr_flags = CXL_MEMDEV_SPPR_DPA_SUPPORT_FLAG |
+ CXL_MEMDEV_SPPR_MEM_SPARING_EV_REC_CAP_FLAG,
+ .restriction_flags = 0,
+ .sppr_op_mode = CXL_MEMDEV_SPPR_OP_MODE_MEM_SPARING_EV_REC_EN
+ };
+
+ /* Set default value for hard-PPR attributes */
+ ct3d->hard_ppr_attrs = (CXLMemHardPPRReadAttrs) {
+ .max_maint_latency = 0x5, /* 100 ms */
+ .op_caps = 0, /* require host involvement */
+ .op_mode = 0,
+ .maint_op_class = CXL_MEMDEV_MAINT_CLASS_PPR,
+ .maint_op_subclass = CXL_MEMDEV_MAINT_SUBCLASS_HPPR,
+ .hppr_flags = CXL_MEMDEV_HPPR_DPA_SUPPORT_FLAG |
+ CXL_MEMDEV_HPPR_MEM_SPARING_EV_REC_CAP_FLAG,
+ .restriction_flags = 0,
+ .hppr_op_mode = CXL_MEMDEV_HPPR_OP_MODE_MEM_SPARING_EV_REC_EN
+ };
+
return;
err_release_cdat:
@@ -1635,6 +1661,75 @@ static int ct3d_qmp_cxl_event_log_enc(CxlEventLog log)
return -EINVAL;
}
}
+
+static void cxl_maintenance_insert(CXLType3Dev *ct3d, uint64_t dpa,
+ bool has_channel, uint8_t channel,
+ bool has_rank, uint8_t rank,
+ bool has_nibble_mask, uint32_t nibble_mask,
+ bool has_bank_group, uint8_t bank_group,
+ bool has_bank, uint8_t bank,
+ bool has_row, uint32_t row,
+ bool has_column, uint16_t column,
+ const char *component_id,
+ bool has_comp_id_pldm, bool is_comp_id_pldm,
+ bool has_sub_channel, uint8_t sub_channel)
+{
+ CXLMaintenance *ent, *m;
+
+ QLIST_FOREACH(ent, &ct3d->maint_list, node) {
+ if (dpa == ent->dpa) {
+ return;
+ }
+ }
+ m = g_new0(CXLMaintenance, 1);
+ memset(m, 0, sizeof(*m));
+ m->dpa = dpa;
+ m->validity_flags = 0;
+
+ if (has_channel) {
+ m->channel = channel;
+ m->validity_flags |= CXL_MSER_VALID_CHANNEL;
+ }
+ if (has_rank) {
+ m->rank = rank;
+ m->validity_flags |= CXL_MSER_VALID_RANK;
+ }
+ if (has_nibble_mask) {
+ m->nibble_mask = nibble_mask;
+ m->validity_flags |= CXL_MSER_VALID_NIB_MASK;
+ }
+ if (has_bank_group) {
+ m->bank_group = bank_group;
+ m->validity_flags |= CXL_MSER_VALID_BANK_GROUP;
+ }
+ if (has_bank) {
+ m->bank = bank;
+ m->validity_flags |= CXL_MSER_VALID_BANK;
+ }
+ if (has_row) {
+ m->row = row;
+ m->validity_flags |= CXL_MSER_VALID_ROW;
+ }
+ if (has_column) {
+ m->column = column;
+ m->validity_flags |= CXL_MSER_VALID_COLUMN;
+ }
+ if (has_sub_channel) {
+ m->sub_channel = sub_channel;
+ m->validity_flags |= CXL_MSER_VALID_SUB_CHANNEL;
+ }
+ if (component_id) {
+ strncpy((char *)m->component_id, component_id,
+ sizeof(m->component_id) - 1);
+ m->validity_flags |= CXL_MSER_VALID_COMP_ID;
+ if (has_comp_id_pldm && is_comp_id_pldm) {
+ m->validity_flags |= CXL_MSER_VALID_COMP_ID_FORMAT;
+ }
+ }
+
+ QLIST_INSERT_HEAD(&ct3d->maint_list, m, node);
+}
+
/* Component ID is device specific. Define this as a string. */
void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
uint8_t flags, uint64_t dpa,
@@ -1671,6 +1766,11 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
error_setg(errp, "Unhandled error log type");
return;
}
+ if (rc == CXL_EVENT_TYPE_INFO &&
+ (flags & CXL_EVENT_REC_FLAGS_MAINT_NEEDED)) {
+ error_setg(errp, "Informational event cannot require maintenance");
+ return;
+ }
enc_log = rc;
memset(&gem, 0, sizeof(gem));
@@ -1708,6 +1808,15 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
if (cxl_event_insert(cxlds, enc_log, (CXLEventRecordRaw *)&gem)) {
cxl_event_irq_assert(ct3d);
}
+
+ if (flags & CXL_EVENT_REC_FLAGS_MAINT_NEEDED) {
+ cxl_maintenance_insert(ct3d, dpa, has_channel, channel,
+ has_rank, rank,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, component_id,
+ has_comp_id_pldm, is_comp_id_pldm,
+ 0, 0);
+ }
}
#define CXL_DRAM_VALID_CHANNEL BIT(0)
@@ -1758,6 +1867,11 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
error_setg(errp, "Unhandled error log type");
return;
}
+ if (rc == CXL_EVENT_TYPE_INFO &&
+ (flags & CXL_EVENT_REC_FLAGS_MAINT_NEEDED)) {
+ error_setg(errp, "Informational event cannot require maintenance");
+ return;
+ }
enc_log = rc;
memset(&dram, 0, sizeof(dram));
@@ -1819,6 +1933,17 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
if (cxl_event_insert(cxlds, enc_log, (CXLEventRecordRaw *)&dram)) {
cxl_event_irq_assert(ct3d);
}
+
+ if (flags & CXL_EVENT_REC_FLAGS_MAINT_NEEDED) {
+ cxl_maintenance_insert(ct3d, dpa, has_channel, channel,
+ has_rank, rank,
+ has_nibble_mask, nibble_mask,
+ has_bank_group, bank_group,
+ has_bank, bank, has_row, row,
+ has_column, column, component_id,
+ has_comp_id_pldm, is_comp_id_pldm,
+ has_sub_channel, sub_channel);
+ }
}
void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 165355baf9..72e8c68187 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -430,6 +430,12 @@ 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 maintenance_running(CXLCCI *cci)
+{
+ return cci->bg.runtime && cci->bg.opcode == 0x0600;
+}
+
static inline bool scan_media_running(CXLCCI *cci)
{
return !!cci->bg.runtime && cci->bg.opcode == 0x4304;
@@ -443,6 +449,23 @@ typedef struct CXLError {
typedef QTAILQ_HEAD(, CXLError) CXLErrorList;
+typedef struct CXLMaintenance {
+ uint64_t dpa;
+ uint16_t validity_flags;
+ uint8_t channel;
+ uint8_t rank;
+ uint32_t nibble_mask;
+ uint8_t bank_group;
+ uint8_t bank;
+ uint32_t row;
+ uint16_t column;
+ uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
+ uint8_t sub_channel;
+ QLIST_ENTRY(CXLMaintenance) node;
+} CXLMaintenance;
+
+typedef QLIST_HEAD(, CXLMaintenance) CXLMaintenanceList;
+
typedef struct CXLPoison {
uint64_t start, length;
uint8_t type;
@@ -455,6 +478,87 @@ typedef struct CXLPoison {
typedef QLIST_HEAD(, CXLPoison) CXLPoisonList;
#define CXL_POISON_LIST_LIMIT 256
+/* CXL memory maintenance operation */
+/*
+ * CXL r3.2 section 8.2.10.7.2, Table 8-125: Mainteance Operation:
+ * Classes, Subclasses, and Feature UUIDs
+ */
+#define CXL_MEMDEV_MAINT_CLASS_NO_OP 0x0
+#define CXL_MEMDEV_MAINT_CLASS_PPR 0x1
+#define CXL_MEMDEV_MAINT_CLASS_SPARING 0x2
+#define CXL_MEMDEV_MAINT_CLASS_DEV_BUILT_IN_TEST 0x3
+
+#define CXL_MEMDEV_MAINT_SUBCLASS_SPPR 0x0
+#define CXL_MEMDEV_MAINT_SUBCLASS_HPPR 0x1
+
+#define CXL_MEMDEV_MAINT_SUBCLASS_CACHELINE_SPARING 0x0
+#define CXL_MEMDEV_MAINT_SUBCLASS_ROW_SPARING 0x1
+#define CXL_MEMDEV_MAINT_SUBCLASS_BANK_SPARING 0x2
+#define CXL_MEMDEV_MAINT_SUBCLASS_RANK_SPARING 0x3
+
+/* CXL memory Post Package Repair control attributes */
+/*
+ * CXL r3.2 section 8.2.10.7.2.1, Table 8-128 and 8-129:
+ * sPPR Feature Readable/Writable Attributes
+ */
+typedef struct CXLMemSoftPPRReadAttrs {
+ uint8_t max_maint_latency;
+ uint16_t op_caps;
+ uint16_t op_mode;
+ uint8_t maint_op_class;
+ uint8_t maint_op_subclass;
+ uint8_t rsvd[9];
+ uint8_t sppr_flags;
+ uint16_t restriction_flags;
+ uint8_t sppr_op_mode;
+} QEMU_PACKED CXLMemSoftPPRReadAttrs;
+
+typedef struct CXLMemSoftPPRWriteAttrs {
+ uint16_t op_mode;
+ uint8_t sppr_op_mode;
+} QEMU_PACKED CXLMemSoftPPRWriteAttrs;
+
+#define CXL_MEMDEV_SPPR_GET_FEATURE_VERSION 0x03
+#define CXL_MEMDEV_SPPR_SET_FEATURE_VERSION 0x03
+#define CXL_MEMDEV_SPPR_DPA_SUPPORT_FLAG BIT(0)
+#define CXL_MEMDEV_SPPR_NIBBLE_SUPPORT_FLAG BIT(1)
+#define CXL_MEMDEV_SPPR_MEM_SPARING_EV_REC_CAP_FLAG BIT(2)
+#define CXL_MEMDEV_SPPR_DEV_INITIATED_AT_BOOT_CAP_FLAG BIT(3)
+
+#define CXL_MEMDEV_SPPR_OP_MODE_MEM_SPARING_EV_REC_EN BIT(0)
+#define CXL_MEMDEV_SPPR_OP_MODE_DEV_INITIATED_AT_BOOT BIT(1)
+
+/*
+ * CXL r3.2 section 8.2.10.7.2.2, Table 8-131 and 8-132:
+ * hPPR Feature Readable/Writable Attributes
+ */
+typedef struct CXLMemHardPPRReadAttrs {
+ uint8_t max_maint_latency;
+ uint16_t op_caps;
+ uint16_t op_mode;
+ uint8_t maint_op_class;
+ uint8_t maint_op_subclass;
+ uint8_t rsvd[9];
+ uint8_t hppr_flags;
+ uint16_t restriction_flags;
+ uint8_t hppr_op_mode;
+} QEMU_PACKED CXLMemHardPPRReadAttrs;
+
+typedef struct CXLMemHardPPRWriteAttrs {
+ uint16_t op_mode;
+ uint8_t hppr_op_mode;
+} QEMU_PACKED CXLMemHardPPRWriteAttrs;
+
+#define CXL_MEMDEV_HPPR_GET_FEATURE_VERSION 0x03
+#define CXL_MEMDEV_HPPR_SET_FEATURE_VERSION 0x03
+#define CXL_MEMDEV_HPPR_DPA_SUPPORT_FLAG BIT(0)
+#define CXL_MEMDEV_HPPR_NIBBLE_SUPPORT_FLAG BIT(1)
+#define CXL_MEMDEV_HPPR_MEM_SPARING_EV_REC_CAP_FLAG BIT(2)
+#define CXL_MEMDEV_HPPR_DEV_INITIATED_AT_BOOT_CAP_FLAG BIT(3)
+
+#define CXL_MEMDEV_HPPR_OP_MODE_MEM_SPARING_EV_REC_EN BIT(0)
+#define CXL_MEMDEV_HPPR_OP_MODE_DEV_INITIATED_AT_BOOT BIT(1)
+
/* CXL memory device patrol scrub control attributes */
typedef struct CXLMemPatrolScrubReadAttrs {
uint8_t scrub_cycle_cap;
@@ -605,6 +709,9 @@ struct CXLType3Dev {
/* Error injection */
CXLErrorList error_list;
+ /* Keep track of maintenance requests */
+ CXLMaintenanceList maint_list;
+
/* Poison Injection - cache */
CXLPoisonList poison_list;
unsigned int poison_list_cnt;
@@ -617,6 +724,11 @@ struct CXLType3Dev {
CXLSetFeatureInfo set_feat_info;
+ /* PPR control attributes */
+ CXLMemSoftPPRReadAttrs soft_ppr_attrs;
+ CXLMemSoftPPRWriteAttrs soft_ppr_wr_attrs;
+ CXLMemHardPPRReadAttrs hard_ppr_attrs;
+ CXLMemHardPPRWriteAttrs hard_ppr_wr_attrs;
/* Patrol scrub control attributes */
CXLMemPatrolScrubReadAttrs patrol_scrub_attrs;
CXLMemPatrolScrubWriteAttrs patrol_scrub_wr_attrs;
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index 758b075a64..7cba494b72 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -199,4 +199,46 @@ typedef enum CXLDCEventType {
DC_EVENT_CAPACITY_RELEASED = 0x5,
} CXLDCEventType;
+/*
+ * CXL r3.2 section Table 8-60: Memory Sparing Event Record
+ * All fields little endian.
+ */
+#define CXL_MSER_VALID_CHANNEL BIT(0)
+#define CXL_MSER_VALID_RANK BIT(1)
+#define CXL_MSER_VALID_NIB_MASK BIT(2)
+#define CXL_MSER_VALID_BANK_GROUP BIT(3)
+#define CXL_MSER_VALID_BANK BIT(4)
+#define CXL_MSER_VALID_ROW BIT(5)
+#define CXL_MSER_VALID_COLUMN BIT(6)
+#define CXL_MSER_VALID_COMP_ID BIT(7)
+#define CXL_MSER_VALID_COMP_ID_FORMAT BIT(8)
+#define CXL_MSER_VALID_SUB_CHANNEL BIT(9)
+
+typedef struct CXLEventSparing {
+ CXLEventRecordHdr hdr;
+ uint8_t maint_op_class;
+ uint8_t maint_op_subclass;
+ uint8_t flags;
+ uint8_t result;
+ uint16_t validity_flags;
+ uint8_t reserved1[6];
+ uint16_t res_avail;
+ uint8_t channel;
+ uint8_t rank;
+ uint8_t nibble_mask[3];
+ uint8_t bank_group;
+ uint8_t bank;
+ uint8_t row[3];
+ uint16_t column;
+ uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
+ uint8_t sub_channel;
+ uint8_t reserved2[0x25];
+} QEMU_PACKED CXLEventSparing;
+
+/* CXL r3.2 Table 8-60: Memory Sparing Event Record */
+static const QemuUUID sparing_uuid = {
+ .data = UUID(0xe71f3a40, 0x2d29, 0x4092, 0x8a, 0x39,
+ 0x4d, 0x1c, 0x96, 0x6c, 0x7c, 0x65),
+};
+
#endif /* CXL_EVENTS_H */
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 04/51] hw/cxl: Add emulation for memory sparing control feature
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (2 preceding siblings ...)
2026-02-04 19:02 ` [PULL 03/51] hw/cxl: Add support for Maintenance command and Post Package Repair (PPR) Michael S. Tsirkin
@ 2026-02-04 19:02 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 05/51] qapi: cxl: Refactor CXL event injection for common commands arguments Michael S. Tsirkin
` (49 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Shiju Jose, Jonathan Cameron, Fan Ni
From: Shiju Jose <shiju.jose@huawei.com>
Memory sparing is defined as a repair function that replaces a portion of
memory with a portion of functional memory at that same DPA. The
subclasses for this operation vary in terms of the scope of the sparing
being performed. The Cacheline sparing subclass refers to a sparing
action that can replace a full cacheline. Row sparing is provided as an
alternative to PPR sparing functions and its scope is that of a single
DDR row. Bank sparing allows an entire bank to be replaced. Rank sparing
is defined as an operation in which an entire DDR rank is replaced.
Memory sparing maintenance operations may be supported by CXL devices
that implement CXL.mem protocol. A sparing maintenance operation requests
the CXL device to perform a repair operation on its media.
For example, a CXL device with DRAM components that support memory sparing
features may implement sparing Maintenance operations.
The host may issue a query command by setting Query Resources flag in the
Input Payload (CXL Spec 3.2 Table 8-120) to determine availability of
sparing resources for a given address. In response to a query request,
the device shall report the resource availability by producing the Memory
Sparing Event Record (CXL Spec 3.2 Table 8-60) in which the Channel, Rank,
Nibble Mask, Bank Group, Bank, Row, Column, Sub-Channel fields are a copy
of the values specified in the request.
During the execution of a sparing maintenance operation, a CXL memory
device:
- May or may not retain data
- May or may not be able to process CXL.mem requests correctly.
These CXL memory device capabilities are specified by restriction flags
in the memory sparing feature readable attributes.
When a CXL device identifies error on a memory component, the device
may inform the host about the need for a memory sparing maintenance
operation by using DRAM event record, where the 'maintenance needed' flag
may set. The event record contains some of the DPA, Channel, Rank,
Nibble Mask, Bank Group, Bank, Row, Column, Sub-Channel fields that
should be repaired. The userspace tool requests for maintenance operation
if the 'maintenance needed' flag set in the CXL DRAM error record.
CXL spec 3.2 section 8.2.10.7.2.3 describes the memory sparing feature
discovery and configuration.
CXL spec 3.2 section 8.2.10.7.1.4 describes the device's memory sparing
maintenance operation feature.
Add emulation for CXL memory device memory sparing control feature
and memory sparing maintenance operation command.
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20250917143330.294698-4-Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-mailbox-utils.c | 317 +++++++++++++++++++++++++++++++++++-
hw/mem/cxl_type3.c | 44 +++++
include/hw/cxl/cxl_device.h | 33 ++++
include/hw/cxl/cxl_events.h | 5 +
4 files changed, 395 insertions(+), 4 deletions(-)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 8c38b88ad4..a4bd49e113 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -1135,6 +1135,10 @@ enum CXL_SUPPORTED_FEATURES_LIST {
CXL_FEATURE_ECS,
CXL_FEATURE_SPPR,
CXL_FEATURE_HPPR,
+ CXL_FEATURE_CACHELINE_SPARING,
+ CXL_FEATURE_ROW_SPARING,
+ CXL_FEATURE_BANK_SPARING,
+ CXL_FEATURE_RANK_SPARING,
CXL_FEATURE_MAX
};
@@ -1223,6 +1227,35 @@ typedef struct CXLMemECSSetFeature {
CXLMemECSWriteAttrs feat_data[];
} QEMU_PACKED QEMU_ALIGNED(16) CXLMemECSSetFeature;
+/*
+ * CXL r3.2 section 8.2.10.7.2.3:
+ * Memory Sparing Features Discovery and Configuration
+ */
+static const QemuUUID cacheline_sparing_uuid = {
+ .data = UUID(0x96C33386, 0x91dd, 0x44c7, 0x9e, 0xcb,
+ 0xfd, 0xaf, 0x65, 0x03, 0xba, 0xc4)
+};
+
+static const QemuUUID row_sparing_uuid = {
+ .data = UUID(0x450ebf67, 0xb135, 0x4f97, 0xa4, 0x98,
+ 0xc2, 0xd5, 0x7f, 0x27, 0x9b, 0xed)
+};
+
+static const QemuUUID bank_sparing_uuid = {
+ .data = UUID(0x78b79636, 0x90ac, 0x4b64, 0xa4, 0xef,
+ 0xfa, 0xac, 0x5d, 0x18, 0xa8, 0x63)
+};
+
+static const QemuUUID rank_sparing_uuid = {
+ .data = UUID(0x34dbaff5, 0x0552, 0x4281, 0x8f, 0x76,
+ 0xda, 0x0b, 0x5e, 0x7a, 0x76, 0xa7)
+};
+
+typedef struct CXLMemSparingSetFeature {
+ CXLSetFeatureInHeader hdr;
+ CXLMemSparingWriteAttrs feat_data;
+} QEMU_PACKED QEMU_ALIGNED(16) CXLMemSparingSetFeature;
+
/* CXL r3.1 section 8.2.9.6.1: Get Supported Features (Opcode 0500h) */
static CXLRetCode cmd_features_get_supported(const struct cxl_cmd *cmd,
uint8_t *payload_in,
@@ -1323,6 +1356,70 @@ static CXLRetCode cmd_features_get_supported(const struct cxl_cmd *cmd,
CXL_FEAT_ENTRY_SFE_CEL_VALID,
};
break;
+ case CXL_FEATURE_CACHELINE_SPARING:
+ /* Fill supported feature entry for Cacheline Memory Sparing */
+ get_feats_out->feat_entries[entry++] =
+ (struct CXLSupportedFeatureEntry) {
+ .uuid = cacheline_sparing_uuid,
+ .feat_index = index,
+ .get_feat_size = sizeof(CXLMemSparingReadAttrs),
+ .set_feat_size = sizeof(CXLMemSparingWriteAttrs),
+ .attr_flags = CXL_FEAT_ENTRY_ATTR_FLAG_CHANGABLE |
+ CXL_FEAT_ENTRY_ATTR_FLAG_SUPPORT_DEFAULT_SEL,
+ .get_feat_version = CXL_MEMDEV_SPARING_GET_FEATURE_VERSION,
+ .set_feat_version = CXL_MEMDEV_SPARING_SET_FEATURE_VERSION,
+ .set_feat_effects = CXL_FEAT_ENTRY_SFE_IMMEDIATE_CONFIG_CHANGE |
+ CXL_FEAT_ENTRY_SFE_CEL_VALID,
+ };
+ break;
+ case CXL_FEATURE_ROW_SPARING:
+ /* Fill supported feature entry for Row Memory Sparing */
+ get_feats_out->feat_entries[entry++] =
+ (struct CXLSupportedFeatureEntry) {
+ .uuid = row_sparing_uuid,
+ .feat_index = index,
+ .get_feat_size = sizeof(CXLMemSparingReadAttrs),
+ .set_feat_size = sizeof(CXLMemSparingWriteAttrs),
+ .attr_flags = CXL_FEAT_ENTRY_ATTR_FLAG_CHANGABLE |
+ CXL_FEAT_ENTRY_ATTR_FLAG_SUPPORT_DEFAULT_SEL,
+ .get_feat_version = CXL_MEMDEV_SPARING_GET_FEATURE_VERSION,
+ .set_feat_version = CXL_MEMDEV_SPARING_SET_FEATURE_VERSION,
+ .set_feat_effects = CXL_FEAT_ENTRY_SFE_IMMEDIATE_CONFIG_CHANGE |
+ CXL_FEAT_ENTRY_SFE_CEL_VALID,
+ };
+ break;
+ case CXL_FEATURE_BANK_SPARING:
+ /* Fill supported feature entry for Bank Memory Sparing */
+ get_feats_out->feat_entries[entry++] =
+ (struct CXLSupportedFeatureEntry) {
+ .uuid = bank_sparing_uuid,
+ .feat_index = index,
+ .get_feat_size = sizeof(CXLMemSparingReadAttrs),
+ .set_feat_size = sizeof(CXLMemSparingWriteAttrs),
+ .attr_flags = CXL_FEAT_ENTRY_ATTR_FLAG_CHANGABLE |
+ CXL_FEAT_ENTRY_ATTR_FLAG_SUPPORT_DEFAULT_SEL,
+ .get_feat_version = CXL_MEMDEV_SPARING_GET_FEATURE_VERSION,
+ .set_feat_version = CXL_MEMDEV_SPARING_SET_FEATURE_VERSION,
+ .set_feat_effects = CXL_FEAT_ENTRY_SFE_IMMEDIATE_CONFIG_CHANGE |
+ CXL_FEAT_ENTRY_SFE_CEL_VALID,
+ };
+ break;
+ case CXL_FEATURE_RANK_SPARING:
+ /* Fill supported feature entry for Rank Memory Sparing */
+ get_feats_out->feat_entries[entry++] =
+ (struct CXLSupportedFeatureEntry) {
+ .uuid = rank_sparing_uuid,
+ .feat_index = index,
+ .get_feat_size = sizeof(CXLMemSparingReadAttrs),
+ .set_feat_size = sizeof(CXLMemSparingWriteAttrs),
+ .attr_flags = CXL_FEAT_ENTRY_ATTR_FLAG_CHANGABLE |
+ CXL_FEAT_ENTRY_ATTR_FLAG_SUPPORT_DEFAULT_SEL,
+ .get_feat_version = CXL_MEMDEV_SPARING_GET_FEATURE_VERSION,
+ .set_feat_version = CXL_MEMDEV_SPARING_SET_FEATURE_VERSION,
+ .set_feat_effects = CXL_FEAT_ENTRY_SFE_IMMEDIATE_CONFIG_CHANGE |
+ CXL_FEAT_ENTRY_SFE_CEL_VALID,
+ };
+ break;
default:
__builtin_unreachable();
}
@@ -1411,6 +1508,47 @@ static CXLRetCode cmd_features_get_feature(const struct cxl_cmd *cmd,
memcpy(payload_out,
(uint8_t *)&ct3d->hard_ppr_attrs + get_feature->offset,
bytes_to_copy);
+ } else if (qemu_uuid_is_equal(&get_feature->uuid,
+ &cacheline_sparing_uuid)) {
+ if (get_feature->offset >= sizeof(CXLMemSparingReadAttrs)) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ bytes_to_copy = sizeof(CXLMemSparingReadAttrs) -
+ get_feature->offset;
+ bytes_to_copy = MIN(bytes_to_copy, get_feature->count);
+ memcpy(payload_out,
+ (uint8_t *)&ct3d->cacheline_sparing_attrs + get_feature->offset,
+ bytes_to_copy);
+ } else if (qemu_uuid_is_equal(&get_feature->uuid, &row_sparing_uuid)) {
+ if (get_feature->offset >= sizeof(CXLMemSparingReadAttrs)) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ bytes_to_copy = sizeof(CXLMemSparingReadAttrs) -
+ get_feature->offset;
+ bytes_to_copy = MIN(bytes_to_copy, get_feature->count);
+ memcpy(payload_out,
+ (uint8_t *)&ct3d->row_sparing_attrs + get_feature->offset,
+ bytes_to_copy);
+ } else if (qemu_uuid_is_equal(&get_feature->uuid, &bank_sparing_uuid)) {
+ if (get_feature->offset >= sizeof(CXLMemSparingReadAttrs)) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ bytes_to_copy = sizeof(CXLMemSparingReadAttrs) -
+ get_feature->offset;
+ bytes_to_copy = MIN(bytes_to_copy, get_feature->count);
+ memcpy(payload_out,
+ (uint8_t *)&ct3d->bank_sparing_attrs + get_feature->offset,
+ bytes_to_copy);
+ } else if (qemu_uuid_is_equal(&get_feature->uuid, &rank_sparing_uuid)) {
+ if (get_feature->offset >= sizeof(CXLMemSparingReadAttrs)) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ bytes_to_copy = sizeof(CXLMemSparingReadAttrs) -
+ get_feature->offset;
+ bytes_to_copy = MIN(bytes_to_copy, get_feature->count);
+ memcpy(payload_out,
+ (uint8_t *)&ct3d->rank_sparing_attrs + get_feature->offset,
+ bytes_to_copy);
} else {
return CXL_MBOX_UNSUPPORTED;
}
@@ -1560,6 +1698,78 @@ static CXLRetCode cmd_features_set_feature(const struct cxl_cmd *cmd,
ct3d->hard_ppr_attrs.hppr_op_mode =
ct3d->hard_ppr_wr_attrs.hppr_op_mode;
}
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &cacheline_sparing_uuid)) {
+ CXLMemSparingSetFeature *mem_sparing_set_feature = (void *)payload_in;
+ CXLMemSparingWriteAttrs *mem_sparing_write_attrs =
+ &mem_sparing_set_feature->feat_data;
+
+ if (hdr->version != CXL_MEMDEV_SPARING_SET_FEATURE_VERSION) {
+ return CXL_MBOX_UNSUPPORTED;
+ }
+
+ memcpy((uint8_t *)&ct3d->cacheline_sparing_wr_attrs + hdr->offset,
+ mem_sparing_write_attrs, bytes_to_copy);
+ set_feat_info->data_size += bytes_to_copy;
+
+ if (data_transfer_flag == CXL_SET_FEATURE_FLAG_FULL_DATA_TRANSFER ||
+ data_transfer_flag == CXL_SET_FEATURE_FLAG_FINISH_DATA_TRANSFER) {
+ ct3d->cacheline_sparing_attrs.op_mode =
+ ct3d->cacheline_sparing_wr_attrs.op_mode;
+ }
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &row_sparing_uuid)) {
+ CXLMemSparingSetFeature *mem_sparing_set_feature = (void *)payload_in;
+ CXLMemSparingWriteAttrs *mem_sparing_write_attrs =
+ &mem_sparing_set_feature->feat_data;
+
+ if (hdr->version != CXL_MEMDEV_SPARING_SET_FEATURE_VERSION) {
+ return CXL_MBOX_UNSUPPORTED;
+ }
+
+ memcpy((uint8_t *)&ct3d->row_sparing_wr_attrs + hdr->offset,
+ mem_sparing_write_attrs, bytes_to_copy);
+ set_feat_info->data_size += bytes_to_copy;
+
+ if (data_transfer_flag == CXL_SET_FEATURE_FLAG_FULL_DATA_TRANSFER ||
+ data_transfer_flag == CXL_SET_FEATURE_FLAG_FINISH_DATA_TRANSFER) {
+ ct3d->row_sparing_attrs.op_mode =
+ ct3d->row_sparing_wr_attrs.op_mode;
+ }
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &bank_sparing_uuid)) {
+ CXLMemSparingSetFeature *mem_sparing_set_feature = (void *)payload_in;
+ CXLMemSparingWriteAttrs *mem_sparing_write_attrs =
+ &mem_sparing_set_feature->feat_data;
+
+ if (hdr->version != CXL_MEMDEV_SPARING_SET_FEATURE_VERSION) {
+ return CXL_MBOX_UNSUPPORTED;
+ }
+
+ memcpy((uint8_t *)&ct3d->bank_sparing_wr_attrs + hdr->offset,
+ mem_sparing_write_attrs, bytes_to_copy);
+ set_feat_info->data_size += bytes_to_copy;
+
+ if (data_transfer_flag == CXL_SET_FEATURE_FLAG_FULL_DATA_TRANSFER ||
+ data_transfer_flag == CXL_SET_FEATURE_FLAG_FINISH_DATA_TRANSFER) {
+ ct3d->bank_sparing_attrs.op_mode =
+ ct3d->bank_sparing_wr_attrs.op_mode;
+ }
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &rank_sparing_uuid)) {
+ CXLMemSparingSetFeature *mem_sparing_set_feature = (void *)payload_in;
+ CXLMemSparingWriteAttrs *mem_sparing_write_attrs =
+ &mem_sparing_set_feature->feat_data;
+
+ if (hdr->version != CXL_MEMDEV_SPARING_SET_FEATURE_VERSION) {
+ return CXL_MBOX_UNSUPPORTED;
+ }
+
+ memcpy((uint8_t *)&ct3d->rank_sparing_wr_attrs + hdr->offset,
+ mem_sparing_write_attrs, bytes_to_copy);
+ set_feat_info->data_size += bytes_to_copy;
+
+ if (data_transfer_flag == CXL_SET_FEATURE_FLAG_FULL_DATA_TRANSFER ||
+ data_transfer_flag == CXL_SET_FEATURE_FLAG_FINISH_DATA_TRANSFER) {
+ ct3d->rank_sparing_attrs.op_mode =
+ ct3d->rank_sparing_wr_attrs.op_mode;
+ }
} else {
return CXL_MBOX_UNSUPPORTED;
}
@@ -1576,6 +1786,15 @@ static CXLRetCode cmd_features_set_feature(const struct cxl_cmd *cmd,
memset(&ct3d->soft_ppr_wr_attrs, 0, set_feat_info->data_size);
} else if (qemu_uuid_is_equal(&hdr->uuid, &hard_ppr_uuid)) {
memset(&ct3d->hard_ppr_wr_attrs, 0, set_feat_info->data_size);
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &cacheline_sparing_uuid)) {
+ memset(&ct3d->cacheline_sparing_wr_attrs, 0,
+ set_feat_info->data_size);
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &row_sparing_uuid)) {
+ memset(&ct3d->row_sparing_wr_attrs, 0, set_feat_info->data_size);
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &bank_sparing_uuid)) {
+ memset(&ct3d->bank_sparing_wr_attrs, 0, set_feat_info->data_size);
+ } else if (qemu_uuid_is_equal(&hdr->uuid, &rank_sparing_uuid)) {
+ memset(&ct3d->rank_sparing_wr_attrs, 0, set_feat_info->data_size);
}
set_feat_info->data_transfer_flag = 0;
set_feat_info->data_saved_across_reset = false;
@@ -1586,9 +1805,27 @@ static CXLRetCode cmd_features_set_feature(const struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
-static void cxl_mbox_create_mem_sparing_event_records(CXLType3Dev *ct3d,
+#define CXL_MEM_SPARING_FLAGS_QUERY_RESOURCES BIT(0)
+#define CXL_MEM_SPARING_FLAGS_HARD_SPARING BIT(1)
+#define CXL_MEM_SPARING_FLAGS_SUB_CHANNEL_VALID BIT(2)
+#define CXL_MEM_SPARING_FLAGS_NIB_MASK_VALID BIT(3)
+
+typedef struct CXLMemSparingMaintInPayload {
+ uint8_t flags;
+ uint8_t channel;
+ uint8_t rank;
+ uint8_t nibble_mask[3];
+ uint8_t bank_group;
+ uint8_t bank;
+ uint8_t row[3];
+ uint16_t column;
+ uint8_t sub_channel;
+} QEMU_PACKED CXLMemSparingMaintInPayload;
+
+static void cxl_create_mem_sparing_event_records(CXLType3Dev *ct3d,
uint8_t maint_op_class, uint8_t maint_op_sub_class,
- CXLMaintenance *ent)
+ CXLMaintenance *ent,
+ CXLMemSparingMaintInPayload *sparing_pi)
{
CXLEventSparing event_rec = {};
@@ -1616,6 +1853,31 @@ static void cxl_mbox_create_mem_sparing_event_records(CXLType3Dev *ct3d,
strncpy((char *)event_rec.component_id, (char *)ent->component_id,
sizeof(event_rec.component_id));
}
+ } else if (sparing_pi) {
+ event_rec.flags = CXL_MSER_FLAGS_QUERY_RESOURCES;
+ event_rec.result = 0;
+ event_rec.validity_flags = CXL_MSER_VALID_CHANNEL |
+ CXL_MSER_VALID_RANK |
+ CXL_MSER_VALID_NIB_MASK |
+ CXL_MSER_VALID_BANK_GROUP |
+ CXL_MSER_VALID_BANK |
+ CXL_MSER_VALID_ROW |
+ CXL_MSER_VALID_COLUMN;
+ event_rec.res_avail = 1;
+ event_rec.channel = sparing_pi->channel;
+ event_rec.rank = sparing_pi->rank;
+ if (sparing_pi->flags & CXL_MEM_SPARING_FLAGS_NIB_MASK_VALID) {
+ memcpy(event_rec.nibble_mask, sparing_pi->nibble_mask,
+ sizeof(sparing_pi->nibble_mask));
+ }
+ event_rec.bank_group = sparing_pi->bank_group;
+ event_rec.bank = sparing_pi->bank;
+ event_rec.column = sparing_pi->column;
+ memcpy(event_rec.row, sparing_pi->row, sizeof(sparing_pi->row));
+ if (sparing_pi->flags & CXL_MEM_SPARING_FLAGS_SUB_CHANNEL_VALID) {
+ event_rec.sub_channel = sparing_pi->sub_channel;
+ event_rec.validity_flags |= CXL_MSER_VALID_SUB_CHANNEL;
+ }
} else {
return;
}
@@ -1627,6 +1889,26 @@ static void cxl_mbox_create_mem_sparing_event_records(CXLType3Dev *ct3d,
}
}
+static CXLRetCode cxl_perform_mem_sparing(CXLType3Dev *ct3d, uint8_t sub_class,
+ void *maint_pi)
+{
+ switch (sub_class) {
+ case CXL_MEMDEV_MAINT_SUBCLASS_CACHELINE_SPARING:
+ qemu_log("Cacheline Memory Sparing\n");
+ return CXL_MBOX_SUCCESS;
+ case CXL_MEMDEV_MAINT_SUBCLASS_ROW_SPARING:
+ qemu_log("Row Memory Sparing\n");
+ return CXL_MBOX_SUCCESS;
+ case CXL_MEMDEV_MAINT_SUBCLASS_BANK_SPARING:
+ qemu_log("Bank Memory Sparing\n");
+ return CXL_MBOX_SUCCESS;
+ case CXL_MEMDEV_MAINT_SUBCLASS_RANK_SPARING:
+ qemu_log("Rank Memory Sparing\n");
+ return CXL_MBOX_SUCCESS;
+ default:
+ return CXL_MBOX_INVALID_INPUT;
+ }
+}
static void cxl_perform_ppr(CXLType3Dev *ct3d, uint64_t dpa)
{
@@ -1637,10 +1919,10 @@ static void cxl_perform_ppr(CXLType3Dev *ct3d, uint64_t dpa)
/* Produce a Memory Sparing Event Record */
if (ct3d->soft_ppr_attrs.sppr_op_mode &
CXL_MEMDEV_SPPR_OP_MODE_MEM_SPARING_EV_REC_EN) {
- cxl_mbox_create_mem_sparing_event_records(ct3d,
+ cxl_create_mem_sparing_event_records(ct3d,
CXL_MEMDEV_MAINT_CLASS_SPARING,
CXL_MEMDEV_MAINT_SUBCLASS_CACHELINE_SPARING,
- ent);
+ ent, NULL);
}
break;
}
@@ -1664,6 +1946,7 @@ static CXLRetCode cmd_media_perform_maintenance(const struct cxl_cmd *cmd,
uint64_t dpa;
uint8_t nibble_mask[3];
} QEMU_PACKED ppr;
+ CXLMemSparingMaintInPayload mem_sparing_pi;
};
} QEMU_PACKED *maint_in = (void *)payload_in;
CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
@@ -1689,6 +1972,32 @@ static CXLRetCode cmd_media_perform_maintenance(const struct cxl_cmd *cmd,
return CXL_MBOX_INVALID_INPUT;
}
break;
+ case CXL_MEMDEV_MAINT_CLASS_SPARING:
+ if (maint_in->mem_sparing_pi.flags &
+ CXL_MEM_SPARING_FLAGS_QUERY_RESOURCES) {
+ /*
+ * CXL r3.2 sect 8.2.10.7.1.4 - Memory Sparing Maintenance Operation
+ * Produce Memory Sparing Event record to report resources
+ * availability.
+ */
+ cxl_create_mem_sparing_event_records(ct3d, maint_in->class,
+ maint_in->subclass, NULL,
+ &maint_in->mem_sparing_pi);
+
+ return CXL_MBOX_SUCCESS;
+ }
+
+ switch (maint_in->subclass) {
+ case CXL_MEMDEV_MAINT_SUBCLASS_CACHELINE_SPARING:
+ case CXL_MEMDEV_MAINT_SUBCLASS_ROW_SPARING:
+ case CXL_MEMDEV_MAINT_SUBCLASS_BANK_SPARING:
+ case CXL_MEMDEV_MAINT_SUBCLASS_RANK_SPARING:
+ return cxl_perform_mem_sparing(ct3d, maint_in->subclass,
+ &maint_in->mem_sparing_pi);
+ default:
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ break;
default:
return CXL_MBOX_INVALID_INPUT;
}
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index b02dc31f11..7e309af935 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -990,6 +990,50 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
.hppr_op_mode = CXL_MEMDEV_HPPR_OP_MODE_MEM_SPARING_EV_REC_EN
};
+ /* Set default value for Cacheline Memory Sparing attributes */
+ ct3d->cacheline_sparing_attrs = (CXLMemSparingReadAttrs) {
+ .max_maint_latency = 0x5, /* 100 ms */
+ .op_caps = 0, /* require host involvement */
+ .op_mode = 0,
+ .maint_op_class = CXL_MEMDEV_MAINT_CLASS_SPARING,
+ .maint_op_subclass = CXL_MEMDEV_MAINT_SUBCLASS_CACHELINE_SPARING,
+ .restriction_flags = CXL_MEMDEV_HARD_SPARING_SUPPORT_FLAG |
+ CXL_MEMDEV_SOFT_SPARING_SUPPORT_FLAG,
+ };
+
+ /* Set default value for Row Memory Sparing attributes */
+ ct3d->row_sparing_attrs = (CXLMemSparingReadAttrs) {
+ .max_maint_latency = 0x5, /* 100 ms */
+ .op_caps = 0, /* require host involvement */
+ .op_mode = 0,
+ .maint_op_class = CXL_MEMDEV_MAINT_CLASS_SPARING,
+ .maint_op_subclass = CXL_MEMDEV_MAINT_SUBCLASS_ROW_SPARING,
+ .restriction_flags = CXL_MEMDEV_HARD_SPARING_SUPPORT_FLAG |
+ CXL_MEMDEV_SOFT_SPARING_SUPPORT_FLAG,
+ };
+
+ /* Set default value for Bank Memory Sparing attributes */
+ ct3d->bank_sparing_attrs = (CXLMemSparingReadAttrs) {
+ .max_maint_latency = 0x5, /* 100 ms */
+ .op_caps = 0, /* require host involvement */
+ .op_mode = 0,
+ .maint_op_class = CXL_MEMDEV_MAINT_CLASS_SPARING,
+ .maint_op_subclass = CXL_MEMDEV_MAINT_SUBCLASS_BANK_SPARING,
+ .restriction_flags = CXL_MEMDEV_HARD_SPARING_SUPPORT_FLAG |
+ CXL_MEMDEV_SOFT_SPARING_SUPPORT_FLAG,
+ };
+
+ /* Set default value for Rank Memory Sparing attributes */
+ ct3d->rank_sparing_attrs = (CXLMemSparingReadAttrs) {
+ .max_maint_latency = 0x5, /* 100 ms */
+ .op_caps = 0, /* require host involvement */
+ .op_mode = 0,
+ .maint_op_class = CXL_MEMDEV_MAINT_CLASS_SPARING,
+ .maint_op_subclass = CXL_MEMDEV_MAINT_SUBCLASS_RANK_SPARING,
+ .restriction_flags = CXL_MEMDEV_HARD_SPARING_SUPPORT_FLAG |
+ CXL_MEMDEV_SOFT_SPARING_SUPPORT_FLAG,
+ };
+
return;
err_release_cdat:
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 72e8c68187..55797a9ec3 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -608,6 +608,30 @@ typedef struct CXLMemECSWriteAttrs {
CXLMemECSFRUWriteAttrs fru_attrs[CXL_ECS_NUM_MEDIA_FRUS];
} QEMU_PACKED CXLMemECSWriteAttrs;
+/*
+ * CXL r3.2 section 8.2.10.7.2.3, Table 8-134 and 8-135:
+ * Memory Sparing Feature Readable/Writable Attributes
+ */
+typedef struct CXLMemSparingReadAttrs {
+ uint8_t max_maint_latency;
+ uint16_t op_caps;
+ uint16_t op_mode;
+ uint8_t maint_op_class;
+ uint8_t maint_op_subclass;
+ uint8_t rsvd[10];
+ uint16_t restriction_flags;
+} QEMU_PACKED CXLMemSparingReadAttrs;
+
+typedef struct CXLMemSparingWriteAttrs {
+ uint16_t op_mode;
+} QEMU_PACKED CXLMemSparingWriteAttrs;
+
+#define CXL_MEMDEV_SPARING_GET_FEATURE_VERSION 0x01
+#define CXL_MEMDEV_SPARING_SET_FEATURE_VERSION 0x01
+#define CXL_MEMDEV_SPARING_SAFE_IN_USE_FLAG BIT(0)
+#define CXL_MEMDEV_HARD_SPARING_SUPPORT_FLAG BIT(1)
+#define CXL_MEMDEV_SOFT_SPARING_SUPPORT_FLAG BIT(2)
+
#define DCD_MAX_NUM_REGION 8
typedef struct CXLDCExtentRaw {
@@ -735,6 +759,15 @@ struct CXLType3Dev {
/* ECS control attributes */
CXLMemECSReadAttrs ecs_attrs;
CXLMemECSWriteAttrs ecs_wr_attrs;
+ /* Memory Sparing control attributes */
+ CXLMemSparingReadAttrs cacheline_sparing_attrs;
+ CXLMemSparingWriteAttrs cacheline_sparing_wr_attrs;
+ CXLMemSparingReadAttrs row_sparing_attrs;
+ CXLMemSparingWriteAttrs row_sparing_wr_attrs;
+ CXLMemSparingReadAttrs bank_sparing_attrs;
+ CXLMemSparingWriteAttrs bank_sparing_wr_attrs;
+ CXLMemSparingReadAttrs rank_sparing_attrs;
+ CXLMemSparingWriteAttrs rank_sparing_wr_attrs;
struct dynamic_capacity {
HostMemoryBackend *host_dc;
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index 7cba494b72..8a660c7a62 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -203,6 +203,11 @@ typedef enum CXLDCEventType {
* CXL r3.2 section Table 8-60: Memory Sparing Event Record
* All fields little endian.
*/
+
+#define CXL_MSER_FLAGS_QUERY_RESOURCES BIT(0)
+#define CXL_MSER_FLAGS_HARD_SPARING BIT(1)
+#define CXL_MSER_FLAGS_DEV_INITIATED BIT(2)
+
#define CXL_MSER_VALID_CHANNEL BIT(0)
#define CXL_MSER_VALID_RANK BIT(1)
#define CXL_MSER_VALID_NIB_MASK BIT(2)
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 05/51] qapi: cxl: Refactor CXL event injection for common commands arguments
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (3 preceding siblings ...)
2026-02-04 19:02 ` [PULL 04/51] hw/cxl: Add emulation for memory sparing control feature Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-05 6:45 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 06/51] hw/cxl/events: Update for rev3.2 common event record format Michael S. Tsirkin
` (48 subsequent siblings)
53 siblings, 1 reply; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Shiju Jose, Markus Armbruster, Jonathan Cameron,
Fan Ni, Eric Blake
From: Shiju Jose <shiju.jose@huawei.com>
Refactor CXL event injection to use struct for common command
arguments.
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260114142713.617806-2-Jonathan.Cameron@huawei.com>
---
qapi/cxl.json | 89 +++++++++++++++++++++++++++++++++------------------
1 file changed, 58 insertions(+), 31 deletions(-)
diff --git a/qapi/cxl.json b/qapi/cxl.json
index eeddb58d1d..55a088586e 100644
--- a/qapi/cxl.json
+++ b/qapi/cxl.json
@@ -31,11 +31,10 @@
}
##
-# @cxl-inject-general-media-event:
+# @CXLCommonEventBase:
#
-# Inject an event record for a General Media Event (CXL r3.0
-# 8.2.9.2.1.1). This event type is reported via one of the event logs
-# specified via the log parameter.
+# Common event base for a CXL Event (CXL r3.0 8.2.9.2.1
+# Table 8-42 Common Event Record Format).
#
# @path: CXL type 3 device canonical QOM path
#
@@ -44,6 +43,16 @@
# @flags: Event Record Flags. See CXL r3.0 Table 8-42 Common Event
# Record Format, Event Record Flags for subfield definitions.
#
+# Since: 8.1
+##
+{ 'struct': 'CXLCommonEventBase',
+ 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint8' } }
+
+##
+# @CXLGeneralMediaEvent:
+#
+# Event record for a General Media Event (CXL r3.0 8.2.9.2.1.1).
+#
# @dpa: Device Physical Address (relative to @path device). Note
# lower bits include some flags. See CXL r3.0 Table 8-43 General
# Media Event Record, Physical Address.
@@ -74,26 +83,29 @@
#
# Since: 8.1
##
-{ 'command': 'cxl-inject-general-media-event',
- 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint8',
- 'dpa': 'uint64', 'descriptor': 'uint8',
+{ 'struct': 'CXLGeneralMediaEvent',
+ 'base': 'CXLCommonEventBase',
+ 'data': { 'dpa': 'uint64', 'descriptor': 'uint8',
'type': 'uint8', 'transaction-type': 'uint8',
'*channel': 'uint8', '*rank': 'uint8',
'*device': 'uint32', '*component-id': 'str' } }
##
-# @cxl-inject-dram-event:
+# @cxl-inject-general-media-event:
#
-# Inject an event record for a DRAM Event (CXL r3.0 8.2.9.2.1.2).
-# This event type is reported via one of the event logs specified via
-# the log parameter.
+# Inject an event record for a General Media Event (CXL r3.0
+# 8.2.9.2.1.1). This event type is reported via one of the event
+# logs specified via the log parameter.
#
-# @path: CXL type 3 device canonical QOM path
+# Since: 8.1
+##
+{ 'command': 'cxl-inject-general-media-event',
+ 'data': 'CXLGeneralMediaEvent' }
+
+##
+# @CXLDRAMEvent:
#
-# @log: Event log to add the event to
-#
-# @flags: Event Record Flags. See CXL r3.0 Table 8-42 Common Event
-# Record Format, Event Record Flags for subfield definitions.
+# Event record for a DRAM Event (CXL r3.0 8.2.9.2.1.2).
#
# @dpa: Device Physical Address (relative to @path device). Note
# lower bits include some flags. See CXL r3.0 Table 8-44 DRAM
@@ -133,9 +145,9 @@
#
# Since: 8.1
##
-{ 'command': 'cxl-inject-dram-event',
- 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint8',
- 'dpa': 'uint64', 'descriptor': 'uint8',
+{ 'struct': 'CXLDRAMEvent',
+ 'base': 'CXLCommonEventBase',
+ 'data': { 'dpa': 'uint64', 'descriptor': 'uint8',
'type': 'uint8', 'transaction-type': 'uint8',
'*channel': 'uint8', '*rank': 'uint8', '*nibble-mask': 'uint32',
'*bank-group': 'uint8', '*bank': 'uint8', '*row': 'uint32',
@@ -143,18 +155,21 @@
}}
##
-# @cxl-inject-memory-module-event:
+# @cxl-inject-dram-event:
#
-# Inject an event record for a Memory Module Event (CXL r3.0
-# 8.2.9.2.1.3). This event includes a copy of the Device Health info
-# at the time of the event.
+# Inject an event record for a DRAM Event (CXL r3.0 8.2.9.2.1.2).
+# This event type is reported via one of the event logs
+# specified via the log parameter.
#
-# @path: CXL type 3 device canonical QOM path
+# Since: 8.1
+##
+{ 'command': 'cxl-inject-dram-event',
+ 'data': 'CXLDRAMEvent' }
+
+##
+# @CXLMemModuleEvent:
#
-# @log: Event Log to add the event to
-#
-# @flags: Event Record Flags. See CXL r3.0 Table 8-42 Common Event
-# Record Format, Event Record Flags for subfield definitions.
+# Event record for a Memory Module Event (CXL r3.0 8.2.9.2.1.3).
#
# @type: Device Event Type. See CXL r3.0 Table 8-45 Memory Module
# Event Record for bit definitions for bit definiions.
@@ -185,9 +200,9 @@
#
# Since: 8.1
##
-{ 'command': 'cxl-inject-memory-module-event',
- 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags' : 'uint8',
- 'type': 'uint8', 'health-status': 'uint8',
+{ 'struct': 'CXLMemModuleEvent',
+ 'base': 'CXLCommonEventBase',
+ 'data': { 'type': 'uint8', 'health-status': 'uint8',
'media-status': 'uint8', 'additional-status': 'uint8',
'life-used': 'uint8', 'temperature' : 'int16',
'dirty-shutdown-count': 'uint32',
@@ -195,6 +210,18 @@
'corrected-persistent-error-count': 'uint32'
}}
+##
+# @cxl-inject-memory-module-event:
+#
+# Inject an event record for a Memory Module Event (CXL r3.0
+# 8.2.9.2.1.3). This event includes a copy of the Device Health info
+# at the time of the event.
+#
+# Since: 8.1
+##
+{ 'command': 'cxl-inject-memory-module-event',
+ 'data': 'CXLMemModuleEvent' }
+
##
# @cxl-inject-poison:
#
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* Re: [PULL 05/51] qapi: cxl: Refactor CXL event injection for common commands arguments
2026-02-04 19:03 ` [PULL 05/51] qapi: cxl: Refactor CXL event injection for common commands arguments Michael S. Tsirkin
@ 2026-02-05 6:45 ` Michael S. Tsirkin
0 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-05 6:45 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Shiju Jose, Markus Armbruster, Jonathan Cameron,
Fan Ni, Eric Blake
On Wed, Feb 04, 2026 at 02:03:02PM -0500, Michael S. Tsirkin wrote:
> From: Shiju Jose <shiju.jose@huawei.com>
>
> Refactor CXL event injection to use struct for common command
> arguments.
>
> Suggested-by: Markus Armbruster <armbru@redhat.com>
> Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Acked-by: Markus Armbruster <armbru@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> Message-Id: <20260114142713.617806-2-Jonathan.Cameron@huawei.com>
I dropped this and the following 4 patches since there's a
new version under review now.
> ---
> qapi/cxl.json | 89 +++++++++++++++++++++++++++++++++------------------
> 1 file changed, 58 insertions(+), 31 deletions(-)
>
> diff --git a/qapi/cxl.json b/qapi/cxl.json
> index eeddb58d1d..55a088586e 100644
> --- a/qapi/cxl.json
> +++ b/qapi/cxl.json
> @@ -31,11 +31,10 @@
> }
>
> ##
> -# @cxl-inject-general-media-event:
> +# @CXLCommonEventBase:
> #
> -# Inject an event record for a General Media Event (CXL r3.0
> -# 8.2.9.2.1.1). This event type is reported via one of the event logs
> -# specified via the log parameter.
> +# Common event base for a CXL Event (CXL r3.0 8.2.9.2.1
> +# Table 8-42 Common Event Record Format).
> #
> # @path: CXL type 3 device canonical QOM path
> #
> @@ -44,6 +43,16 @@
> # @flags: Event Record Flags. See CXL r3.0 Table 8-42 Common Event
> # Record Format, Event Record Flags for subfield definitions.
> #
> +# Since: 8.1
> +##
> +{ 'struct': 'CXLCommonEventBase',
> + 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint8' } }
> +
> +##
> +# @CXLGeneralMediaEvent:
> +#
> +# Event record for a General Media Event (CXL r3.0 8.2.9.2.1.1).
> +#
> # @dpa: Device Physical Address (relative to @path device). Note
> # lower bits include some flags. See CXL r3.0 Table 8-43 General
> # Media Event Record, Physical Address.
> @@ -74,26 +83,29 @@
> #
> # Since: 8.1
> ##
> -{ 'command': 'cxl-inject-general-media-event',
> - 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint8',
> - 'dpa': 'uint64', 'descriptor': 'uint8',
> +{ 'struct': 'CXLGeneralMediaEvent',
> + 'base': 'CXLCommonEventBase',
> + 'data': { 'dpa': 'uint64', 'descriptor': 'uint8',
> 'type': 'uint8', 'transaction-type': 'uint8',
> '*channel': 'uint8', '*rank': 'uint8',
> '*device': 'uint32', '*component-id': 'str' } }
>
> ##
> -# @cxl-inject-dram-event:
> +# @cxl-inject-general-media-event:
> #
> -# Inject an event record for a DRAM Event (CXL r3.0 8.2.9.2.1.2).
> -# This event type is reported via one of the event logs specified via
> -# the log parameter.
> +# Inject an event record for a General Media Event (CXL r3.0
> +# 8.2.9.2.1.1). This event type is reported via one of the event
> +# logs specified via the log parameter.
> #
> -# @path: CXL type 3 device canonical QOM path
> +# Since: 8.1
> +##
> +{ 'command': 'cxl-inject-general-media-event',
> + 'data': 'CXLGeneralMediaEvent' }
> +
> +##
> +# @CXLDRAMEvent:
> #
> -# @log: Event log to add the event to
> -#
> -# @flags: Event Record Flags. See CXL r3.0 Table 8-42 Common Event
> -# Record Format, Event Record Flags for subfield definitions.
> +# Event record for a DRAM Event (CXL r3.0 8.2.9.2.1.2).
> #
> # @dpa: Device Physical Address (relative to @path device). Note
> # lower bits include some flags. See CXL r3.0 Table 8-44 DRAM
> @@ -133,9 +145,9 @@
> #
> # Since: 8.1
> ##
> -{ 'command': 'cxl-inject-dram-event',
> - 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint8',
> - 'dpa': 'uint64', 'descriptor': 'uint8',
> +{ 'struct': 'CXLDRAMEvent',
> + 'base': 'CXLCommonEventBase',
> + 'data': { 'dpa': 'uint64', 'descriptor': 'uint8',
> 'type': 'uint8', 'transaction-type': 'uint8',
> '*channel': 'uint8', '*rank': 'uint8', '*nibble-mask': 'uint32',
> '*bank-group': 'uint8', '*bank': 'uint8', '*row': 'uint32',
> @@ -143,18 +155,21 @@
> }}
>
> ##
> -# @cxl-inject-memory-module-event:
> +# @cxl-inject-dram-event:
> #
> -# Inject an event record for a Memory Module Event (CXL r3.0
> -# 8.2.9.2.1.3). This event includes a copy of the Device Health info
> -# at the time of the event.
> +# Inject an event record for a DRAM Event (CXL r3.0 8.2.9.2.1.2).
> +# This event type is reported via one of the event logs
> +# specified via the log parameter.
> #
> -# @path: CXL type 3 device canonical QOM path
> +# Since: 8.1
> +##
> +{ 'command': 'cxl-inject-dram-event',
> + 'data': 'CXLDRAMEvent' }
> +
> +##
> +# @CXLMemModuleEvent:
> #
> -# @log: Event Log to add the event to
> -#
> -# @flags: Event Record Flags. See CXL r3.0 Table 8-42 Common Event
> -# Record Format, Event Record Flags for subfield definitions.
> +# Event record for a Memory Module Event (CXL r3.0 8.2.9.2.1.3).
> #
> # @type: Device Event Type. See CXL r3.0 Table 8-45 Memory Module
> # Event Record for bit definitions for bit definiions.
> @@ -185,9 +200,9 @@
> #
> # Since: 8.1
> ##
> -{ 'command': 'cxl-inject-memory-module-event',
> - 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags' : 'uint8',
> - 'type': 'uint8', 'health-status': 'uint8',
> +{ 'struct': 'CXLMemModuleEvent',
> + 'base': 'CXLCommonEventBase',
> + 'data': { 'type': 'uint8', 'health-status': 'uint8',
> 'media-status': 'uint8', 'additional-status': 'uint8',
> 'life-used': 'uint8', 'temperature' : 'int16',
> 'dirty-shutdown-count': 'uint32',
> @@ -195,6 +210,18 @@
> 'corrected-persistent-error-count': 'uint32'
> }}
>
> +##
> +# @cxl-inject-memory-module-event:
> +#
> +# Inject an event record for a Memory Module Event (CXL r3.0
> +# 8.2.9.2.1.3). This event includes a copy of the Device Health info
> +# at the time of the event.
> +#
> +# Since: 8.1
> +##
> +{ 'command': 'cxl-inject-memory-module-event',
> + 'data': 'CXLMemModuleEvent' }
> +
> ##
> # @cxl-inject-poison:
> #
> --
> MST
>
^ permalink raw reply [flat|nested] 77+ messages in thread
* [PULL 06/51] hw/cxl/events: Update for rev3.2 common event record format
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (4 preceding siblings ...)
2026-02-04 19:03 ` [PULL 05/51] qapi: cxl: Refactor CXL event injection for common commands arguments Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 07/51] hw/cxl/events: Updates for rev3.2 general media event record Michael S. Tsirkin
` (47 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Shiju Jose, Jonathan Cameron, Markus Armbruster,
Fan Ni, Eric Blake
From: Shiju Jose <shiju.jose@huawei.com>
CXL spec 3.2 section 8.2.9.2.1 Table 8-55, Common Event Record
format has updated with optional Maintenance Operation Subclass,
LD ID and ID of the device head information.
Add updates for the above optional parameters in the related
CXL events reporting and in the QMP commands to inject CXL events.
Update all related specification references to CXL r3.2 to ensure
one consistent source.
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260114142713.617806-3-Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-events.c | 3 +-
hw/cxl/cxl-mailbox-utils.c | 3 +-
hw/mem/cxl_type3.c | 70 ++++++++++++++++++++++++++++++++-----
hw/mem/cxl_type3_stubs.c | 24 +++++++++++--
include/hw/cxl/cxl_device.h | 7 +++-
include/hw/cxl/cxl_events.h | 15 ++++++--
qapi/cxl.json | 21 ++++++++---
7 files changed, 122 insertions(+), 21 deletions(-)
diff --git a/hw/cxl/cxl-events.c b/hw/cxl/cxl-events.c
index 7583dd9162..5356dfb5b3 100644
--- a/hw/cxl/cxl-events.c
+++ b/hw/cxl/cxl-events.c
@@ -271,7 +271,8 @@ void cxl_create_dc_event_records_for_extents(CXLType3Dev *ct3d,
&dynamic_capacity_uuid,
(1 << CXL_EVENT_TYPE_INFO),
sizeof(event_rec),
- cxl_device_get_timestamp(&ct3d->cxl_dstate));
+ cxl_device_get_timestamp(&ct3d->cxl_dstate),
+ 0, 0, 0, 0, 0, 0, 0, 0);
event_rec.type = type;
event_rec.validity_flags = 1;
event_rec.host_id = 0;
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index a4bd49e113..a64b8ba535 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -3994,7 +3994,8 @@ static CXLRetCode cmd_fm_set_dc_region_config(const struct cxl_cmd *cmd,
&dynamic_capacity_uuid,
(1 << CXL_EVENT_TYPE_INFO),
sizeof(dcEvent),
- cxl_device_get_timestamp(&ct3d->cxl_dstate));
+ cxl_device_get_timestamp(&ct3d->cxl_dstate),
+ 0, 0, 0, 0, 0, 0, 0, 0);
dcEvent.type = DC_EVENT_REGION_CONFIG_UPDATED;
dcEvent.validity_flags = 1;
dcEvent.host_id = 0;
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 7e309af935..e5248ba4b6 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -1662,12 +1662,39 @@ void qmp_cxl_inject_correctable_error(const char *path, CxlCorErrorType type,
void cxl_assign_event_header(CXLEventRecordHdr *hdr,
const QemuUUID *uuid, uint32_t flags,
- uint8_t length, uint64_t timestamp)
+ uint8_t length, uint64_t timestamp,
+ bool has_maint_op_class, uint8_t maint_op_class,
+ bool has_maint_op_subclass,
+ uint8_t maint_op_subclass,
+ bool has_ld_id, uint16_t ld_id,
+ bool has_head_id, uint8_t head_id)
{
- st24_le_p(&hdr->flags, flags);
hdr->length = length;
memcpy(&hdr->id, uuid, sizeof(hdr->id));
stq_le_p(&hdr->timestamp, timestamp);
+
+ if (has_maint_op_class) {
+ hdr->maint_op_class = maint_op_class;
+ } else {
+ hdr->maint_op_class = 0;
+ }
+
+ if (has_maint_op_subclass) {
+ flags |= CXL_EVENT_REC_FLAGS_MAINT_OP_SUBCLASS_VALID;
+ hdr->maint_op_subclass = maint_op_subclass;
+ }
+
+ if (has_ld_id) {
+ flags |= CXL_EVENT_REC_FLAGS_LD_ID_VALID;
+ stw_le_p(&hdr->ld_id, ld_id);
+ }
+
+ if (has_head_id) {
+ flags |= CXL_EVENT_REC_FLAGS_HEAD_ID_VALID;
+ hdr->head_id = head_id;
+ }
+
+ st24_le_p(&hdr->flags, flags);
}
static const QemuUUID gen_media_uuid = {
@@ -1776,7 +1803,13 @@ static void cxl_maintenance_insert(CXLType3Dev *ct3d, uint64_t dpa,
/* Component ID is device specific. Define this as a string. */
void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
- uint8_t flags, uint64_t dpa,
+ uint32_t flags, bool has_maint_op_class,
+ uint8_t maint_op_class,
+ bool has_maint_op_subclass,
+ uint8_t maint_op_subclass,
+ bool has_ld_id, uint16_t ld_id,
+ bool has_head_id, uint8_t head_id,
+ uint64_t dpa,
uint8_t descriptor, uint8_t type,
uint8_t transaction_type,
bool has_channel, uint8_t channel,
@@ -1819,7 +1852,10 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
memset(&gem, 0, sizeof(gem));
cxl_assign_event_header(hdr, &gen_media_uuid, flags, sizeof(gem),
- cxl_device_get_timestamp(&ct3d->cxl_dstate));
+ cxl_device_get_timestamp(&ct3d->cxl_dstate),
+ has_maint_op_class, maint_op_class,
+ has_maint_op_subclass, maint_op_subclass,
+ has_ld_id, ld_id, has_head_id, head_id);
stq_le_p(&gem.phys_addr, dpa);
gem.descriptor = descriptor;
@@ -1872,7 +1908,13 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
#define CXL_DRAM_VALID_COLUMN BIT(6)
#define CXL_DRAM_VALID_CORRECTION_MASK BIT(7)
-void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
+void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
+ uint32_t flags,
+ bool has_maint_op_class, uint8_t maint_op_class,
+ bool has_maint_op_subclass,
+ uint8_t maint_op_subclass,
+ bool has_ld_id, uint16_t ld_id,
+ bool has_head_id, uint8_t head_id,
uint64_t dpa, uint8_t descriptor,
uint8_t type, uint8_t transaction_type,
bool has_channel, uint8_t channel,
@@ -1920,7 +1962,10 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
memset(&dram, 0, sizeof(dram));
cxl_assign_event_header(hdr, &dram_uuid, flags, sizeof(dram),
- cxl_device_get_timestamp(&ct3d->cxl_dstate));
+ cxl_device_get_timestamp(&ct3d->cxl_dstate),
+ has_maint_op_class, maint_op_class,
+ has_maint_op_subclass, maint_op_subclass,
+ has_ld_id, ld_id, has_head_id, head_id);
stq_le_p(&dram.phys_addr, dpa);
dram.descriptor = descriptor;
dram.type = type;
@@ -1991,7 +2036,13 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
}
void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
- uint8_t flags, uint8_t type,
+ uint32_t flags, bool has_maint_op_class,
+ uint8_t maint_op_class,
+ bool has_maint_op_subclass,
+ uint8_t maint_op_subclass,
+ bool has_ld_id, uint16_t ld_id,
+ bool has_head_id, uint8_t head_id,
+ uint8_t type,
uint8_t health_status,
uint8_t media_status,
uint8_t additional_status,
@@ -2030,7 +2081,10 @@ void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
memset(&module, 0, sizeof(module));
cxl_assign_event_header(hdr, &memory_module_uuid, flags, sizeof(module),
- cxl_device_get_timestamp(&ct3d->cxl_dstate));
+ cxl_device_get_timestamp(&ct3d->cxl_dstate),
+ has_maint_op_class, maint_op_class,
+ has_maint_op_subclass, maint_op_subclass,
+ has_ld_id, ld_id, has_head_id, head_id);
module.type = type;
module.health_status = health_status;
diff --git a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c
index c1a5e4a7c1..91b1478114 100644
--- a/hw/mem/cxl_type3_stubs.c
+++ b/hw/mem/cxl_type3_stubs.c
@@ -14,7 +14,13 @@
#include "qapi/qapi-commands-cxl.h"
void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
- uint8_t flags, uint64_t dpa,
+ uint32_t flags, bool has_maint_op_class,
+ uint8_t maint_op_class,
+ bool has_maint_op_subclass,
+ uint8_t maint_op_subclass,
+ bool has_ld_id, uint16_t ld_id,
+ bool has_head_id, uint8_t head_id,
+ uint64_t dpa,
uint8_t descriptor, uint8_t type,
uint8_t transaction_type,
bool has_channel, uint8_t channel,
@@ -23,7 +29,13 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
const char *component_id,
Error **errp) {}
-void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
+void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
+ uint32_t flags,
+ bool has_maint_op_class, uint8_t maint_op_class,
+ bool has_maint_op_subclass,
+ uint8_t maint_op_subclass,
+ bool has_ld_id, uint16_t ld_id,
+ bool has_head_id, uint8_t head_id,
uint64_t dpa, uint8_t descriptor,
uint8_t type, uint8_t transaction_type,
bool has_channel, uint8_t channel,
@@ -38,7 +50,13 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
Error **errp) {}
void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
- uint8_t flags, uint8_t type,
+ uint32_t flags, bool has_maint_op_class,
+ uint8_t maint_op_class,
+ bool has_maint_op_subclass,
+ uint8_t maint_op_subclass,
+ bool has_ld_id, uint16_t ld_id,
+ bool has_head_id, uint8_t head_id,
+ uint8_t type,
uint8_t health_status,
uint8_t media_status,
uint8_t additional_status,
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 55797a9ec3..d5906afb19 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -868,7 +868,12 @@ bool ct3_test_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
uint64_t len);
void cxl_assign_event_header(CXLEventRecordHdr *hdr,
const QemuUUID *uuid, uint32_t flags,
- uint8_t length, uint64_t timestamp);
+ uint8_t length, uint64_t timestamp,
+ bool has_maint_op_class, uint8_t maint_op_class,
+ bool has_maint_op_subclass,
+ uint8_t maint_op_subclass,
+ bool has_ld_id, uint16_t ld_id,
+ bool has_head_id, uint8_t head_id);
void cxl_create_dc_event_records_for_extents(CXLType3Dev *ct3d,
CXLDCEventType type,
CXLDCExtentRaw extents[],
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index 8a660c7a62..a88fbab751 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -29,9 +29,15 @@ typedef enum CXLEventLogType {
/*
* Common Event Record Format
- * CXL r3.1 section 8.2.9.2.1: Event Records; Table 8-43
+ * CXL r3.2 section 8.2.10.2.1: Event Records; Table 8-55
*/
-#define CXL_EVENT_REC_HDR_RES_LEN 0xf
+#define CXL_EVENT_REC_FLAGS_PERMANENT_COND BIT(2)
+#define CXL_EVENT_REC_FLAGS_MAINT_NEEDED BIT(3)
+#define CXL_EVENT_REC_FLAGS_PERF_DEGRADED BIT(4)
+#define CXL_EVENT_REC_FLAGS_HW_REPLACEMENT_NEEDED BIT(5)
+#define CXL_EVENT_REC_FLAGS_MAINT_OP_SUBCLASS_VALID BIT(6)
+#define CXL_EVENT_REC_FLAGS_LD_ID_VALID BIT(7)
+#define CXL_EVENT_REC_FLAGS_HEAD_ID_VALID BIT(8)
typedef struct CXLEventRecordHdr {
QemuUUID id;
uint8_t length;
@@ -40,7 +46,10 @@ typedef struct CXLEventRecordHdr {
uint16_t related_handle;
uint64_t timestamp;
uint8_t maint_op_class;
- uint8_t reserved[CXL_EVENT_REC_HDR_RES_LEN];
+ uint8_t maint_op_subclass;
+ uint16_t ld_id;
+ uint8_t head_id;
+ uint8_t reserved[0xb];
} QEMU_PACKED CXLEventRecordHdr;
#define CXL_EVENT_RECORD_DATA_LENGTH 0x50
diff --git a/qapi/cxl.json b/qapi/cxl.json
index 55a088586e..82001c0591 100644
--- a/qapi/cxl.json
+++ b/qapi/cxl.json
@@ -33,20 +33,33 @@
##
# @CXLCommonEventBase:
#
-# Common event base for a CXL Event (CXL r3.0 8.2.9.2.1
-# Table 8-42 Common Event Record Format).
+# Common event base for a CXL Event (CXL r3.2 8.2.10.2.1
+# Table 8-55 Common Event Record Format).
#
# @path: CXL type 3 device canonical QOM path
#
# @log: event log to add the event to
#
-# @flags: Event Record Flags. See CXL r3.0 Table 8-42 Common Event
+# @flags: Event Record Flags. See CXL r3.2 Table 8-55 Common Event
# Record Format, Event Record Flags for subfield definitions.
#
+# @maint-op-class: Maintenance operation class the device requests to
+# initiate.
+#
+# @maint-op-subclass: Maintenance operation subclass the device
+# requests to initiate.
+#
+# @ld-id: Logical Device (LD) ID of LD from where the event
+# originated.
+#
+# @head-id: ID of the device head from where the event originated.
+#
# Since: 8.1
##
{ 'struct': 'CXLCommonEventBase',
- 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint8' } }
+ 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint32',
+ '*maint-op-class':'uint8', '*maint-op-subclass':'uint8',
+ '*ld-id':'uint16', '*head-id':'uint8' } }
##
# @CXLGeneralMediaEvent:
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 07/51] hw/cxl/events: Updates for rev3.2 general media event record
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (5 preceding siblings ...)
2026-02-04 19:03 ` [PULL 06/51] hw/cxl/events: Update for rev3.2 common event record format Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 08/51] hw/cxl/events: Updates for rev3.2 DRAM " Michael S. Tsirkin
` (46 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Shiju Jose, Jonathan Cameron, Fan Ni, Eric Blake,
Markus Armbruster
From: Shiju Jose <shiju.jose@huawei.com>
CXL spec rev3.2 section 8.2.10.2.1.1 Table 8-57, general media event
table has updated with following new fields.
1. Advanced Programmable Corrected Memory Error Threshold Event Flags
2. Corrected Memory Error Count at Event
3. Memory Event Sub-Type
4. Support for component ID in the PLDM format.
Add updates for the above spec changes in the CXL general media event
reporting and QMP command to inject general media event.
In order to have one consistent source of references, update all to
references for this command to CXL r3.2.
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260114142713.617806-4-Jonathan.Cameron@huawei.com>
---
hw/mem/cxl_type3.c | 29 +++++++++++++++++++++++++++++
hw/mem/cxl_type3_stubs.c | 6 ++++++
include/hw/cxl/cxl_events.h | 7 +++++--
qapi/cxl.json | 25 +++++++++++++++++++------
4 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index e5248ba4b6..73fd85daa7 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -1716,6 +1716,11 @@ static const QemuUUID memory_module_uuid = {
#define CXL_GMER_VALID_RANK BIT(1)
#define CXL_GMER_VALID_DEVICE BIT(2)
#define CXL_GMER_VALID_COMPONENT BIT(3)
+#define CXL_GMER_VALID_COMPONENT_ID_FORMAT BIT(4)
+
+#define CXL_GMER_EV_DESC_UCE BIT(0)
+#define CXL_GMER_EV_DESC_THRESHOLD_EVENT BIT(1)
+#define CXL_GMER_EV_DESC_POISON_LIST_OVERFLOW_EVENT BIT(2)
static int ct3d_qmp_cxl_event_log_enc(CxlEventLog log)
{
@@ -1816,6 +1821,12 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
bool has_rank, uint8_t rank,
bool has_device, uint32_t device,
const char *component_id,
+ bool has_comp_id_pldm,
+ bool is_comp_id_pldm,
+ bool has_cme_ev_flags,
+ uint8_t cme_ev_flags,
+ bool has_cme_count, uint32_t cme_count,
+ uint8_t sub_type,
Error **errp)
{
Object *obj = object_resolve_path(path, NULL);
@@ -1881,10 +1892,28 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
strncpy((char *)gem.component_id, component_id,
sizeof(gem.component_id) - 1);
valid_flags |= CXL_GMER_VALID_COMPONENT;
+ if (has_comp_id_pldm && is_comp_id_pldm) {
+ valid_flags |= CXL_GMER_VALID_COMPONENT_ID_FORMAT;
+ }
}
stw_le_p(&gem.validity_flags, valid_flags);
+ if (has_cme_ev_flags) {
+ gem.cme_ev_flags = cme_ev_flags;
+ } else {
+ gem.cme_ev_flags = 0;
+ }
+
+ if (has_cme_count) {
+ descriptor |= CXL_GMER_EV_DESC_THRESHOLD_EVENT;
+ st24_le_p(gem.cme_count, cme_count);
+ } else {
+ st24_le_p(gem.cme_count, 0);
+ }
+
+ gem.sub_type = sub_type;
+
if (cxl_event_insert(cxlds, enc_log, (CXLEventRecordRaw *)&gem)) {
cxl_event_irq_assert(ct3d);
}
diff --git a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c
index 91b1478114..2047e97846 100644
--- a/hw/mem/cxl_type3_stubs.c
+++ b/hw/mem/cxl_type3_stubs.c
@@ -27,6 +27,12 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
bool has_rank, uint8_t rank,
bool has_device, uint32_t device,
const char *component_id,
+ bool has_comp_id_pldm,
+ bool is_comp_id_pldm,
+ bool has_cme_ev_flags,
+ uint8_t cme_ev_flags,
+ bool has_cme_count, uint32_t cme_count,
+ uint8_t sub_type,
Error **errp) {}
void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index a88fbab751..a3f69b99a4 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -115,10 +115,10 @@ typedef struct CXLEventInterruptPolicy {
/*
* General Media Event Record
- * CXL r3.1 Section 8.2.9.2.1.1; Table 8-45
+ * CXL r3.2 Section 8.2.10.2.1.1; Table 8-57
*/
#define CXL_EVENT_GEN_MED_COMP_ID_SIZE 0x10
-#define CXL_EVENT_GEN_MED_RES_SIZE 0x2e
+#define CXL_EVENT_GEN_MED_RES_SIZE 0x29
typedef struct CXLEventGenMedia {
CXLEventRecordHdr hdr;
uint64_t phys_addr;
@@ -130,6 +130,9 @@ typedef struct CXLEventGenMedia {
uint8_t rank;
uint8_t device[3];
uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
+ uint8_t cme_ev_flags;
+ uint8_t cme_count[3];
+ uint8_t sub_type;
uint8_t reserved[CXL_EVENT_GEN_MED_RES_SIZE];
} QEMU_PACKED CXLEventGenMedia;
diff --git a/qapi/cxl.json b/qapi/cxl.json
index 82001c0591..c159687f84 100644
--- a/qapi/cxl.json
+++ b/qapi/cxl.json
@@ -64,22 +64,22 @@
##
# @CXLGeneralMediaEvent:
#
-# Event record for a General Media Event (CXL r3.0 8.2.9.2.1.1).
+# Event record for a General Media Event (CXL r3.2 8.2.10.2.1.1).
#
# @dpa: Device Physical Address (relative to @path device). Note
-# lower bits include some flags. See CXL r3.0 Table 8-43 General
+# lower bits include some flags. See CXL r3.2 Table 8-57 General
# Media Event Record, Physical Address.
#
# @descriptor: Memory Event Descriptor with additional memory event
-# information. See CXL r3.0 Table 8-43 General Media Event
+# information. See CXL r3.2 Table 8-57 General Media Event
# Record, Memory Event Descriptor for bit definitions.
#
-# @type: Type of memory event that occurred. See CXL r3.0 Table 8-43
+# @type: Type of memory event that occurred. See CXL r3.2 Table 8-57
# General Media Event Record, Memory Event Type for possible
# values.
#
# @transaction-type: Type of first transaction that caused the event
-# to occur. See CXL r3.0 Table 8-43 General Media Event Record,
+# to occur. See CXL r3-2 Table 8-57 General Media Event Record,
# Transaction Type for possible values.
#
# @channel: The channel of the memory event location. A channel is an
@@ -94,6 +94,16 @@
# @component-id: Device specific component identifier for the event.
# May describe a field replaceable sub-component of the device.
#
+# @is-comp-id-pldm: This flag specifies whether the device-specific
+# component identifier format follows PLDM.
+#
+# @cme-ev-flags: Advanced programmable corrected memory error
+# threshold event flags.
+#
+# @cme-count: Corrected memory error count at event.
+#
+# @sub-type: Memory event sub-type.
+#
# Since: 8.1
##
{ 'struct': 'CXLGeneralMediaEvent',
@@ -101,7 +111,10 @@
'data': { 'dpa': 'uint64', 'descriptor': 'uint8',
'type': 'uint8', 'transaction-type': 'uint8',
'*channel': 'uint8', '*rank': 'uint8',
- '*device': 'uint32', '*component-id': 'str' } }
+ '*device': 'uint32', '*component-id': 'str',
+ '*is-comp-id-pldm':'bool',
+ '*cme-ev-flags':'uint8', '*cme-count':'uint32',
+ 'sub-type':'uint8' } }
##
# @cxl-inject-general-media-event:
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 08/51] hw/cxl/events: Updates for rev3.2 DRAM event record
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (6 preceding siblings ...)
2026-02-04 19:03 ` [PULL 07/51] hw/cxl/events: Updates for rev3.2 general media event record Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 09/51] hw/cxl/events: Updates for rev3.2 memory module " Michael S. Tsirkin
` (45 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Shiju Jose, Jonathan Cameron, Fan Ni, Eric Blake,
Markus Armbruster
From: Shiju Jose <shiju.jose@huawei.com>
CXL spec rev3.2 section 8.2.10.2.1.2 Table 8-58, DRAM event record
has updated with following new fields.
1. Component Identifier
2. Sub-channel of the memory event location
3. Advanced Programmable Corrected Memory Error Threshold Event Flags
4. Corrected Volatile Memory Error Count at Event
5. Memory Event Sub-Type
Add updates for the above spec changes in the CXL DRAM event
reporting and QMP command to inject DRAM event.
In order to ensure consistency update all specification references
for this command to CXL r3.2.
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260114142713.617806-5-Jonathan.Cameron@huawei.com>
---
hw/mem/cxl_type3.c | 42 +++++++++++++++++++++++++++++++++++++
hw/mem/cxl_type3_stubs.c | 7 +++++++
include/hw/cxl/cxl_events.h | 9 ++++++--
qapi/cxl.json | 31 +++++++++++++++++++++------
4 files changed, 81 insertions(+), 8 deletions(-)
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 73fd85daa7..d6bb219597 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -1936,6 +1936,13 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
#define CXL_DRAM_VALID_ROW BIT(5)
#define CXL_DRAM_VALID_COLUMN BIT(6)
#define CXL_DRAM_VALID_CORRECTION_MASK BIT(7)
+#define CXL_DRAM_VALID_COMPONENT BIT(8)
+#define CXL_DRAM_VALID_COMPONENT_ID_FORMAT BIT(9)
+#define CXL_DRAM_VALID_SUB_CHANNEL BIT(10)
+
+#define CXL_DRAM_EV_DESC_UCE BIT(0)
+#define CXL_DRAM_EV_DESC_THRESHOLD_EVENT BIT(1)
+#define CXL_DRAM_EV_DESC_POISON_LIST_OVERFLOW_EVENT BIT(2)
void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
uint32_t flags,
@@ -1955,6 +1962,12 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
bool has_column, uint16_t column,
bool has_correction_mask,
uint64List *correction_mask,
+ const char *component_id,
+ bool has_comp_id_pldm, bool is_comp_id_pldm,
+ bool has_sub_channel, uint8_t sub_channel,
+ bool has_cme_ev_flags, uint8_t cme_ev_flags,
+ bool has_cvme_count, uint32_t cvme_count,
+ uint8_t sub_type,
Error **errp)
{
Object *obj = object_resolve_path(path, NULL);
@@ -2046,6 +2059,35 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
valid_flags |= CXL_DRAM_VALID_CORRECTION_MASK;
}
+ if (component_id) {
+ strncpy((char *)dram.component_id, component_id,
+ sizeof(dram.component_id) - 1);
+ valid_flags |= CXL_DRAM_VALID_COMPONENT;
+ if (has_comp_id_pldm && is_comp_id_pldm) {
+ valid_flags |= CXL_DRAM_VALID_COMPONENT_ID_FORMAT;
+ }
+ }
+
+ if (has_sub_channel) {
+ dram.sub_channel = sub_channel;
+ valid_flags |= CXL_DRAM_VALID_SUB_CHANNEL;
+ }
+
+ if (has_cme_ev_flags) {
+ dram.cme_ev_flags = cme_ev_flags;
+ } else {
+ dram.cme_ev_flags = 0;
+ }
+
+ if (has_cvme_count) {
+ descriptor |= CXL_DRAM_EV_DESC_THRESHOLD_EVENT;
+ st24_le_p(dram.cvme_count, cvme_count);
+ } else {
+ st24_le_p(dram.cvme_count, 0);
+ }
+
+ dram.sub_type = sub_type;
+
stw_le_p(&dram.validity_flags, valid_flags);
if (cxl_event_insert(cxlds, enc_log, (CXLEventRecordRaw *)&dram)) {
diff --git a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c
index 2047e97846..231dda263f 100644
--- a/hw/mem/cxl_type3_stubs.c
+++ b/hw/mem/cxl_type3_stubs.c
@@ -53,6 +53,13 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
bool has_column, uint16_t column,
bool has_correction_mask,
uint64List *correction_mask,
+ const char *component_id,
+ bool has_comp_id_pldm,
+ bool is_comp_id_pldm,
+ bool has_sub_channel, uint8_t sub_channel,
+ bool has_cme_ev_flags, uint8_t cme_ev_flags,
+ bool has_cvme_count, uint32_t cvme_count,
+ uint8_t sub_type,
Error **errp) {}
void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index a3f69b99a4..0cc7372101 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -138,7 +138,7 @@ typedef struct CXLEventGenMedia {
/*
* DRAM Event Record
- * CXL r3.1 Section 8.2.9.2.1.2: Table 8-46
+ * CXL r3.2 Section 8.2.10.2.1.2: Table 8-58
* All fields little endian.
*/
typedef struct CXLEventDram {
@@ -156,7 +156,12 @@ typedef struct CXLEventDram {
uint8_t row[3];
uint16_t column;
uint64_t correction_mask[4];
- uint8_t reserved[0x17];
+ uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
+ uint8_t sub_channel;
+ uint8_t cme_ev_flags;
+ uint8_t cvme_count[3];
+ uint8_t sub_type;
+ uint8_t reserved;
} QEMU_PACKED CXLEventDram;
/*
diff --git a/qapi/cxl.json b/qapi/cxl.json
index c159687f84..630c37d64e 100644
--- a/qapi/cxl.json
+++ b/qapi/cxl.json
@@ -131,21 +131,21 @@
##
# @CXLDRAMEvent:
#
-# Event record for a DRAM Event (CXL r3.0 8.2.9.2.1.2).
+# Event record for a DRAM Event (CXL r3.2 8.2.10.2.1.2).
#
# @dpa: Device Physical Address (relative to @path device). Note
-# lower bits include some flags. See CXL r3.0 Table 8-44 DRAM
+# lower bits include some flags. See CXL r3.2 Table 8-58 DRAM
# Event Record, Physical Address.
#
# @descriptor: Memory Event Descriptor with additional memory event
-# information. See CXL r3.0 Table 8-44 DRAM Event Record, Memory
+# information. See CXL r3.2 Table 8-58 DRAM Event Record, Memory
# Event Descriptor for bit definitions.
#
-# @type: Type of memory event that occurred. See CXL r3.0 Table 8-44
+# @type: Type of memory event that occurred. See CXL r3.2 Table 8-58
# DRAM Event Record, Memory Event Type for possible values.
#
# @transaction-type: Type of first transaction that caused the event
-# to occur. See CXL r3.0 Table 8-44 DRAM Event Record,
+# to occur. See CXL r3.2 Table 8-58 DRAM Event Record,
# Transaction Type for possible values.
#
# @channel: The channel of the memory event location. A channel is an
@@ -169,6 +169,21 @@
# @correction-mask: Bits within each nibble. Used in order of bits
# set in the nibble-mask. Up to 4 nibbles may be covered.
#
+# @component-id: Device specific component identifier for the event.
+# May describe a field replaceable sub-component of the device.
+#
+# @is-comp-id-pldm: This flag specifies whether the device-specific
+# component identifier format follows PLDM.
+#
+# @sub-channel: The sub-channel of the memory event location.
+#
+# @cme-ev-flags: Advanced programmable corrected memory error
+# threshold event flags.
+#
+# @cvme-count: Corrected volatile memory error count at event.
+#
+# @sub-type: Memory event sub-type.
+#
# Since: 8.1
##
{ 'struct': 'CXLDRAMEvent',
@@ -177,7 +192,11 @@
'type': 'uint8', 'transaction-type': 'uint8',
'*channel': 'uint8', '*rank': 'uint8', '*nibble-mask': 'uint32',
'*bank-group': 'uint8', '*bank': 'uint8', '*row': 'uint32',
- '*column': 'uint16', '*correction-mask': [ 'uint64' ]
+ '*column': 'uint16', '*correction-mask': [ 'uint64' ],
+ '*component-id': 'str', '*is-comp-id-pldm':'bool',
+ '*sub-channel':'uint8',
+ '*cme-ev-flags':'uint8', '*cvme-count':'uint32',
+ 'sub-type':'uint8'
}}
##
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 09/51] hw/cxl/events: Updates for rev3.2 memory module event record
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (7 preceding siblings ...)
2026-02-04 19:03 ` [PULL 08/51] hw/cxl/events: Updates for rev3.2 DRAM " Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 10/51] pci/shpc: Do not unparent in instance_finalize() Michael S. Tsirkin
` (44 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Shiju Jose, Jonathan Cameron, Fan Ni, Eric Blake,
Markus Armbruster
From: Shiju Jose <shiju.jose@huawei.com>
CXL spec rev3.2 section 8.2.10.2.1.3 Table 8-50, memory module
event record has updated with following new fields.
1. Validity Flags
2. Component Identifier
3. Device Event Sub-Type
Add updates for the above spec changes in the CXL memory module
event reporting and QMP command to inject memory module event.
Updated all references for this command to the CXL r3.2
specification.
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260114142713.617806-6-Jonathan.Cameron@huawei.com>
---
hw/mem/cxl_type3.c | 20 ++++++++++++++++++++
hw/mem/cxl_type3_stubs.c | 4 ++++
include/hw/cxl/cxl_events.h | 7 +++++--
qapi/cxl.json | 26 ++++++++++++++++++--------
4 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index d6bb219597..85694707e2 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -2106,6 +2106,9 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
}
}
+#define CXL_MMER_VALID_COMPONENT BIT(0)
+#define CXL_MMER_VALID_COMPONENT_ID_FORMAT BIT(1)
+
void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
uint32_t flags, bool has_maint_op_class,
uint8_t maint_op_class,
@@ -2122,11 +2125,16 @@ void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
uint32_t dirty_shutdown_count,
uint32_t corrected_volatile_error_count,
uint32_t corrected_persist_error_count,
+ const char *component_id,
+ bool has_comp_id_pldm,
+ bool is_comp_id_pldm,
+ uint8_t sub_type,
Error **errp)
{
Object *obj = object_resolve_path(path, NULL);
CXLEventMemoryModule module;
CXLEventRecordHdr *hdr = &module.hdr;
+ uint16_t valid_flags = 0;
CXLDeviceState *cxlds;
CXLType3Dev *ct3d;
uint8_t enc_log;
@@ -2169,6 +2177,18 @@ void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
stl_le_p(&module.corrected_persistent_error_count,
corrected_persist_error_count);
+ if (component_id) {
+ strncpy((char *)module.component_id, component_id,
+ sizeof(module.component_id) - 1);
+ valid_flags |= CXL_MMER_VALID_COMPONENT;
+ if (has_comp_id_pldm && is_comp_id_pldm) {
+ valid_flags |= CXL_MMER_VALID_COMPONENT_ID_FORMAT;
+ }
+ }
+ module.sub_type = sub_type;
+
+ stw_le_p(&module.validity_flags, valid_flags);
+
if (cxl_event_insert(cxlds, enc_log, (CXLEventRecordRaw *)&module)) {
cxl_event_irq_assert(ct3d);
}
diff --git a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c
index 231dda263f..98292a931c 100644
--- a/hw/mem/cxl_type3_stubs.c
+++ b/hw/mem/cxl_type3_stubs.c
@@ -78,6 +78,10 @@ void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
uint32_t dirty_shutdown_count,
uint32_t corrected_volatile_error_count,
uint32_t corrected_persist_error_count,
+ const char *component_id,
+ bool has_comp_id_pldm,
+ bool is_comp_id_pldm,
+ uint8_t sub_type,
Error **errp) {}
void qmp_cxl_inject_poison(const char *path, uint64_t start, uint64_t length,
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index 0cc7372101..89f6aad531 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -166,7 +166,7 @@ typedef struct CXLEventDram {
/*
* Memory Module Event Record
- * CXL r3.1 Section 8.2.9.2.1.3: Table 8-47
+ * CXL r3.2 Section 8.2.10.2.1.3: Table 8-59
* All fields little endian.
*/
typedef struct CXLEventMemoryModule {
@@ -180,7 +180,10 @@ typedef struct CXLEventMemoryModule {
uint32_t dirty_shutdown_count;
uint32_t corrected_volatile_error_count;
uint32_t corrected_persistent_error_count;
- uint8_t reserved[0x3d];
+ uint16_t validity_flags;
+ uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
+ uint8_t sub_type;
+ uint8_t reserved[0x2a];
} QEMU_PACKED CXLEventMemoryModule;
/*
diff --git a/qapi/cxl.json b/qapi/cxl.json
index 630c37d64e..fc2ff2e080 100644
--- a/qapi/cxl.json
+++ b/qapi/cxl.json
@@ -214,20 +214,20 @@
##
# @CXLMemModuleEvent:
#
-# Event record for a Memory Module Event (CXL r3.0 8.2.9.2.1.3).
+# Event record for a Memory Module Event (CXL r3.2 8.2.10.2.1.3).
#
-# @type: Device Event Type. See CXL r3.0 Table 8-45 Memory Module
+# @type: Device Event Type. See CXL r3.2 Table 8-59 Memory Module
# Event Record for bit definitions for bit definiions.
#
-# @health-status: Overall health summary bitmap. See CXL r3.0 Table
-# 8-100 Get Health Info Output Payload, Health Status for bit
+# @health-status: Overall health summary bitmap. See CXL r3.2 Table
+# 8-148 Get Health Info Output Payload, Health Status for bit
# definitions.
#
-# @media-status: Overall media health summary. See CXL r3.0 Table
-# 8-100 Get Health Info Output Payload, Media Status for bit
+# @media-status: Overall media health summary. See CXL r3.2 Table
+# 8-148 Get Health Info Output Payload, Media Status for bit
# definitions.
#
-# @additional-status: See CXL r3.0 Table 8-100 Get Health Info Output
+# @additional-status: See CXL r3.2 Table 8-148 Get Health Info Output
# Payload, Additional Status for subfield definitions.
#
# @life-used: Percentage (0-100) of factory expected life span.
@@ -243,6 +243,14 @@
# @corrected-persistent-error-count: Total number of correctable
# errors in persistent memory
#
+# @component-id: Device specific component identifier for the event.
+# May describe a field replaceable sub-component of the device.
+#
+# @is-comp-id-pldm: This flag specifies whether the device-specific
+# component identifier format follows PLDM.
+#
+# @sub-type: Device event sub-type.
+#
# Since: 8.1
##
{ 'struct': 'CXLMemModuleEvent',
@@ -252,7 +260,9 @@
'life-used': 'uint8', 'temperature' : 'int16',
'dirty-shutdown-count': 'uint32',
'corrected-volatile-error-count': 'uint32',
- 'corrected-persistent-error-count': 'uint32'
+ 'corrected-persistent-error-count': 'uint32',
+ '*component-id': 'str', '*is-comp-id-pldm':'bool',
+ 'sub-type':'uint8'
}}
##
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 10/51] pci/shpc: Do not unparent in instance_finalize()
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (8 preceding siblings ...)
2026-02-04 19:03 ` [PULL 09/51] hw/cxl/events: Updates for rev3.2 memory module " Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 11/51] hw/pci-host: Set DEVICE_CATEGORY_BRIDGE once in parent class_init() Michael S. Tsirkin
` (43 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Akihiko Odaki, Marcel Apfelbaum
From: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Children are automatically unparented so manually unparenting is
unnecessary.
Worse, automatic unparenting happens before the instance_finalize()
callback of the parent gets called, so object_unparent() calls in
the callback will refer to objects that are already unparented, which
is semantically incorrect.
Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20251027-shpc-v1-1-00e9b20a355d@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251027-shpc-v1-1-00e9b20a355d@rsg.ci.i.u-tokyo.ac.jp>
---
hw/pci/shpc.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index aac6f2d034..938602866d 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -735,7 +735,6 @@ void shpc_free(PCIDevice *d)
if (!shpc) {
return;
}
- object_unparent(OBJECT(&shpc->mmio));
g_free(shpc->config);
g_free(shpc->cmask);
g_free(shpc->wmask);
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 11/51] hw/pci-host: Set DEVICE_CATEGORY_BRIDGE once in parent class_init()
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (9 preceding siblings ...)
2026-02-04 19:03 ` [PULL 10/51] pci/shpc: Do not unparent in instance_finalize() Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 12/51] intel_iommu: Add an IOMMU index for pre-translated addresses Michael S. Tsirkin
` (42 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Philippe Mathieu-Daudé,
Marc-André Lureau, BALATON Zoltan, Cédric Le Goater,
Steven Lee, Troy Lee, Jamin Lin, Andrew Jeffery, Joel Stanley,
Andrey Smirnov, Mark Cave-Ayland, Aurelien Jarno, Nicholas Piggin,
Aditya Gupta, Glenn Miles, Bernhard Beschow, Marcel Apfelbaum,
Hervé Poussineau, Elena Ufimtseva, Jagannathan Raman,
Paul Burton, Aleksandar Rikalo, qemu-ppc, qemu-arm
From: Philippe Mathieu-Daudé <philmd@linaro.org>
No need to set DEVICE_CATEGORY_BRIDGE for each device
implementing TYPE_PCI_HOST_BRIDGE: set it once in the
parent.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20251027112306.57634-1-philmd@linaro.org>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251027112306.57634-1-philmd@linaro.org>
---
hw/pci-host/articia.c | 1 -
hw/pci-host/aspeed_pcie.c | 1 -
hw/pci-host/designware.c | 3 ---
hw/pci-host/gpex.c | 2 --
hw/pci-host/grackle.c | 1 -
hw/pci-host/gt64120.c | 1 -
hw/pci-host/mv64361.c | 1 -
hw/pci-host/pnv_phb.c | 1 -
hw/pci-host/ppce500.c | 1 -
hw/pci-host/q35.c | 1 -
hw/pci-host/raven.c | 1 -
hw/pci-host/remote.c | 1 -
hw/pci-host/sabre.c | 1 -
hw/pci-host/uninorth.c | 4 ----
hw/pci-host/xilinx-pcie.c | 2 --
hw/pci/pci_host.c | 1 +
16 files changed, 1 insertion(+), 22 deletions(-)
diff --git a/hw/pci-host/articia.c b/hw/pci-host/articia.c
index 1881e03d58..04623dfd84 100644
--- a/hw/pci-host/articia.c
+++ b/hw/pci-host/articia.c
@@ -200,7 +200,6 @@ static void articia_class_init(ObjectClass *klass, const void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = articia_realize;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
/* TYPE_ARTICIA_PCI_HOST */
diff --git a/hw/pci-host/aspeed_pcie.c b/hw/pci-host/aspeed_pcie.c
index 83a1c7075c..8eeba1f9f3 100644
--- a/hw/pci-host/aspeed_pcie.c
+++ b/hw/pci-host/aspeed_pcie.c
@@ -350,7 +350,6 @@ static void aspeed_pcie_rc_class_init(ObjectClass *klass, const void *data)
dc->desc = "ASPEED PCIe RC";
dc->realize = aspeed_pcie_rc_realize;
dc->fw_name = "pci";
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
hc->root_bus_path = aspeed_pcie_rc_root_bus_path;
device_class_set_props(dc, aspeed_pcie_rc_props);
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
index 019e025382..00c9449c4d 100644
--- a/hw/pci-host/designware.c
+++ b/hw/pci-host/designware.c
@@ -593,8 +593,6 @@ static void designware_pcie_root_class_init(ObjectClass *klass,
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
-
k->vendor_id = PCI_VENDOR_ID_SYNOPSYS;
k->device_id = 0xABCD;
k->revision = 0;
@@ -736,7 +734,6 @@ static void designware_pcie_host_class_init(ObjectClass *klass,
hc->root_bus_path = designware_pcie_host_root_bus_path;
dc->realize = designware_pcie_host_realize;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->fw_name = "pci";
dc->vmsd = &vmstate_designware_pcie_host;
}
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
index b5074c05c0..e66784ce51 100644
--- a/hw/pci-host/gpex.c
+++ b/hw/pci-host/gpex.c
@@ -200,7 +200,6 @@ static void gpex_host_class_init(ObjectClass *klass, const void *data)
hc->root_bus_path = gpex_host_root_bus_path;
dc->realize = gpex_host_realize;
dc->unrealize = gpex_host_unrealize;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->fw_name = "pci";
device_class_set_props(dc, gpex_host_properties);
}
@@ -242,7 +241,6 @@ static void gpex_root_class_init(ObjectClass *klass, const void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->desc = "QEMU generic PCIe host bridge";
dc->vmsd = &vmstate_gpex_root;
k->vendor_id = PCI_VENDOR_ID_REDHAT;
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index 9a58f0e9b5..b0db7870b0 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -140,7 +140,6 @@ static void grackle_class_init(ObjectClass *klass, const void *data)
dc->realize = grackle_realize;
device_class_set_props(dc, grackle_properties);
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->fw_name = "pci";
sbc->explicit_ofw_unit_address = grackle_ofw_unit_address;
}
diff --git a/hw/pci-host/gt64120.c b/hw/pci-host/gt64120.c
index d361c457ed..566f928304 100644
--- a/hw/pci-host/gt64120.c
+++ b/hw/pci-host/gt64120.c
@@ -1298,7 +1298,6 @@ static void gt64120_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
device_class_set_props(dc, gt64120_properties);
dc->realize = gt64120_realize;
device_class_set_legacy_reset(dc, gt64120_reset);
diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
index ef1c77563e..495a82befd 100644
--- a/hw/pci-host/mv64361.c
+++ b/hw/pci-host/mv64361.c
@@ -108,7 +108,6 @@ static void mv64361_pcihost_class_init(ObjectClass *klass, const void *data)
dc->realize = mv64361_pcihost_realize;
device_class_set_props(dc, mv64361_pcihost_props);
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
static const TypeInfo mv64361_pcihost_info = {
diff --git a/hw/pci-host/pnv_phb.c b/hw/pci-host/pnv_phb.c
index 85fcc3b686..0b556d1bf5 100644
--- a/hw/pci-host/pnv_phb.c
+++ b/hw/pci-host/pnv_phb.c
@@ -202,7 +202,6 @@ static void pnv_phb_class_init(ObjectClass *klass, const void *data)
hc->root_bus_path = pnv_phb_root_bus_path;
dc->realize = pnv_phb_realize;
device_class_set_props(dc, pnv_phb_properties);
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->user_creatable = true;
}
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 76623f78c4..67180ba5f0 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -516,7 +516,6 @@ static void e500_pcihost_class_init(ObjectClass *klass, const void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = e500_pcihost_realize;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
device_class_set_props(dc, pcihost_properties);
dc->vmsd = &vmstate_ppce500_pci;
}
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index bf56229051..b353d3e1e6 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -194,7 +194,6 @@ static void q35_host_class_init(ObjectClass *klass, const void *data)
device_class_set_props(dc, q35_host_props);
/* Reason: needs to be wired up by pc_q35_init */
dc->user_creatable = false;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->fw_name = "pci";
}
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
index c50061996c..b3c2678667 100644
--- a/hw/pci-host/raven.c
+++ b/hw/pci-host/raven.c
@@ -296,7 +296,6 @@ static void raven_pcihost_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->realize = raven_pcihost_realizefn;
dc->fw_name = "pci";
}
diff --git a/hw/pci-host/remote.c b/hw/pci-host/remote.c
index feaaa9adaa..9ea95fac6e 100644
--- a/hw/pci-host/remote.c
+++ b/hw/pci-host/remote.c
@@ -55,7 +55,6 @@ static void remote_pcihost_class_init(ObjectClass *klass, const void *data)
dc->realize = remote_pcihost_realize;
dc->user_creatable = false;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->fw_name = "pci";
}
diff --git a/hw/pci-host/sabre.c b/hw/pci-host/sabre.c
index b3f57dca7d..cd2328ad53 100644
--- a/hw/pci-host/sabre.c
+++ b/hw/pci-host/sabre.c
@@ -505,7 +505,6 @@ static void sabre_class_init(ObjectClass *klass, const void *data)
dc->realize = sabre_realize;
device_class_set_legacy_reset(dc, sabre_reset);
device_class_set_props(dc, sabre_properties);
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->fw_name = "pci";
sbc->explicit_ofw_unit_address = sabre_ofw_unit_address;
}
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index d39546b6f4..10972de694 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -435,7 +435,6 @@ static void pci_unin_main_class_init(ObjectClass *klass, const void *data)
dc->realize = pci_unin_main_realize;
device_class_set_props(dc, pci_unin_main_pci_host_props);
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->fw_name = "pci";
sbc->explicit_ofw_unit_address = pci_unin_main_ofw_unit_address;
}
@@ -453,7 +452,6 @@ static void pci_u3_agp_class_init(ObjectClass *klass, const void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = pci_u3_agp_realize;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
static const TypeInfo pci_u3_agp_info = {
@@ -469,7 +467,6 @@ static void pci_unin_agp_class_init(ObjectClass *klass, const void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = pci_unin_agp_realize;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
static const TypeInfo pci_unin_agp_info = {
@@ -485,7 +482,6 @@ static void pci_unin_internal_class_init(ObjectClass *klass, const void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = pci_unin_internal_realize;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
static const TypeInfo pci_unin_internal_info = {
diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c
index 86c20377d1..40f625b61d 100644
--- a/hw/pci-host/xilinx-pcie.c
+++ b/hw/pci-host/xilinx-pcie.c
@@ -172,7 +172,6 @@ static void xilinx_pcie_host_class_init(ObjectClass *klass, const void *data)
hc->root_bus_path = xilinx_pcie_host_root_bus_path;
dc->realize = xilinx_pcie_host_realize;
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->fw_name = "pci";
device_class_set_props(dc, xilinx_pcie_host_props);
}
@@ -291,7 +290,6 @@ static void xilinx_pcie_root_class_init(ObjectClass *klass, const void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->desc = "Xilinx AXI-PCIe Host Bridge";
k->vendor_id = PCI_VENDOR_ID_XILINX;
k->device_id = 0x7021;
diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 05f1475dc7..91e3885c7f 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -245,6 +245,7 @@ static void pci_host_class_init(ObjectClass *klass, const void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
device_class_set_props(dc, pci_host_properties_common);
dc->vmsd = &vmstate_pcihost;
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}
static const TypeInfo pci_host_type_info = {
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 12/51] intel_iommu: Add an IOMMU index for pre-translated addresses
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (10 preceding siblings ...)
2026-02-04 19:03 ` [PULL 11/51] hw/pci-host: Set DEVICE_CATEGORY_BRIDGE once in parent class_init() Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 13/51] intel_iommu: Support memory operations with " Michael S. Tsirkin
` (41 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, CLEMENT MATHIEU--DRIF, Jason Wang, Yi Liu,
Marcel Apfelbaum, Paolo Bonzini, Richard Henderson,
Eduardo Habkost
From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251029105137.1097933-2-clement.mathieu--drif@eviden.com>
---
hw/i386/intel_iommu.c | 13 +++++++++++++
hw/i386/intel_iommu_internal.h | 7 +++++++
2 files changed, 20 insertions(+)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index e8a6f50a5a..80b21a6468 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -5601,6 +5601,17 @@ static const TypeInfo vtd_info = {
.class_init = vtd_class_init,
};
+static int vtd_attrs_to_index(IOMMUMemoryRegion *iommu_mr, MemTxAttrs attrs)
+{
+ return attrs.address_type == PCI_AT_TRANSLATED ?
+ VTD_IDX_TRANSLATED : VTD_IDX_UNTRANSLATED;
+}
+
+static int vtd_num_indexes(IOMMUMemoryRegion *iommu)
+{
+ return VTD_IDX_COUNT;
+}
+
static void vtd_iommu_memory_region_class_init(ObjectClass *klass,
const void *data)
{
@@ -5609,6 +5620,8 @@ static void vtd_iommu_memory_region_class_init(ObjectClass *klass,
imrc->translate = vtd_iommu_translate;
imrc->notify_flag_changed = vtd_iommu_notify_flag_changed;
imrc->replay = vtd_iommu_replay;
+ imrc->attrs_to_index = vtd_attrs_to_index;
+ imrc->num_indexes = vtd_num_indexes;
}
static const TypeInfo vtd_iommu_memory_region_info = {
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index a2ca79f925..be757c290d 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -688,6 +688,13 @@ typedef struct VTDPIOTLBInvInfo {
/* Bits to decide the offset for each level */
#define VTD_LEVEL_BITS 9
+/* IOMMU Index */
+typedef enum VTDIOMMUIndex {
+ VTD_IDX_UNTRANSLATED = 0, /* Default */
+ VTD_IDX_TRANSLATED = 1,
+ VTD_IDX_COUNT = 2, /* Number of supported indexes */
+} VTDIOMMUIndex;
+
typedef struct VTDHostIOMMUDevice {
IntelIOMMUState *iommu_state;
PCIBus *bus;
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 13/51] intel_iommu: Support memory operations with pre-translated addresses
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (11 preceding siblings ...)
2026-02-04 19:03 ` [PULL 12/51] intel_iommu: Add an IOMMU index for pre-translated addresses Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 14/51] pcie: Add a function to check if pasid privileged mode is enabled Michael S. Tsirkin
` (40 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, CLEMENT MATHIEU--DRIF, Jason Wang, Yi Liu,
Paolo Bonzini, Richard Henderson, Eduardo Habkost,
Marcel Apfelbaum
From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251029105137.1097933-3-clement.mathieu--drif@eviden.com>
---
hw/i386/intel_iommu.c | 118 +++++++++++++++++++++++++++++-------------
1 file changed, 81 insertions(+), 37 deletions(-)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 80b21a6468..7e7c31cb55 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -3985,6 +3985,25 @@ static void vtd_mem_write(void *opaque, hwaddr addr,
}
}
+static void vtd_prepare_identity_entry(hwaddr addr, IOMMUAccessFlags perm,
+ uint32_t pasid, IOMMUTLBEntry *iotlb)
+{
+ iotlb->iova = addr & VTD_PAGE_MASK_4K;
+ iotlb->translated_addr = addr & VTD_PAGE_MASK_4K;
+ iotlb->addr_mask = ~VTD_PAGE_MASK_4K;
+ iotlb->perm = perm;
+ iotlb->pasid = pasid;
+}
+
+static inline void vtd_prepare_error_entry(IOMMUTLBEntry *entry)
+{
+ entry->iova = 0;
+ entry->translated_addr = 0;
+ entry->addr_mask = ~VTD_PAGE_MASK_4K;
+ entry->perm = IOMMU_NONE;
+ entry->pasid = PCI_NO_PASID;
+}
+
static IOMMUTLBEntry vtd_iommu_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
IOMMUAccessFlags flag, int iommu_idx)
{
@@ -3996,16 +4015,29 @@ static IOMMUTLBEntry vtd_iommu_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
.pasid = vtd_as->pasid,
};
bool success;
+ bool is_write = flag & IOMMU_WO;
if (likely(s->dmar_enabled)) {
- success = vtd_do_iommu_translate(vtd_as, vtd_as->bus, vtd_as->devfn,
- addr, flag & IOMMU_WO, &iotlb);
+ /* Only support translated requests in scalable mode */
+ if (iommu_idx == VTD_IDX_TRANSLATED && s->root_scalable) {
+ if (vtd_as->pasid == PCI_NO_PASID) {
+ vtd_prepare_identity_entry(addr, IOMMU_RW, PCI_NO_PASID,
+ &iotlb);
+ success = true;
+ } else {
+ vtd_prepare_error_entry(&iotlb);
+ error_report_once("%s: translated request with PASID not "
+ "allowed (pasid=0x%" PRIx32 ")", __func__,
+ vtd_as->pasid);
+ success = false;
+ }
+ } else {
+ success = vtd_do_iommu_translate(vtd_as, vtd_as->bus, vtd_as->devfn,
+ addr, is_write, &iotlb);
+ }
} else {
/* DMAR disabled, passthrough, use 4k-page*/
- iotlb.iova = addr & VTD_PAGE_MASK_4K;
- iotlb.translated_addr = addr & VTD_PAGE_MASK_4K;
- iotlb.addr_mask = ~VTD_PAGE_MASK_4K;
- iotlb.perm = IOMMU_RW;
+ vtd_prepare_identity_entry(addr, IOMMU_RW, vtd_as->pasid, &iotlb);
success = true;
}
@@ -4414,6 +4446,37 @@ static int vtd_int_remap(X86IOMMUState *iommu, MSIMessage *src,
src, dst, sid, false);
}
+static void vtd_report_sid_ir_illegal_access(IntelIOMMUState *s, uint16_t sid,
+ uint32_t pasid, hwaddr addr,
+ bool is_write)
+{
+ uint8_t bus_n = VTD_SID_TO_BUS(sid);
+ uint8_t devfn = VTD_SID_TO_DEVFN(sid);
+ bool is_fpd_set = false;
+ VTDContextEntry ce;
+
+ /* Try out best to fetch FPD, we can't do anything more */
+ if (vtd_dev_to_context_entry(s, bus_n, devfn, &ce) == 0) {
+ is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD;
+ if (!is_fpd_set && s->root_scalable) {
+ vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set, pasid);
+ }
+ }
+
+ vtd_report_fault(s, VTD_FR_SM_INTERRUPT_ADDR, is_fpd_set, sid, addr,
+ is_write, pasid != PCI_NO_PASID, pasid);
+}
+
+static void vtd_report_ir_illegal_access(VTDAddressSpace *vtd_as,
+ hwaddr addr, bool is_write)
+{
+ uint8_t bus_n = pci_bus_num(vtd_as->bus);
+ uint16_t sid = PCI_BUILD_BDF(bus_n, vtd_as->devfn);
+
+ vtd_report_sid_ir_illegal_access(vtd_as->iommu_state, sid, vtd_as->pasid,
+ addr, is_write);
+}
+
static MemTxResult vtd_mem_ir_read(void *opaque, hwaddr addr,
uint64_t *data, unsigned size,
MemTxAttrs attrs)
@@ -4425,9 +4488,11 @@ static MemTxResult vtd_mem_ir_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size,
MemTxAttrs attrs)
{
+ IntelIOMMUState *s = opaque;
int ret = 0;
MSIMessage from = {}, to = {};
uint16_t sid = X86_IOMMU_SID_INVALID;
+ uint32_t pasid;
from.address = (uint64_t) addr + VTD_INTERRUPT_ADDR_FIRST;
from.data = (uint32_t) value;
@@ -4435,9 +4500,16 @@ static MemTxResult vtd_mem_ir_write(void *opaque, hwaddr addr,
if (!attrs.unspecified) {
/* We have explicit Source ID */
sid = attrs.requester_id;
+ pasid = attrs.pid != 0 ? attrs.pid : PCI_NO_PASID;
+
+ if (attrs.address_type == PCI_AT_TRANSLATED &&
+ sid != X86_IOMMU_SID_INVALID) {
+ vtd_report_sid_ir_illegal_access(s, sid, pasid, from.address, true);
+ return MEMTX_ERROR;
+ }
}
- ret = vtd_interrupt_remap_msi(opaque, &from, &to, sid, true);
+ ret = vtd_interrupt_remap_msi(s, &from, &to, sid, true);
if (ret) {
/* Drop this interrupt */
return MEMTX_ERROR;
@@ -4462,30 +4534,6 @@ static const MemoryRegionOps vtd_mem_ir_ops = {
},
};
-static void vtd_report_ir_illegal_access(VTDAddressSpace *vtd_as,
- hwaddr addr, bool is_write)
-{
- IntelIOMMUState *s = vtd_as->iommu_state;
- uint8_t bus_n = pci_bus_num(vtd_as->bus);
- uint16_t sid = PCI_BUILD_BDF(bus_n, vtd_as->devfn);
- bool is_fpd_set = false;
- VTDContextEntry ce;
-
- assert(vtd_as->pasid != PCI_NO_PASID);
-
- /* Try out best to fetch FPD, we can't do anything more */
- if (vtd_dev_to_context_entry(s, bus_n, vtd_as->devfn, &ce) == 0) {
- is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD;
- if (!is_fpd_set && s->root_scalable) {
- vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set, vtd_as->pasid);
- }
- }
-
- vtd_report_fault(s, VTD_FR_SM_INTERRUPT_ADDR,
- is_fpd_set, sid, addr, is_write,
- true, vtd_as->pasid);
-}
-
static MemTxResult vtd_mem_ir_fault_read(void *opaque, hwaddr addr,
uint64_t *data, unsigned size,
MemTxAttrs attrs)
@@ -5145,14 +5193,10 @@ static IOMMUTLBEntry vtd_iommu_ats_do_translate(IOMMUMemoryRegion *iommu,
if (vtd_is_interrupt_addr(addr)) {
vtd_report_ir_illegal_access(vtd_as, addr, flags & IOMMU_WO);
+ vtd_prepare_error_entry(&entry);
entry.target_as = &address_space_memory;
- entry.iova = 0;
- entry.translated_addr = 0;
- entry.addr_mask = ~VTD_PAGE_MASK_4K;
- entry.perm = IOMMU_NONE;
- entry.pasid = PCI_NO_PASID;
} else {
- entry = vtd_iommu_translate(iommu, addr, flags, 0);
+ entry = vtd_iommu_translate(iommu, addr, flags, VTD_IDX_UNTRANSLATED);
}
return entry;
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 14/51] pcie: Add a function to check if pasid privileged mode is enabled
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (12 preceding siblings ...)
2026-02-04 19:03 ` [PULL 13/51] intel_iommu: Support memory operations with " Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 15/51] pci: Block ATS requests when privileged mode is disabled Michael S. Tsirkin
` (39 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, CLEMENT MATHIEU--DRIF, Marcel Apfelbaum
From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251029105137.1097933-4-clement.mathieu--drif@eviden.com>
---
hw/pci/pcie.c | 21 ++++++++++++++++-----
include/hw/pci/pcie.h | 1 +
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index c481c16c0f..50fc4aa8eb 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -1340,6 +1340,16 @@ void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
dev->exp.pri_cap = offset;
}
+static inline bool pcie_pasid_check_ctrl_bit_enabled(const PCIDevice *dev,
+ uint16_t mask)
+{
+ if (!pci_is_express(dev) || !dev->exp.pasid_cap) {
+ return false;
+ }
+ return (pci_get_word(dev->config + dev->exp.pasid_cap + PCI_PASID_CTRL) &
+ mask) != 0;
+}
+
uint32_t pcie_pri_get_req_alloc(const PCIDevice *dev)
{
if (!pcie_pri_enabled(dev)) {
@@ -1359,11 +1369,12 @@ bool pcie_pri_enabled(const PCIDevice *dev)
bool pcie_pasid_enabled(const PCIDevice *dev)
{
- if (!pci_is_express(dev) || !dev->exp.pasid_cap) {
- return false;
- }
- return (pci_get_word(dev->config + dev->exp.pasid_cap + PCI_PASID_CTRL) &
- PCI_PASID_CTRL_ENABLE) != 0;
+ return pcie_pasid_check_ctrl_bit_enabled(dev, PCI_PASID_CTRL_ENABLE);
+}
+
+bool pcie_pasid_priv_enabled(PCIDevice *dev)
+{
+ return pcie_pasid_check_ctrl_bit_enabled(dev, PCI_PASID_CTRL_PRIV);
}
bool pcie_ats_enabled(const PCIDevice *dev)
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index fc02aeb169..d4e065db82 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -165,5 +165,6 @@ void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
uint32_t pcie_pri_get_req_alloc(const PCIDevice *dev);
bool pcie_pri_enabled(const PCIDevice *dev);
bool pcie_pasid_enabled(const PCIDevice *dev);
+bool pcie_pasid_priv_enabled(PCIDevice *dev);
bool pcie_ats_enabled(const PCIDevice *dev);
#endif /* QEMU_PCIE_H */
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 15/51] pci: Block ATS requests when privileged mode is disabled
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (13 preceding siblings ...)
2026-02-04 19:03 ` [PULL 14/51] pcie: Add a function to check if pasid privileged mode is enabled Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 16/51] intel_iommu: Handle insufficient permissions during translation requests Michael S. Tsirkin
` (38 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, CLEMENT MATHIEU--DRIF, Marcel Apfelbaum
From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251029105137.1097933-5-clement.mathieu--drif@eviden.com>
---
hw/pci/pci.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 9035caca92..90d6d71efd 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -3171,6 +3171,10 @@ ssize_t pci_ats_request_translation(PCIDevice *dev, uint32_t pasid,
return -EPERM;
}
+ if (priv_req && !pcie_pasid_priv_enabled(dev)) {
+ return -EPERM;
+ }
+
pci_device_get_iommu_bus_devfn(dev, &iommu_bus, &bus, &devfn);
if (iommu_bus && iommu_bus->iommu_ops->ats_request_translation) {
return iommu_bus->iommu_ops->ats_request_translation(bus,
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 16/51] intel_iommu: Handle insufficient permissions during translation requests
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (14 preceding siblings ...)
2026-02-04 19:03 ` [PULL 15/51] pci: Block ATS requests when privileged mode is disabled Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 17/51] intel_iommu: Minimal handling of privileged ATS request Michael S. Tsirkin
` (37 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, CLEMENT MATHIEU--DRIF, Jason Wang, Yi Liu,
Paolo Bonzini, Richard Henderson, Eduardo Habkost,
Marcel Apfelbaum
From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
ATS translations should not fail when the write permission is not set.
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251029105137.1097933-6-clement.mathieu--drif@eviden.com>
---
hw/i386/intel_iommu.c | 14 ++++++++------
hw/i386/intel_iommu_internal.h | 3 ++-
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 7e7c31cb55..6ba1c1676b 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1998,7 +1998,7 @@ static int vtd_iova_to_fspte(IntelIOMMUState *s, VTDContextEntry *ce,
uint64_t iova, bool is_write,
uint64_t *fsptep, uint32_t *fspte_level,
bool *reads, bool *writes, uint8_t aw_bits,
- uint32_t pasid)
+ uint32_t pasid, int iommu_idx)
{
dma_addr_t addr = vtd_get_iova_pgtbl_base(s, ce, pasid);
uint32_t offset;
@@ -2039,7 +2039,8 @@ static int vtd_iova_to_fspte(IntelIOMMUState *s, VTDContextEntry *ce,
*reads = true;
*writes = (*writes) && (fspte & VTD_FS_RW);
- if (is_write && !(fspte & VTD_FS_RW)) {
+ /* ATS should not fail when the write permission is not set */
+ if (is_write && !(fspte & VTD_FS_RW) && iommu_idx != VTD_IDX_ATS) {
return -VTD_FR_SM_WRITE;
}
if (vtd_fspte_nonzero_rsvd(fspte, *fspte_level)) {
@@ -2098,7 +2099,7 @@ static void vtd_report_fault(IntelIOMMUState *s,
*/
static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
uint8_t devfn, hwaddr addr, bool is_write,
- IOMMUTLBEntry *entry)
+ IOMMUTLBEntry *entry, int iommu_idx)
{
IntelIOMMUState *s = vtd_as->iommu_state;
VTDContextEntry ce;
@@ -2204,7 +2205,8 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
if (s->fsts && s->root_scalable) {
ret_fr = vtd_iova_to_fspte(s, &ce, addr, is_write, &pte, &level,
- &reads, &writes, s->aw_bits, pasid);
+ &reads, &writes, s->aw_bits, pasid,
+ iommu_idx);
pgtt = VTD_SM_PASID_ENTRY_FST;
} else {
ret_fr = vtd_iova_to_sspte(s, &ce, addr, is_write, &pte, &level,
@@ -4033,7 +4035,7 @@ static IOMMUTLBEntry vtd_iommu_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
}
} else {
success = vtd_do_iommu_translate(vtd_as, vtd_as->bus, vtd_as->devfn,
- addr, is_write, &iotlb);
+ addr, is_write, &iotlb, iommu_idx);
}
} else {
/* DMAR disabled, passthrough, use 4k-page*/
@@ -5196,7 +5198,7 @@ static IOMMUTLBEntry vtd_iommu_ats_do_translate(IOMMUMemoryRegion *iommu,
vtd_prepare_error_entry(&entry);
entry.target_as = &address_space_memory;
} else {
- entry = vtd_iommu_translate(iommu, addr, flags, VTD_IDX_UNTRANSLATED);
+ entry = vtd_iommu_translate(iommu, addr, flags, VTD_IDX_ATS);
}
return entry;
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index be757c290d..18d50191d2 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -692,7 +692,8 @@ typedef struct VTDPIOTLBInvInfo {
typedef enum VTDIOMMUIndex {
VTD_IDX_UNTRANSLATED = 0, /* Default */
VTD_IDX_TRANSLATED = 1,
- VTD_IDX_COUNT = 2, /* Number of supported indexes */
+ VTD_IDX_ATS = 2,
+ VTD_IDX_COUNT = 3, /* Number of supported indexes */
} VTDIOMMUIndex;
typedef struct VTDHostIOMMUDevice {
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 17/51] intel_iommu: Minimal handling of privileged ATS request
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (15 preceding siblings ...)
2026-02-04 19:03 ` [PULL 16/51] intel_iommu: Handle insufficient permissions during translation requests Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 18/51] intel_iommu: Add a CLI option to enable SVM Michael S. Tsirkin
` (36 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, CLEMENT MATHIEU--DRIF, Jason Wang, Yi Liu,
Marcel Apfelbaum, Paolo Bonzini, Richard Henderson,
Eduardo Habkost
From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
The purpose of this commit is not to support privileged requests but
to prevent devices from doing things they wouldn't be able to do
with real hardware.
We simply block privileged requests when the SRS ecap is not set
and abort when the ecap is present.
For now, its not worth implementing support for privileged requests
because the kernel does not support it.
(https://lore.kernel.org/linux-iommu/20230411064815.31456-11-baolu.lu@linux.intel.com/)
However, we may consider working on it depending on how the development
goes in the kernel.
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251029105137.1097933-7-clement.mathieu--drif@eviden.com>
---
hw/i386/intel_iommu.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 6ba1c1676b..77adeed0cc 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -5190,13 +5190,27 @@ static IOMMUTLBEntry vtd_iommu_ats_do_translate(IOMMUMemoryRegion *iommu,
hwaddr addr,
IOMMUAccessFlags flags)
{
- IOMMUTLBEntry entry;
+ IOMMUTLBEntry entry = { .target_as = &address_space_memory };
VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
+ IntelIOMMUState *s = vtd_as->iommu_state;
+
+ /* Guard that makes sure we avoid weird behaviors */
+ if ((flags & IOMMU_PRIV) && (s->ecap & VTD_ECAP_SRS)) {
+ error_report_once("Privileged ATS not supported");
+ abort();
+ }
if (vtd_is_interrupt_addr(addr)) {
- vtd_report_ir_illegal_access(vtd_as, addr, flags & IOMMU_WO);
vtd_prepare_error_entry(&entry);
- entry.target_as = &address_space_memory;
+ vtd_report_ir_illegal_access(vtd_as, addr, flags & IOMMU_WO);
+ } else if ((flags & IOMMU_PRIV) && !(s->ecap & VTD_ECAP_SRS)) {
+ /*
+ * For translation-request-with-PASID with PR=1, remapping hardware
+ * not supporting supervisor requests (SRS=0 in the Extended
+ * Capability Register) forces R=W=E=0 in addition to setting PRIV=1.
+ */
+ vtd_prepare_error_entry(&entry);
+ entry.perm = IOMMU_PRIV;
} else {
entry = vtd_iommu_translate(iommu, addr, flags, VTD_IDX_ATS);
}
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 18/51] intel_iommu: Add a CLI option to enable SVM
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (16 preceding siblings ...)
2026-02-04 19:03 ` [PULL 17/51] intel_iommu: Minimal handling of privileged ATS request Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 19/51] x86: q35: ich9: add 'wdat' property Michael S. Tsirkin
` (35 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, CLEMENT MATHIEU--DRIF, Jason Wang, Yi Liu,
Paolo Bonzini, Richard Henderson, Eduardo Habkost,
Marcel Apfelbaum
From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251029105137.1097933-8-clement.mathieu--drif@eviden.com>
---
hw/i386/intel_iommu.c | 45 ++++++++++++++++++++++++----------
hw/i386/intel_iommu_internal.h | 6 ++++-
include/hw/i386/intel_iommu.h | 1 +
3 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 77adeed0cc..dd00079a40 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2862,8 +2862,10 @@ static bool vtd_inv_desc_reserved_check(IntelIOMMUState *s,
static bool vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc)
{
- uint64_t mask[4] = {VTD_INV_DESC_WAIT_RSVD_LO, VTD_INV_DESC_WAIT_RSVD_HI,
- VTD_INV_DESC_ALL_ONE, VTD_INV_DESC_ALL_ONE};
+ uint64_t mask[4] = {
+ VTD_INV_DESC_WAIT_RSVD_LO(s->ecap), VTD_INV_DESC_WAIT_RSVD_HI,
+ VTD_INV_DESC_ALL_ONE, VTD_INV_DESC_ALL_ONE
+ };
bool ret = true;
if (!vtd_inv_desc_reserved_check(s, inv_desc, mask, false,
@@ -4186,6 +4188,7 @@ static const Property vtd_properties[] = {
DEFINE_PROP_BOOL("x-flts", IntelIOMMUState, fsts, FALSE),
DEFINE_PROP_BOOL("snoop-control", IntelIOMMUState, snoop_control, false),
DEFINE_PROP_BOOL("x-pasid-mode", IntelIOMMUState, pasid, false),
+ DEFINE_PROP_BOOL("svm", IntelIOMMUState, svm, false),
DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true),
DEFINE_PROP_BOOL("stale-tm", IntelIOMMUState, stale_tm, false),
DEFINE_PROP_BOOL("fs1gp", IntelIOMMUState, fs1gp, true),
@@ -5096,6 +5099,10 @@ static void vtd_init(IntelIOMMUState *s)
vtd_spte_rsvd_large[3] &= ~VTD_SPTE_SNP;
}
+ if (s->svm) {
+ s->ecap |= VTD_ECAP_PRS | VTD_ECAP_PDS | VTD_ECAP_NWFS;
+ }
+
vtd_reset_caches(s);
/* Define registers with default values and bit semantics */
@@ -5573,6 +5580,29 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp)
return false;
}
+ if (s->svm) {
+ if (!x86_iommu->dt_supported) {
+ error_setg(errp, "Need to set device IOTLB for svm");
+ return false;
+ }
+
+ if (!s->fsts) {
+ error_setg(errp, "Need to set flts for svm");
+ return false;
+ }
+
+ if (!x86_iommu->dma_translation) {
+ error_setg(errp, "Need to set dma-translation for svm");
+ return false;
+ }
+
+ if (!s->pasid) {
+ error_setg(errp, "Need to set PASID support for svm");
+ return false;
+ }
+ }
+
+
return true;
}
@@ -5583,17 +5613,6 @@ static void vtd_realize(DeviceState *dev, Error **errp)
X86MachineState *x86ms = X86_MACHINE(ms);
PCIBus *bus = pcms->pcibus;
IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev);
- X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
-
- if (s->pasid && x86_iommu->dt_supported) {
- /*
- * PASID-based-Device-TLB Invalidate Descriptor is not
- * implemented and it requires support from vhost layer which
- * needs to be implemented in the future.
- */
- error_setg(errp, "PASID based device IOTLB is not supported");
- return;
- }
if (!vtd_decide_config(s, errp)) {
return;
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 18d50191d2..11a53aa369 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -194,8 +194,10 @@
#define VTD_ECAP_PRS (1ULL << 29)
#define VTD_ECAP_MHMV (15ULL << 20)
#define VTD_ECAP_SRS (1ULL << 31)
+#define VTD_ECAP_NWFS (1ULL << 33)
#define VTD_ECAP_PSS (7ULL << 35) /* limit: MemTxAttrs::pid */
#define VTD_ECAP_PASID (1ULL << 40)
+#define VTD_ECAP_PDS (1ULL << 42)
#define VTD_ECAP_SMTS (1ULL << 43)
#define VTD_ECAP_SSTS (1ULL << 46)
#define VTD_ECAP_FSTS (1ULL << 47)
@@ -417,7 +419,9 @@ typedef union VTDPRDesc VTDPRDesc;
#define VTD_INV_DESC_WAIT_IF (1ULL << 4)
#define VTD_INV_DESC_WAIT_FN (1ULL << 6)
#define VTD_INV_DESC_WAIT_DATA_SHIFT 32
-#define VTD_INV_DESC_WAIT_RSVD_LO 0Xfffff180ULL
+#define VTD_INV_DESC_WAIT_RSVD_LO(ecap) (0Xfffff100ULL | \
+ (((ecap) & VTD_ECAP_PDS) \
+ ? 0 : (1 << 7)))
#define VTD_INV_DESC_WAIT_RSVD_HI 3ULL
/* Masks for Context-cache Invalidation Descriptor */
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 6c61fd39c7..d600e5495f 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -275,6 +275,7 @@ struct IntelIOMMUState {
bool scalable_mode; /* RO - is Scalable Mode supported? */
bool fsts; /* RO - is first stage translation supported? */
bool snoop_control; /* RO - is SNP filed supported? */
+ bool svm; /* RO - is SVA/SVM supported? */
dma_addr_t root; /* Current root table pointer */
bool root_scalable; /* Type of root table (scalable or not) */
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 19/51] x86: q35: ich9: add 'wdat' property
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (17 preceding siblings ...)
2026-02-04 19:03 ` [PULL 18/51] intel_iommu: Add a CLI option to enable SVM Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 20/51] acpi: add API to build WDAT instructions Michael S. Tsirkin
` (34 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Igor Mammedov, Marcel Apfelbaum, Ani Sinha
From: Igor Mammedov <imammedo@redhat.com>
it will be used to make QEMU generate WDAT ACPI table,
that describes TCO watchdog in platfom independed way
and allows guest to use generic 'wdat' driver.
To enable it use '-global ICH9-LPC.wdat=on' option.
PS:
On linux wdat driver takes ove TCO watchdog if WDAT
table is present, hence 'wdat=off' by default to
avoid guest visible change on existing VMs.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251030123750.136175-2-imammedo@redhat.com>
---
hw/acpi/ich9.c | 5 +++++
hw/isa/lpc_ich9.c | 1 +
include/hw/acpi/ich9.h | 1 +
3 files changed, 7 insertions(+)
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 2b3b493c01..08a01aa1aa 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -321,6 +321,11 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, qemu_irq sci_irq)
acpi_pm_tco_init(&pm->tco_regs, &pm->io);
}
+ if (pm->enable_wdat && !pm->enable_tco) {
+ error_setg(&error_fatal,
+ "'wdat' can not be enabled without 'enable_tco=on'");
+ }
+
if (pm->acpi_pci_hotplug.use_acpi_hotplug_bridge) {
object_property_set_link(OBJECT(lpc_pci), "bus",
OBJECT(pci_get_bus(lpc_pci)), &error_abort);
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 51dc680029..2bf6becb5f 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -832,6 +832,7 @@ static const VMStateDescription vmstate_ich9_lpc = {
static const Property ich9_lpc_properties[] = {
DEFINE_PROP_BOOL("noreboot", ICH9LPCState, pin_strap.spkr_hi, false),
+ DEFINE_PROP_BOOL("wdat", ICH9LPCState, pm.enable_wdat, false),
DEFINE_PROP_BOOL("smm-compat", ICH9LPCState, pm.smm_compat, false),
DEFINE_PROP_BOOL("smm-enabled", ICH9LPCState, pm.smm_enabled, false),
DEFINE_PROP_BIT64("x-smi-broadcast", ICH9LPCState, smi_host_features,
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 245fe08dc2..c84e17f9f6 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -69,6 +69,7 @@ typedef struct ICH9LPCPMRegs {
bool smm_compat;
bool enable_tco;
TCOIORegs tco_regs;
+ bool enable_wdat;
bool swsmi_timer_enabled;
bool periodic_timer_enabled;
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 20/51] acpi: add API to build WDAT instructions
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (18 preceding siblings ...)
2026-02-04 19:03 ` [PULL 19/51] x86: q35: ich9: add 'wdat' property Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 21/51] x86: q35: generate WDAT ACPI table Michael S. Tsirkin
` (33 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Igor Mammedov, Ani Sinha
From: Igor Mammedov <imammedo@redhat.com>
Add definitions for WDAT[1] actions/instructions
and build_append_wdat_ins() API to build table entries.
1)
"Hardware Watchdog Timers Design Specification"
https://uefi.org/acpi 'Watchdog Action Table (WDAT)'
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251030123750.136175-3-imammedo@redhat.com>
---
hw/acpi/aml-build.c | 14 +++++
include/hw/acpi/wdat.h | 118 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 132 insertions(+)
create mode 100644 include/hw/acpi/wdat.h
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index dad4cfcc7d..3ec70825de 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -31,6 +31,7 @@
#include "hw/pci/pci_bus.h"
#include "hw/pci/pci_bridge.h"
#include "qemu/cutils.h"
+#include "hw/acpi/wdat.h"
static GArray *build_alloc_array(void)
{
@@ -2639,3 +2640,16 @@ Aml *aml_error_device(void)
return dev;
}
+
+void build_append_wdat_ins(GArray *table_data,
+ WDATAction action, uint8_t flags,
+ struct AcpiGenericAddress as,
+ uint32_t val, uint32_t mask)
+{
+ build_append_int_noprefix(table_data, action, 1); /* Watchdog Action */
+ build_append_int_noprefix(table_data, flags, 1); /* Instruction Flags */
+ build_append_int_noprefix(table_data, 0, 2); /* Reserved */
+ build_append_gas_from_struct(table_data, &as); /* Register Region */
+ build_append_int_noprefix(table_data, val, 4); /* Value */
+ build_append_int_noprefix(table_data, mask, 4); /* Mask */
+}
diff --git a/include/hw/acpi/wdat.h b/include/hw/acpi/wdat.h
new file mode 100644
index 0000000000..c539e97e9b
--- /dev/null
+++ b/include/hw/acpi/wdat.h
@@ -0,0 +1,118 @@
+/*
+ * Watchdog Action Table (WDAT) definitions
+ *
+ * Copyright Red Hat, Inc. 2025
+ * Author(s): Igor Mammedov <imammedo@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef QEMU_HW_ACPI_WDAT_H
+#define QEMU_HW_ACPI_WDAT_H
+
+#include "hw/acpi/acpi-defs.h"
+
+/*
+ * Watchdog actions as described in
+ * "Hardware Watchdog Timers Design Specification"
+ * for link to spec see https://uefi.org/acpi
+ * 'Watchdog Action Table (WDAT)'
+ */
+typedef enum {
+ /*
+ * Restarts the watchdog timer's countdown. This action is
+ * required.
+ */
+ WDAT_ACTION_RESET = 0x1,
+ /*
+ * Returns the current countdown value of the watchdog hardware
+ * (in count intervals).
+ */
+ WDAT_ACTION_QUERY_CURRENT_COUNTDOWN_PERIOD = 0x4,
+ /*
+ * Returns the countdown value the watchdog hardware is
+ * configured to use when reset (in count intervals).
+ */
+ WDAT_ACTION_QUERY_COUNTDOWN_PERIOD = 0x5,
+ /*
+ * Sets the countdown value (in count intervals) to be used when
+ * the watchdog timer is reset. This action is required if
+ * WDAT_ACTION_RESET does not explicitly write a new
+ * countdown value to a register during a reset. Otherwise, this
+ * action is optional.
+ */
+ WDAT_ACTION_SET_COUNTDOWN_PERIOD = 0x6,
+ /*
+ * Determines if the watchdog hardware is currently in enabled/
+ * running state. The same result must occur when performed from
+ * both from enabled/stopped state and enabled/running state. If
+ * the watchdog hardware is disabled, results are indeterminate.
+ * This action is required.
+ */
+ WDAT_ACTION_QUERY_RUNNING_STATE = 0x8,
+ /*
+ * Starts the watchdog, if not already in running state. If the
+ * watchdog hardware is disabled, results are indeterminate.
+ * This action is required.
+ */
+ WDAT_ACTION_SET_RUNNING_STATE = 0x9,
+ /*
+ * Determines if the watchdog hardware is currently in enabled/
+ * stopped state. The same result must occur when performed from
+ * both the enabled/stopped state and enabled/running state. If
+ * the watchdog hardware is disabled, results are indeterminate.
+ * This action is required.
+ */
+ WDAT_ACTION_QUERY_STOPPED_STATE = 0xA,
+ /*
+ * Stops the watchdog, if not already in stopped state. If the
+ * watchdog hardware is disabled, results are indeterminate.
+ * This action is required.
+ */
+ WDAT_ACTION_SET_STOPPED_STATE = 0xB,
+ /*
+ * Determines if the watchdog hardware is configured to perform a
+ * reboot when the watchdog is fired.
+ */
+ WDAT_ACTION_QUERY_REBOOT = 0x10,
+ /*
+ * Configures the watchdog hardware to perform a reboot when it
+ * is fired.
+ */
+ WDAT_ACTION_SET_REBOOT = 0x11,
+ /*
+ * Determines if the watchdog hardware is configured to perform a
+ * system shutdown when fired.
+ */
+ WDAT_ACTION_QUERY_SHUTDOWN = 0x12,
+ /*
+ * Configures the watchdog hardware to perform a system shutdown
+ * when fired.
+ */
+ WDAT_ACTION_SET_SHUTDOWN = 0x13,
+ /*
+ * Determines if the current boot was caused by the watchdog
+ * firing. The boot status is required to be set if the watchdog
+ * fired and caused a reboot. It is recommended that the
+ * Watchdog Status be set if the watchdog fired and caused a
+ * shutdown. This action is required.
+ */
+ WDAT_ACTION_QUERY_WATCHDOG_STATUS = 0x20,
+ /*
+ * Sets the watchdog's boot status to the default value. This
+ * action is required.
+ */
+ WDAT_ACTION_SET_WATCHDOG_STATUS = 0x21,
+} WDATAction;
+
+#define WDAT_INS_READ_VALUE 0x0
+#define WDAT_INS_READ_COUNTDOWN 0x1
+#define WDAT_INS_WRITE_VALUE 0x2
+#define WDAT_INS_WRITE_COUNTDOWN 0x3
+#define WDAT_INS_PRESERVE_REGISTER 0x80
+
+void build_append_wdat_ins(GArray *table_data,
+ WDATAction action, uint8_t flags,
+ struct AcpiGenericAddress as,
+ uint32_t val, uint32_t mask);
+
+#endif /* QEMU_HW_ACPI_WDAT_H */
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 21/51] x86: q35: generate WDAT ACPI table
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (19 preceding siblings ...)
2026-02-04 19:03 ` [PULL 20/51] acpi: add API to build WDAT instructions Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 22/51] tests: x86: q35: acpi: add WDAT table test case Michael S. Tsirkin
` (32 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Igor Mammedov, Ani Sinha, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, Marcel Apfelbaum
From: Igor Mammedov <imammedo@redhat.com>
It will generate WDAT table [1] customized for TCO watchdog.
This allows Windows guests (Windows Server 2008/Vista) to
use TCO watchdog using built-in generic driver, which
aleviates need to install vendor specific drivers.
Given that enabling it might change guest behaviour
(both Windows/Linux) the feature is disabled by default.
Users that need it can enable the feature with
following CLI option.
-global 'ICH9-LPC.wdat=on'
1)
"Hardware Watchdog Timers Design Specification"
https://uefi.org/acpi 'Watchdog Action Table (WDAT)'
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251030123750.136175-4-imammedo@redhat.com>
---
hw/acpi/meson.build | 3 +-
hw/acpi/wdat-ich9.c | 85 ++++++++++++++++++++++++++++++++++++++++++
hw/acpi/wdat-stub.c | 16 ++++++++
hw/i386/acpi-build.c | 13 +++++++
include/hw/acpi/wdat.h | 3 ++
5 files changed, 119 insertions(+), 1 deletion(-)
create mode 100644 hw/acpi/wdat-ich9.c
create mode 100644 hw/acpi/wdat-stub.c
diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build
index 56b5d1ec96..fb4304f21c 100644
--- a/hw/acpi/meson.build
+++ b/hw/acpi/meson.build
@@ -24,7 +24,7 @@ acpi_ss.add(when: 'CONFIG_ACPI_PCI_BRIDGE', if_true: files('pci-bridge.c'))
acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_true: files('pcihp.c'))
acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_false: files('acpi-pci-hotplug-stub.c'))
acpi_ss.add(when: 'CONFIG_ACPI_VIOT', if_true: files('viot.c'))
-acpi_ss.add(when: 'CONFIG_ACPI_ICH9', if_true: files('ich9.c', 'ich9_tco.c', 'ich9_timer.c'))
+acpi_ss.add(when: 'CONFIG_ACPI_ICH9', if_true: files('ich9.c', 'ich9_tco.c', 'ich9_timer.c', 'wdat-ich9.c'))
acpi_ss.add(when: 'CONFIG_ACPI_ERST', if_true: files('erst.c'))
acpi_ss.add(when: 'CONFIG_IPMI', if_true: files('ipmi.c'), if_false: files('ipmi-stub.c'))
acpi_ss.add(when: 'CONFIG_PC', if_false: files('acpi-x86-stub.c'))
@@ -33,6 +33,7 @@ if have_tpm
endif
system_ss.add(when: 'CONFIG_ACPI', if_false: files('acpi-stub.c', 'aml-build-stub.c', 'ghes-stub.c', 'acpi_interface.c'))
system_ss.add(when: 'CONFIG_ACPI_PCI_BRIDGE', if_false: files('pci-bridge-stub.c'))
+system_ss.add(when: 'CONFIG_ACPI_ICH9', if_false: files('wdat-stub.c'))
system_ss.add_all(when: 'CONFIG_ACPI', if_true: acpi_ss)
system_ss.add(when: 'CONFIG_GHES_CPER', if_true: files('ghes_cper.c'))
system_ss.add(when: 'CONFIG_GHES_CPER', if_false: files('ghes_cper_stub.c'))
diff --git a/hw/acpi/wdat-ich9.c b/hw/acpi/wdat-ich9.c
new file mode 100644
index 0000000000..c32ecf922c
--- /dev/null
+++ b/hw/acpi/wdat-ich9.c
@@ -0,0 +1,85 @@
+/*
+ * TCO Watchdog Action Table (WDAT)
+ *
+ * Copyright Red Hat, Inc. 2025
+ * Author(s): Igor Mammedov <imammedo@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/acpi/wdat.h"
+#include "hw/southbridge/ich9.h"
+
+#define TCO_REG(base, reg_offset, reg_width) { .space_id = AML_AS_SYSTEM_IO, \
+ .address = base + reg_offset, .bit_width = reg_width, \
+ .access_width = AML_WORD_ACC, };
+
+/*
+ * "Hardware Watchdog Timers Design Specification"
+ * https://uefi.org/acpi 'Watchdog Action Table (WDAT)'
+ */
+void build_wdat(GArray *table_data, BIOSLinker *linker, const char *oem_id,
+ const char *oem_table_id, uint64_t tco_base)
+{
+ AcpiTable table = { .sig = "WDAT", .rev = 1, .oem_id = oem_id,
+ .oem_table_id = oem_table_id };
+ struct AcpiGenericAddress tco_rld = TCO_REG(tco_base, 0x0, 16);
+ struct AcpiGenericAddress tco2_sts = TCO_REG(tco_base, 0x6, 16);
+ struct AcpiGenericAddress tco1_cnt = TCO_REG(tco_base, 0x8, 16);
+ struct AcpiGenericAddress tco_tmr = TCO_REG(tco_base, 0x12, 16);
+
+ acpi_table_begin(&table, table_data);
+ build_append_int_noprefix(table_data, 0x20, 4); /* Watchdog Header Length */
+ build_append_int_noprefix(table_data, 0xff, 2); /* PCI Segment */
+ build_append_int_noprefix(table_data, 0xff, 1); /* PCI Bus Number */
+ build_append_int_noprefix(table_data, 0xff, 1); /* PCI Device Number */
+ build_append_int_noprefix(table_data, 0xff, 1); /* PCI Function Number */
+ build_append_int_noprefix(table_data, 0, 3); /* Reserved */
+ build_append_int_noprefix(table_data, 0x258, 4);/* Timer Period, ms */
+ build_append_int_noprefix(table_data, 0x3ff, 4);/* Maximum Count */
+ build_append_int_noprefix(table_data, 0x4, 4); /* Minimum Count */
+ /*
+ * WATCHDOG_ENABLED & WATCHDOG_STOPPED_IN_SLEEP_STATE
+ */
+ build_append_int_noprefix(table_data, 0x81, 1); /* Watchdog Flags */
+ build_append_int_noprefix(table_data, 0, 3); /* Reserved */
+ /*
+ * watchdog instruction entries
+ */
+ build_append_int_noprefix(table_data, 10, 4);
+ /* Action table */
+ build_append_wdat_ins(table_data, WDAT_ACTION_RESET,
+ WDAT_INS_WRITE_VALUE,
+ tco_rld, 0x1, 0x1ff);
+ build_append_wdat_ins(table_data, WDAT_ACTION_QUERY_RUNNING_STATE,
+ WDAT_INS_READ_VALUE,
+ tco1_cnt, 0x0, 0x800);
+ build_append_wdat_ins(table_data, WDAT_ACTION_SET_RUNNING_STATE,
+ WDAT_INS_WRITE_VALUE | WDAT_INS_PRESERVE_REGISTER,
+ tco1_cnt, 0, 0x800);
+ build_append_wdat_ins(table_data, WDAT_ACTION_QUERY_STOPPED_STATE,
+ WDAT_INS_READ_VALUE,
+ tco1_cnt, 0x800, 0x800);
+ build_append_wdat_ins(table_data, WDAT_ACTION_SET_STOPPED_STATE,
+ WDAT_INS_WRITE_VALUE | WDAT_INS_PRESERVE_REGISTER,
+ tco1_cnt, 0x800, 0x800);
+ build_append_wdat_ins(table_data, WDAT_ACTION_SET_COUNTDOWN_PERIOD,
+ WDAT_INS_WRITE_COUNTDOWN,
+ tco_tmr, 0x0, 0x3FF);
+ build_append_wdat_ins(table_data, WDAT_ACTION_QUERY_COUNTDOWN_PERIOD,
+ WDAT_INS_READ_COUNTDOWN,
+ tco_tmr, 0x0, 0x3FF);
+ build_append_wdat_ins(table_data, WDAT_ACTION_QUERY_WATCHDOG_STATUS,
+ WDAT_INS_READ_VALUE,
+ tco2_sts, 0x2, 0x2);
+ build_append_wdat_ins(table_data, WDAT_ACTION_SET_WATCHDOG_STATUS,
+ WDAT_INS_WRITE_VALUE | WDAT_INS_PRESERVE_REGISTER,
+ tco2_sts, 0x2, 0x2);
+ build_append_wdat_ins(table_data, WDAT_ACTION_SET_WATCHDOG_STATUS,
+ WDAT_INS_WRITE_VALUE | WDAT_INS_PRESERVE_REGISTER,
+ tco2_sts, 0x4, 0x4);
+
+ acpi_table_end(linker, &table);
+}
diff --git a/hw/acpi/wdat-stub.c b/hw/acpi/wdat-stub.c
new file mode 100644
index 0000000000..a9b57a047b
--- /dev/null
+++ b/hw/acpi/wdat-stub.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright Red Hat, Inc. 2025
+ * Author(s): Igor Mammedov <imammedo@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/acpi/wdat.h"
+
+void build_wdat(GArray *table_data, BIOSLinker *linker, const char *oem_id,
+ const char *oem_table_id, uint64_t tco_base)
+{
+ g_assert_not_reached();
+}
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 9446a9f862..ac420eab81 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -77,6 +77,7 @@
#include "hw/acpi/hmat.h"
#include "hw/acpi/viot.h"
+#include "hw/acpi/wdat.h"
#include CONFIG_DEVICES
@@ -104,11 +105,13 @@ typedef struct AcpiPmInfo {
bool smi_on_cpuhp;
bool smi_on_cpu_unplug;
bool pcihp_root_en;
+ bool wdat_enabled;
uint8_t s4_val;
AcpiFadtData fadt;
uint16_t cpu_hp_io_base;
uint16_t pcihp_io_base;
uint16_t pcihp_io_len;
+ uint64_t tco_io_base;
} AcpiPmInfo;
typedef struct AcpiMiscInfo {
@@ -203,6 +206,7 @@ static void acpi_get_pm_info(MachineState *machine, AcpiPmInfo *pm)
pm->pcihp_io_len = 0;
pm->smi_on_cpuhp = false;
pm->smi_on_cpu_unplug = false;
+ pm->wdat_enabled = false;
assert(obj);
init_common_fadt_data(machine, obj, &pm->fadt);
@@ -224,6 +228,9 @@ static void acpi_get_pm_info(MachineState *machine, AcpiPmInfo *pm)
!!(smi_features & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOTPLUG_BIT));
pm->smi_on_cpu_unplug =
!!(smi_features & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT));
+ pm->wdat_enabled = object_property_get_bool(obj, "wdat", NULL);
+ pm->tco_io_base = object_property_get_uint(obj, ACPI_PM_PROP_PM_IO_BASE,
+ NULL) + ICH9_PMIO_TCO_RLD;
}
pm->pcihp_io_base =
object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
@@ -2079,6 +2086,12 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
acpi_add_table(table_offsets, tables_blob);
build_waet(tables_blob, tables->linker, x86ms->oem_id, x86ms->oem_table_id);
+ if (pm.wdat_enabled == true) {
+ acpi_add_table(table_offsets, tables_blob);
+ build_wdat(tables_blob, tables->linker, x86ms->oem_id,
+ x86ms->oem_table_id, pm.tco_io_base);
+ }
+
/* Add tables supplied by user (if any) */
for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
unsigned len = acpi_table_len(u);
diff --git a/include/hw/acpi/wdat.h b/include/hw/acpi/wdat.h
index c539e97e9b..67b9136d8c 100644
--- a/include/hw/acpi/wdat.h
+++ b/include/hw/acpi/wdat.h
@@ -115,4 +115,7 @@ void build_append_wdat_ins(GArray *table_data,
struct AcpiGenericAddress as,
uint32_t val, uint32_t mask);
+void build_wdat(GArray *table_data, BIOSLinker *linker, const char *oem_id,
+ const char *oem_table_id, uint64_t tco_base);
+
#endif /* QEMU_HW_ACPI_WDAT_H */
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 22/51] tests: x86: q35: acpi: add WDAT table test case
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (20 preceding siblings ...)
2026-02-04 19:03 ` [PULL 21/51] x86: q35: generate WDAT ACPI table Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 23/51] tests: acpi: update expected WDAT blob Michael S. Tsirkin
` (31 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Igor Mammedov, Ani Sinha
From: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251030123750.136175-5-imammedo@redhat.com>
---
tests/qtest/bios-tables-test-allowed-diff.h | 1 +
tests/qtest/bios-tables-test.c | 13 +++++++++++++
2 files changed, 14 insertions(+)
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..14b680debe 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,2 @@
/* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/x86/q35/WDAT.wdat",
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index e489d94331..99cd714aa7 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -2511,6 +2511,18 @@ static void test_acpi_isapc_smbios_legacy(void)
free_test_data(&data);
}
+static void test_acpi_q35_wdat(void)
+{
+ test_data data = {
+ .machine = MACHINE_Q35,
+ .arch = "x86",
+ .variant = ".wdat",
+ };
+
+ test_acpi_one("-global ICH9-LPC.wdat=on", &data);
+ free_test_data(&data);
+}
+
static void test_oem_fields(test_data *data)
{
int i;
@@ -2805,6 +2817,7 @@ int main(int argc, char *argv[])
qtest_add_func("acpi/q35/cxl", test_acpi_q35_cxl);
#endif
qtest_add_func("acpi/q35/slic", test_acpi_q35_slic);
+ qtest_add_func("acpi/q35/wdat", test_acpi_q35_wdat);
}
if (qtest_has_machine("microvm")) {
qtest_add_func("acpi/microvm", test_acpi_microvm_tcg);
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 23/51] tests: acpi: update expected WDAT blob
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (21 preceding siblings ...)
2026-02-04 19:03 ` [PULL 22/51] tests: x86: q35: acpi: add WDAT table test case Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 24/51] virtio/vhost: don't consider non-MAP_SHARED regions public Michael S. Tsirkin
` (30 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Igor Mammedov, Ani Sinha
From: Igor Mammedov <imammedo@redhat.com>
replace blank table with a new one:
+[000h 0000 4] Signature : "WDAT" [Watchdog Action Table]
+[004h 0004 4] Table Length : 00000134
+[008h 0008 1] Revision : 01
+[009h 0009 1] Checksum : 31
+[00Ah 0010 6] Oem ID : "BOCHS "
+[010h 0016 8] Oem Table ID : "BXPC "
+[018h 0024 4] Oem Revision : 00000001
+[01Ch 0028 4] Asl Compiler ID : "BXPC"
+[020h 0032 4] Asl Compiler Revision : 00000001
+
+[024h 0036 4] Header Length : 00000020
+[028h 0040 2] PCI Segment : 00FF
+[02Ah 0042 1] PCI Bus : FF
+[02Bh 0043 1] PCI Device : FF
+[02Ch 0044 1] PCI Function : FF
+[02Dh 0045 3] Reserved : 000000
+[030h 0048 4] Timer Period : 00000258
+[034h 0052 4] Max Count : 000003FF
+[038h 0056 4] Min Count : 00000004
+[03Ch 0060 1] Flags (decoded below) : 81
+ Enabled : 1
+ Stopped When Asleep : 1
+[03Dh 0061 3] Reserved : 000000
+[040h 0064 4] Watchdog Entry Count : 0000000A
+
+[044h 0068 1] Watchdog Action : 01
+[045h 0069 1] Instruction : 02
+[046h 0070 2] Reserved : 0000
+
+[048h 0072 12] Register Region : [Generic Address Structure]
+[048h 0072 1] Space ID : 01 [SystemIO]
+[049h 0073 1] Bit Width : 10
+[04Ah 0074 1] Bit Offset : 00
+[04Bh 0075 1] Encoded Access Width : 02 [Word Access:16]
+[04Ch 0076 8] Address : 0000000000000660
+
+[054h 0084 4] Value : 00000001
+[058h 0088 4] Register Mask : 000001FF
+
+[05Ch 0092 1] Watchdog Action : 08
+[05Dh 0093 1] Instruction : 00
+[05Eh 0094 2] Reserved : 0000
+
+[060h 0096 12] Register Region : [Generic Address Structure]
+[060h 0096 1] Space ID : 01 [SystemIO]
+[061h 0097 1] Bit Width : 10
+[062h 0098 1] Bit Offset : 00
+[063h 0099 1] Encoded Access Width : 02 [Word Access:16]
+[064h 0100 8] Address : 0000000000000668
+
+[06Ch 0108 4] Value : 00000000
+[070h 0112 4] Register Mask : 00000800
+
+[074h 0116 1] Watchdog Action : 09
+[075h 0117 1] Instruction : 82
+[076h 0118 2] Reserved : 0000
+
+[078h 0120 12] Register Region : [Generic Address Structure]
+[078h 0120 1] Space ID : 01 [SystemIO]
+[079h 0121 1] Bit Width : 10
+[07Ah 0122 1] Bit Offset : 00
+[07Bh 0123 1] Encoded Access Width : 02 [Word Access:16]
+[07Ch 0124 8] Address : 0000000000000668
+
+[084h 0132 4] Value : 00000000
+[088h 0136 4] Register Mask : 00000800
+
+[08Ch 0140 1] Watchdog Action : 0A
+[08Dh 0141 1] Instruction : 00
+[08Eh 0142 2] Reserved : 0000
+
+[090h 0144 12] Register Region : [Generic Address Structure]
+[090h 0144 1] Space ID : 01 [SystemIO]
+[091h 0145 1] Bit Width : 10
+[092h 0146 1] Bit Offset : 00
+[093h 0147 1] Encoded Access Width : 02 [Word Access:16]
+[094h 0148 8] Address : 0000000000000668
+
+[09Ch 0156 4] Value : 00000800
+[0A0h 0160 4] Register Mask : 00000800
+
+[0A4h 0164 1] Watchdog Action : 0B
+[0A5h 0165 1] Instruction : 82
+[0A6h 0166 2] Reserved : 0000
+
+[0A8h 0168 12] Register Region : [Generic Address Structure]
+[0A8h 0168 1] Space ID : 01 [SystemIO]
+[0A9h 0169 1] Bit Width : 10
+[0AAh 0170 1] Bit Offset : 00
+[0ABh 0171 1] Encoded Access Width : 02 [Word Access:16]
+[0ACh 0172 8] Address : 0000000000000668
+
+[0B4h 0180 4] Value : 00000800
+[0B8h 0184 4] Register Mask : 00000800
+
+[0BCh 0188 1] Watchdog Action : 06
+[0BDh 0189 1] Instruction : 03
+[0BEh 0190 2] Reserved : 0000
+
+[0C0h 0192 12] Register Region : [Generic Address Structure]
+[0C0h 0192 1] Space ID : 01 [SystemIO]
+[0C1h 0193 1] Bit Width : 10
+[0C2h 0194 1] Bit Offset : 00
+[0C3h 0195 1] Encoded Access Width : 02 [Word Access:16]
+[0C4h 0196 8] Address : 0000000000000672
+
+[0CCh 0204 4] Value : 00000000
+[0D0h 0208 4] Register Mask : 000003FF
+
+[0D4h 0212 1] Watchdog Action : 05
+[0D5h 0213 1] Instruction : 01
+[0D6h 0214 2] Reserved : 0000
+
+[0D8h 0216 12] Register Region : [Generic Address Structure]
+[0D8h 0216 1] Space ID : 01 [SystemIO]
+[0D9h 0217 1] Bit Width : 10
+[0DAh 0218 1] Bit Offset : 00
+[0DBh 0219 1] Encoded Access Width : 02 [Word Access:16]
+[0DCh 0220 8] Address : 0000000000000672
+
+[0E4h 0228 4] Value : 00000000
+[0E8h 0232 4] Register Mask : 000003FF
+
+[0ECh 0236 1] Watchdog Action : 20
+[0EDh 0237 1] Instruction : 00
+[0EEh 0238 2] Reserved : 0000
+
+[0F0h 0240 12] Register Region : [Generic Address Structure]
+[0F0h 0240 1] Space ID : 01 [SystemIO]
+[0F1h 0241 1] Bit Width : 10
+[0F2h 0242 1] Bit Offset : 00
+[0F3h 0243 1] Encoded Access Width : 02 [Word Access:16]
+[0F4h 0244 8] Address : 0000000000000666
+
+[0FCh 0252 4] Value : 00000002
+[100h 0256 4] Register Mask : 00000002
+
+[104h 0260 1] Watchdog Action : 21
+[105h 0261 1] Instruction : 82
+[106h 0262 2] Reserved : 0000
+
+[108h 0264 12] Register Region : [Generic Address Structure]
+[108h 0264 1] Space ID : 01 [SystemIO]
+[109h 0265 1] Bit Width : 10
+[10Ah 0266 1] Bit Offset : 00
+[10Bh 0267 1] Encoded Access Width : 02 [Word Access:16]
+[10Ch 0268 8] Address : 0000000000000666
+
+[114h 0276 4] Value : 00000002
+[118h 0280 4] Register Mask : 00000002
+
+[11Ch 0284 1] Watchdog Action : 21
+[11Dh 0285 1] Instruction : 82
+[11Eh 0286 2] Reserved : 0000
+
+[120h 0288 12] Register Region : [Generic Address Structure]
+[120h 0288 1] Space ID : 01 [SystemIO]
+[121h 0289 1] Bit Width : 10
+[122h 0290 1] Bit Offset : 00
+[123h 0291 1] Encoded Access Width : 02 [Word Access:16]
+[124h 0292 8] Address : 0000000000000666
+
+[12Ch 0300 4] Value : 00000004
+[130h 0304 4] Register Mask : 00000004
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251030123750.136175-6-imammedo@redhat.com>
---
tests/data/acpi/x86/q35/WDAT.wdat | Bin 0 -> 308 bytes
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
2 files changed, 1 deletion(-)
create mode 100644 tests/data/acpi/x86/q35/WDAT.wdat
diff --git a/tests/data/acpi/x86/q35/WDAT.wdat b/tests/data/acpi/x86/q35/WDAT.wdat
new file mode 100644
index 0000000000000000000000000000000000000000..e1e056b390e51c49f11f7b0d35e4e7c55d8067b1
GIT binary patch
literal 308
zcmaivF$w}f3`JkEx{TV)5#kX9FW|0)oq~c}T8Xtc(2GYhPO+$9AY^#?`OH6WH>b6L
zth#-_J6bm!dNVTt;vLff$K8QJ!5f$W4`2?6f@Jj4QYvm-AjK}Dx5`T;m_2{<;x*QX
lL4w7nzVfzt``kzV@waK@$$at15&T;93Z<9T{~wRc(JwJ97XbhO
literal 0
HcmV?d00001
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
index 14b680debe..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,2 +1 @@
/* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/x86/q35/WDAT.wdat",
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 24/51] virtio/vhost: don't consider non-MAP_SHARED regions public
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (22 preceding siblings ...)
2026-02-04 19:03 ` [PULL 23/51] tests: acpi: update expected WDAT blob Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 25/51] vdpa: fix vhost-vdpa suspended state not be shared Michael S. Tsirkin
` (29 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Daniil Tatianin, Stefano Garzarella
From: Daniil Tatianin <d-tatianin@yandex-team.ru>
Just having a file descriptor is not enough to consider a memory region
public. If QEMU didn't map it as MAP_SHARED (in case of share=off), guest
writes to this region won't be visible to the vhost-user backend, thus
causing it to read all zeroes or garbage. Make sure we don't pass such
regions and include that to our definition of what a private region is.
Signed-off-by: Daniil Tatianin <d-tatianin@yandex-team.ru>
Fixes: 552b25229c ("vhost: Rework memslot filtering and fix "used_memslot" tracking")
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251113085842.323745-1-d-tatianin@yandex-team.ru>
---
hw/virtio/vhost.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 31e9704cdc..c6a5928cb1 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -592,11 +592,13 @@ static bool vhost_section(struct vhost_dev *dev, MemoryRegionSection *section)
/*
* Some backends (like vhost-user) can only handle memory regions
* that have an fd (can be mapped into a different process). Filter
- * the ones without an fd out, if requested.
- *
- * TODO: we might have to limit to MAP_SHARED as well.
+ * the ones without an fd out, if requested. Also make sure that
+ * this region is mapped as shared so that the vhost backend can
+ * observe modifications to this region, otherwise we consider it
+ * private.
*/
- if (memory_region_get_fd(section->mr) < 0 &&
+ if ((memory_region_get_fd(section->mr) < 0 ||
+ !qemu_ram_is_shared(section->mr->ram_block)) &&
dev->vhost_ops->vhost_backend_no_private_memslots &&
dev->vhost_ops->vhost_backend_no_private_memslots(dev)) {
trace_vhost_reject_section(mr->name, 2);
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 25/51] vdpa: fix vhost-vdpa suspended state not be shared
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (23 preceding siblings ...)
2026-02-04 19:03 ` [PULL 24/51] virtio/vhost: don't consider non-MAP_SHARED regions public Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 26/51] acpi/ghes: Automate data block cleanup in acpi_ghes_memory_errors() Michael S. Tsirkin
` (28 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Wafer Xie, Eugenio Pérez, Jason Wang,
Stefano Garzarella
From: Wafer Xie <wafer@jaguarmicro.com>
When stopping a vhost-vdpa device, only the first queue pair is marked as suspended,
while the remaining queues are not updated to the suspended state.
As a result, when stopping a multi-queue vhost-vdpa device,
the following error message will be printed.
qemu-system-x86_64:vhost VQ 2 ring restore failed: -1: Operation not permitted (1)
qemu-system-x86_64:vhost VQ 3 ring restore failed: -1: Operation not permitted (1)
So move v->suspended to v->shared, and then all the vhost_vdpa devices cannot
have different suspended states.
Fixes: 0bb302a9960a ("vdpa: add vhost_vdpa_suspend")
Suggested-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Wafer Xie <wafer@jaguarmicro.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20251119132452.3117-1-wafer@jaguarmicro.com>
---
hw/virtio/vhost-vdpa.c | 6 +++---
include/hw/virtio/vhost-vdpa.h | 8 ++++++--
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 7061b6e1a3..2f8f11df86 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -905,7 +905,7 @@ static int vhost_vdpa_reset_device(struct vhost_dev *dev)
memory_listener_unregister(&v->shared->listener);
v->shared->listener_registered = false;
- v->suspended = false;
+ v->shared->suspended = false;
return 0;
}
@@ -1354,7 +1354,7 @@ static void vhost_vdpa_suspend(struct vhost_dev *dev)
if (unlikely(r)) {
error_report("Cannot suspend: %s(%d)", g_strerror(errno), errno);
} else {
- v->suspended = true;
+ v->shared->suspended = true;
return;
}
}
@@ -1481,7 +1481,7 @@ static int vhost_vdpa_get_vring_base(struct vhost_dev *dev,
return 0;
}
- if (!v->suspended) {
+ if (!v->shared->suspended) {
/*
* Cannot trust in value returned by device, let vhost recover used
* idx from guest.
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 449bf5c840..80ff670e23 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -76,6 +76,12 @@ typedef struct vhost_vdpa_shared {
/* SVQ switching is in progress, or already completed? */
SVQTransitionState svq_switching;
+
+ /*
+ * Device suspended successfully.
+ * The vhost_vdpa devices cannot have different suspended states.
+ */
+ bool suspended;
} VhostVDPAShared;
typedef struct vhost_vdpa {
@@ -83,8 +89,6 @@ typedef struct vhost_vdpa {
uint32_t address_space_id;
uint64_t acked_features;
bool shadow_vqs_enabled;
- /* Device suspended successfully */
- bool suspended;
VhostVDPAShared *shared;
GPtrArray *shadow_vqs;
const VhostShadowVirtqueueOps *shadow_vq_ops;
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 26/51] acpi/ghes: Automate data block cleanup in acpi_ghes_memory_errors()
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (24 preceding siblings ...)
2026-02-04 19:03 ` [PULL 25/51] vdpa: fix vhost-vdpa suspended state not be shared Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 27/51] acpi/ghes: Abort in acpi_ghes_memory_errors() if necessary Michael S. Tsirkin
` (27 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Gavin Shan, Markus Armbruster, Igor Mammedov,
Mauro Carvalho Chehab, Dongjiu Geng, Ani Sinha, qemu-arm
From: Gavin Shan <gshan@redhat.com>
Use g_auto_ptr() to automate data block cleanup in the function so
that it won't be a burden to us.
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251201141803.2386129-2-gshan@redhat.com>
---
hw/acpi/ghes.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
index 5445dc11bd..4e6903a8d3 100644
--- a/hw/acpi/ghes.c
+++ b/hw/acpi/ghes.c
@@ -566,9 +566,7 @@ int acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
0xED, 0x7C, 0x83, 0xB1);
Error *err = NULL;
int data_length;
- GArray *block;
-
- block = g_array_new(false, true /* clear */, 1);
+ g_autoptr(GArray) block = g_array_new(false, true /* clear */, 1);
data_length = ACPI_GHES_DATA_LENGTH + ACPI_GHES_MEM_CPER_LENGTH;
/*
@@ -586,8 +584,6 @@ int acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
/* Report the error */
ghes_record_cper_errors(ags, block->data, block->len, source_id, &err);
- g_array_free(block, true);
-
if (err) {
error_report_err(err);
return -1;
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 27/51] acpi/ghes: Abort in acpi_ghes_memory_errors() if necessary
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (25 preceding siblings ...)
2026-02-04 19:03 ` [PULL 26/51] acpi/ghes: Automate data block cleanup in acpi_ghes_memory_errors() Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 28/51] target/arm/kvm: Exit on error from acpi_ghes_memory_errors() Michael S. Tsirkin
` (26 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Gavin Shan, Markus Armbruster, Igor Mammedov,
Mauro Carvalho Chehab, Ani Sinha
From: Gavin Shan <gshan@redhat.com>
The function hw/acpi/ghes-stub.c::acpi_ghes_memory_errors() shouldn't
be called by any one. Take g_assert_not_reached() as a clearer indication.
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251201141803.2386129-3-gshan@redhat.com>
---
hw/acpi/ghes-stub.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/acpi/ghes-stub.c b/hw/acpi/ghes-stub.c
index 40f660c246..b54f1b093c 100644
--- a/hw/acpi/ghes-stub.c
+++ b/hw/acpi/ghes-stub.c
@@ -14,7 +14,7 @@
int acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
uint64_t physical_address)
{
- return -1;
+ g_assert_not_reached();
}
AcpiGhesState *acpi_ghes_get_state(void)
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 28/51] target/arm/kvm: Exit on error from acpi_ghes_memory_errors()
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (26 preceding siblings ...)
2026-02-04 19:03 ` [PULL 27/51] acpi/ghes: Abort in acpi_ghes_memory_errors() if necessary Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 29/51] acpi/ghes: Bail early on error from get_ghes_source_offsets() Michael S. Tsirkin
` (25 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Gavin Shan, Igor Mammedov, Markus Armbruster,
Mauro Carvalho Chehab, Paolo Bonzini, qemu-arm, kvm
From: Gavin Shan <gshan@redhat.com>
A core dump is no sense as there isn't programming bugs related to
errors from acpi_ghes_memory_errors().
Exit instead of abort when the function returns errors, and the
excessive error message is also dropped.
Suggested-by: Igor Mammedov <imammedo@redhat.com>
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251201141803.2386129-4-gshan@redhat.com>
---
target/arm/kvm.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 0828e8b87b..b83f1d5e4f 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -2477,8 +2477,7 @@ void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
paddr)) {
kvm_inject_arm_sea(c);
} else {
- error_report("failed to record the error");
- abort();
+ exit(1);
}
}
return;
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 29/51] acpi/ghes: Bail early on error from get_ghes_source_offsets()
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (27 preceding siblings ...)
2026-02-04 19:03 ` [PULL 28/51] target/arm/kvm: Exit on error from acpi_ghes_memory_errors() Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:03 ` [PULL 30/51] acpi/ghes: Use error_fatal in acpi_ghes_memory_errors() Michael S. Tsirkin
` (24 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Gavin Shan, Jonathan Cameron, Markus Armbruster,
Igor Mammedov, Mauro Carvalho Chehab, Ani Sinha, Dongjiu Geng,
qemu-arm
From: Gavin Shan <gshan@redhat.com>
In ghes_record_cper_errors(), get_ghes_source_offsets() can return
a error initialized by error_setg(). Without bailing on this error,
it can call into the second error_setg() due to the unexpected value
returned from the read acknowledgement register. The second error_setg()
can trigger assert(*errp == NULL) in its callee error_setv(), which
isn't expected.
Bail early in ghes_record_cper_errors() when error is received from
get_ghes_source_offsets() to avoid the unexpected behavior.
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251201141803.2386129-5-gshan@redhat.com>
---
hw/acpi/ghes.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
index 4e6903a8d3..d51d4bd466 100644
--- a/hw/acpi/ghes.c
+++ b/hw/acpi/ghes.c
@@ -444,7 +444,7 @@ static void get_hw_error_offsets(uint64_t ghes_addr,
*read_ack_register_addr = ghes_addr + sizeof(uint64_t);
}
-static void get_ghes_source_offsets(uint16_t source_id,
+static bool get_ghes_source_offsets(uint16_t source_id,
uint64_t hest_addr,
uint64_t *cper_addr,
uint64_t *read_ack_start_addr,
@@ -475,7 +475,7 @@ static void get_ghes_source_offsets(uint16_t source_id,
/* For now, we only know the size of GHESv2 table */
if (type != ACPI_GHES_SOURCE_GENERIC_ERROR_V2) {
error_setg(errp, "HEST: type %d not supported.", type);
- return;
+ return false;
}
/* Compare CPER source ID at the GHESv2 structure */
@@ -489,7 +489,7 @@ static void get_ghes_source_offsets(uint16_t source_id,
}
if (i == num_sources) {
error_setg(errp, "HEST: Source %d not found.", source_id);
- return;
+ return false;
}
/* Navigate through table address pointers */
@@ -509,6 +509,8 @@ static void get_ghes_source_offsets(uint16_t source_id,
cpu_physical_memory_read(hest_read_ack_addr, read_ack_start_addr,
sizeof(*read_ack_start_addr));
*read_ack_start_addr = le64_to_cpu(*read_ack_start_addr);
+
+ return true;
}
NotifierList acpi_generic_error_notifiers =
@@ -527,9 +529,10 @@ void ghes_record_cper_errors(AcpiGhesState *ags, const void *cper, size_t len,
if (!ags->use_hest_addr) {
get_hw_error_offsets(le64_to_cpu(ags->hw_error_le),
&cper_addr, &read_ack_register_addr);
- } else {
- get_ghes_source_offsets(source_id, le64_to_cpu(ags->hest_addr_le),
- &cper_addr, &read_ack_register_addr, errp);
+ } else if (!get_ghes_source_offsets(source_id,
+ le64_to_cpu(ags->hest_addr_le),
+ &cper_addr, &read_ack_register_addr, errp)) {
+ return;
}
cpu_physical_memory_read(read_ack_register_addr,
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 30/51] acpi/ghes: Use error_fatal in acpi_ghes_memory_errors()
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (28 preceding siblings ...)
2026-02-04 19:03 ` [PULL 29/51] acpi/ghes: Bail early on error from get_ghes_source_offsets() Michael S. Tsirkin
@ 2026-02-04 19:03 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 31/51] vhost: accept indirect descriptors in shadow virtqueue Michael S. Tsirkin
` (23 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:03 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Gavin Shan, Igor Mammedov, Markus Armbruster,
Jonathan Cameron, Mauro Carvalho Chehab, Ani Sinha, Dongjiu Geng,
Paolo Bonzini, qemu-arm, kvm
From: Gavin Shan <gshan@redhat.com>
Use error_fatal in acpi_ghes_memory_errors() so that the caller needn't
explicitly call exit(). The return value of acpi_ghes_memory_errors()
and ghes_record_cper_errors() is changed to 'bool' indicating an error
has been raised, to be compatible with what's documented in error.h.
Suggested-by: Igor Mammedov <imammedo@redhat.com>
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251201141803.2386129-6-gshan@redhat.com>
---
hw/acpi/ghes-stub.c | 4 ++--
hw/acpi/ghes.c | 26 ++++++++++----------------
include/hw/acpi/ghes.h | 6 +++---
target/arm/kvm.c | 9 +++------
4 files changed, 18 insertions(+), 27 deletions(-)
diff --git a/hw/acpi/ghes-stub.c b/hw/acpi/ghes-stub.c
index b54f1b093c..5f9313cce9 100644
--- a/hw/acpi/ghes-stub.c
+++ b/hw/acpi/ghes-stub.c
@@ -11,8 +11,8 @@
#include "qemu/osdep.h"
#include "hw/acpi/ghes.h"
-int acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
- uint64_t physical_address)
+bool acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
+ uint64_t physical_address, Error **errp)
{
g_assert_not_reached();
}
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
index d51d4bd466..c42f1721c4 100644
--- a/hw/acpi/ghes.c
+++ b/hw/acpi/ghes.c
@@ -516,14 +516,14 @@ static bool get_ghes_source_offsets(uint16_t source_id,
NotifierList acpi_generic_error_notifiers =
NOTIFIER_LIST_INITIALIZER(acpi_generic_error_notifiers);
-void ghes_record_cper_errors(AcpiGhesState *ags, const void *cper, size_t len,
+bool ghes_record_cper_errors(AcpiGhesState *ags, const void *cper, size_t len,
uint16_t source_id, Error **errp)
{
uint64_t cper_addr = 0, read_ack_register_addr = 0, read_ack_register;
if (len > ACPI_GHES_MAX_RAW_DATA_LENGTH) {
error_setg(errp, "GHES CPER record is too big: %zd", len);
- return;
+ return false;
}
if (!ags->use_hest_addr) {
@@ -532,7 +532,7 @@ void ghes_record_cper_errors(AcpiGhesState *ags, const void *cper, size_t len,
} else if (!get_ghes_source_offsets(source_id,
le64_to_cpu(ags->hest_addr_le),
&cper_addr, &read_ack_register_addr, errp)) {
- return;
+ return false;
}
cpu_physical_memory_read(read_ack_register_addr,
@@ -543,7 +543,7 @@ void ghes_record_cper_errors(AcpiGhesState *ags, const void *cper, size_t len,
error_setg(errp,
"OSPM does not acknowledge previous error,"
" so can not record CPER for current error anymore");
- return;
+ return false;
}
read_ack_register = cpu_to_le64(0);
@@ -558,16 +558,17 @@ void ghes_record_cper_errors(AcpiGhesState *ags, const void *cper, size_t len,
cpu_physical_memory_write(cper_addr, cper, len);
notifier_list_notify(&acpi_generic_error_notifiers, &source_id);
+
+ return true;
}
-int acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
- uint64_t physical_address)
+bool acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
+ uint64_t physical_address, Error **errp)
{
/* Memory Error Section Type */
const uint8_t guid[] =
UUID_LE(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83, \
0xED, 0x7C, 0x83, 0xB1);
- Error *err = NULL;
int data_length;
g_autoptr(GArray) block = g_array_new(false, true /* clear */, 1);
@@ -584,15 +585,8 @@ int acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
/* Build the memory section CPER for above new generic error data entry */
acpi_ghes_build_append_mem_cper(block, physical_address);
- /* Report the error */
- ghes_record_cper_errors(ags, block->data, block->len, source_id, &err);
-
- if (err) {
- error_report_err(err);
- return -1;
- }
-
- return 0;
+ return ghes_record_cper_errors(ags, block->data, block->len,
+ source_id, errp);
}
AcpiGhesState *acpi_ghes_get_state(void)
diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
index df2ecbf6e4..5b29aae4dd 100644
--- a/include/hw/acpi/ghes.h
+++ b/include/hw/acpi/ghes.h
@@ -98,9 +98,9 @@ void acpi_build_hest(AcpiGhesState *ags, GArray *table_data,
const char *oem_id, const char *oem_table_id);
void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s,
GArray *hardware_errors);
-int acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
- uint64_t error_physical_addr);
-void ghes_record_cper_errors(AcpiGhesState *ags, const void *cper, size_t len,
+bool acpi_ghes_memory_errors(AcpiGhesState *ags, uint16_t source_id,
+ uint64_t error_physical_addr, Error **errp);
+bool ghes_record_cper_errors(AcpiGhesState *ags, const void *cper, size_t len,
uint16_t source_id, Error **errp);
/**
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index b83f1d5e4f..3e35570f15 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -2473,12 +2473,9 @@ void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
*/
if (code == BUS_MCEERR_AR) {
kvm_cpu_synchronize_state(c);
- if (!acpi_ghes_memory_errors(ags, ACPI_HEST_SRC_ID_SYNC,
- paddr)) {
- kvm_inject_arm_sea(c);
- } else {
- exit(1);
- }
+ acpi_ghes_memory_errors(ags, ACPI_HEST_SRC_ID_SYNC,
+ paddr, &error_fatal);
+ kvm_inject_arm_sea(c);
}
return;
}
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 31/51] vhost: accept indirect descriptors in shadow virtqueue
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (29 preceding siblings ...)
2026-02-04 19:03 ` [PULL 30/51] acpi/ghes: Use error_fatal in acpi_ghes_memory_errors() Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 32/51] virtio-dmabuf: Ensure UUID persistence for hash table insertion Michael S. Tsirkin
` (22 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Eugenio Pérez, Jason Wang, Stefano Garzarella
From: Eugenio Pérez <eperezma@redhat.com>
The device is not able to generate indirect descriptors by itself, only
the driver can do it. And SVQ is already able to handle them by reusing
VirtQueue struct.
Shadow VirtQueue just transform the indirect descriptors to chained
buffers. This way we don't need to map a new buffer for the indirect
table and handle its exhaustion etc. As they are only used in control
plane and HW devices don't like indirect, we should not see significant
downsides with these.
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
--
Tested functionally by forwarding the CVQ descriptors.
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251201125149.2151026-1-eperezma@redhat.com>
---
hw/virtio/vhost-shadow-virtqueue.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index 2481d49345..6242aeb69c 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -34,6 +34,7 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp)
switch (b) {
case VIRTIO_F_ANY_LAYOUT:
case VIRTIO_RING_F_EVENT_IDX:
+ case VIRTIO_RING_F_INDIRECT_DESC:
continue;
case VIRTIO_F_ACCESS_PLATFORM:
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 32/51] virtio-dmabuf: Ensure UUID persistence for hash table insertion
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (30 preceding siblings ...)
2026-02-04 19:04 ` [PULL 31/51] vhost: accept indirect descriptors in shadow virtqueue Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 33/51] virtio: Fix crash when sriov-pf is set for non-PCI-Express device Michael S. Tsirkin
` (21 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Dorinda Bassey, Stefano Garzarella, Albert Esteve,
Marc-André Lureau, Jim MacArthur
From: Dorinda Bassey <dbassey@redhat.com>
In `virtio_add_resource` function, the UUID used as a key for
`g_hash_table_insert` was temporary, which could lead to
invalid lookups when accessed later. This patch ensures that
the UUID remains valid by duplicating it into a newly allocated
memory space. The value is then inserted into the hash table
with this persistent UUID key to ensure that the key stored in
the hash table remains valid as long as the hash table entry
exists.
Fixes: faefdba847 ("hw/display: introduce virtio-dmabuf")
Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Albert Esteve <aesteve@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Jim MacArthur <jim.macarthur@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251204162129.262745-1-dbassey@redhat.com>
---
hw/display/virtio-dmabuf.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/hw/display/virtio-dmabuf.c b/hw/display/virtio-dmabuf.c
index 3dba4577ca..5e0395be77 100644
--- a/hw/display/virtio-dmabuf.c
+++ b/hw/display/virtio-dmabuf.c
@@ -35,11 +35,13 @@ static bool virtio_add_resource(QemuUUID *uuid, VirtioSharedObject *value)
if (resource_uuids == NULL) {
resource_uuids = g_hash_table_new_full(qemu_uuid_hash,
uuid_equal_func,
- NULL,
+ g_free,
g_free);
}
if (g_hash_table_lookup(resource_uuids, uuid) == NULL) {
- g_hash_table_insert(resource_uuids, uuid, value);
+ g_hash_table_insert(resource_uuids,
+ g_memdup2(uuid, sizeof(*uuid)),
+ value);
} else {
result = false;
}
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 33/51] virtio: Fix crash when sriov-pf is set for non-PCI-Express device
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (31 preceding siblings ...)
2026-02-04 19:04 ` [PULL 32/51] virtio-dmabuf: Ensure UUID persistence for hash table insertion Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 34/51] pcie_sriov: Fix PCI_SRIOV_* accesses in pcie_sriov_pf_exit() Michael S. Tsirkin
` (20 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Kevin Wolf, qemu-stable, Stefan Hajnoczi
From: Kevin Wolf <kwolf@redhat.com>
Setting the sriov-pf property on devices that aren't PCI Express causes
an assertion failure:
$ qemu-system-x86_64 \
-blockdev null-co,node-name=null \
-blockdev null-co,node-name=null2 \
-device virtio-blk,drive=null,id=pf \
-device virtio-blk,sriov-pf=pf,drive=null2
qemu-system-x86_64: ../hw/pci/pcie.c:1062: void pcie_add_capability(PCIDevice *, uint16_t, uint8_t, uint16_t, uint16_t): Assertion `offset >= PCI_CONFIG_SPACE_SIZE' failed.
This is because proxy->last_pcie_cap_offset is only initialised to a
non-zero value in virtio_pci_realize() if it's a PCI Express device, and
then virtio_pci_device_plugged() still tries to use it.
To fix this, just skip the SR-IOV code for !pci_is_express(). Then the
next thing pci_qdev_realize() does is call pcie_sriov_register_device(),
which returns the appropriate error.
Cc: qemu-stable@nongnu.org
Fixes: d0c280d3fac6 ('pcie_sriov: Make a PCI device with user-created VF ARI-capable')
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251204172657.174391-1-kwolf@redhat.com>
---
hw/virtio/virtio-pci.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index b273eb2691..1e8f90df34 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -2183,15 +2183,17 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
PCI_BASE_ADDRESS_SPACE_IO, &proxy->bar);
}
- if (pci_is_vf(&proxy->pci_dev)) {
- pcie_ari_init(&proxy->pci_dev, proxy->last_pcie_cap_offset);
- proxy->last_pcie_cap_offset += PCI_ARI_SIZEOF;
- } else {
- 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);
+ if (pci_is_express(&proxy->pci_dev)) {
+ if (pci_is_vf(&proxy->pci_dev)) {
+ pcie_ari_init(&proxy->pci_dev, proxy->last_pcie_cap_offset);
+ proxy->last_pcie_cap_offset += PCI_ARI_SIZEOF;
+ } else {
+ 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);
+ }
}
}
}
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 34/51] pcie_sriov: Fix PCI_SRIOV_* accesses in pcie_sriov_pf_exit()
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (32 preceding siblings ...)
2026-02-04 19:04 ` [PULL 33/51] virtio: Fix crash when sriov-pf is set for non-PCI-Express device Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 35/51] q35: Fix migration of SMRAM state Michael S. Tsirkin
` (19 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Kevin Wolf, qemu-stable, Marcel Apfelbaum
From: Kevin Wolf <kwolf@redhat.com>
PCI_SRIOV_* are offsets into the SR-IOV capability, not into the PCI
config space. pcie_sriov_pf_exit() erroneously takes them as the latter,
which makes it read PCI_HEADER_TYPE and PCI_BIST when it tries to read
PCI_SRIOV_TOTAL_VF.
In many cases we're lucky enough that the PCI config space will be 0
there, so we just skip the whole for loop, but this isn't guaranteed.
For example, setting the multifunction bit on the PF and then doing a
'device_del' on it will get a larger number and cause a segfault.
Fix this and access the real PCI_SRIOV_* fields in the capability.
Cc: qemu-stable@nongnu.org
Fixes: 19e55471d4e8 ('pcie_sriov: Allow user to create SR-IOV device')
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251205145718.55136-1-kwolf@redhat.com>
---
hw/pci/pcie_sriov.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
index 34e0875d21..c41ac95bee 100644
--- a/hw/pci/pcie_sriov.c
+++ b/hw/pci/pcie_sriov.c
@@ -195,14 +195,17 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
void pcie_sriov_pf_exit(PCIDevice *dev)
{
+ uint8_t *cfg;
+
if (dev->exp.sriov_cap == 0) {
return;
}
+ cfg = dev->config + dev->exp.sriov_cap;
if (dev->exp.sriov_pf.vf_user_created) {
uint16_t ven_id = pci_get_word(dev->config + PCI_VENDOR_ID);
- uint16_t total_vfs = pci_get_word(dev->config + PCI_SRIOV_TOTAL_VF);
- uint16_t vf_dev_id = pci_get_word(dev->config + PCI_SRIOV_VF_DID);
+ uint16_t total_vfs = pci_get_word(cfg + PCI_SRIOV_TOTAL_VF);
+ uint16_t vf_dev_id = pci_get_word(cfg + PCI_SRIOV_VF_DID);
unregister_vfs(dev);
@@ -213,8 +216,6 @@ void pcie_sriov_pf_exit(PCIDevice *dev)
pci_config_set_device_id(dev->exp.sriov_pf.vf[i]->config, vf_dev_id);
}
} else {
- uint8_t *cfg = dev->config + dev->exp.sriov_cap;
-
unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
}
}
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 35/51] q35: Fix migration of SMRAM state
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (33 preceding siblings ...)
2026-02-04 19:04 ` [PULL 34/51] pcie_sriov: Fix PCI_SRIOV_* accesses in pcie_sriov_pf_exit() Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 36/51] standard-headers: Update virtio_spi.h from Linux v6.18-rc3 Michael S. Tsirkin
` (18 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Igor Mammedov, Andrey Ryabinin, Marcel Apfelbaum,
Fabiano Rosas, Laurent Vivier, Paolo Bonzini
From: Igor Mammedov <imammedo@redhat.com>
When migrating, dst QEMU by default has SMRAM unlocked,
and since wmask is not migrated, the migrated value of
MCH_HOST_BRIDGE_F_SMBASE in config space fall to prey of
mch_update_smbase_smram()
...
if (pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] == 0xff) {
*reg = 0x00;
and is getting cleared and leads to unlocked smram
on dst even if on source it's been locked.
As Andrey has pointed out [1], we should derive wmask
from config and not other way around.
Drop offending chunk and resync wmask based on MCH_HOST_BRIDGE_F_SMBASE
register value. That would preserve the register during
migration and set smram regions into corresponding state.
What that changes is:
that it would let guest write junk values in register
(with no apparent effect) until it's stumbles upon
reserved 0x1 [|] 0x2 values, at which point it
would be only possible to lock register and trigger
switch to SMRAM blackhole in CPU AS.
While at it, fix up test by removing junk discard before negotiation hunk.
PS2:
Instead of adding a dedicated post_load handler for it,
reuse mch_update->mch_update_smbase_smram call chain
that is called on write/reset/post_load to be consistent
with how we handle mch registers.
PS3:
for prosterity here is erro message Andrey got due to this bug:
qemu: vfio_container_dma_map(0x..., 0x0, 0xa0000, 0x....) = -22 (Invalid argument)
qemu: hardware error: vfio: DMA mapping failed, unable to continue
1) https://patchew.org/QEMU/20251203180851.6390-1-arbn@yandex-team.com/
Fixes: f404220e279c ("q35: implement 128K SMRAM at default SMBASE address")
Reported-by: Andrey Ryabinin <arbn@yandex-team.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Andrey Ryabinin <arbn@yandex-team.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251211165454.288476-1-imammedo@redhat.com>
---
hw/pci-host/q35.c | 27 ++++++++++++---------------
tests/qtest/q35-test.c | 6 ------
2 files changed, 12 insertions(+), 21 deletions(-)
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index b353d3e1e6..e85e4227b3 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -431,30 +431,27 @@ static void mch_update_smbase_smram(MCHPCIState *mch)
}
if (*reg == MCH_HOST_BRIDGE_F_SMBASE_QUERY) {
- pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] =
- MCH_HOST_BRIDGE_F_SMBASE_LCK;
+ pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] = MCH_HOST_BRIDGE_F_SMBASE_LCK;
*reg = MCH_HOST_BRIDGE_F_SMBASE_IN_RAM;
return;
}
/*
- * default/reset state, discard written value
- * which will disable SMRAM balackhole at SMBASE
+ * reg value can come from register write/reset/migration source,
+ * update wmask to be in sync with it regardless of source
*/
- if (pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] == 0xff) {
- *reg = 0x00;
+ if (*reg == MCH_HOST_BRIDGE_F_SMBASE_IN_RAM) {
+ pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] = MCH_HOST_BRIDGE_F_SMBASE_LCK;
+ return;
+ }
+ if (*reg & MCH_HOST_BRIDGE_F_SMBASE_LCK) {
+ /* lock register at 0x2 and disable all writes */
+ pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] = 0;
+ *reg = MCH_HOST_BRIDGE_F_SMBASE_LCK;
}
+ lck = *reg & MCH_HOST_BRIDGE_F_SMBASE_LCK;
memory_region_transaction_begin();
- if (*reg & MCH_HOST_BRIDGE_F_SMBASE_LCK) {
- /* disable all writes */
- pd->wmask[MCH_HOST_BRIDGE_F_SMBASE] &=
- ~MCH_HOST_BRIDGE_F_SMBASE_LCK;
- *reg = MCH_HOST_BRIDGE_F_SMBASE_LCK;
- lck = true;
- } else {
- lck = false;
- }
memory_region_set_enabled(&mch->smbase_blackhole, lck);
memory_region_set_enabled(&mch->smbase_window, lck);
memory_region_transaction_commit();
diff --git a/tests/qtest/q35-test.c b/tests/qtest/q35-test.c
index 62fff49fc8..4e3a4457f6 100644
--- a/tests/qtest/q35-test.c
+++ b/tests/qtest/q35-test.c
@@ -206,12 +206,6 @@ static void test_smram_smbase_lock(void)
qtest_writeb(qts, SMBASE, SMRAM_TEST_PATTERN);
g_assert_cmpint(qtest_readb(qts, SMBASE), ==, SMRAM_TEST_PATTERN);
- /* check that writing junk to 0x9c before before negotiating is ignored */
- for (i = 0; i < 0xff; i++) {
- qpci_config_writeb(pcidev, MCH_HOST_BRIDGE_F_SMBASE, i);
- g_assert(qpci_config_readb(pcidev, MCH_HOST_BRIDGE_F_SMBASE) == 0);
- }
-
/* enable SMRAM at SMBASE */
qpci_config_writeb(pcidev, MCH_HOST_BRIDGE_F_SMBASE, 0xff);
g_assert(qpci_config_readb(pcidev, MCH_HOST_BRIDGE_F_SMBASE) == 0x01);
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 36/51] standard-headers: Update virtio_spi.h from Linux v6.18-rc3
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (34 preceding siblings ...)
2026-02-04 19:04 ` [PULL 35/51] q35: Fix migration of SMRAM state Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 37/51] virtio-spi: Add vhost-user-spi device support Michael S. Tsirkin
` (17 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Haixu Cui, Manos Pitsidianakis, Cornelia Huck,
Paolo Bonzini
From: Haixu Cui <quic_haixcui@quicinc.com>
Synced virtio_spi.h from upstream Linux kernelusing
scripts/update-linux-headers.sh.
Source:
- Linux commit dcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa (v6.18-rc3)
- Author: Linus Torvalds <torvalds@linux-foundation.org>
- Date: Sun Oct 26 15:59:49 2025 -0700
This update ensures QEMU's standard headers are consistent with the latest
virtio SPI definitions from Linux v6.18-rc3.
Signed-off-by: Haixu Cui <quic_haixcui@quicinc.com>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251216032122.1316684-2-quic_haixcui@quicinc.com>
---
include/standard-headers/linux/virtio_spi.h | 181 ++++++++++++++++++++
1 file changed, 181 insertions(+)
create mode 100644 include/standard-headers/linux/virtio_spi.h
diff --git a/include/standard-headers/linux/virtio_spi.h b/include/standard-headers/linux/virtio_spi.h
new file mode 100644
index 0000000000..54e570fb4a
--- /dev/null
+++ b/include/standard-headers/linux/virtio_spi.h
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (C) 2023 OpenSynergy GmbH
+ * Copyright (C) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef _LINUX_VIRTIO_VIRTIO_SPI_H
+#define _LINUX_VIRTIO_VIRTIO_SPI_H
+
+#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/virtio_config.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_types.h"
+
+/* Sample data on trailing clock edge */
+#define VIRTIO_SPI_CPHA _BITUL(0)
+/* Clock is high when IDLE */
+#define VIRTIO_SPI_CPOL _BITUL(1)
+/* Chip Select is active high */
+#define VIRTIO_SPI_CS_HIGH _BITUL(2)
+/* Transmit LSB first */
+#define VIRTIO_SPI_MODE_LSB_FIRST _BITUL(3)
+/* Loopback mode */
+#define VIRTIO_SPI_MODE_LOOP _BITUL(4)
+
+/**
+ * struct virtio_spi_config - All config fields are read-only for the
+ * Virtio SPI driver
+ * @cs_max_number: maximum number of chipselect the host SPI controller
+ * supports.
+ * @cs_change_supported: indicates if the host SPI controller supports to toggle
+ * chipselect after each transfer in one message:
+ * 0: unsupported, chipselect will be kept in active state throughout the
+ * message transaction;
+ * 1: supported.
+ * Note: Message here contains a sequence of SPI transfers.
+ * @tx_nbits_supported: indicates the supported number of bit for writing:
+ * bit 0: DUAL (2-bit transfer), 1 for supported
+ * bit 1: QUAD (4-bit transfer), 1 for supported
+ * bit 2: OCTAL (8-bit transfer), 1 for supported
+ * other bits are reserved as 0, 1-bit transfer is always supported.
+ * @rx_nbits_supported: indicates the supported number of bit for reading:
+ * bit 0: DUAL (2-bit transfer), 1 for supported
+ * bit 1: QUAD (4-bit transfer), 1 for supported
+ * bit 2: OCTAL (8-bit transfer), 1 for supported
+ * other bits are reserved as 0, 1-bit transfer is always supported.
+ * @bits_per_word_mask: mask indicating which values of bits_per_word are
+ * supported. If not set, no limitation for bits_per_word.
+ * @mode_func_supported: indicates the following features are supported or not:
+ * bit 0-1: CPHA feature
+ * 0b00: invalid, should support as least one CPHA setting
+ * 0b01: supports CPHA=0 only
+ * 0b10: supports CPHA=1 only
+ * 0b11: supports CPHA=0 and CPHA=1.
+ * bit 2-3: CPOL feature
+ * 0b00: invalid, should support as least one CPOL setting
+ * 0b01: supports CPOL=0 only
+ * 0b10: supports CPOL=1 only
+ * 0b11: supports CPOL=0 and CPOL=1.
+ * bit 4: chipselect active high feature, 0 for unsupported and 1 for
+ * supported, chipselect active low is supported by default.
+ * bit 5: LSB first feature, 0 for unsupported and 1 for supported,
+ * MSB first is supported by default.
+ * bit 6: loopback mode feature, 0 for unsupported and 1 for supported,
+ * normal mode is supported by default.
+ * @max_freq_hz: the maximum clock rate supported in Hz unit, 0 means no
+ * limitation for transfer speed.
+ * @max_word_delay_ns: the maximum word delay supported, in nanoseconds.
+ * A value of 0 indicates that word delay is unsupported.
+ * Each transfer may consist of a sequence of words.
+ * @max_cs_setup_ns: the maximum delay supported after chipselect is asserted,
+ * in ns unit, 0 means delay is not supported to introduce after chipselect is
+ * asserted.
+ * @max_cs_hold_ns: the maximum delay supported before chipselect is deasserted,
+ * in ns unit, 0 means delay is not supported to introduce before chipselect
+ * is deasserted.
+ * @max_cs_incative_ns: maximum delay supported after chipselect is deasserted,
+ * in ns unit, 0 means delay is not supported to introduce after chipselect is
+ * deasserted.
+ */
+struct virtio_spi_config {
+ uint8_t cs_max_number;
+ uint8_t cs_change_supported;
+#define VIRTIO_SPI_RX_TX_SUPPORT_DUAL _BITUL(0)
+#define VIRTIO_SPI_RX_TX_SUPPORT_QUAD _BITUL(1)
+#define VIRTIO_SPI_RX_TX_SUPPORT_OCTAL _BITUL(2)
+ uint8_t tx_nbits_supported;
+ uint8_t rx_nbits_supported;
+ uint32_t bits_per_word_mask;
+#define VIRTIO_SPI_MF_SUPPORT_CPHA_0 _BITUL(0)
+#define VIRTIO_SPI_MF_SUPPORT_CPHA_1 _BITUL(1)
+#define VIRTIO_SPI_MF_SUPPORT_CPOL_0 _BITUL(2)
+#define VIRTIO_SPI_MF_SUPPORT_CPOL_1 _BITUL(3)
+#define VIRTIO_SPI_MF_SUPPORT_CS_HIGH _BITUL(4)
+#define VIRTIO_SPI_MF_SUPPORT_LSB_FIRST _BITUL(5)
+#define VIRTIO_SPI_MF_SUPPORT_LOOPBACK _BITUL(6)
+ uint32_t mode_func_supported;
+ uint32_t max_freq_hz;
+ uint32_t max_word_delay_ns;
+ uint32_t max_cs_setup_ns;
+ uint32_t max_cs_hold_ns;
+ uint32_t max_cs_inactive_ns;
+};
+
+/**
+ * struct spi_transfer_head - virtio SPI transfer descriptor
+ * @chip_select_id: chipselect index the SPI transfer used.
+ * @bits_per_word: the number of bits in each SPI transfer word.
+ * @cs_change: whether to deselect device after finishing this transfer
+ * before starting the next transfer, 0 means cs keep asserted and
+ * 1 means cs deasserted then asserted again.
+ * @tx_nbits: bus width for write transfer.
+ * 0,1: bus width is 1, also known as SINGLE
+ * 2 : bus width is 2, also known as DUAL
+ * 4 : bus width is 4, also known as QUAD
+ * 8 : bus width is 8, also known as OCTAL
+ * other values are invalid.
+ * @rx_nbits: bus width for read transfer.
+ * 0,1: bus width is 1, also known as SINGLE
+ * 2 : bus width is 2, also known as DUAL
+ * 4 : bus width is 4, also known as QUAD
+ * 8 : bus width is 8, also known as OCTAL
+ * other values are invalid.
+ * @reserved: for future use.
+ * @mode: SPI transfer mode.
+ * bit 0: CPHA, determines the timing (i.e. phase) of the data
+ * bits relative to the clock pulses.For CPHA=0, the
+ * "out" side changes the data on the trailing edge of the
+ * preceding clock cycle, while the "in" side captures the data
+ * on (or shortly after) the leading edge of the clock cycle.
+ * For CPHA=1, the "out" side changes the data on the leading
+ * edge of the current clock cycle, while the "in" side
+ * captures the data on (or shortly after) the trailing edge of
+ * the clock cycle.
+ * bit 1: CPOL, determines the polarity of the clock. CPOL=0 is a
+ * clock which idles at 0, and each cycle consists of a pulse
+ * of 1. CPOL=1 is a clock which idles at 1, and each cycle
+ * consists of a pulse of 0.
+ * bit 2: CS_HIGH, if 1, chip select active high, else active low.
+ * bit 3: LSB_FIRST, determines per-word bits-on-wire, if 0, MSB
+ * first, else LSB first.
+ * bit 4: LOOP, loopback mode.
+ * @freq: the transfer speed in Hz.
+ * @word_delay_ns: delay to be inserted between consecutive words of a
+ * transfer, in ns unit.
+ * @cs_setup_ns: delay to be introduced after CS is asserted, in ns
+ * unit.
+ * @cs_delay_hold_ns: delay to be introduced before CS is deasserted
+ * for each transfer, in ns unit.
+ * @cs_change_delay_inactive_ns: delay to be introduced after CS is
+ * deasserted and before next asserted, in ns unit.
+ */
+struct spi_transfer_head {
+ uint8_t chip_select_id;
+ uint8_t bits_per_word;
+ uint8_t cs_change;
+ uint8_t tx_nbits;
+ uint8_t rx_nbits;
+ uint8_t reserved[3];
+ uint32_t mode;
+ uint32_t freq;
+ uint32_t word_delay_ns;
+ uint32_t cs_setup_ns;
+ uint32_t cs_delay_hold_ns;
+ uint32_t cs_change_delay_inactive_ns;
+};
+
+/**
+ * struct spi_transfer_result - virtio SPI transfer result
+ * @result: Transfer result code.
+ * VIRTIO_SPI_TRANS_OK: Transfer successful.
+ * VIRTIO_SPI_PARAM_ERR: Parameter error.
+ * VIRTIO_SPI_TRANS_ERR: Transfer error.
+ */
+struct spi_transfer_result {
+#define VIRTIO_SPI_TRANS_OK 0
+#define VIRTIO_SPI_PARAM_ERR 1
+#define VIRTIO_SPI_TRANS_ERR 2
+ uint8_t result;
+};
+
+#endif /* #ifndef _LINUX_VIRTIO_VIRTIO_SPI_H */
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 37/51] virtio-spi: Add vhost-user-spi device support
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (35 preceding siblings ...)
2026-02-04 19:04 ` [PULL 36/51] standard-headers: Update virtio_spi.h from Linux v6.18-rc3 Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 38/51] hw/virtio/virtio-crypto: verify asym request size Michael S. Tsirkin
` (16 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Haixu Cui, Manos Pitsidianakis, Pierrick Bouvier,
Paolo Bonzini, Stefano Garzarella
From: Haixu Cui <quic_haixcui@quicinc.com>
This patch introduces support for vhost-user-spi and vhost-user-spi-pci
devices in QEMU, enabling virtio-based SPI communication via the vhost-user
protocol.
The implementation follows the virtio-spi specification and leverages
the upstream virtio-spi driver in Linux. Relevant references:
- Virtio SPI specification:
https://github.com/oasis-tcs/virtio-spec/tree/master/device-types/spi
- Linux virtio-spi driver:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-virtio.c?h=v6.18-rc3
- vhost-user-spi daemon:
https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-spi
Example usage with rust-vmm vhost-user-spi daemon:
Start the vhost-user-spi daemon:
vhost-device-spi --socket-path=vspi.sock --socket-count=1 \
--device "/dev/spidev0.0"
Launch QEMU with:
qemu-system-aarch64 -m 1G \
-chardev socket,path=/home/root/vspi.sock0,id=vspi \
-device vhost-user-spi-device,chardev=vspi,id=spi \
-object memory-backend-file,id=mem,size=1G,mem-path=/dev/shm,share=on \
-numa node,memdev=mem
Signed-off-by: Haixu Cui <quic_haixcui@quicinc.com>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251216032122.1316684-3-quic_haixcui@quicinc.com>
---
MAINTAINERS | 6 ++
docs/system/devices/virtio/vhost-user.rst | 3 +
hw/virtio/Kconfig | 5 ++
hw/virtio/meson.build | 3 +
hw/virtio/vhost-user-spi-pci.c | 69 +++++++++++++++++++++++
hw/virtio/vhost-user-spi.c | 65 +++++++++++++++++++++
hw/virtio/virtio.c | 4 +-
include/hw/virtio/vhost-user-spi.h | 25 ++++++++
8 files changed, 179 insertions(+), 1 deletion(-)
create mode 100644 hw/virtio/vhost-user-spi-pci.c
create mode 100644 hw/virtio/vhost-user-spi.c
create mode 100644 include/hw/virtio/vhost-user-spi.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 9b7ed4fccb..d049270777 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2556,6 +2556,12 @@ F: hw/virtio/vhost-user-scmi*
F: include/hw/virtio/vhost-user-scmi.h
F: tests/qtest/libqos/virtio-scmi.*
+vhost-user-spi
+M: Haixu Cui <quic_haixcui@quicinc.com>
+S: Maintained
+F: include/hw/virtio/vhost-user-spi.h
+F: hw/virtio/vhost-user-spi*
+
virtio-crypto
M: Gonglei <arei.gonglei@huawei.com>
S: Supported
diff --git a/docs/system/devices/virtio/vhost-user.rst b/docs/system/devices/virtio/vhost-user.rst
index f556a840e9..2806d81ca2 100644
--- a/docs/system/devices/virtio/vhost-user.rst
+++ b/docs/system/devices/virtio/vhost-user.rst
@@ -58,6 +58,9 @@ platform details for what sort of virtio bus to use.
* - vhost-user-vsock
- Socket based communication
- `vhost-device-vsock <https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-vsock>`_
+ * - vhost-user-spi
+ - Proxy spi devices to host
+ - `vhost-device-spi <https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-spi>`_
The referenced *daemons* are not exhaustive, any conforming backend
implementing the device and using the vhost-user protocol should work.
diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index 10f5c53ac0..8895682c61 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -127,6 +127,11 @@ config VHOST_USER_SCMI
default y
depends on VIRTIO && VHOST_USER && ARM
+config VHOST_USER_SPI
+ bool
+ default y
+ depends on VIRTIO && VHOST_USER
+
config VHOST_USER_TEST
bool
default y
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index affd66887d..6675b63ce6 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -28,6 +28,7 @@ if have_vhost
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c'))
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SND', if_true: files('vhost-user-snd.c'))
system_virtio_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
+ system_virtio_ss.add(when: 'CONFIG_VHOST_USER_SPI', if_true: files('vhost-user-spi.c'))
# PCI Stubs
system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_TEST'],
@@ -42,6 +43,8 @@ if have_vhost
if_true: files('vhost-user-snd-pci.c'))
system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_INPUT'],
if_true: files('vhost-user-input-pci.c'))
+ system_virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_SPI'],
+ if_true: files('vhost-user-spi-pci.c'))
endif
if have_vhost_vdpa
system_virtio_ss.add(files('vhost-vdpa.c'))
diff --git a/hw/virtio/vhost-user-spi-pci.c b/hw/virtio/vhost-user-spi-pci.c
new file mode 100644
index 0000000000..f813b824b6
--- /dev/null
+++ b/hw/virtio/vhost-user-spi-pci.c
@@ -0,0 +1,69 @@
+/*
+ * Vhost-user spi virtio device PCI glue
+ *
+ * Copyright (C) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/virtio/vhost-user-spi.h"
+#include "hw/virtio/virtio-pci.h"
+
+struct VHostUserSPIPCI {
+ VirtIOPCIProxy parent_obj;
+ VHostUserSPI vdev;
+};
+
+typedef struct VHostUserSPIPCI VHostUserSPIPCI;
+
+#define TYPE_VHOST_USER_SPI_PCI "vhost-user-spi-pci-base"
+
+DECLARE_INSTANCE_CHECKER(VHostUserSPIPCI, VHOST_USER_SPI_PCI,
+ TYPE_VHOST_USER_SPI_PCI)
+
+static void vhost_user_spi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+ VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(vpci_dev);
+ DeviceState *vdev = DEVICE(&dev->vdev);
+
+ vpci_dev->nvectors = 1;
+ qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
+}
+
+static void vhost_user_spi_pci_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+ PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+ k->realize = vhost_user_spi_pci_realize;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+ pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+ pcidev_k->device_id = 0; /* Set by virtio-pci based on virtio id */
+ pcidev_k->revision = 0x00;
+ pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
+}
+
+static void vhost_user_spi_pci_instance_init(Object *obj)
+{
+ VHostUserSPIPCI *dev = VHOST_USER_SPI_PCI(obj);
+
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+ TYPE_VHOST_USER_SPI);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_spi_pci_info = {
+ .base_name = TYPE_VHOST_USER_SPI_PCI,
+ .non_transitional_name = "vhost-user-spi-pci",
+ .instance_size = sizeof(VHostUserSPIPCI),
+ .instance_init = vhost_user_spi_pci_instance_init,
+ .class_init = vhost_user_spi_pci_class_init,
+};
+
+static void vhost_user_spi_pci_register(void)
+{
+ virtio_pci_types_register(&vhost_user_spi_pci_info);
+}
+
+type_init(vhost_user_spi_pci_register);
diff --git a/hw/virtio/vhost-user-spi.c b/hw/virtio/vhost-user-spi.c
new file mode 100644
index 0000000000..707f96c250
--- /dev/null
+++ b/hw/virtio/vhost-user-spi.c
@@ -0,0 +1,65 @@
+/*
+ * Vhost-user spi virtio device
+ *
+ * Copyright (C) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/vhost-user-spi.h"
+#include "qemu/error-report.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_spi.h"
+
+static const Property vspi_properties[] = {
+ DEFINE_PROP_CHR("chardev", VHostUserBase, chardev),
+};
+
+static void vspi_realize(DeviceState *dev, Error **errp)
+{
+ VHostUserBase *vub = VHOST_USER_BASE(dev);
+ VHostUserBaseClass *vubc = VHOST_USER_BASE_GET_CLASS(dev);
+
+ /* Fixed for SPI */
+ vub->virtio_id = VIRTIO_ID_SPI;
+ vub->num_vqs = 1;
+ vub->vq_size = 4;
+ vub->config_size = sizeof(struct virtio_spi_config);
+
+ vubc->parent_realize(dev, errp);
+}
+
+static const VMStateDescription vu_spi_vmstate = {
+ .name = "vhost-user-spi",
+ .unmigratable = 1,
+};
+
+static void vu_spi_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass);
+
+ dc->vmsd = &vu_spi_vmstate;
+ device_class_set_props(dc, vspi_properties);
+ device_class_set_parent_realize(dc, vspi_realize,
+ &vubc->parent_realize);
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+}
+
+static const TypeInfo vu_spi_info = {
+ .name = TYPE_VHOST_USER_SPI,
+ .parent = TYPE_VHOST_USER_BASE,
+ .instance_size = sizeof(VHostUserSPI),
+ .class_init = vu_spi_class_init,
+};
+
+static void vu_spi_register_types(void)
+{
+ type_register_static(&vu_spi_info);
+}
+
+type_init(vu_spi_register_types)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 3dc9423eae..77ca54e520 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -48,6 +48,7 @@
#include "standard-headers/linux/virtio_iommu.h"
#include "standard-headers/linux/virtio_mem.h"
#include "standard-headers/linux/virtio_vsock.h"
+#include "standard-headers/linux/virtio_spi.h"
/*
* Maximum size of virtio device config space
@@ -196,7 +197,8 @@ const char *virtio_device_names[] = {
[VIRTIO_ID_PARAM_SERV] = "virtio-param-serv",
[VIRTIO_ID_AUDIO_POLICY] = "virtio-audio-pol",
[VIRTIO_ID_BT] = "virtio-bluetooth",
- [VIRTIO_ID_GPIO] = "virtio-gpio"
+ [VIRTIO_ID_GPIO] = "virtio-gpio",
+ [VIRTIO_ID_SPI] = "virtio-spi"
};
static const char *virtio_id_to_name(uint16_t device_id)
diff --git a/include/hw/virtio/vhost-user-spi.h b/include/hw/virtio/vhost-user-spi.h
new file mode 100644
index 0000000000..a1a65820cd
--- /dev/null
+++ b/include/hw/virtio/vhost-user-spi.h
@@ -0,0 +1,25 @@
+/*
+ * Vhost-user spi virtio device
+ *
+ * Copyright (C) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_VHOST_USER_SPI_H
+#define QEMU_VHOST_USER_SPI_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "hw/virtio/vhost-user-base.h"
+
+#define TYPE_VHOST_USER_SPI "vhost-user-spi-device"
+
+OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSPI, VHOST_USER_SPI)
+
+struct VHostUserSPI {
+ VHostUserBase parent_obj;
+};
+
+#endif /* QEMU_VHOST_USER_SPI_H */
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 38/51] hw/virtio/virtio-crypto: verify asym request size
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (36 preceding siblings ...)
2026-02-04 19:04 ` [PULL 37/51] virtio-spi: Add vhost-user-spi device support Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 39/51] cryptodev-builtin: Limit the maximum size Michael S. Tsirkin
` (15 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, zhenwei pi, 이재영, zhenwei pi,
Gonglei (Arei)
From: zhenwei pi <pizhenwei@tensorfer.com>
The total lenght of request is limited by cryptodev config, verify it
to avoid unexpected request from guest.
Fixes: CVE-2025-14876
Fixes: 0e660a6f90a ("crypto: Introduce RSA algorithm")
Reported-by: 이재영 <nakamurajames123@gmail.com>
Signed-off-by: zhenwei pi <zhenwei.pi@linux.dev>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251221024321.143196-2-zhenwei.pi@linux.dev>
---
hw/virtio/virtio-crypto.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index cbd1810fbc..6fceb39681 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -767,11 +767,18 @@ virtio_crypto_handle_asym_req(VirtIOCrypto *vcrypto,
uint32_t len;
uint8_t *src = NULL;
uint8_t *dst = NULL;
+ uint64_t max_len;
asym_op_info = g_new0(CryptoDevBackendAsymOpInfo, 1);
src_len = ldl_le_p(&req->para.src_data_len);
dst_len = ldl_le_p(&req->para.dst_data_len);
+ max_len = (uint64_t)src_len + dst_len;
+ if (unlikely(max_len > vcrypto->conf.max_size)) {
+ virtio_error(vdev, "virtio-crypto asym request is too large");
+ goto err;
+ }
+
if (src_len > 0) {
src = g_malloc0(src_len);
len = iov_to_buf(iov, out_num, 0, src, src_len);
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 39/51] cryptodev-builtin: Limit the maximum size
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (37 preceding siblings ...)
2026-02-04 19:04 ` [PULL 38/51] hw/virtio/virtio-crypto: verify asym request size Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 40/51] MAINTAINERS: Update VIOT maintainer Michael S. Tsirkin
` (14 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, zhenwei pi, 이재영, zhenwei pi,
Gonglei (Arei)
From: zhenwei pi <pizhenwei@tensorfer.com>
This backend driver is used for demonstration purposes only, unlimited
size leads QEMU OOM.
Fixes: CVE-2025-14876
Fixes: 1653a5f3fc7 ("cryptodev: introduce a new cryptodev backend")
Reported-by: 이재영 <nakamurajames123@gmail.com>
Signed-off-by: zhenwei pi <zhenwei.pi@linux.dev>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251221024321.143196-3-zhenwei.pi@linux.dev>
---
backends/cryptodev-builtin.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c
index 0414c01e06..55a3fbd27b 100644
--- a/backends/cryptodev-builtin.c
+++ b/backends/cryptodev-builtin.c
@@ -53,6 +53,8 @@ typedef struct CryptoDevBackendBuiltinSession {
#define CRYPTODEV_BUITLIN_MAX_AUTH_KEY_LEN 512
#define CRYPTODEV_BUITLIN_MAX_CIPHER_KEY_LEN 64
+/* demonstration purposes only, use a limited size to avoid QEMU OOM */
+#define CRYPTODEV_BUITLIN_MAX_REQUEST_SIZE (1024 * 1024)
struct CryptoDevBackendBuiltin {
CryptoDevBackend parent_obj;
@@ -98,12 +100,7 @@ static void cryptodev_builtin_init(
1u << QCRYPTODEV_BACKEND_SERVICE_TYPE_MAC;
backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
- /*
- * Set the Maximum length of crypto request.
- * Why this value? Just avoid to overflow when
- * memory allocation for each crypto request.
- */
- backend->conf.max_size = LONG_MAX - sizeof(CryptoDevBackendOpInfo);
+ backend->conf.max_size = CRYPTODEV_BUITLIN_MAX_REQUEST_SIZE;
backend->conf.max_cipher_key_len = CRYPTODEV_BUITLIN_MAX_CIPHER_KEY_LEN;
backend->conf.max_auth_key_len = CRYPTODEV_BUITLIN_MAX_AUTH_KEY_LEN;
cryptodev_builtin_init_akcipher(backend);
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 40/51] MAINTAINERS: Update VIOT maintainer
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (38 preceding siblings ...)
2026-02-04 19:04 ` [PULL 39/51] cryptodev-builtin: Limit the maximum size Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region Michael S. Tsirkin
` (13 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Jean-Philippe Brucker, Eric Auger,
Philippe Mathieu-Daudé, Thomas Huth, Pierrick Bouvier,
Richard Henderson, Cédric Le Goater
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
Unfortunately I can't contribute to QEMU for the time being, but Eric
has offered to take on maintainership of the ACPI VIOT. Thank you!
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20251230154844.325364-2-jean-philippe@linaro.org>
---
MAINTAINERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index d049270777..ebd27cd7f3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2197,7 +2197,7 @@ S: Maintained
F: hw/riscv/virt-acpi-build.c
ACPI/VIOT
-M: Jean-Philippe Brucker <jean-philippe@linaro.org>
+M: Eric Auger <eric.auger@redhat.com>
S: Supported
F: hw/acpi/viot.c
F: hw/acpi/viot.h
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (39 preceding siblings ...)
2026-02-04 19:04 ` [PULL 40/51] MAINTAINERS: Update VIOT maintainer Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-11 20:46 ` Dmitry Osipenko
2026-02-13 14:29 ` Peter Maydell
2026-02-04 19:04 ` [PULL 42/51] virtio-pmem: ignore empty queue notifications Michael S. Tsirkin
` (12 subsequent siblings)
53 siblings, 2 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Joelle van Dyne, Akihiko Odaki, Alex Bennée,
Dmitry Osipenko
From: Joelle van Dyne <j@getutm.app>
When `owner` == `mr`, `object_unparent` will crash:
object_unparent(mr) ->
object_property_del_child(mr, mr) ->
object_finalize_child_property(mr, name, mr) ->
object_unref(mr) ->
object_finalize(mr) ->
object_property_del_all(mr) ->
object_finalize_child_property(mr, name, mr) ->
object_unref(mr) ->
fail on g_assert(obj->ref > 0)
However, passing a different `owner` to `memory_region_init` does not
work. `memory_region_ref` has an optimization where it takes a ref
only on the owner. That means when flatviews are created, it does not
take a ref on the region and you can get a UAF from `flatview_destroy`
called from RCU.
The correct fix therefore is to use `NULL` as the name which will set
the `owner` but not the `parent` (which is still NULL). This allows us
to use `memory_region_ref` on itself while not having to rely on unparent
for cleanup.
Signed-off-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260103214400.71694-1-j@getutm.app>
---
hw/display/virtio-gpu-virgl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 07f6355ad6..6a83fb63c8 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -120,7 +120,7 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
vmr->g = g;
mr = &vmr->mr;
- memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data);
+ memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data);
memory_region_add_subregion(&b->hostmem, offset, mr);
memory_region_set_enabled(mr, true);
@@ -186,7 +186,7 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g,
/* memory region owns self res->mr object and frees it by itself */
memory_region_set_enabled(mr, false);
memory_region_del_subregion(&b->hostmem, mr);
- object_unparent(OBJECT(mr));
+ object_unref(OBJECT(mr));
}
return 0;
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-04 19:04 ` [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region Michael S. Tsirkin
@ 2026-02-11 20:46 ` Dmitry Osipenko
2026-02-11 21:32 ` Joelle van Dyne
2026-02-12 6:29 ` Michael S. Tsirkin
2026-02-13 14:29 ` Peter Maydell
1 sibling, 2 replies; 77+ messages in thread
From: Dmitry Osipenko @ 2026-02-11 20:46 UTC (permalink / raw)
To: Michael S. Tsirkin, qemu-devel
Cc: Peter Maydell, Joelle van Dyne, Akihiko Odaki, Alex Bennée
On 2/4/26 22:04, Michael S. Tsirkin wrote:
> From: Joelle van Dyne <j@getutm.app>
>
> When `owner` == `mr`, `object_unparent` will crash:
>
> object_unparent(mr) ->
> object_property_del_child(mr, mr) ->
> object_finalize_child_property(mr, name, mr) ->
> object_unref(mr) ->
> object_finalize(mr) ->
> object_property_del_all(mr) ->
> object_finalize_child_property(mr, name, mr) ->
> object_unref(mr) ->
> fail on g_assert(obj->ref > 0)
>
> However, passing a different `owner` to `memory_region_init` does not
> work. `memory_region_ref` has an optimization where it takes a ref
> only on the owner. That means when flatviews are created, it does not
> take a ref on the region and you can get a UAF from `flatview_destroy`
> called from RCU.
>
> The correct fix therefore is to use `NULL` as the name which will set
> the `owner` but not the `parent` (which is still NULL). This allows us
> to use `memory_region_ref` on itself while not having to rely on unparent
> for cleanup.
>
> Signed-off-by: Joelle van Dyne <j@getutm.app>
> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> Message-Id: <20260103214400.71694-1-j@getutm.app>
> ---
> hw/display/virtio-gpu-virgl.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> index 07f6355ad6..6a83fb63c8 100644
> --- a/hw/display/virtio-gpu-virgl.c
> +++ b/hw/display/virtio-gpu-virgl.c
> @@ -120,7 +120,7 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
> vmr->g = g;
>
> mr = &vmr->mr;
> - memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data);
> + memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data);
> memory_region_add_subregion(&b->hostmem, offset, mr);
> memory_region_set_enabled(mr, true);
>
> @@ -186,7 +186,7 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g,
> /* memory region owns self res->mr object and frees it by itself */
> memory_region_set_enabled(mr, false);
> memory_region_del_subregion(&b->hostmem, mr);
> - object_unparent(OBJECT(mr));
> + object_unref(OBJECT(mr));
> }
>
> return 0;
Hello Michael,
This patch introduces regression. Running any venus application results
in a crash:
Thread 2 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
(gdb) bt
#0 0x00007ffff56565e2 in __strcmp_evex () at /lib64/libc.so.6
#1 0x0000555555841bdb in find_fd (head=0x5555572337d0 <cpr_state>,
name=0x0, id=0) at ../migration/cpr.c:68
#2 cpr_delete_fd (name=name@entry=0x0, id=id@entry=0) at
../migration/cpr.c:77
#3 0x000055555582290a in qemu_ram_free (block=0x7ff7e93aa7f0) at
../system/physmem.c:2615
#4 0x000055555581ae02 in memory_region_finalize (obj=<optimized out>)
at ../system/memory.c:1816
#5 0x0000555555a70ab9 in object_deinit (obj=<optimized out>,
type=<optimized out>) at ../qom/object.c:715
#6 object_finalize (data=0x7ff7e936eff0) at ../qom/object.c:729
#7 object_unref (objptr=0x7ff7e936eff0) at ../qom/object.c:1232
#8 0x0000555555814fae in memory_region_unref (mr=<optimized out>) at
../system/memory.c:1848
#9 flatview_destroy (view=0x555559ed6c40) at ../system/memory.c:301
#10 0x0000555555bfc122 in call_rcu_thread (opaque=<optimized out>) at
../util/rcu.c:324
#11 0x0000555555bf17a7 in qemu_thread_start (args=0x555557b99520) at
../util/qemu-thread-posix.c:393
#12 0x00007ffff556f464 in start_thread () at /lib64/libc.so.6
#13 0x00007ffff55f25ac in __clone3 () at /lib64/libc.so.6
There is a v2 version of this patch that doesn't crash [1]. Was v1
applied by mistake instead of v2?
[1] https://lore.kernel.org/qemu-devel/20251223184023.1913-1-j@getutm.app/
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-11 20:46 ` Dmitry Osipenko
@ 2026-02-11 21:32 ` Joelle van Dyne
2026-02-11 22:53 ` Dmitry Osipenko
2026-02-12 6:29 ` Michael S. Tsirkin
1 sibling, 1 reply; 77+ messages in thread
From: Joelle van Dyne @ 2026-02-11 21:32 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Michael S. Tsirkin, qemu-devel@nongnu.org, Peter Maydell,
Joelle van Dyne, Akihiko Odaki, Alex Bennée
[-- Attachment #1: Type: text/plain, Size: 4168 bytes --]
Yes, it does seem like v1 was picked up and not v2. v1 was broken for this
reason.
On Wednesday, February 11, 2026, Dmitry Osipenko <
dmitry.osipenko@collabora.com> wrote:
> On 2/4/26 22:04, Michael S. Tsirkin wrote:
> > From: Joelle van Dyne <j@getutm.app>
> >
> > When `owner` == `mr`, `object_unparent` will crash:
> >
> > object_unparent(mr) ->
> > object_property_del_child(mr, mr) ->
> > object_finalize_child_property(mr, name, mr) ->
> > object_unref(mr) ->
> > object_finalize(mr) ->
> > object_property_del_all(mr) ->
> > object_finalize_child_property(mr, name, mr) ->
> > object_unref(mr) ->
> > fail on g_assert(obj->ref > 0)
> >
> > However, passing a different `owner` to `memory_region_init` does not
> > work. `memory_region_ref` has an optimization where it takes a ref
> > only on the owner. That means when flatviews are created, it does not
> > take a ref on the region and you can get a UAF from `flatview_destroy`
> > called from RCU.
> >
> > The correct fix therefore is to use `NULL` as the name which will set
> > the `owner` but not the `parent` (which is still NULL). This allows us
> > to use `memory_region_ref` on itself while not having to rely on unparent
> > for cleanup.
> >
> > Signed-off-by: Joelle van Dyne <j@getutm.app>
> > Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> > Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > Message-Id: <20260103214400.71694-1-j@getutm.app>
> > ---
> > hw/display/virtio-gpu-virgl.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/display/virtio-gpu-virgl.c
> b/hw/display/virtio-gpu-virgl.c
> > index 07f6355ad6..6a83fb63c8 100644
> > --- a/hw/display/virtio-gpu-virgl.c
> > +++ b/hw/display/virtio-gpu-virgl.c
> > @@ -120,7 +120,7 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
> > vmr->g = g;
> >
> > mr = &vmr->mr;
> > - memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data);
> > + memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data);
> > memory_region_add_subregion(&b->hostmem, offset, mr);
> > memory_region_set_enabled(mr, true);
> >
> > @@ -186,7 +186,7 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g,
> > /* memory region owns self res->mr object and frees it by
> itself */
> > memory_region_set_enabled(mr, false);
> > memory_region_del_subregion(&b->hostmem, mr);
> > - object_unparent(OBJECT(mr));
> > + object_unref(OBJECT(mr));
> > }
> >
> > return 0;
>
> Hello Michael,
>
> This patch introduces regression. Running any venus application results
> in a crash:
>
> Thread 2 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
> (gdb) bt
> #0 0x00007ffff56565e2 in __strcmp_evex () at /lib64/libc.so.6
> #1 0x0000555555841bdb in find_fd (head=0x5555572337d0 <cpr_state>,
> name=0x0, id=0) at ../migration/cpr.c:68
> #2 cpr_delete_fd (name=name@entry=0x0, id=id@entry=0) at
> ../migration/cpr.c:77
> #3 0x000055555582290a in qemu_ram_free (block=0x7ff7e93aa7f0) at
> ../system/physmem.c:2615
> #4 0x000055555581ae02 in memory_region_finalize (obj=<optimized out>)
> at ../system/memory.c:1816
> #5 0x0000555555a70ab9 in object_deinit (obj=<optimized out>,
> type=<optimized out>) at ../qom/object.c:715
> #6 object_finalize (data=0x7ff7e936eff0) at ../qom/object.c:729
> #7 object_unref (objptr=0x7ff7e936eff0) at ../qom/object.c:1232
> #8 0x0000555555814fae in memory_region_unref (mr=<optimized out>) at
> ../system/memory.c:1848
> #9 flatview_destroy (view=0x555559ed6c40) at ../system/memory.c:301
> #10 0x0000555555bfc122 in call_rcu_thread (opaque=<optimized out>) at
> ../util/rcu.c:324
> #11 0x0000555555bf17a7 in qemu_thread_start (args=0x555557b99520) at
> ../util/qemu-thread-posix.c:393
> #12 0x00007ffff556f464 in start_thread () at /lib64/libc.so.6
> #13 0x00007ffff55f25ac in __clone3 () at /lib64/libc.so.6
>
> There is a v2 version of this patch that doesn't crash [1]. Was v1
> applied by mistake instead of v2?
>
> [1] https://lore.kernel.org/qemu-devel/20251223184023.1913-1-j@getutm.app/
>
> --
> Best regards,
> Dmitry
>
[-- Attachment #2: Type: text/html, Size: 5449 bytes --]
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-11 21:32 ` Joelle van Dyne
@ 2026-02-11 22:53 ` Dmitry Osipenko
2026-02-12 7:01 ` Michael S. Tsirkin
0 siblings, 1 reply; 77+ messages in thread
From: Dmitry Osipenko @ 2026-02-11 22:53 UTC (permalink / raw)
To: Joelle van Dyne
Cc: Michael S. Tsirkin, qemu-devel@nongnu.org, Peter Maydell,
Akihiko Odaki, Alex Bennée
On 2/12/26 00:32, Joelle van Dyne wrote:
> Yes, it does seem like v1 was picked up and not v2. v1 was broken for this
> reason.
Thanks for the confirmation. Most likely you will need to send a new
version of the patch fixing the applied one.
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-11 22:53 ` Dmitry Osipenko
@ 2026-02-12 7:01 ` Michael S. Tsirkin
2026-02-12 11:00 ` Dmitry Osipenko
0 siblings, 1 reply; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-12 7:01 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Joelle van Dyne, qemu-devel@nongnu.org, Peter Maydell,
Akihiko Odaki, Alex Bennée
On Thu, Feb 12, 2026 at 01:53:09AM +0300, Dmitry Osipenko wrote:
> On 2/12/26 00:32, Joelle van Dyne wrote:
> > Yes, it does seem like v1 was picked up and not v2. v1 was broken for this
> > reason.
>
> Thanks for the confirmation. Most likely you will need to send a new
> version of the patch fixing the applied one.
>
> --
> Best regards,
> Dmitry
applied one was v3 according to my records
but if it crashes pls do send a fixup.
Thanks!
--
MST
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-12 7:01 ` Michael S. Tsirkin
@ 2026-02-12 11:00 ` Dmitry Osipenko
2026-02-12 23:57 ` Joelle van Dyne
0 siblings, 1 reply; 77+ messages in thread
From: Dmitry Osipenko @ 2026-02-12 11:00 UTC (permalink / raw)
To: Michael S. Tsirkin, Joelle van Dyne
Cc: qemu-devel@nongnu.org, Peter Maydell, Akihiko Odaki,
Alex Bennée
On 2/12/26 10:01, Michael S. Tsirkin wrote:
> On Thu, Feb 12, 2026 at 01:53:09AM +0300, Dmitry Osipenko wrote:
>> On 2/12/26 00:32, Joelle van Dyne wrote:
>>> Yes, it does seem like v1 was picked up and not v2. v1 was broken for this
>>> reason.
>>
>> Thanks for the confirmation. Most likely you will need to send a new
>> version of the patch fixing the applied one.
>>
>> --
>> Best regards,
>> Dmitry
>
> applied one was v3 according to my records
> but if it crashes pls do send a fixup.
Alright, I previosly missed v3 and see that it's identical to v1, which
has the crash problem.
Joelle, are you aware of this problem with the version that got applied
to the qemu/staging tree? If yes, could you please send patch fixing it?
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-12 11:00 ` Dmitry Osipenko
@ 2026-02-12 23:57 ` Joelle van Dyne
2026-02-13 0:01 ` Michael S. Tsirkin
` (2 more replies)
0 siblings, 3 replies; 77+ messages in thread
From: Joelle van Dyne @ 2026-02-12 23:57 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: Michael S. Tsirkin, Joelle van Dyne, qemu-devel@nongnu.org,
Peter Maydell, Akihiko Odaki, Alex Bennée
On Thu, Feb 12, 2026 at 3:00 AM Dmitry Osipenko
<dmitry.osipenko@collabora.com> wrote:
>
> On 2/12/26 10:01, Michael S. Tsirkin wrote:
> > On Thu, Feb 12, 2026 at 01:53:09AM +0300, Dmitry Osipenko wrote:
> >> On 2/12/26 00:32, Joelle van Dyne wrote:
> >>> Yes, it does seem like v1 was picked up and not v2. v1 was broken for this
> >>> reason.
> >>
> >> Thanks for the confirmation. Most likely you will need to send a new
> >> version of the patch fixing the applied one.
> >>
> >> --
> >> Best regards,
> >> Dmitry
> >
> > applied one was v3 according to my records
> > but if it crashes pls do send a fixup.
Sorry for the confusion, I was traveling and when I originally
reviewed this thread, the stack trace + the link to v2 caused me to
claim that it looked like v1 (since it didn't have the NULL name
change) but after looking at the changes properly I see that v3 was
the patch that was picked up. There was no mistake in applying the
wrong patch.
>
> Alright, I previosly missed v3 and see that it's identical to v1, which
> has the crash problem.
v3 is not identical to v1. v1 changed the owner of the region from
itself to the parent object. This fixed the original crash but
introduced a new issue. v2 tried to fix the original crash a different
way that was brittle because it involved manually writing to a field
in the memory region struct. v3 was the proper fix which used a NULL
name which allows the parent to be unset and then we have to use unref
instead of unparent in cleanup.
>
> Joelle, are you aware of this problem with the version that got applied
> to the qemu/staging tree? If yes, could you please send patch fixing it?
Unfortunately, this means that the patch should not have been back
ported. It is possible that the crash which this patch was addressing
was introduced as a result of changes elsewhere. For example
https://lore.kernel.org/all/20250924-use-v4-0-07c6c598f53d@rsg.ci.i.u-tokyo.ac.jp/
changed some internal mechanics of finalize. I didn't raise any
objection to the back port because it seemed like the original code
where the object was its own parent was wrong but I guess it was
working fine somehow. I think in the meantime the best course of
action is to revert the patch in the stable branches.
>
>
> --
> Best regards,
> Dmitry
^ permalink raw reply [flat|nested] 77+ messages in thread* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-12 23:57 ` Joelle van Dyne
@ 2026-02-13 0:01 ` Michael S. Tsirkin
2026-02-13 13:07 ` Dmitry Osipenko
2026-02-13 13:27 ` Dmitry Osipenko
2026-02-13 13:30 ` Michael Tokarev
2 siblings, 1 reply; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-13 0:01 UTC (permalink / raw)
To: Joelle van Dyne
Cc: Dmitry Osipenko, qemu-devel@nongnu.org, Peter Maydell,
Akihiko Odaki, Alex Bennée
On Thu, Feb 12, 2026 at 03:57:04PM -0800, Joelle van Dyne wrote:
> > Joelle, are you aware of this problem with the version that got applied
> > to the qemu/staging tree? If yes, could you please send patch fixing it?
> Unfortunately, this means that the patch should not have been back
> ported. It is possible that the crash which this patch was addressing
> was introduced as a result of changes elsewhere. For example
> https://lore.kernel.org/all/20250924-use-v4-0-07c6c598f53d@rsg.ci.i.u-tokyo.ac.jp/
> changed some internal mechanics of finalize. I didn't raise any
> objection to the back port because it seemed like the original code
> where the object was its own parent was wrong but I guess it was
> working fine somehow. I think in the meantime the best course of
> action is to revert the patch in the stable branches.
wait a sec the crash is on stable? not master?
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-13 0:01 ` Michael S. Tsirkin
@ 2026-02-13 13:07 ` Dmitry Osipenko
0 siblings, 0 replies; 77+ messages in thread
From: Dmitry Osipenko @ 2026-02-13 13:07 UTC (permalink / raw)
To: Michael S. Tsirkin, Joelle van Dyne
Cc: qemu-devel@nongnu.org, Peter Maydell, Akihiko Odaki,
Alex Bennée
On 2/13/26 03:01, Michael S. Tsirkin wrote:
> On Thu, Feb 12, 2026 at 03:57:04PM -0800, Joelle van Dyne wrote:
>>> Joelle, are you aware of this problem with the version that got applied
>>> to the qemu/staging tree? If yes, could you please send patch fixing it?
>> Unfortunately, this means that the patch should not have been back
>> ported. It is possible that the crash which this patch was addressing
>> was introduced as a result of changes elsewhere. For example
>> https://lore.kernel.org/all/20250924-use-v4-0-07c6c598f53d@rsg.ci.i.u-tokyo.ac.jp/
>> changed some internal mechanics of finalize. I didn't raise any
>> objection to the back port because it seemed like the original code
>> where the object was its own parent was wrong but I guess it was
>> working fine somehow. I think in the meantime the best course of
>> action is to revert the patch in the stable branches.
>
> wait a sec the crash is on stable? not master?
Joelle, please clarify which QEMU version has the problem you're fixing
and how to reproduce it.
I only tested latest staging branch so far. There was a report in the
past about potentially wrong mem region refcounting, but it was reported
for a very unstable WIP code and I couldn't reproduce the problem. We
can always revert patch and try again later if you're short on time.
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-12 23:57 ` Joelle van Dyne
2026-02-13 0:01 ` Michael S. Tsirkin
@ 2026-02-13 13:27 ` Dmitry Osipenko
2026-02-13 13:30 ` Michael Tokarev
2 siblings, 0 replies; 77+ messages in thread
From: Dmitry Osipenko @ 2026-02-13 13:27 UTC (permalink / raw)
To: Joelle van Dyne
Cc: Michael S. Tsirkin, qemu-devel@nongnu.org, Peter Maydell,
Akihiko Odaki, Alex Bennée
On 2/13/26 02:57, Joelle van Dyne wrote:
>>> applied one was v3 according to my records
>>> but if it crashes pls do send a fixup.
> Sorry for the confusion, I was traveling and when I originally
> reviewed this thread, the stack trace + the link to v2 caused me to
> claim that it looked like v1 (since it didn't have the NULL name
> change) but after looking at the changes properly I see that v3 was
> the patch that was picked up. There was no mistake in applying the
> wrong patch.
Indeed!
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-12 23:57 ` Joelle van Dyne
2026-02-13 0:01 ` Michael S. Tsirkin
2026-02-13 13:27 ` Dmitry Osipenko
@ 2026-02-13 13:30 ` Michael Tokarev
2026-02-13 14:04 ` Dmitry Osipenko
2 siblings, 1 reply; 77+ messages in thread
From: Michael Tokarev @ 2026-02-13 13:30 UTC (permalink / raw)
To: Joelle van Dyne, Dmitry Osipenko
Cc: Michael S. Tsirkin, qemu-devel@nongnu.org, Peter Maydell,
Akihiko Odaki, Alex Bennée
13.02.2026 02:57, Joelle van Dyne wrpte:
> On Thu, Feb 12, 2026 at 3:00 AM Dmitry Osipenko
> <dmitry.osipenko@collabora.com> wrote:...>> Joelle, are you aware of this problem with the version that got applied
>> to the qemu/staging tree? If yes, could you please send patch fixing it?
> Unfortunately, this means that the patch should not have been back
> ported. It is possible that the crash which this patch was addressing
> was introduced as a result of changes elsewhere. For example
> https://lore.kernel.org/all/20250924-use-v4-0-07c6c598f53d@rsg.ci.i.u-tokyo.ac.jp/
> changed some internal mechanics of finalize. I didn't raise any
> objection to the back port because it seemed like the original code
> where the object was its own parent was wrong but I guess it was
> working fine somehow. I think in the meantime the best course of
> action is to revert the patch in the stable branches.
Ok, it was me who thought it's a good idea to apply it to stable branches.
Sure thing, if it's wrong, I should revert it.
Do I understand it correctly that in current master, this change is okay,
due to other changes (maybe like the above-mentioned one), but in previous
stable versions, it is not?
Should I make another stable release to fix this one? I mean, how serious
it is?
I'm sorry for the trouble.
Thanks,
/mjt
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-13 13:30 ` Michael Tokarev
@ 2026-02-13 14:04 ` Dmitry Osipenko
2026-02-13 14:16 ` Dmitry Osipenko
0 siblings, 1 reply; 77+ messages in thread
From: Dmitry Osipenko @ 2026-02-13 14:04 UTC (permalink / raw)
To: Michael Tokarev, Joelle van Dyne
Cc: Michael S. Tsirkin, qemu-devel@nongnu.org, Peter Maydell,
Akihiko Odaki, Alex Bennée
On 2/13/26 16:30, Michael Tokarev wrote:
> 13.02.2026 02:57, Joelle van Dyne wrpte:
>> On Thu, Feb 12, 2026 at 3:00 AM Dmitry Osipenko
>> <dmitry.osipenko@collabora.com> wrote:...>> Joelle, are you aware of
>> this problem with the version that got applied
>>> to the qemu/staging tree? If yes, could you please send patch fixing it?
>
>> Unfortunately, this means that the patch should not have been back
>> ported. It is possible that the crash which this patch was addressing
>> was introduced as a result of changes elsewhere. For example
>> https://lore.kernel.org/all/20250924-use-v4-0-07c6c598f53d@rsg.ci.i.u-
>> tokyo.ac.jp/
>> changed some internal mechanics of finalize. I didn't raise any
>> objection to the back port because it seemed like the original code
>> where the object was its own parent was wrong but I guess it was
>> working fine somehow. I think in the meantime the best course of
>> action is to revert the patch in the stable branches.
>
> Ok, it was me who thought it's a good idea to apply it to stable branches.
> Sure thing, if it's wrong, I should revert it.
>
> Do I understand it correctly that in current master, this change is okay,
> due to other changes (maybe like the above-mentioned one), but in previous
> stable versions, it is not?
>
> Should I make another stable release to fix this one? I mean, how serious
> it is?
>
> I'm sorry for the trouble.
I tested master and stable 10.1.4 in addition to the staging branch, all
three are broken by this patch. Hence the patch is wrong in the first
place and not fixing anything.
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-13 14:04 ` Dmitry Osipenko
@ 2026-02-13 14:16 ` Dmitry Osipenko
0 siblings, 0 replies; 77+ messages in thread
From: Dmitry Osipenko @ 2026-02-13 14:16 UTC (permalink / raw)
To: Michael Tokarev, Joelle van Dyne
Cc: Michael S. Tsirkin, qemu-devel@nongnu.org, Peter Maydell,
Akihiko Odaki, Alex Bennée
On 2/13/26 17:04, Dmitry Osipenko wrote:
> On 2/13/26 16:30, Michael Tokarev wrote:
>> 13.02.2026 02:57, Joelle van Dyne wrpte:
>>> On Thu, Feb 12, 2026 at 3:00 AM Dmitry Osipenko
>>> <dmitry.osipenko@collabora.com> wrote:...>> Joelle, are you aware of
>>> this problem with the version that got applied
>>>> to the qemu/staging tree? If yes, could you please send patch fixing it?
>>
>>> Unfortunately, this means that the patch should not have been back
>>> ported. It is possible that the crash which this patch was addressing
>>> was introduced as a result of changes elsewhere. For example
>>> https://lore.kernel.org/all/20250924-use-v4-0-07c6c598f53d@rsg.ci.i.u-
>>> tokyo.ac.jp/
>>> changed some internal mechanics of finalize. I didn't raise any
>>> objection to the back port because it seemed like the original code
>>> where the object was its own parent was wrong but I guess it was
>>> working fine somehow. I think in the meantime the best course of
>>> action is to revert the patch in the stable branches.
>>
>> Ok, it was me who thought it's a good idea to apply it to stable branches.
>> Sure thing, if it's wrong, I should revert it.
>>
>> Do I understand it correctly that in current master, this change is okay,
>> due to other changes (maybe like the above-mentioned one), but in previous
>> stable versions, it is not?
>>
>> Should I make another stable release to fix this one? I mean, how serious
>> it is?
>>
>> I'm sorry for the trouble.
>
> I tested master and stable 10.1.4 in addition to the staging branch, all
> three are broken by this patch. Hence the patch is wrong in the first
> place and not fixing anything.
Once again, Joelle needs to explain how to reproduce the addressed
problem as virgl and venus are known to work properly. I suggest to
revert the patch from all branches and try again with another version
later after clarifications from Joelle.
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-11 20:46 ` Dmitry Osipenko
2026-02-11 21:32 ` Joelle van Dyne
@ 2026-02-12 6:29 ` Michael S. Tsirkin
1 sibling, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-12 6:29 UTC (permalink / raw)
To: Dmitry Osipenko
Cc: qemu-devel, Peter Maydell, Joelle van Dyne, Akihiko Odaki,
Alex Bennée
On Wed, Feb 11, 2026 at 11:46:51PM +0300, Dmitry Osipenko wrote:
> On 2/4/26 22:04, Michael S. Tsirkin wrote:
> > From: Joelle van Dyne <j@getutm.app>
> >
> > When `owner` == `mr`, `object_unparent` will crash:
> >
> > object_unparent(mr) ->
> > object_property_del_child(mr, mr) ->
> > object_finalize_child_property(mr, name, mr) ->
> > object_unref(mr) ->
> > object_finalize(mr) ->
> > object_property_del_all(mr) ->
> > object_finalize_child_property(mr, name, mr) ->
> > object_unref(mr) ->
> > fail on g_assert(obj->ref > 0)
> >
> > However, passing a different `owner` to `memory_region_init` does not
> > work. `memory_region_ref` has an optimization where it takes a ref
> > only on the owner. That means when flatviews are created, it does not
> > take a ref on the region and you can get a UAF from `flatview_destroy`
> > called from RCU.
> >
> > The correct fix therefore is to use `NULL` as the name which will set
> > the `owner` but not the `parent` (which is still NULL). This allows us
> > to use `memory_region_ref` on itself while not having to rely on unparent
> > for cleanup.
> >
> > Signed-off-by: Joelle van Dyne <j@getutm.app>
> > Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> > Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > Message-Id: <20260103214400.71694-1-j@getutm.app>
> > ---
> > hw/display/virtio-gpu-virgl.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> > index 07f6355ad6..6a83fb63c8 100644
> > --- a/hw/display/virtio-gpu-virgl.c
> > +++ b/hw/display/virtio-gpu-virgl.c
> > @@ -120,7 +120,7 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
> > vmr->g = g;
> >
> > mr = &vmr->mr;
> > - memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data);
> > + memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data);
> > memory_region_add_subregion(&b->hostmem, offset, mr);
> > memory_region_set_enabled(mr, true);
> >
> > @@ -186,7 +186,7 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g,
> > /* memory region owns self res->mr object and frees it by itself */
> > memory_region_set_enabled(mr, false);
> > memory_region_del_subregion(&b->hostmem, mr);
> > - object_unparent(OBJECT(mr));
> > + object_unref(OBJECT(mr));
> > }
> >
> > return 0;
>
> Hello Michael,
>
> This patch introduces regression. Running any venus application results
> in a crash:
>
> Thread 2 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
> (gdb) bt
> #0 0x00007ffff56565e2 in __strcmp_evex () at /lib64/libc.so.6
> #1 0x0000555555841bdb in find_fd (head=0x5555572337d0 <cpr_state>,
> name=0x0, id=0) at ../migration/cpr.c:68
> #2 cpr_delete_fd (name=name@entry=0x0, id=id@entry=0) at
> ../migration/cpr.c:77
> #3 0x000055555582290a in qemu_ram_free (block=0x7ff7e93aa7f0) at
> ../system/physmem.c:2615
> #4 0x000055555581ae02 in memory_region_finalize (obj=<optimized out>)
> at ../system/memory.c:1816
> #5 0x0000555555a70ab9 in object_deinit (obj=<optimized out>,
> type=<optimized out>) at ../qom/object.c:715
> #6 object_finalize (data=0x7ff7e936eff0) at ../qom/object.c:729
> #7 object_unref (objptr=0x7ff7e936eff0) at ../qom/object.c:1232
> #8 0x0000555555814fae in memory_region_unref (mr=<optimized out>) at
> ../system/memory.c:1848
> #9 flatview_destroy (view=0x555559ed6c40) at ../system/memory.c:301
> #10 0x0000555555bfc122 in call_rcu_thread (opaque=<optimized out>) at
> ../util/rcu.c:324
> #11 0x0000555555bf17a7 in qemu_thread_start (args=0x555557b99520) at
> ../util/qemu-thread-posix.c:393
> #12 0x00007ffff556f464 in start_thread () at /lib64/libc.so.6
> #13 0x00007ffff55f25ac in __clone3 () at /lib64/libc.so.6
>
> There is a v2 version of this patch that doesn't crash [1]. Was v1
> applied by mistake instead of v2?
>
> [1] https://lore.kernel.org/qemu-devel/20251223184023.1913-1-j@getutm.app/
>
> --
> Best regards,
> Dmitry
According to my records, what was applied is v3:
https://lore.kernel.org/qemu-devel/20260103214400.71694-1-j@getutm.app/
--
MST
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-04 19:04 ` [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region Michael S. Tsirkin
2026-02-11 20:46 ` Dmitry Osipenko
@ 2026-02-13 14:29 ` Peter Maydell
2026-02-13 16:18 ` Alex Bennée
1 sibling, 1 reply; 77+ messages in thread
From: Peter Maydell @ 2026-02-13 14:29 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: qemu-devel, Joelle van Dyne, Akihiko Odaki, Alex Bennée,
Dmitry Osipenko
On Wed, 4 Feb 2026 at 19:04, Michael S. Tsirkin <mst@redhat.com> wrote:
>
> From: Joelle van Dyne <j@getutm.app>
>
> When `owner` == `mr`, `object_unparent` will crash:
>
> object_unparent(mr) ->
> object_property_del_child(mr, mr) ->
> object_finalize_child_property(mr, name, mr) ->
> object_unref(mr) ->
> object_finalize(mr) ->
> object_property_del_all(mr) ->
> object_finalize_child_property(mr, name, mr) ->
> object_unref(mr) ->
> fail on g_assert(obj->ref > 0)
>
> However, passing a different `owner` to `memory_region_init` does not
> work. `memory_region_ref` has an optimization where it takes a ref
> only on the owner. That means when flatviews are created, it does not
> take a ref on the region and you can get a UAF from `flatview_destroy`
> called from RCU.
>
> The correct fix therefore is to use `NULL` as the name which will set
> the `owner` but not the `parent` (which is still NULL). This allows us
> to use `memory_region_ref` on itself while not having to rely on unparent
> for cleanup.
>
> Signed-off-by: Joelle van Dyne <j@getutm.app>
> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> Message-Id: <20260103214400.71694-1-j@getutm.app>
> ---
> hw/display/virtio-gpu-virgl.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> index 07f6355ad6..6a83fb63c8 100644
> --- a/hw/display/virtio-gpu-virgl.c
> +++ b/hw/display/virtio-gpu-virgl.c
> @@ -120,7 +120,7 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
> vmr->g = g;
>
> mr = &vmr->mr;
> - memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data);
> + memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data);
This looks very odd. The owner of an MR should be the
device that that MR belongs to, not the MR itself,
and usually not NULL either. The name should be something
useful for people looking at the HMP info output about
memory layouts.
If there's a use-after-free issue then I suspect that the right
fix must be somewhere else, not here.
thanks
-- PMM
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-13 14:29 ` Peter Maydell
@ 2026-02-13 16:18 ` Alex Bennée
2026-02-13 19:48 ` Joelle van Dyne
0 siblings, 1 reply; 77+ messages in thread
From: Alex Bennée @ 2026-02-13 16:18 UTC (permalink / raw)
To: Peter Maydell
Cc: Michael S. Tsirkin, qemu-devel, Joelle van Dyne, Akihiko Odaki,
Dmitry Osipenko
Peter Maydell <peter.maydell@linaro.org> writes:
> On Wed, 4 Feb 2026 at 19:04, Michael S. Tsirkin <mst@redhat.com> wrote:
>>
>> From: Joelle van Dyne <j@getutm.app>
>>
>> When `owner` == `mr`, `object_unparent` will crash:
>>
>> object_unparent(mr) ->
>> object_property_del_child(mr, mr) ->
>> object_finalize_child_property(mr, name, mr) ->
>> object_unref(mr) ->
>> object_finalize(mr) ->
>> object_property_del_all(mr) ->
>> object_finalize_child_property(mr, name, mr) ->
>> object_unref(mr) ->
>> fail on g_assert(obj->ref > 0)
>>
>> However, passing a different `owner` to `memory_region_init` does not
>> work. `memory_region_ref` has an optimization where it takes a ref
>> only on the owner. That means when flatviews are created, it does not
>> take a ref on the region and you can get a UAF from `flatview_destroy`
>> called from RCU.
>>
>> The correct fix therefore is to use `NULL` as the name which will set
>> the `owner` but not the `parent` (which is still NULL). This allows us
>> to use `memory_region_ref` on itself while not having to rely on unparent
>> for cleanup.
>>
>> Signed-off-by: Joelle van Dyne <j@getutm.app>
>> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
>> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>> Message-Id: <20260103214400.71694-1-j@getutm.app>
>> ---
>> hw/display/virtio-gpu-virgl.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
>> index 07f6355ad6..6a83fb63c8 100644
>> --- a/hw/display/virtio-gpu-virgl.c
>> +++ b/hw/display/virtio-gpu-virgl.c
>> @@ -120,7 +120,7 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
>> vmr->g = g;
>>
>> mr = &vmr->mr;
>> - memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data);
>> + memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data);
>
> This looks very odd. The owner of an MR should be the
> device that that MR belongs to, not the MR itself,
> and usually not NULL either. The name should be something
> useful for people looking at the HMP info output about
> memory layouts.
>
> If there's a use-after-free issue then I suspect that the right
> fix must be somewhere else, not here.
The blobs really cause issues for our MemoryRegion code because they are
transient and aren't easily cleaned up with RCU because of the dance we
have to do between qemu and virglrenderer for the underlying memory.
There have been multiple attempts to clean this up and so far I don't
think we've managed to reach a solid solution.
>
> thanks
> -- PMM
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-13 16:18 ` Alex Bennée
@ 2026-02-13 19:48 ` Joelle van Dyne
2026-02-16 15:31 ` Dmitry Osipenko
0 siblings, 1 reply; 77+ messages in thread
From: Joelle van Dyne @ 2026-02-13 19:48 UTC (permalink / raw)
To: Alex Bennée
Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Joelle van Dyne,
Akihiko Odaki, Dmitry Osipenko
On Fri, Feb 13, 2026 at 8:18 AM Alex Bennée <alex.bennee@linaro.org> wrote:
>
> Peter Maydell <peter.maydell@linaro.org> writes:
>
> > On Wed, 4 Feb 2026 at 19:04, Michael S. Tsirkin <mst@redhat.com> wrote:
> >>
> >> From: Joelle van Dyne <j@getutm.app>
> >>
> >> When `owner` == `mr`, `object_unparent` will crash:
> >>
> >> object_unparent(mr) ->
> >> object_property_del_child(mr, mr) ->
> >> object_finalize_child_property(mr, name, mr) ->
> >> object_unref(mr) ->
> >> object_finalize(mr) ->
> >> object_property_del_all(mr) ->
> >> object_finalize_child_property(mr, name, mr) ->
> >> object_unref(mr) ->
> >> fail on g_assert(obj->ref > 0)
> >>
> >> However, passing a different `owner` to `memory_region_init` does not
> >> work. `memory_region_ref` has an optimization where it takes a ref
> >> only on the owner. That means when flatviews are created, it does not
> >> take a ref on the region and you can get a UAF from `flatview_destroy`
> >> called from RCU.
> >>
> >> The correct fix therefore is to use `NULL` as the name which will set
> >> the `owner` but not the `parent` (which is still NULL). This allows us
> >> to use `memory_region_ref` on itself while not having to rely on unparent
> >> for cleanup.
> >>
> >> Signed-off-by: Joelle van Dyne <j@getutm.app>
> >> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> >> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> >> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> >> Message-Id: <20260103214400.71694-1-j@getutm.app>
> >> ---
> >> hw/display/virtio-gpu-virgl.c | 4 ++--
> >> 1 file changed, 2 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> >> index 07f6355ad6..6a83fb63c8 100644
> >> --- a/hw/display/virtio-gpu-virgl.c
> >> +++ b/hw/display/virtio-gpu-virgl.c
> >> @@ -120,7 +120,7 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
> >> vmr->g = g;
> >>
> >> mr = &vmr->mr;
> >> - memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data);
> >> + memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data);
> >
> > This looks very odd. The owner of an MR should be the
> > device that that MR belongs to, not the MR itself,
> > and usually not NULL either. The name should be something
> > useful for people looking at the HMP info output about
> > memory layouts.
The owner of the MR was set to itself before the change and this
caused a crash on my ARM64 host (I'm not sure why this wasn't a issue
beforehand on other architectures, I suspect it was a race condition
that was always won before). The original fix (see v2) was to call
memory_region_init_ram_ptr() with "owner" set to VirtIOGPU *g and then
manually setting "mr->owner = OBJECT(mr)" after the call, thus
breaking the self <-> parent loop that caused the original crash.
However, this was brittle as we were modifiying MR internals outside
of MR APIs so the suggestion was made to use NULL for "name" and
"object_unref" instead of "object_unparent" in cleanup. This MR was
properly an orphan and does not have a parent. We depended on the
behavior of "memory_region_do_init" to not call
"object_property_add_child" when "name" is NULL. The APIs were not
clear if "name" is allowed to be NULL but the existance of that code
path led to the assumption that NULL was permitted as an argument.
Obivously this assumption was flawed as the crash log that Dmitry
shared showed that cpr_name() in physmem.c will return NULL and this
causes the NULL name to be passed to cpr_delete_fd(). There might be
other places that expect the name to be non-NULL as well.
> >
> > If there's a use-after-free issue then I suspect that the right
> > fix must be somewhere else, not here.
The obivous fix is to revert the change but the original crash
referenced in the patch will still be an issue. Alternatively, it
seems that the v2 version is unclean but can still work because we
just need the MR to not have itself as the parent. This would be the
minimal patch that addresses both issues. (A proper fix should also
remove the code path in memory_region_do_init() for when name is NULL
and instead return an error because that path is invalid.) Another
alternative would be to modify the MR APIs with a clear way to create
an orphan MR. Finally, object_unparent() could recognize when the
object is its own parent and handle that case gracefully. Let me know
what people's preferred solution is and I'll whip up a patch.
>
> The blobs really cause issues for our MemoryRegion code because they are
> transient and aren't easily cleaned up with RCU because of the dance we
> have to do between qemu and virglrenderer for the underlying memory.
> There have been multiple attempts to clean this up and so far I don't
> think we've managed to reach a solid solution.
>
> >
> > thanks
> > -- PMM
>
> --
> Alex Bennée
> Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region
2026-02-13 19:48 ` Joelle van Dyne
@ 2026-02-16 15:31 ` Dmitry Osipenko
0 siblings, 0 replies; 77+ messages in thread
From: Dmitry Osipenko @ 2026-02-16 15:31 UTC (permalink / raw)
To: Joelle van Dyne, Alex Bennée
Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Akihiko Odaki
On 2/13/26 22:48, Joelle van Dyne wrote:
> On Fri, Feb 13, 2026 at 8:18 AM Alex Bennée <alex.bennee@linaro.org> wrote:
>>
>> Peter Maydell <peter.maydell@linaro.org> writes:
>>
>>> On Wed, 4 Feb 2026 at 19:04, Michael S. Tsirkin <mst@redhat.com> wrote:
>>>>
>>>> From: Joelle van Dyne <j@getutm.app>
>>>>
>>>> When `owner` == `mr`, `object_unparent` will crash:
>>>>
>>>> object_unparent(mr) ->
>>>> object_property_del_child(mr, mr) ->
>>>> object_finalize_child_property(mr, name, mr) ->
>>>> object_unref(mr) ->
>>>> object_finalize(mr) ->
>>>> object_property_del_all(mr) ->
>>>> object_finalize_child_property(mr, name, mr) ->
>>>> object_unref(mr) ->
>>>> fail on g_assert(obj->ref > 0)
>>>>
>>>> However, passing a different `owner` to `memory_region_init` does not
>>>> work. `memory_region_ref` has an optimization where it takes a ref
>>>> only on the owner. That means when flatviews are created, it does not
>>>> take a ref on the region and you can get a UAF from `flatview_destroy`
>>>> called from RCU.
>>>>
>>>> The correct fix therefore is to use `NULL` as the name which will set
>>>> the `owner` but not the `parent` (which is still NULL). This allows us
>>>> to use `memory_region_ref` on itself while not having to rely on unparent
>>>> for cleanup.
>>>>
>>>> Signed-off-by: Joelle van Dyne <j@getutm.app>
>>>> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
>>>> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
>>>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>>>> Message-Id: <20260103214400.71694-1-j@getutm.app>
>>>> ---
>>>> hw/display/virtio-gpu-virgl.c | 4 ++--
>>>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
>>>> index 07f6355ad6..6a83fb63c8 100644
>>>> --- a/hw/display/virtio-gpu-virgl.c
>>>> +++ b/hw/display/virtio-gpu-virgl.c
>>>> @@ -120,7 +120,7 @@ virtio_gpu_virgl_map_resource_blob(VirtIOGPU *g,
>>>> vmr->g = g;
>>>>
>>>> mr = &vmr->mr;
>>>> - memory_region_init_ram_ptr(mr, OBJECT(mr), "blob", size, data);
>>>> + memory_region_init_ram_ptr(mr, OBJECT(mr), NULL, size, data);
>>>
>>> This looks very odd. The owner of an MR should be the
>>> device that that MR belongs to, not the MR itself,
>>> and usually not NULL either. The name should be something
>>> useful for people looking at the HMP info output about
>>> memory layouts.
> The owner of the MR was set to itself before the change and this
> caused a crash on my ARM64 host (I'm not sure why this wasn't a issue
> beforehand on other architectures, I suspect it was a race condition
> that was always won before). The original fix (see v2) was to call
> memory_region_init_ram_ptr() with "owner" set to VirtIOGPU *g and then
> manually setting "mr->owner = OBJECT(mr)" after the call, thus
> breaking the self <-> parent loop that caused the original crash.
> However, this was brittle as we were modifiying MR internals outside
> of MR APIs so the suggestion was made to use NULL for "name" and
> "object_unref" instead of "object_unparent" in cleanup. This MR was
> properly an orphan and does not have a parent. We depended on the
> behavior of "memory_region_do_init" to not call
> "object_property_add_child" when "name" is NULL. The APIs were not
> clear if "name" is allowed to be NULL but the existance of that code
> path led to the assumption that NULL was permitted as an argument.
> Obivously this assumption was flawed as the crash log that Dmitry
> shared showed that cpr_name() in physmem.c will return NULL and this
> causes the NULL name to be passed to cpr_delete_fd(). There might be
> other places that expect the name to be non-NULL as well.
>
>>>
>>> If there's a use-after-free issue then I suspect that the right
>>> fix must be somewhere else, not here.
> The obivous fix is to revert the change but the original crash
> referenced in the patch will still be an issue. Alternatively, it
> seems that the v2 version is unclean but can still work because we
> just need the MR to not have itself as the parent. This would be the
> minimal patch that addresses both issues. (A proper fix should also
> remove the code path in memory_region_do_init() for when name is NULL
> and instead return an error because that path is invalid.) Another
> alternative would be to modify the MR APIs with a clear way to create
> an orphan MR. Finally, object_unparent() could recognize when the
> object is its own parent and handle that case gracefully. Let me know
> what people's preferred solution is and I'll whip up a patch.
>
>>
>> The blobs really cause issues for our MemoryRegion code because they are
>> transient and aren't easily cleaned up with RCU because of the dance we
>> have to do between qemu and virglrenderer for the underlying memory.
>> There have been multiple attempts to clean this up and so far I don't
>> think we've managed to reach a solid solution.
Thanks for the clarification. Curious which gfx mode showed this
problem, virgl or venus? What's the GPU card/model on host?
--
Best regards,
Dmitry
^ permalink raw reply [flat|nested] 77+ messages in thread
* [PULL 42/51] virtio-pmem: ignore empty queue notifications
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (40 preceding siblings ...)
2026-02-04 19:04 ` [PULL 41/51] virtio-gpu-virgl: correct parent for blob memory region Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 43/51] virtio-gpu: fix error handling in virgl_cmd_resource_create_blob Michael S. Tsirkin
` (11 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Li Chen, Li Chen
From: Li Chen <chenl311@chinatelecom.cn>
virtio_pmem_flush() treats a NULL return from virtqueue_pop() as a fatal
error and calls virtio_error(), which puts the device into NEEDS_RESET.
However, virtqueue handlers can be invoked when no element is available,
so an empty queue should be handled as a benign no-op.
With a Linux guest this avoids spurious NEEDS_RESET and the resulting
-EIO propagation (e.g. EXT4 journal abort and remount-ro).
Signed-off-by: Li Chen <me@linux.beauty>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260106083859.380338-1-me@linux.beauty>
---
hw/virtio/virtio-pmem.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c
index 5381d59282..c3b3299c9c 100644
--- a/hw/virtio/virtio-pmem.c
+++ b/hw/virtio/virtio-pmem.c
@@ -73,7 +73,6 @@ static void virtio_pmem_flush(VirtIODevice *vdev, VirtQueue *vq)
trace_virtio_pmem_flush_request();
req_data = virtqueue_pop(vq, sizeof(VirtIODeviceRequest));
if (!req_data) {
- virtio_error(vdev, "virtio-pmem missing request data");
return;
}
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 43/51] virtio-gpu: fix error handling in virgl_cmd_resource_create_blob
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (41 preceding siblings ...)
2026-02-04 19:04 ` [PULL 42/51] virtio-pmem: ignore empty queue notifications Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 44/51] virtio-gpu: use consistent error checking for virtio_gpu_create_mapping_iov Michael S. Tsirkin
` (10 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Honglei Huang, Akihiko Odaki, Dmitry Osipenko,
Philippe Mathieu-Daudé, Alex Bennée
From: Honglei Huang <honghuan@amd.com>
Fix inverted error check in virgl_cmd_resource_create_blob() that causes
the function to return error when virtio_gpu_create_mapping_iov() succeeds.
virtio_gpu_create_mapping_iov() returns 0 on success and negative values
on error. The check 'if (!ret)' incorrectly treats success (ret=0) as an
error condition, causing the function to fail when it should succeed.
Change the condition to 'if (ret != 0)' to properly detect errors.
Fixes: 7c092f17ccee ("virtio-gpu: Handle resource blob commands")
Signed-off-by: Honglei Huang <honghuan@amd.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260113015203.3643608-2-honghuan@amd.com>
---
hw/display/virtio-gpu-virgl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 6a83fb63c8..741728cabb 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -705,7 +705,7 @@ static void virgl_cmd_resource_create_blob(VirtIOGPU *g,
ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
cmd, &res->base.addrs,
&res->base.iov, &res->base.iov_cnt);
- if (!ret) {
+ if (ret != 0) {
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
return;
}
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 44/51] virtio-gpu: use consistent error checking for virtio_gpu_create_mapping_iov
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (42 preceding siblings ...)
2026-02-04 19:04 ` [PULL 43/51] virtio-gpu: fix error handling in virgl_cmd_resource_create_blob Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 45/51] vhost-user.rst: specify vhost-user back-end action on GET_VRING_BASE Michael S. Tsirkin
` (9 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Honglei Huang, Markus Armbruster, Akihiko Odaki,
Dmitry Osipenko, Philippe Mathieu-Daudé, Alex Bennée
From: Honglei Huang <honghuan@amd.com>
Unify error checking style for virtio_gpu_create_mapping_iov() across the
codebase to improve consistency and readability.
virtio_gpu_create_mapping_iov() returns 0 on success and negative values
on error. The original code used inconsistent patterns for checking errors:
- Some used 'if (ret != 0)' in virtio-gpu-virgl.c and virtio-gpu.c
- Some used 'CHECK(!ret, cmd)' in virtio-gpu-rutabaga.c
For if-statement checks, change to 'if (ret < 0)' which is the preferred
QEMU coding convention for functions that return 0 on success and negative
on error. This makes the return value convention immediately clear to code
readers.
For CHECK macro usage in virtio-gpu-rutabaga.c, keep the original
'CHECK(!ret, cmd)' pattern as it is more concise and consistent with other
error checks in the same file.
Updated locations:
- hw/display/virtio-gpu-virgl.c: virgl_resource_attach_backing()
- hw/display/virtio-gpu-virgl.c: virgl_cmd_resource_create_blob()
- hw/display/virtio-gpu.c: virtio_gpu_resource_create_blob()
- hw/display/virtio-gpu.c: virtio_gpu_resource_attach_backing()
Signed-off-by: Honglei Huang <honghuan@amd.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260113015203.3643608-3-honghuan@amd.com>
---
hw/display/virtio-gpu-virgl.c | 4 ++--
hw/display/virtio-gpu.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 741728cabb..ecf8494f36 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -561,7 +561,7 @@ static void virgl_resource_attach_backing(VirtIOGPU *g,
ret = virtio_gpu_create_mapping_iov(g, att_rb.nr_entries, sizeof(att_rb),
cmd, NULL, &res_iovs, &res_niov);
- if (ret != 0) {
+ if (ret < 0) {
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
return;
}
@@ -705,7 +705,7 @@ static void virgl_cmd_resource_create_blob(VirtIOGPU *g,
ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
cmd, &res->base.addrs,
&res->base.iov, &res->base.iov_cnt);
- if (ret != 0) {
+ if (ret < 0) {
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
return;
}
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f23eec6862..643e91ca2a 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -354,7 +354,7 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
cmd, &res->addrs, &res->iov,
&res->iov_cnt);
- if (ret != 0) {
+ if (ret < 0) {
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
g_free(res);
return;
@@ -933,7 +933,7 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
ret = virtio_gpu_create_mapping_iov(g, ab.nr_entries, sizeof(ab), cmd,
&res->addrs, &res->iov, &res->iov_cnt);
- if (ret != 0) {
+ if (ret < 0) {
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
return;
}
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 45/51] vhost-user.rst: specify vhost-user back-end action on GET_VRING_BASE
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (43 preceding siblings ...)
2026-02-04 19:04 ` [PULL 44/51] virtio-gpu: use consistent error checking for virtio_gpu_create_mapping_iov Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 46/51] vhost-user: introduce protocol feature for skip drain " Michael S. Tsirkin
` (8 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Alexandr Moshkov, Stefan Hajnoczi,
Stefano Garzarella, Pierrick Bouvier
From: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
By default, we assume that server need to wait all inflight IO on
GET_VRING_BASE. However, this fact is not recorded anywhere in the
documentation.
So, add this info in rst.
Signed-off-by: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260115081103.655749-2-dtalexundeer@yandex-team.ru>
---
docs/interop/vhost-user.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
index 93f756d3f4..505f8d3a33 100644
--- a/docs/interop/vhost-user.rst
+++ b/docs/interop/vhost-user.rst
@@ -1250,7 +1250,8 @@ Front-end message types
When and as long as all of a device's vrings are stopped, it is
*suspended*, see :ref:`Suspended device state
- <suspended_device_state>`.
+ <suspended_device_state>`. The back-end must complete all inflight I/O
+ requests for the specified vring before stopping it.
The request payload's *num* field is currently reserved and must be
set to 0.
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 46/51] vhost-user: introduce protocol feature for skip drain on GET_VRING_BASE
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (44 preceding siblings ...)
2026-02-04 19:04 ` [PULL 45/51] vhost-user.rst: specify vhost-user back-end action on GET_VRING_BASE Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 47/51] vmstate: introduce VMSTATE_VBUFFER_UINT64 Michael S. Tsirkin
` (7 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Alexandr Moshkov, Stefan Hajnoczi,
Stefano Garzarella, Pierrick Bouvier
From: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
Add vhost-user protocol feature
VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT
Now on GET_VRING_BASE this feature can control whether to wait for
in-flight requests to complete or not.
Also we have to validate that this feature will be enabled only when
qemu and back-end supports in-flight buffer and in-flight migration
It will be helpfull in future for in-flight requests migration in
vhost-user devices.
Update docs, add ref to label for inflight-io-tracking
Signed-off-by: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260115081103.655749-3-dtalexundeer@yandex-team.ru>
---
docs/interop/vhost-user.rst | 59 +++++++++++++++++++++-------------
hw/virtio/vhost-user.c | 7 ++++
include/hw/virtio/vhost-user.h | 2 ++
3 files changed, 46 insertions(+), 22 deletions(-)
diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
index 505f8d3a33..137c9f3669 100644
--- a/docs/interop/vhost-user.rst
+++ b/docs/interop/vhost-user.rst
@@ -743,6 +743,8 @@ negotiated, back-end can send file descriptors (at most 8 descriptors in
each message) to front-end via ancillary data using this fd communication
channel.
+.. _inflight_io_tracking:
+
Inflight I/O tracking
---------------------
@@ -1040,26 +1042,27 @@ Protocol features
.. code:: c
- #define VHOST_USER_PROTOCOL_F_MQ 0
- #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
- #define VHOST_USER_PROTOCOL_F_RARP 2
- #define VHOST_USER_PROTOCOL_F_REPLY_ACK 3
- #define VHOST_USER_PROTOCOL_F_MTU 4
- #define VHOST_USER_PROTOCOL_F_BACKEND_REQ 5
- #define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6
- #define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
- #define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
- #define VHOST_USER_PROTOCOL_F_CONFIG 9
- #define VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD 10
- #define VHOST_USER_PROTOCOL_F_HOST_NOTIFIER 11
- #define VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD 12
- #define VHOST_USER_PROTOCOL_F_RESET_DEVICE 13
- #define VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS 14
- #define VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS 15
- #define VHOST_USER_PROTOCOL_F_STATUS 16
- #define VHOST_USER_PROTOCOL_F_XEN_MMAP 17
- #define VHOST_USER_PROTOCOL_F_SHARED_OBJECT 18
- #define VHOST_USER_PROTOCOL_F_DEVICE_STATE 19
+ #define VHOST_USER_PROTOCOL_F_MQ 0
+ #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
+ #define VHOST_USER_PROTOCOL_F_RARP 2
+ #define VHOST_USER_PROTOCOL_F_REPLY_ACK 3
+ #define VHOST_USER_PROTOCOL_F_MTU 4
+ #define VHOST_USER_PROTOCOL_F_BACKEND_REQ 5
+ #define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6
+ #define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
+ #define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
+ #define VHOST_USER_PROTOCOL_F_CONFIG 9
+ #define VHOST_USER_PROTOCOL_F_BACKEND_SEND_FD 10
+ #define VHOST_USER_PROTOCOL_F_HOST_NOTIFIER 11
+ #define VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD 12
+ #define VHOST_USER_PROTOCOL_F_RESET_DEVICE 13
+ #define VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS 14
+ #define VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS 15
+ #define VHOST_USER_PROTOCOL_F_STATUS 16
+ #define VHOST_USER_PROTOCOL_F_XEN_MMAP 17
+ #define VHOST_USER_PROTOCOL_F_SHARED_OBJECT 18
+ #define VHOST_USER_PROTOCOL_F_DEVICE_STATE 19
+ #define VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT 20
Front-end message types
-----------------------
@@ -1250,12 +1253,24 @@ Front-end message types
When and as long as all of a device's vrings are stopped, it is
*suspended*, see :ref:`Suspended device state
- <suspended_device_state>`. The back-end must complete all inflight I/O
- requests for the specified vring before stopping it.
+ <suspended_device_state>`.
The request payload's *num* field is currently reserved and must be
set to 0.
+ By default, the back-end must complete all inflight I/O requests for the
+ specified vring before stopping it.
+
+ If the ``VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT`` protocol
+ feature has been negotiated, the back-end may suspend in-flight I/O
+ requests and record them as described in :ref:`Inflight I/O tracking
+ <inflight_io_tracking>` instead of completing them before stopping the vring.
+ How to suspend an in-flight request depends on the implementation of the back-end
+ but it typically can be done by aborting or cancelling the underlying I/O
+ request. The ``VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT``
+ protocol feature must only be neogotiated if
+ ``VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD`` is also negotiated.
+
``VHOST_USER_SET_VRING_KICK``
:id: 12
:equivalent ioctl: ``VHOST_SET_VRING_KICK``
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 63fa9a1b4b..bb8f8eab77 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -2225,6 +2225,13 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque,
}
}
+ if (!u->user->supports_inflight_migration ||
+ !virtio_has_feature(protocol_features,
+ VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) {
+ protocol_features &= ~(1ULL <<
+ VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT);
+ }
+
/* final set of protocol features */
dev->protocol_features = protocol_features;
err = vhost_user_set_protocol_features(dev, dev->protocol_features);
diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h
index 55d5725ef8..53fe996686 100644
--- a/include/hw/virtio/vhost-user.h
+++ b/include/hw/virtio/vhost-user.h
@@ -32,6 +32,7 @@ enum VhostUserProtocolFeature {
/* Feature 17 reserved for VHOST_USER_PROTOCOL_F_XEN_MMAP. */
VHOST_USER_PROTOCOL_F_SHARED_OBJECT = 18,
VHOST_USER_PROTOCOL_F_DEVICE_STATE = 19,
+ VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT = 20,
VHOST_USER_PROTOCOL_F_MAX
};
@@ -68,6 +69,7 @@ typedef struct VhostUserState {
GPtrArray *notifiers;
int memory_slots;
bool supports_config;
+ bool supports_inflight_migration;
} VhostUserState;
/**
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 47/51] vmstate: introduce VMSTATE_VBUFFER_UINT64
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (45 preceding siblings ...)
2026-02-04 19:04 ` [PULL 46/51] vhost-user: introduce protocol feature for skip drain " Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 48/51] vhost: add vmstate for inflight region with inner buffer Michael S. Tsirkin
` (6 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Alexandr Moshkov, Peter Xu, Stefan Hajnoczi,
Fabiano Rosas
From: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
This is an analog of VMSTATE_VBUFFER_UINT32 macro, but for uint64 type.
Signed-off-by: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
Acked-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260115081103.655749-4-dtalexundeer@yandex-team.ru>
---
include/migration/vmstate.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index ed9095a466..89f9f49d20 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -706,6 +706,16 @@ extern const VMStateInfo vmstate_info_qlist;
.offset = offsetof(_state, _field), \
}
+#define VMSTATE_VBUFFER_UINT64(_field, _state, _version, _test, _field_size) { \
+ .name = (stringify(_field)), \
+ .version_id = (_version), \
+ .field_exists = (_test), \
+ .size_offset = vmstate_offset_value(_state, _field_size, uint64_t),\
+ .info = &vmstate_info_buffer, \
+ .flags = VMS_VBUFFER | VMS_POINTER, \
+ .offset = offsetof(_state, _field), \
+}
+
#define VMSTATE_VBUFFER_ALLOC_UINT32(_field, _state, _version, \
_test, _field_size) { \
.name = (stringify(_field)), \
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 48/51] vhost: add vmstate for inflight region with inner buffer
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (46 preceding siblings ...)
2026-02-04 19:04 ` [PULL 47/51] vmstate: introduce VMSTATE_VBUFFER_UINT64 Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 49/51] vhost-user-blk: support inter-host inflight migration Michael S. Tsirkin
` (5 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Alexandr Moshkov, Stefan Hajnoczi,
Stefano Garzarella
From: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
Prepare for future inflight region migration for vhost-user-blk.
We need to migrate size, queue_size, and inner buffer.
So firstly it migrate size and queue_size fields, then allocate memory
for buffer with
migrated size, then migrate inner buffer itself.
Signed-off-by: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260115081103.655749-5-dtalexundeer@yandex-team.ru>
---
hw/virtio/vhost.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index c6a5928cb1..52801c1796 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1918,6 +1918,62 @@ void vhost_get_features_ex(struct vhost_dev *hdev,
}
}
+static bool vhost_inflight_buffer_pre_load(void *opaque, Error **errp)
+{
+ struct vhost_inflight *inflight = opaque;
+
+ int fd = -1;
+ void *addr = qemu_memfd_alloc("vhost-inflight", inflight->size,
+ F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL,
+ &fd, errp);
+ if (*errp) {
+ return -ENOMEM;
+ }
+
+ inflight->offset = 0;
+ inflight->addr = addr;
+ inflight->fd = fd;
+
+ return true;
+}
+
+const VMStateDescription vmstate_vhost_inflight_region_buffer = {
+ .name = "vhost-inflight-region/buffer",
+ .pre_load_errp = vhost_inflight_buffer_pre_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_VBUFFER_UINT64(addr, struct vhost_inflight, 0, NULL, size),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static bool vhost_inflight_region_post_load(void *opaque,
+ int version_id,
+ Error **errp)
+{
+ struct vhost_inflight *inflight = opaque;
+
+ if (inflight->addr == NULL) {
+ error_setg(errp, "inflight buffer subsection has not been loaded");
+ return false;
+ }
+
+ return true;
+}
+
+const VMStateDescription vmstate_vhost_inflight_region = {
+ .name = "vhost-inflight-region",
+ .post_load_errp = vhost_inflight_region_post_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT64(size, struct vhost_inflight),
+ VMSTATE_UINT16(queue_size, struct vhost_inflight),
+ VMSTATE_END_OF_LIST()
+ },
+ .subsections = (const VMStateDescription * const []) {
+ &vmstate_vhost_inflight_region_buffer,
+ NULL
+ }
+};
+
void vhost_ack_features_ex(struct vhost_dev *hdev, const int *feature_bits,
const uint64_t *features)
{
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 49/51] vhost-user-blk: support inter-host inflight migration
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (47 preceding siblings ...)
2026-02-04 19:04 ` [PULL 48/51] vhost: add vmstate for inflight region with inner buffer Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 50/51] hw/cxl: Check for overflow on santize media as both base and offset 64bit Michael S. Tsirkin
` (4 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Alexandr Moshkov, Stefan Hajnoczi, Raphael Norwitz,
Raphael Norwitz, Stefano Garzarella, Kevin Wolf, Hanna Reitz,
qemu-block
From: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
During inter-host migration, waiting for disk requests to be drained
in the vhost-user backend can incur significant downtime.
This can be avoided if QEMU migrates the inflight region in
vhost-user-blk.
Thus, during the qemu migration, with feature flag the vhost-user
back-end can immediately stop vrings, so all in-flight requests will be
migrated to another host.
Signed-off-by: Alexandr Moshkov <dtalexundeer@yandex-team.ru>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Raphael Norwitz <raphael.s.norwitz@gmail.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260115081103.655749-6-dtalexundeer@yandex-team.ru>
---
hw/block/vhost-user-blk.c | 27 +++++++++++++++++++++++++++
include/hw/virtio/vhost-user-blk.h | 1 +
include/hw/virtio/vhost.h | 6 ++++++
3 files changed, 34 insertions(+)
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 4d81d2dc34..c151e83677 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -353,6 +353,7 @@ static int vhost_user_blk_connect(DeviceState *dev, Error **errp)
vhost_dev_set_config_notifier(&s->dev, &blk_ops);
s->vhost_user.supports_config = true;
+ s->vhost_user.supports_inflight_migration = s->inflight_migration;
ret = vhost_dev_init(&s->dev, &s->vhost_user, VHOST_BACKEND_TYPE_USER, 0,
errp);
if (ret < 0) {
@@ -568,6 +569,26 @@ static struct vhost_dev *vhost_user_blk_get_vhost(VirtIODevice *vdev)
return &s->dev;
}
+static bool vhost_user_blk_inflight_needed(void *opaque)
+{
+ struct VHostUserBlk *s = opaque;
+
+ bool inflight_migration = virtio_has_feature(s->dev.protocol_features,
+ VHOST_USER_PROTOCOL_F_GET_VRING_BASE_INFLIGHT);
+
+ return inflight_migration;
+}
+
+static const VMStateDescription vmstate_vhost_user_blk_inflight = {
+ .name = "vhost-user-blk/inflight",
+ .version_id = 1,
+ .needed = vhost_user_blk_inflight_needed,
+ .fields = (const VMStateField[]) {
+ VMSTATE_VHOST_INFLIGHT_REGION(inflight, VHostUserBlk),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
static const VMStateDescription vmstate_vhost_user_blk = {
.name = "vhost-user-blk",
.minimum_version_id = 1,
@@ -576,6 +597,10 @@ static const VMStateDescription vmstate_vhost_user_blk = {
VMSTATE_VIRTIO_DEVICE,
VMSTATE_END_OF_LIST()
},
+ .subsections = (const VMStateDescription * const []) {
+ &vmstate_vhost_user_blk_inflight,
+ NULL
+ }
};
static const Property vhost_user_blk_properties[] = {
@@ -591,6 +616,8 @@ static const Property vhost_user_blk_properties[] = {
VIRTIO_BLK_F_WRITE_ZEROES, true),
DEFINE_PROP_BOOL("skip-get-vring-base-on-force-shutdown", VHostUserBlk,
skip_get_vring_base_on_force_shutdown, false),
+ DEFINE_PROP_BOOL("inflight-migration", VHostUserBlk,
+ inflight_migration, false),
};
static void vhost_user_blk_class_init(ObjectClass *klass, const void *data)
diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h
index 8158d4673d..1e41a2bcdf 100644
--- a/include/hw/virtio/vhost-user-blk.h
+++ b/include/hw/virtio/vhost-user-blk.h
@@ -52,6 +52,7 @@ struct VHostUserBlk {
bool started_vu;
bool skip_get_vring_base_on_force_shutdown;
+ bool inflight_migration;
};
#endif
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 08bbb4dfe9..89817bd848 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -554,4 +554,10 @@ static inline int vhost_load_backend_state(struct vhost_dev *dev, QEMUFile *f,
}
#endif
+extern const VMStateDescription vmstate_vhost_inflight_region;
+#define VMSTATE_VHOST_INFLIGHT_REGION(_field, _state) \
+ VMSTATE_STRUCT_POINTER(_field, _state, \
+ vmstate_vhost_inflight_region, \
+ struct vhost_inflight)
+
#endif
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 50/51] hw/cxl: Check for overflow on santize media as both base and offset 64bit.
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (48 preceding siblings ...)
2026-02-04 19:04 ` [PULL 49/51] vhost-user-blk: support inter-host inflight migration Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-04 19:04 ` [PULL 51/51] hw/cxl: Take into account how many media operations are requested for param check Michael S. Tsirkin
` (3 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Jonathan Cameron, Fan Ni
From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
The both the size and base of a media sanitize operation are both provided
by the VM, an overflow is possible which may result in checks on valid
range passing when they should not. Close that by checking for overflow
on the addition.
Fixes: 40ab4ed10775 ("hw/cxl/cxl-mailbox-utils: Media operations Sanitize and Write Zeros commands CXL r3.2(8.2.10.9.5.3)")
Closes: https://lore.kernel.org/qemu-devel/CAFEAcA8Rqop+ju0fuxN+0T57NBG+bep80z45f6pY0ci2fz_G3A@mail.gmail.com/
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260102154731.474859-2-Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-mailbox-utils.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index a64b8ba535..d8f62a13a8 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -2411,7 +2411,7 @@ static uint64_t get_dc_size(CXLType3Dev *ct3d, MemoryRegion **dc_mr)
static int validate_dpa_addr(CXLType3Dev *ct3d, uint64_t dpa_addr,
size_t length)
{
- uint64_t vmr_size, pmr_size, dc_size;
+ uint64_t vmr_size, pmr_size, dc_size, dpa_end;
if ((dpa_addr % CXL_CACHE_LINE_SIZE) ||
(length % CXL_CACHE_LINE_SIZE) ||
@@ -2423,7 +2423,12 @@ static int validate_dpa_addr(CXLType3Dev *ct3d, uint64_t dpa_addr,
pmr_size = get_pmr_size(ct3d, NULL);
dc_size = get_dc_size(ct3d, NULL);
- if (dpa_addr + length > vmr_size + pmr_size + dc_size) {
+ /* sanitize 64 bit values coming from guest */
+ if (uadd64_overflow(dpa_addr, length, &dpa_end)) {
+ return -EINVAL;
+ }
+
+ if (dpa_end > vmr_size + pmr_size + dc_size) {
return -EINVAL;
}
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* [PULL 51/51] hw/cxl: Take into account how many media operations are requested for param check
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (49 preceding siblings ...)
2026-02-04 19:04 ` [PULL 50/51] hw/cxl: Check for overflow on santize media as both base and offset 64bit Michael S. Tsirkin
@ 2026-02-04 19:04 ` Michael S. Tsirkin
2026-02-05 6:31 ` [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (2 subsequent siblings)
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-04 19:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Jonathan Cameron, Fan Ni
From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Whilst the spec doesn't speak to it directly my assumption is that
a request for more operations than exist should result in an invalid
input error return.
Fixes: 77a8e9fe0ecb ("hw/cxl/cxl-mailbox-utils: Add support for Media operations discovery commands cxl r3.2 (8.2.10.9.5.3)")
Closes: https://lore.kernel.org/qemu-devel/CAFEAcA-p5wZkNxK7wNVq_3PAzEE-muOd1Def-0O-FSpck4DrBQ@mail.gmail.com/
Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260102154731.474859-3-Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-mailbox-utils.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index d8f62a13a8..2f449980cd 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -2547,7 +2547,7 @@ static CXLRetCode media_operations_discovery(uint8_t *payload_in,
* sub class command.
*/
if (media_op_in_disc_pl->dpa_range_count ||
- start_index > ARRAY_SIZE(media_op_matrix)) {
+ start_index + num_ops > ARRAY_SIZE(media_op_matrix)) {
return CXL_MBOX_INVALID_INPUT;
}
--
MST
^ permalink raw reply related [flat|nested] 77+ messages in thread* Re: [PULL 00/51] virtio,pci,pc: features, fixes
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (50 preceding siblings ...)
2026-02-04 19:04 ` [PULL 51/51] hw/cxl: Take into account how many media operations are requested for param check Michael S. Tsirkin
@ 2026-02-05 6:31 ` Michael S. Tsirkin
2026-02-05 6:51 ` Michael S. Tsirkin
2026-02-05 12:08 ` [PULL v2 00/38] " Michael S. Tsirkin
53 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-05 6:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
On Wed, Feb 04, 2026 at 02:16:23PM -0500, Michael S. Tsirkin wrote:
> The following changes since commit b377abc220fc53e9cab2aac3c73fc20be6d85eea:
>
> Merge tag 'hw-misc-20260202' of https://github.com/philmd/qemu into staging (2026-02-03 07:52:04 +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 1ef708ee4b765b9eac097192d54b69a603589f9b:
>
> hw/cxl: Take into account how many media operations are requested for param check (2026-02-04 07:42:50 -0500)
Oops. Missed v4 of CXL 3.2 update patchset. Pls ignore will send v2 soon.
> ----------------------------------------------------------------
> virtio,pci,pc: features, fixes
>
> cxl:
> Additional RAS features support.
> Back-Invalidate support
> PCIe Flit mode support
> Misc fixes
> intel_iommu:
> SVM support
> vhost:
> support for indirect descriptors in shadow virtqueue
> vhost-user:
> vhost-user-spi support
> vhost-user-blk inflight migration support
> vhost-user-blk inflight migration support
> acpi:
> update VIOT maintainer
> WDAT watchdog support
>
> misc fixes in pci, vhost, virtio, acpi
> cleanups in acpi/ghes
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>
> ----------------------------------------------------------------
> Akihiko Odaki (1):
> pci/shpc: Do not unparent in instance_finalize()
>
> Alexandr Moshkov (5):
> vhost-user.rst: specify vhost-user back-end action on GET_VRING_BASE
> vhost-user: introduce protocol feature for skip drain on GET_VRING_BASE
> vmstate: introduce VMSTATE_VBUFFER_UINT64
> vhost: add vmstate for inflight region with inner buffer
> vhost-user-blk: support inter-host inflight migration
>
> Clément Mathieu--Drif (7):
> intel_iommu: Add an IOMMU index for pre-translated addresses
> intel_iommu: Support memory operations with pre-translated addresses
> pcie: Add a function to check if pasid privileged mode is enabled
> pci: Block ATS requests when privileged mode is disabled
> intel_iommu: Handle insufficient permissions during translation requests
> intel_iommu: Minimal handling of privileged ATS request
> intel_iommu: Add a CLI option to enable SVM
>
> Daniil Tatianin (1):
> virtio/vhost: don't consider non-MAP_SHARED regions public
>
> Davidlohr Bueso (1):
> hw/cxl: Add support for Maintenance command and Post Package Repair (PPR)
>
> Dorinda Bassey (1):
> virtio-dmabuf: Ensure UUID persistence for hash table insertion
>
> Eugenio Pérez (1):
> vhost: accept indirect descriptors in shadow virtqueue
>
> Gavin Shan (5):
> acpi/ghes: Automate data block cleanup in acpi_ghes_memory_errors()
> acpi/ghes: Abort in acpi_ghes_memory_errors() if necessary
> target/arm/kvm: Exit on error from acpi_ghes_memory_errors()
> acpi/ghes: Bail early on error from get_ghes_source_offsets()
> acpi/ghes: Use error_fatal in acpi_ghes_memory_errors()
>
> Haixu Cui (2):
> standard-headers: Update virtio_spi.h from Linux v6.18-rc3
> virtio-spi: Add vhost-user-spi device support
>
> Honglei Huang (2):
> virtio-gpu: fix error handling in virgl_cmd_resource_create_blob
> virtio-gpu: use consistent error checking for virtio_gpu_create_mapping_iov
>
> Igor Mammedov (6):
> x86: q35: ich9: add 'wdat' property
> acpi: add API to build WDAT instructions
> x86: q35: generate WDAT ACPI table
> tests: x86: q35: acpi: add WDAT table test case
> tests: acpi: update expected WDAT blob
> q35: Fix migration of SMRAM state
>
> Jean-Philippe Brucker (1):
> MAINTAINERS: Update VIOT maintainer
>
> Joelle van Dyne (1):
> virtio-gpu-virgl: correct parent for blob memory region
>
> Jonathan Cameron (2):
> hw/cxl: Check for overflow on santize media as both base and offset 64bit.
> hw/cxl: Take into account how many media operations are requested for param check
>
> Kevin Wolf (2):
> virtio: Fix crash when sriov-pf is set for non-PCI-Express device
> pcie_sriov: Fix PCI_SRIOV_* accesses in pcie_sriov_pf_exit()
>
> Li Chen (1):
> virtio-pmem: ignore empty queue notifications
>
> Michael S. Tsirkin (1):
> vhost-user: ancilliary -> ancillary
>
> Philippe Mathieu-Daudé (1):
> hw/pci-host: Set DEVICE_CATEGORY_BRIDGE once in parent class_init()
>
> Shiju Jose (7):
> hw/cxl/cxl-mailbox-utils: Move declaration of scrub and ECS feature attributes in cmd_features_set_feature()
> hw/cxl: Add emulation for memory sparing control feature
> qapi: cxl: Refactor CXL event injection for common commands arguments
> hw/cxl/events: Update for rev3.2 common event record format
> hw/cxl/events: Updates for rev3.2 general media event record
> hw/cxl/events: Updates for rev3.2 DRAM event record
> hw/cxl/events: Updates for rev3.2 memory module event record
>
> Wafer Xie (1):
> vdpa: fix vhost-vdpa suspended state not be shared
>
> zhenwei pi (2):
> hw/virtio/virtio-crypto: verify asym request size
> cryptodev-builtin: Limit the maximum size
>
> MAINTAINERS | 8 +-
> backends/cryptodev-builtin.c | 9 +-
> docs/interop/vhost-user.rst | 60 +--
> docs/system/devices/virtio/vhost-user.rst | 3 +
> hw/acpi/aml-build.c | 14 +
> hw/acpi/ghes-stub.c | 6 +-
> hw/acpi/ghes.c | 45 +--
> hw/acpi/ich9.c | 5 +
> hw/acpi/meson.build | 3 +-
> hw/acpi/wdat-ich9.c | 85 ++++
> hw/acpi/wdat-stub.c | 16 +
> hw/block/vhost-user-blk.c | 27 ++
> hw/cxl/cxl-events.c | 3 +-
> hw/cxl/cxl-mailbox-utils.c | 580 +++++++++++++++++++++++++++-
> hw/display/virtio-dmabuf.c | 6 +-
> hw/display/virtio-gpu-virgl.c | 8 +-
> hw/display/virtio-gpu.c | 4 +-
> hw/i386/acpi-build.c | 13 +
> hw/i386/intel_iommu.c | 204 +++++++---
> hw/i386/intel_iommu_internal.h | 14 +-
> hw/isa/lpc_ich9.c | 1 +
> hw/mem/cxl_type3.c | 330 +++++++++++++++-
> hw/mem/cxl_type3_stubs.c | 41 +-
> hw/pci-host/articia.c | 1 -
> hw/pci-host/aspeed_pcie.c | 1 -
> hw/pci-host/designware.c | 3 -
> hw/pci-host/gpex.c | 2 -
> hw/pci-host/grackle.c | 1 -
> hw/pci-host/gt64120.c | 1 -
> hw/pci-host/mv64361.c | 1 -
> hw/pci-host/pnv_phb.c | 1 -
> hw/pci-host/ppce500.c | 1 -
> hw/pci-host/q35.c | 28 +-
> hw/pci-host/raven.c | 1 -
> hw/pci-host/remote.c | 1 -
> hw/pci-host/sabre.c | 1 -
> hw/pci-host/uninorth.c | 4 -
> hw/pci-host/xilinx-pcie.c | 2 -
> hw/pci/pci.c | 4 +
> hw/pci/pci_host.c | 1 +
> hw/pci/pcie.c | 21 +-
> hw/pci/pcie_sriov.c | 9 +-
> hw/pci/shpc.c | 1 -
> hw/virtio/Kconfig | 5 +
> hw/virtio/meson.build | 3 +
> hw/virtio/vhost-shadow-virtqueue.c | 1 +
> hw/virtio/vhost-user-spi-pci.c | 69 ++++
> hw/virtio/vhost-user-spi.c | 65 ++++
> hw/virtio/vhost-user.c | 7 +
> hw/virtio/vhost-vdpa.c | 6 +-
> hw/virtio/vhost.c | 66 +++-
> hw/virtio/virtio-crypto.c | 7 +
> hw/virtio/virtio-pci.c | 20 +-
> hw/virtio/virtio-pmem.c | 1 -
> hw/virtio/virtio.c | 4 +-
> include/hw/acpi/ghes.h | 6 +-
> include/hw/acpi/ich9.h | 1 +
> include/hw/acpi/wdat.h | 121 ++++++
> include/hw/cxl/cxl_device.h | 152 +++++++-
> include/hw/cxl/cxl_events.h | 85 +++-
> include/hw/i386/intel_iommu.h | 1 +
> include/hw/pci/pcie.h | 1 +
> include/hw/virtio/vhost-user-blk.h | 1 +
> include/hw/virtio/vhost-user-spi.h | 25 ++
> include/hw/virtio/vhost-user.h | 2 +
> include/hw/virtio/vhost-vdpa.h | 8 +-
> include/hw/virtio/vhost.h | 6 +
> include/migration/vmstate.h | 10 +
> include/standard-headers/linux/virtio_spi.h | 181 +++++++++
> qapi/cxl.json | 186 ++++++---
> target/arm/kvm.c | 10 +-
> tests/data/acpi/x86/q35/WDAT.wdat | Bin 0 -> 308 bytes
> tests/qtest/bios-tables-test.c | 13 +
> tests/qtest/q35-test.c | 6 -
> 74 files changed, 2342 insertions(+), 297 deletions(-)
> create mode 100644 hw/acpi/wdat-ich9.c
> create mode 100644 hw/acpi/wdat-stub.c
> create mode 100644 hw/virtio/vhost-user-spi-pci.c
> create mode 100644 hw/virtio/vhost-user-spi.c
> create mode 100644 include/hw/acpi/wdat.h
> create mode 100644 include/hw/virtio/vhost-user-spi.h
> create mode 100644 include/standard-headers/linux/virtio_spi.h
> create mode 100644 tests/data/acpi/x86/q35/WDAT.wdat
^ permalink raw reply [flat|nested] 77+ messages in thread* Re: [PULL 00/51] virtio,pci,pc: features, fixes
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (51 preceding siblings ...)
2026-02-05 6:31 ` [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
@ 2026-02-05 6:51 ` Michael S. Tsirkin
2026-02-05 7:00 ` Michael S. Tsirkin
2026-02-05 9:56 ` Peter Maydell
2026-02-05 12:08 ` [PULL v2 00/38] " Michael S. Tsirkin
53 siblings, 2 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-05 6:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
On Wed, Feb 04, 2026 at 02:16:23PM -0500, Michael S. Tsirkin wrote:
> The following changes since commit b377abc220fc53e9cab2aac3c73fc20be6d85eea:
>
> Merge tag 'hw-misc-20260202' of https://github.com/philmd/qemu into staging (2026-02-03 07:52:04 +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 1ef708ee4b765b9eac097192d54b69a603589f9b:
>
> hw/cxl: Take into account how many media operations are requested for param check (2026-02-04 07:42:50 -0500)
updated to 591fb214b96be2fab1dcf41282e567d6b64e613d now.
It is the same patchset with 5 patches dropped (and tag message
updated accordingly). So I am guessing it is better not
to resend the whole pull, but pls let me know.
> ----------------------------------------------------------------
> virtio,pci,pc: features, fixes
>
> cxl:
> Additional RAS features support.
> Back-Invalidate support
> PCIe Flit mode support
> Misc fixes
> intel_iommu:
> SVM support
> vhost:
> support for indirect descriptors in shadow virtqueue
> vhost-user:
> vhost-user-spi support
> vhost-user-blk inflight migration support
> vhost-user-blk inflight migration support
> acpi:
> update VIOT maintainer
> WDAT watchdog support
>
> misc fixes in pci, vhost, virtio, acpi
> cleanups in acpi/ghes
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>
> ----------------------------------------------------------------
> Akihiko Odaki (1):
> pci/shpc: Do not unparent in instance_finalize()
>
> Alexandr Moshkov (5):
> vhost-user.rst: specify vhost-user back-end action on GET_VRING_BASE
> vhost-user: introduce protocol feature for skip drain on GET_VRING_BASE
> vmstate: introduce VMSTATE_VBUFFER_UINT64
> vhost: add vmstate for inflight region with inner buffer
> vhost-user-blk: support inter-host inflight migration
>
> Clément Mathieu--Drif (7):
> intel_iommu: Add an IOMMU index for pre-translated addresses
> intel_iommu: Support memory operations with pre-translated addresses
> pcie: Add a function to check if pasid privileged mode is enabled
> pci: Block ATS requests when privileged mode is disabled
> intel_iommu: Handle insufficient permissions during translation requests
> intel_iommu: Minimal handling of privileged ATS request
> intel_iommu: Add a CLI option to enable SVM
>
> Daniil Tatianin (1):
> virtio/vhost: don't consider non-MAP_SHARED regions public
>
> Davidlohr Bueso (1):
> hw/cxl: Add support for Maintenance command and Post Package Repair (PPR)
>
> Dorinda Bassey (1):
> virtio-dmabuf: Ensure UUID persistence for hash table insertion
>
> Eugenio Pérez (1):
> vhost: accept indirect descriptors in shadow virtqueue
>
> Gavin Shan (5):
> acpi/ghes: Automate data block cleanup in acpi_ghes_memory_errors()
> acpi/ghes: Abort in acpi_ghes_memory_errors() if necessary
> target/arm/kvm: Exit on error from acpi_ghes_memory_errors()
> acpi/ghes: Bail early on error from get_ghes_source_offsets()
> acpi/ghes: Use error_fatal in acpi_ghes_memory_errors()
>
> Haixu Cui (2):
> standard-headers: Update virtio_spi.h from Linux v6.18-rc3
> virtio-spi: Add vhost-user-spi device support
>
> Honglei Huang (2):
> virtio-gpu: fix error handling in virgl_cmd_resource_create_blob
> virtio-gpu: use consistent error checking for virtio_gpu_create_mapping_iov
>
> Igor Mammedov (6):
> x86: q35: ich9: add 'wdat' property
> acpi: add API to build WDAT instructions
> x86: q35: generate WDAT ACPI table
> tests: x86: q35: acpi: add WDAT table test case
> tests: acpi: update expected WDAT blob
> q35: Fix migration of SMRAM state
>
> Jean-Philippe Brucker (1):
> MAINTAINERS: Update VIOT maintainer
>
> Joelle van Dyne (1):
> virtio-gpu-virgl: correct parent for blob memory region
>
> Jonathan Cameron (2):
> hw/cxl: Check for overflow on santize media as both base and offset 64bit.
> hw/cxl: Take into account how many media operations are requested for param check
>
> Kevin Wolf (2):
> virtio: Fix crash when sriov-pf is set for non-PCI-Express device
> pcie_sriov: Fix PCI_SRIOV_* accesses in pcie_sriov_pf_exit()
>
> Li Chen (1):
> virtio-pmem: ignore empty queue notifications
>
> Michael S. Tsirkin (1):
> vhost-user: ancilliary -> ancillary
>
> Philippe Mathieu-Daudé (1):
> hw/pci-host: Set DEVICE_CATEGORY_BRIDGE once in parent class_init()
>
> Shiju Jose (7):
> hw/cxl/cxl-mailbox-utils: Move declaration of scrub and ECS feature attributes in cmd_features_set_feature()
> hw/cxl: Add emulation for memory sparing control feature
> qapi: cxl: Refactor CXL event injection for common commands arguments
> hw/cxl/events: Update for rev3.2 common event record format
> hw/cxl/events: Updates for rev3.2 general media event record
> hw/cxl/events: Updates for rev3.2 DRAM event record
> hw/cxl/events: Updates for rev3.2 memory module event record
>
> Wafer Xie (1):
> vdpa: fix vhost-vdpa suspended state not be shared
>
> zhenwei pi (2):
> hw/virtio/virtio-crypto: verify asym request size
> cryptodev-builtin: Limit the maximum size
>
> MAINTAINERS | 8 +-
> backends/cryptodev-builtin.c | 9 +-
> docs/interop/vhost-user.rst | 60 +--
> docs/system/devices/virtio/vhost-user.rst | 3 +
> hw/acpi/aml-build.c | 14 +
> hw/acpi/ghes-stub.c | 6 +-
> hw/acpi/ghes.c | 45 +--
> hw/acpi/ich9.c | 5 +
> hw/acpi/meson.build | 3 +-
> hw/acpi/wdat-ich9.c | 85 ++++
> hw/acpi/wdat-stub.c | 16 +
> hw/block/vhost-user-blk.c | 27 ++
> hw/cxl/cxl-events.c | 3 +-
> hw/cxl/cxl-mailbox-utils.c | 580 +++++++++++++++++++++++++++-
> hw/display/virtio-dmabuf.c | 6 +-
> hw/display/virtio-gpu-virgl.c | 8 +-
> hw/display/virtio-gpu.c | 4 +-
> hw/i386/acpi-build.c | 13 +
> hw/i386/intel_iommu.c | 204 +++++++---
> hw/i386/intel_iommu_internal.h | 14 +-
> hw/isa/lpc_ich9.c | 1 +
> hw/mem/cxl_type3.c | 330 +++++++++++++++-
> hw/mem/cxl_type3_stubs.c | 41 +-
> hw/pci-host/articia.c | 1 -
> hw/pci-host/aspeed_pcie.c | 1 -
> hw/pci-host/designware.c | 3 -
> hw/pci-host/gpex.c | 2 -
> hw/pci-host/grackle.c | 1 -
> hw/pci-host/gt64120.c | 1 -
> hw/pci-host/mv64361.c | 1 -
> hw/pci-host/pnv_phb.c | 1 -
> hw/pci-host/ppce500.c | 1 -
> hw/pci-host/q35.c | 28 +-
> hw/pci-host/raven.c | 1 -
> hw/pci-host/remote.c | 1 -
> hw/pci-host/sabre.c | 1 -
> hw/pci-host/uninorth.c | 4 -
> hw/pci-host/xilinx-pcie.c | 2 -
> hw/pci/pci.c | 4 +
> hw/pci/pci_host.c | 1 +
> hw/pci/pcie.c | 21 +-
> hw/pci/pcie_sriov.c | 9 +-
> hw/pci/shpc.c | 1 -
> hw/virtio/Kconfig | 5 +
> hw/virtio/meson.build | 3 +
> hw/virtio/vhost-shadow-virtqueue.c | 1 +
> hw/virtio/vhost-user-spi-pci.c | 69 ++++
> hw/virtio/vhost-user-spi.c | 65 ++++
> hw/virtio/vhost-user.c | 7 +
> hw/virtio/vhost-vdpa.c | 6 +-
> hw/virtio/vhost.c | 66 +++-
> hw/virtio/virtio-crypto.c | 7 +
> hw/virtio/virtio-pci.c | 20 +-
> hw/virtio/virtio-pmem.c | 1 -
> hw/virtio/virtio.c | 4 +-
> include/hw/acpi/ghes.h | 6 +-
> include/hw/acpi/ich9.h | 1 +
> include/hw/acpi/wdat.h | 121 ++++++
> include/hw/cxl/cxl_device.h | 152 +++++++-
> include/hw/cxl/cxl_events.h | 85 +++-
> include/hw/i386/intel_iommu.h | 1 +
> include/hw/pci/pcie.h | 1 +
> include/hw/virtio/vhost-user-blk.h | 1 +
> include/hw/virtio/vhost-user-spi.h | 25 ++
> include/hw/virtio/vhost-user.h | 2 +
> include/hw/virtio/vhost-vdpa.h | 8 +-
> include/hw/virtio/vhost.h | 6 +
> include/migration/vmstate.h | 10 +
> include/standard-headers/linux/virtio_spi.h | 181 +++++++++
> qapi/cxl.json | 186 ++++++---
> target/arm/kvm.c | 10 +-
> tests/data/acpi/x86/q35/WDAT.wdat | Bin 0 -> 308 bytes
> tests/qtest/bios-tables-test.c | 13 +
> tests/qtest/q35-test.c | 6 -
> 74 files changed, 2342 insertions(+), 297 deletions(-)
> create mode 100644 hw/acpi/wdat-ich9.c
> create mode 100644 hw/acpi/wdat-stub.c
> create mode 100644 hw/virtio/vhost-user-spi-pci.c
> create mode 100644 hw/virtio/vhost-user-spi.c
> create mode 100644 include/hw/acpi/wdat.h
> create mode 100644 include/hw/virtio/vhost-user-spi.h
> create mode 100644 include/standard-headers/linux/virtio_spi.h
> create mode 100644 tests/data/acpi/x86/q35/WDAT.wdat
^ permalink raw reply [flat|nested] 77+ messages in thread* Re: [PULL 00/51] virtio,pci,pc: features, fixes
2026-02-05 6:51 ` Michael S. Tsirkin
@ 2026-02-05 7:00 ` Michael S. Tsirkin
2026-02-05 9:39 ` Igor Mammedov
2026-02-05 9:56 ` Peter Maydell
1 sibling, 1 reply; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-05 7:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
On Thu, Feb 05, 2026 at 01:51:39AM -0500, Michael S. Tsirkin wrote:
> On Wed, Feb 04, 2026 at 02:16:23PM -0500, Michael S. Tsirkin wrote:
> > The following changes since commit b377abc220fc53e9cab2aac3c73fc20be6d85eea:
> >
> > Merge tag 'hw-misc-20260202' of https://github.com/philmd/qemu into staging (2026-02-03 07:52:04 +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 1ef708ee4b765b9eac097192d54b69a603589f9b:
> >
> > hw/cxl: Take into account how many media operations are requested for param check (2026-02-04 07:42:50 -0500)
>
> updated to 591fb214b96be2fab1dcf41282e567d6b64e613d now.
>
> It is the same patchset with 5 patches dropped (and tag message
> updated accordingly). So I am guessing it is better not
> to resend the whole pull, but pls let me know.
sent too early, there is a dependency i missed.
will post v2 later.
>
> > ----------------------------------------------------------------
> > virtio,pci,pc: features, fixes
> >
> > cxl:
> > Additional RAS features support.
> > Back-Invalidate support
> > PCIe Flit mode support
> > Misc fixes
> > intel_iommu:
> > SVM support
> > vhost:
> > support for indirect descriptors in shadow virtqueue
> > vhost-user:
> > vhost-user-spi support
> > vhost-user-blk inflight migration support
> > vhost-user-blk inflight migration support
> > acpi:
> > update VIOT maintainer
> > WDAT watchdog support
> >
> > misc fixes in pci, vhost, virtio, acpi
> > cleanups in acpi/ghes
> >
> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> >
> > ----------------------------------------------------------------
> > Akihiko Odaki (1):
> > pci/shpc: Do not unparent in instance_finalize()
> >
> > Alexandr Moshkov (5):
> > vhost-user.rst: specify vhost-user back-end action on GET_VRING_BASE
> > vhost-user: introduce protocol feature for skip drain on GET_VRING_BASE
> > vmstate: introduce VMSTATE_VBUFFER_UINT64
> > vhost: add vmstate for inflight region with inner buffer
> > vhost-user-blk: support inter-host inflight migration
> >
> > Clément Mathieu--Drif (7):
> > intel_iommu: Add an IOMMU index for pre-translated addresses
> > intel_iommu: Support memory operations with pre-translated addresses
> > pcie: Add a function to check if pasid privileged mode is enabled
> > pci: Block ATS requests when privileged mode is disabled
> > intel_iommu: Handle insufficient permissions during translation requests
> > intel_iommu: Minimal handling of privileged ATS request
> > intel_iommu: Add a CLI option to enable SVM
> >
> > Daniil Tatianin (1):
> > virtio/vhost: don't consider non-MAP_SHARED regions public
> >
> > Davidlohr Bueso (1):
> > hw/cxl: Add support for Maintenance command and Post Package Repair (PPR)
> >
> > Dorinda Bassey (1):
> > virtio-dmabuf: Ensure UUID persistence for hash table insertion
> >
> > Eugenio Pérez (1):
> > vhost: accept indirect descriptors in shadow virtqueue
> >
> > Gavin Shan (5):
> > acpi/ghes: Automate data block cleanup in acpi_ghes_memory_errors()
> > acpi/ghes: Abort in acpi_ghes_memory_errors() if necessary
> > target/arm/kvm: Exit on error from acpi_ghes_memory_errors()
> > acpi/ghes: Bail early on error from get_ghes_source_offsets()
> > acpi/ghes: Use error_fatal in acpi_ghes_memory_errors()
> >
> > Haixu Cui (2):
> > standard-headers: Update virtio_spi.h from Linux v6.18-rc3
> > virtio-spi: Add vhost-user-spi device support
> >
> > Honglei Huang (2):
> > virtio-gpu: fix error handling in virgl_cmd_resource_create_blob
> > virtio-gpu: use consistent error checking for virtio_gpu_create_mapping_iov
> >
> > Igor Mammedov (6):
> > x86: q35: ich9: add 'wdat' property
> > acpi: add API to build WDAT instructions
> > x86: q35: generate WDAT ACPI table
> > tests: x86: q35: acpi: add WDAT table test case
> > tests: acpi: update expected WDAT blob
> > q35: Fix migration of SMRAM state
> >
> > Jean-Philippe Brucker (1):
> > MAINTAINERS: Update VIOT maintainer
> >
> > Joelle van Dyne (1):
> > virtio-gpu-virgl: correct parent for blob memory region
> >
> > Jonathan Cameron (2):
> > hw/cxl: Check for overflow on santize media as both base and offset 64bit.
> > hw/cxl: Take into account how many media operations are requested for param check
> >
> > Kevin Wolf (2):
> > virtio: Fix crash when sriov-pf is set for non-PCI-Express device
> > pcie_sriov: Fix PCI_SRIOV_* accesses in pcie_sriov_pf_exit()
> >
> > Li Chen (1):
> > virtio-pmem: ignore empty queue notifications
> >
> > Michael S. Tsirkin (1):
> > vhost-user: ancilliary -> ancillary
> >
> > Philippe Mathieu-Daudé (1):
> > hw/pci-host: Set DEVICE_CATEGORY_BRIDGE once in parent class_init()
> >
> > Shiju Jose (7):
> > hw/cxl/cxl-mailbox-utils: Move declaration of scrub and ECS feature attributes in cmd_features_set_feature()
> > hw/cxl: Add emulation for memory sparing control feature
> > qapi: cxl: Refactor CXL event injection for common commands arguments
> > hw/cxl/events: Update for rev3.2 common event record format
> > hw/cxl/events: Updates for rev3.2 general media event record
> > hw/cxl/events: Updates for rev3.2 DRAM event record
> > hw/cxl/events: Updates for rev3.2 memory module event record
> >
> > Wafer Xie (1):
> > vdpa: fix vhost-vdpa suspended state not be shared
> >
> > zhenwei pi (2):
> > hw/virtio/virtio-crypto: verify asym request size
> > cryptodev-builtin: Limit the maximum size
> >
> > MAINTAINERS | 8 +-
> > backends/cryptodev-builtin.c | 9 +-
> > docs/interop/vhost-user.rst | 60 +--
> > docs/system/devices/virtio/vhost-user.rst | 3 +
> > hw/acpi/aml-build.c | 14 +
> > hw/acpi/ghes-stub.c | 6 +-
> > hw/acpi/ghes.c | 45 +--
> > hw/acpi/ich9.c | 5 +
> > hw/acpi/meson.build | 3 +-
> > hw/acpi/wdat-ich9.c | 85 ++++
> > hw/acpi/wdat-stub.c | 16 +
> > hw/block/vhost-user-blk.c | 27 ++
> > hw/cxl/cxl-events.c | 3 +-
> > hw/cxl/cxl-mailbox-utils.c | 580 +++++++++++++++++++++++++++-
> > hw/display/virtio-dmabuf.c | 6 +-
> > hw/display/virtio-gpu-virgl.c | 8 +-
> > hw/display/virtio-gpu.c | 4 +-
> > hw/i386/acpi-build.c | 13 +
> > hw/i386/intel_iommu.c | 204 +++++++---
> > hw/i386/intel_iommu_internal.h | 14 +-
> > hw/isa/lpc_ich9.c | 1 +
> > hw/mem/cxl_type3.c | 330 +++++++++++++++-
> > hw/mem/cxl_type3_stubs.c | 41 +-
> > hw/pci-host/articia.c | 1 -
> > hw/pci-host/aspeed_pcie.c | 1 -
> > hw/pci-host/designware.c | 3 -
> > hw/pci-host/gpex.c | 2 -
> > hw/pci-host/grackle.c | 1 -
> > hw/pci-host/gt64120.c | 1 -
> > hw/pci-host/mv64361.c | 1 -
> > hw/pci-host/pnv_phb.c | 1 -
> > hw/pci-host/ppce500.c | 1 -
> > hw/pci-host/q35.c | 28 +-
> > hw/pci-host/raven.c | 1 -
> > hw/pci-host/remote.c | 1 -
> > hw/pci-host/sabre.c | 1 -
> > hw/pci-host/uninorth.c | 4 -
> > hw/pci-host/xilinx-pcie.c | 2 -
> > hw/pci/pci.c | 4 +
> > hw/pci/pci_host.c | 1 +
> > hw/pci/pcie.c | 21 +-
> > hw/pci/pcie_sriov.c | 9 +-
> > hw/pci/shpc.c | 1 -
> > hw/virtio/Kconfig | 5 +
> > hw/virtio/meson.build | 3 +
> > hw/virtio/vhost-shadow-virtqueue.c | 1 +
> > hw/virtio/vhost-user-spi-pci.c | 69 ++++
> > hw/virtio/vhost-user-spi.c | 65 ++++
> > hw/virtio/vhost-user.c | 7 +
> > hw/virtio/vhost-vdpa.c | 6 +-
> > hw/virtio/vhost.c | 66 +++-
> > hw/virtio/virtio-crypto.c | 7 +
> > hw/virtio/virtio-pci.c | 20 +-
> > hw/virtio/virtio-pmem.c | 1 -
> > hw/virtio/virtio.c | 4 +-
> > include/hw/acpi/ghes.h | 6 +-
> > include/hw/acpi/ich9.h | 1 +
> > include/hw/acpi/wdat.h | 121 ++++++
> > include/hw/cxl/cxl_device.h | 152 +++++++-
> > include/hw/cxl/cxl_events.h | 85 +++-
> > include/hw/i386/intel_iommu.h | 1 +
> > include/hw/pci/pcie.h | 1 +
> > include/hw/virtio/vhost-user-blk.h | 1 +
> > include/hw/virtio/vhost-user-spi.h | 25 ++
> > include/hw/virtio/vhost-user.h | 2 +
> > include/hw/virtio/vhost-vdpa.h | 8 +-
> > include/hw/virtio/vhost.h | 6 +
> > include/migration/vmstate.h | 10 +
> > include/standard-headers/linux/virtio_spi.h | 181 +++++++++
> > qapi/cxl.json | 186 ++++++---
> > target/arm/kvm.c | 10 +-
> > tests/data/acpi/x86/q35/WDAT.wdat | Bin 0 -> 308 bytes
> > tests/qtest/bios-tables-test.c | 13 +
> > tests/qtest/q35-test.c | 6 -
> > 74 files changed, 2342 insertions(+), 297 deletions(-)
> > create mode 100644 hw/acpi/wdat-ich9.c
> > create mode 100644 hw/acpi/wdat-stub.c
> > create mode 100644 hw/virtio/vhost-user-spi-pci.c
> > create mode 100644 hw/virtio/vhost-user-spi.c
> > create mode 100644 include/hw/acpi/wdat.h
> > create mode 100644 include/hw/virtio/vhost-user-spi.h
> > create mode 100644 include/standard-headers/linux/virtio_spi.h
> > create mode 100644 tests/data/acpi/x86/q35/WDAT.wdat
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 00/51] virtio,pci,pc: features, fixes
2026-02-05 7:00 ` Michael S. Tsirkin
@ 2026-02-05 9:39 ` Igor Mammedov
0 siblings, 0 replies; 77+ messages in thread
From: Igor Mammedov @ 2026-02-05 9:39 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: qemu-devel, Peter Maydell
On Thu, 5 Feb 2026 02:00:22 -0500
"Michael S. Tsirkin" <mst@redhat.com> wrote:
> On Thu, Feb 05, 2026 at 01:51:39AM -0500, Michael S. Tsirkin wrote:
> > On Wed, Feb 04, 2026 at 02:16:23PM -0500, Michael S. Tsirkin wrote:
> > > The following changes since commit b377abc220fc53e9cab2aac3c73fc20be6d85eea:
> > >
> > > Merge tag 'hw-misc-20260202' of https://github.com/philmd/qemu into staging (2026-02-03 07:52:04 +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 1ef708ee4b765b9eac097192d54b69a603589f9b:
> > >
> > > hw/cxl: Take into account how many media operations are requested for param check (2026-02-04 07:42:50 -0500)
> >
> > updated to 591fb214b96be2fab1dcf41282e567d6b64e613d now.
> >
> > It is the same patchset with 5 patches dropped (and tag message
> > updated accordingly). So I am guessing it is better not
> > to resend the whole pull, but pls let me know.
>
> sent too early, there is a dependency i missed.
> will post v2 later.
Michael,
please drop WDAT patches,
I'm preparing to post v2 soon with arm/virt support included
and x86 part changed as well to make configuration generic.
> >
> > > ----------------------------------------------------------------
> > > virtio,pci,pc: features, fixes
> > >
> > > cxl:
> > > Additional RAS features support.
> > > Back-Invalidate support
> > > PCIe Flit mode support
> > > Misc fixes
> > > intel_iommu:
> > > SVM support
> > > vhost:
> > > support for indirect descriptors in shadow virtqueue
> > > vhost-user:
> > > vhost-user-spi support
> > > vhost-user-blk inflight migration support
> > > vhost-user-blk inflight migration support
> > > acpi:
> > > update VIOT maintainer
> > > WDAT watchdog support
> > >
> > > misc fixes in pci, vhost, virtio, acpi
> > > cleanups in acpi/ghes
> > >
> > > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> > >
> > > ----------------------------------------------------------------
> > > Akihiko Odaki (1):
> > > pci/shpc: Do not unparent in instance_finalize()
> > >
> > > Alexandr Moshkov (5):
> > > vhost-user.rst: specify vhost-user back-end action on GET_VRING_BASE
> > > vhost-user: introduce protocol feature for skip drain on GET_VRING_BASE
> > > vmstate: introduce VMSTATE_VBUFFER_UINT64
> > > vhost: add vmstate for inflight region with inner buffer
> > > vhost-user-blk: support inter-host inflight migration
> > >
> > > Clément Mathieu--Drif (7):
> > > intel_iommu: Add an IOMMU index for pre-translated addresses
> > > intel_iommu: Support memory operations with pre-translated addresses
> > > pcie: Add a function to check if pasid privileged mode is enabled
> > > pci: Block ATS requests when privileged mode is disabled
> > > intel_iommu: Handle insufficient permissions during translation requests
> > > intel_iommu: Minimal handling of privileged ATS request
> > > intel_iommu: Add a CLI option to enable SVM
> > >
> > > Daniil Tatianin (1):
> > > virtio/vhost: don't consider non-MAP_SHARED regions public
> > >
> > > Davidlohr Bueso (1):
> > > hw/cxl: Add support for Maintenance command and Post Package Repair (PPR)
> > >
> > > Dorinda Bassey (1):
> > > virtio-dmabuf: Ensure UUID persistence for hash table insertion
> > >
> > > Eugenio Pérez (1):
> > > vhost: accept indirect descriptors in shadow virtqueue
> > >
> > > Gavin Shan (5):
> > > acpi/ghes: Automate data block cleanup in acpi_ghes_memory_errors()
> > > acpi/ghes: Abort in acpi_ghes_memory_errors() if necessary
> > > target/arm/kvm: Exit on error from acpi_ghes_memory_errors()
> > > acpi/ghes: Bail early on error from get_ghes_source_offsets()
> > > acpi/ghes: Use error_fatal in acpi_ghes_memory_errors()
> > >
> > > Haixu Cui (2):
> > > standard-headers: Update virtio_spi.h from Linux v6.18-rc3
> > > virtio-spi: Add vhost-user-spi device support
> > >
> > > Honglei Huang (2):
> > > virtio-gpu: fix error handling in virgl_cmd_resource_create_blob
> > > virtio-gpu: use consistent error checking for virtio_gpu_create_mapping_iov
> > >
> > > Igor Mammedov (6):
> > > x86: q35: ich9: add 'wdat' property
> > > acpi: add API to build WDAT instructions
> > > x86: q35: generate WDAT ACPI table
> > > tests: x86: q35: acpi: add WDAT table test case
> > > tests: acpi: update expected WDAT blob
> > > q35: Fix migration of SMRAM state
> > >
> > > Jean-Philippe Brucker (1):
> > > MAINTAINERS: Update VIOT maintainer
> > >
> > > Joelle van Dyne (1):
> > > virtio-gpu-virgl: correct parent for blob memory region
> > >
> > > Jonathan Cameron (2):
> > > hw/cxl: Check for overflow on santize media as both base and offset 64bit.
> > > hw/cxl: Take into account how many media operations are requested for param check
> > >
> > > Kevin Wolf (2):
> > > virtio: Fix crash when sriov-pf is set for non-PCI-Express device
> > > pcie_sriov: Fix PCI_SRIOV_* accesses in pcie_sriov_pf_exit()
> > >
> > > Li Chen (1):
> > > virtio-pmem: ignore empty queue notifications
> > >
> > > Michael S. Tsirkin (1):
> > > vhost-user: ancilliary -> ancillary
> > >
> > > Philippe Mathieu-Daudé (1):
> > > hw/pci-host: Set DEVICE_CATEGORY_BRIDGE once in parent class_init()
> > >
> > > Shiju Jose (7):
> > > hw/cxl/cxl-mailbox-utils: Move declaration of scrub and ECS feature attributes in cmd_features_set_feature()
> > > hw/cxl: Add emulation for memory sparing control feature
> > > qapi: cxl: Refactor CXL event injection for common commands arguments
> > > hw/cxl/events: Update for rev3.2 common event record format
> > > hw/cxl/events: Updates for rev3.2 general media event record
> > > hw/cxl/events: Updates for rev3.2 DRAM event record
> > > hw/cxl/events: Updates for rev3.2 memory module event record
> > >
> > > Wafer Xie (1):
> > > vdpa: fix vhost-vdpa suspended state not be shared
> > >
> > > zhenwei pi (2):
> > > hw/virtio/virtio-crypto: verify asym request size
> > > cryptodev-builtin: Limit the maximum size
> > >
> > > MAINTAINERS | 8 +-
> > > backends/cryptodev-builtin.c | 9 +-
> > > docs/interop/vhost-user.rst | 60 +--
> > > docs/system/devices/virtio/vhost-user.rst | 3 +
> > > hw/acpi/aml-build.c | 14 +
> > > hw/acpi/ghes-stub.c | 6 +-
> > > hw/acpi/ghes.c | 45 +--
> > > hw/acpi/ich9.c | 5 +
> > > hw/acpi/meson.build | 3 +-
> > > hw/acpi/wdat-ich9.c | 85 ++++
> > > hw/acpi/wdat-stub.c | 16 +
> > > hw/block/vhost-user-blk.c | 27 ++
> > > hw/cxl/cxl-events.c | 3 +-
> > > hw/cxl/cxl-mailbox-utils.c | 580 +++++++++++++++++++++++++++-
> > > hw/display/virtio-dmabuf.c | 6 +-
> > > hw/display/virtio-gpu-virgl.c | 8 +-
> > > hw/display/virtio-gpu.c | 4 +-
> > > hw/i386/acpi-build.c | 13 +
> > > hw/i386/intel_iommu.c | 204 +++++++---
> > > hw/i386/intel_iommu_internal.h | 14 +-
> > > hw/isa/lpc_ich9.c | 1 +
> > > hw/mem/cxl_type3.c | 330 +++++++++++++++-
> > > hw/mem/cxl_type3_stubs.c | 41 +-
> > > hw/pci-host/articia.c | 1 -
> > > hw/pci-host/aspeed_pcie.c | 1 -
> > > hw/pci-host/designware.c | 3 -
> > > hw/pci-host/gpex.c | 2 -
> > > hw/pci-host/grackle.c | 1 -
> > > hw/pci-host/gt64120.c | 1 -
> > > hw/pci-host/mv64361.c | 1 -
> > > hw/pci-host/pnv_phb.c | 1 -
> > > hw/pci-host/ppce500.c | 1 -
> > > hw/pci-host/q35.c | 28 +-
> > > hw/pci-host/raven.c | 1 -
> > > hw/pci-host/remote.c | 1 -
> > > hw/pci-host/sabre.c | 1 -
> > > hw/pci-host/uninorth.c | 4 -
> > > hw/pci-host/xilinx-pcie.c | 2 -
> > > hw/pci/pci.c | 4 +
> > > hw/pci/pci_host.c | 1 +
> > > hw/pci/pcie.c | 21 +-
> > > hw/pci/pcie_sriov.c | 9 +-
> > > hw/pci/shpc.c | 1 -
> > > hw/virtio/Kconfig | 5 +
> > > hw/virtio/meson.build | 3 +
> > > hw/virtio/vhost-shadow-virtqueue.c | 1 +
> > > hw/virtio/vhost-user-spi-pci.c | 69 ++++
> > > hw/virtio/vhost-user-spi.c | 65 ++++
> > > hw/virtio/vhost-user.c | 7 +
> > > hw/virtio/vhost-vdpa.c | 6 +-
> > > hw/virtio/vhost.c | 66 +++-
> > > hw/virtio/virtio-crypto.c | 7 +
> > > hw/virtio/virtio-pci.c | 20 +-
> > > hw/virtio/virtio-pmem.c | 1 -
> > > hw/virtio/virtio.c | 4 +-
> > > include/hw/acpi/ghes.h | 6 +-
> > > include/hw/acpi/ich9.h | 1 +
> > > include/hw/acpi/wdat.h | 121 ++++++
> > > include/hw/cxl/cxl_device.h | 152 +++++++-
> > > include/hw/cxl/cxl_events.h | 85 +++-
> > > include/hw/i386/intel_iommu.h | 1 +
> > > include/hw/pci/pcie.h | 1 +
> > > include/hw/virtio/vhost-user-blk.h | 1 +
> > > include/hw/virtio/vhost-user-spi.h | 25 ++
> > > include/hw/virtio/vhost-user.h | 2 +
> > > include/hw/virtio/vhost-vdpa.h | 8 +-
> > > include/hw/virtio/vhost.h | 6 +
> > > include/migration/vmstate.h | 10 +
> > > include/standard-headers/linux/virtio_spi.h | 181 +++++++++
> > > qapi/cxl.json | 186 ++++++---
> > > target/arm/kvm.c | 10 +-
> > > tests/data/acpi/x86/q35/WDAT.wdat | Bin 0 -> 308 bytes
> > > tests/qtest/bios-tables-test.c | 13 +
> > > tests/qtest/q35-test.c | 6 -
> > > 74 files changed, 2342 insertions(+), 297 deletions(-)
> > > create mode 100644 hw/acpi/wdat-ich9.c
> > > create mode 100644 hw/acpi/wdat-stub.c
> > > create mode 100644 hw/virtio/vhost-user-spi-pci.c
> > > create mode 100644 hw/virtio/vhost-user-spi.c
> > > create mode 100644 include/hw/acpi/wdat.h
> > > create mode 100644 include/hw/virtio/vhost-user-spi.h
> > > create mode 100644 include/standard-headers/linux/virtio_spi.h
> > > create mode 100644 tests/data/acpi/x86/q35/WDAT.wdat
>
>
^ permalink raw reply [flat|nested] 77+ messages in thread
* Re: [PULL 00/51] virtio,pci,pc: features, fixes
2026-02-05 6:51 ` Michael S. Tsirkin
2026-02-05 7:00 ` Michael S. Tsirkin
@ 2026-02-05 9:56 ` Peter Maydell
1 sibling, 0 replies; 77+ messages in thread
From: Peter Maydell @ 2026-02-05 9:56 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: qemu-devel
On Thu, 5 Feb 2026 at 06:51, Michael S. Tsirkin <mst@redhat.com> wrote:
>
> On Wed, Feb 04, 2026 at 02:16:23PM -0500, Michael S. Tsirkin wrote:
> > The following changes since commit b377abc220fc53e9cab2aac3c73fc20be6d85eea:
> >
> > Merge tag 'hw-misc-20260202' of https://github.com/philmd/qemu into staging (2026-02-03 07:52:04 +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 1ef708ee4b765b9eac097192d54b69a603589f9b:
> >
> > hw/cxl: Take into account how many media operations are requested for param check (2026-02-04 07:42:50 -0500)
>
> updated to 591fb214b96be2fab1dcf41282e567d6b64e613d now.
>
> It is the same patchset with 5 patches dropped (and tag message
> updated accordingly). So I am guessing it is better not
> to resend the whole pull, but pls let me know.
If you make minor changes to a pullreq, you don't need to
send the whole thing again, but please do re-send the
cover letter with "[PULL v2 00/51]" or whatever in the
subject message. That way it's clear that there's a
new version.
thanks
-- PMM
^ permalink raw reply [flat|nested] 77+ messages in thread
* [PULL v2 00/38] virtio,pci,pc: features, fixes
2026-02-04 19:16 [PULL 00/51] virtio,pci,pc: features, fixes Michael S. Tsirkin
` (52 preceding siblings ...)
2026-02-05 6:51 ` Michael S. Tsirkin
@ 2026-02-05 12:08 ` Michael S. Tsirkin
2026-02-05 16:02 ` Peter Maydell
53 siblings, 1 reply; 77+ messages in thread
From: Michael S. Tsirkin @ 2026-02-05 12:08 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Dropped most cxl patches for now.
Dropped WADT due to author's request.
The following changes since commit b377abc220fc53e9cab2aac3c73fc20be6d85eea:
Merge tag 'hw-misc-20260202' of https://github.com/philmd/qemu into staging (2026-02-03 07:52:04 +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 25465c0e1fd74d2118dfec03912f2595eeb497d7:
hw/cxl: Take into account how many media operations are requested for param check (2026-02-05 05:06:46 -0500)
----------------------------------------------------------------
virtio,pci,pc: features, fixes
intel_iommu:
SVM support
vhost:
support for indirect descriptors in shadow virtqueue
vhost-user:
vhost-user-spi support
vhost-user-blk inflight migration support
vhost-user-blk inflight migration support
misc fixes in pci, vhost, virtio, acpi, cxl
cleanups in acpi/ghes
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
----------------------------------------------------------------
Akihiko Odaki (1):
pci/shpc: Do not unparent in instance_finalize()
Alexandr Moshkov (5):
vhost-user.rst: specify vhost-user back-end action on GET_VRING_BASE
vhost-user: introduce protocol feature for skip drain on GET_VRING_BASE
vmstate: introduce VMSTATE_VBUFFER_UINT64
vhost: add vmstate for inflight region with inner buffer
vhost-user-blk: support inter-host inflight migration
Clément Mathieu--Drif (7):
intel_iommu: Add an IOMMU index for pre-translated addresses
intel_iommu: Support memory operations with pre-translated addresses
pcie: Add a function to check if pasid privileged mode is enabled
pci: Block ATS requests when privileged mode is disabled
intel_iommu: Handle insufficient permissions during translation requests
intel_iommu: Minimal handling of privileged ATS request
intel_iommu: Add a CLI option to enable SVM
Daniil Tatianin (1):
virtio/vhost: don't consider non-MAP_SHARED regions public
Dorinda Bassey (1):
virtio-dmabuf: Ensure UUID persistence for hash table insertion
Eugenio Pérez (1):
vhost: accept indirect descriptors in shadow virtqueue
Gavin Shan (5):
acpi/ghes: Automate data block cleanup in acpi_ghes_memory_errors()
acpi/ghes: Abort in acpi_ghes_memory_errors() if necessary
target/arm/kvm: Exit on error from acpi_ghes_memory_errors()
acpi/ghes: Bail early on error from get_ghes_source_offsets()
acpi/ghes: Use error_fatal in acpi_ghes_memory_errors()
Haixu Cui (2):
standard-headers: Update virtio_spi.h from Linux v6.18-rc3
virtio-spi: Add vhost-user-spi device support
Honglei Huang (2):
virtio-gpu: fix error handling in virgl_cmd_resource_create_blob
virtio-gpu: use consistent error checking for virtio_gpu_create_mapping_iov
Igor Mammedov (1):
q35: Fix migration of SMRAM state
Jean-Philippe Brucker (1):
MAINTAINERS: Update VIOT maintainer
Joelle van Dyne (1):
virtio-gpu-virgl: correct parent for blob memory region
Jonathan Cameron (2):
hw/cxl: Check for overflow on santize media as both base and offset 64bit.
hw/cxl: Take into account how many media operations are requested for param check
Kevin Wolf (2):
virtio: Fix crash when sriov-pf is set for non-PCI-Express device
pcie_sriov: Fix PCI_SRIOV_* accesses in pcie_sriov_pf_exit()
Li Chen (1):
virtio-pmem: ignore empty queue notifications
Michael S. Tsirkin (1):
vhost-user: ancilliary -> ancillary
Philippe Mathieu-Daudé (1):
hw/pci-host: Set DEVICE_CATEGORY_BRIDGE once in parent class_init()
Wafer Xie (1):
vdpa: fix vhost-vdpa suspended state not be shared
zhenwei pi (2):
hw/virtio/virtio-crypto: verify asym request size
cryptodev-builtin: Limit the maximum size
MAINTAINERS | 8 +-
backends/cryptodev-builtin.c | 9 +-
docs/interop/vhost-user.rst | 60 +++++---
docs/system/devices/virtio/vhost-user.rst | 3 +
hw/acpi/ghes-stub.c | 6 +-
hw/acpi/ghes.c | 45 +++---
hw/block/vhost-user-blk.c | 27 ++++
hw/cxl/cxl-mailbox-utils.c | 11 +-
hw/display/virtio-dmabuf.c | 6 +-
hw/display/virtio-gpu-virgl.c | 8 +-
hw/display/virtio-gpu.c | 4 +-
hw/i386/intel_iommu.c | 204 ++++++++++++++++++++--------
hw/i386/intel_iommu_internal.h | 14 +-
hw/pci-host/articia.c | 1 -
hw/pci-host/aspeed_pcie.c | 1 -
hw/pci-host/designware.c | 3 -
hw/pci-host/gpex.c | 2 -
hw/pci-host/grackle.c | 1 -
hw/pci-host/gt64120.c | 1 -
hw/pci-host/mv64361.c | 1 -
hw/pci-host/pnv_phb.c | 1 -
hw/pci-host/ppce500.c | 1 -
hw/pci-host/q35.c | 28 ++--
hw/pci-host/raven.c | 1 -
hw/pci-host/remote.c | 1 -
hw/pci-host/sabre.c | 1 -
hw/pci-host/uninorth.c | 4 -
hw/pci-host/xilinx-pcie.c | 2 -
hw/pci/pci.c | 4 +
hw/pci/pci_host.c | 1 +
hw/pci/pcie.c | 21 ++-
hw/pci/pcie_sriov.c | 9 +-
hw/pci/shpc.c | 1 -
hw/virtio/Kconfig | 5 +
hw/virtio/meson.build | 3 +
hw/virtio/vhost-shadow-virtqueue.c | 1 +
hw/virtio/vhost-user-spi-pci.c | 69 ++++++++++
hw/virtio/vhost-user-spi.c | 65 +++++++++
hw/virtio/vhost-user.c | 7 +
hw/virtio/vhost-vdpa.c | 6 +-
hw/virtio/vhost.c | 66 ++++++++-
hw/virtio/virtio-crypto.c | 7 +
hw/virtio/virtio-pci.c | 20 +--
hw/virtio/virtio-pmem.c | 1 -
hw/virtio/virtio.c | 4 +-
include/hw/acpi/ghes.h | 6 +-
include/hw/i386/intel_iommu.h | 1 +
include/hw/pci/pcie.h | 1 +
include/hw/virtio/vhost-user-blk.h | 1 +
include/hw/virtio/vhost-user-spi.h | 25 ++++
include/hw/virtio/vhost-user.h | 2 +
include/hw/virtio/vhost-vdpa.h | 8 +-
include/hw/virtio/vhost.h | 6 +
include/migration/vmstate.h | 10 ++
include/standard-headers/linux/virtio_spi.h | 181 ++++++++++++++++++++++++
target/arm/kvm.c | 10 +-
tests/qtest/q35-test.c | 6 -
57 files changed, 792 insertions(+), 209 deletions(-)
create mode 100644 hw/virtio/vhost-user-spi-pci.c
create mode 100644 hw/virtio/vhost-user-spi.c
create mode 100644 include/hw/virtio/vhost-user-spi.h
create mode 100644 include/standard-headers/linux/virtio_spi.h
^ permalink raw reply [flat|nested] 77+ messages in thread* Re: [PULL v2 00/38] virtio,pci,pc: features, fixes
2026-02-05 12:08 ` [PULL v2 00/38] " Michael S. Tsirkin
@ 2026-02-05 16:02 ` Peter Maydell
0 siblings, 0 replies; 77+ messages in thread
From: Peter Maydell @ 2026-02-05 16:02 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: qemu-devel
On Thu, 5 Feb 2026 at 12:08, Michael S. Tsirkin <mst@redhat.com> wrote:
>
> Dropped most cxl patches for now.
> Dropped WADT due to author's request.
>
> The following changes since commit b377abc220fc53e9cab2aac3c73fc20be6d85eea:
>
> Merge tag 'hw-misc-20260202' of https://github.com/philmd/qemu into staging (2026-02-03 07:52:04 +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 25465c0e1fd74d2118dfec03912f2595eeb497d7:
>
> hw/cxl: Take into account how many media operations are requested for param check (2026-02-05 05:06:46 -0500)
>
> ----------------------------------------------------------------
> virtio,pci,pc: features, fixes
>
> intel_iommu:
> SVM support
> vhost:
> support for indirect descriptors in shadow virtqueue
> vhost-user:
> vhost-user-spi support
> vhost-user-blk inflight migration support
> vhost-user-blk inflight migration support
>
> misc fixes in pci, vhost, virtio, acpi, cxl
> cleanups in acpi/ghes
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>
> ----------------------------------------------------------------
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/11.0
for any user-visible changes.
-- PMM
^ permalink raw reply [flat|nested] 77+ messages in thread