@samitouri / QOSamiQemu / commits / e5b7d31243

hw/cxl/events: Update for rev3.2 common event record format

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> Acked-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Ravi Jonnalagadda <ravis.opensrc@gmail.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: <20260205112350.60681-3-Jonathan.Cameron@huawei.com>

Shiju Jose committed Feb 5, 2026 at 11:23 UTC e5b7d31243dcd075f7f670bb105ac0f742176915
7 files changed +122 -21
hw/cxl/cxl-events.c
+2 -1
@@ -271,7 +271,8 @@ void cxl_create_dc_event_records_for_extents(CXLType3Dev *ct3d,
271 &dynamic_capacity_uuid,
272 (1 << CXL_EVENT_TYPE_INFO),
273 sizeof(event_rec),
274 - cxl_device_get_timestamp(&ct3d->cxl_dstate));
274 + cxl_device_get_timestamp(&ct3d->cxl_dstate),
275 + 0, 0, 0, 0, 0, 0, 0, 0);
276 event_rec.type = type;
277 event_rec.validity_flags = 1;
278 event_rec.host_id = 0;
hw/cxl/cxl-mailbox-utils.c
+2 -1
@@ -3463,7 +3463,8 @@ static CXLRetCode cmd_fm_set_dc_region_config(const struct cxl_cmd *cmd,
3463 &dynamic_capacity_uuid,
3464 (1 << CXL_EVENT_TYPE_INFO),
3465 sizeof(dcEvent),
3466 - cxl_device_get_timestamp(&ct3d->cxl_dstate));
3466 + cxl_device_get_timestamp(&ct3d->cxl_dstate),
3467 + 0, 0, 0, 0, 0, 0, 0, 0);
3468 dcEvent.type = DC_EVENT_REGION_CONFIG_UPDATED;
3469 dcEvent.validity_flags = 1;
3470 dcEvent.host_id = 0;
hw/mem/cxl_type3.c
+62 -8
@@ -1592,12 +1592,39 @@ void qmp_cxl_inject_correctable_error(const char *path, CxlCorErrorType type,
1592
1593 void cxl_assign_event_header(CXLEventRecordHdr *hdr,
1594 const QemuUUID *uuid, uint32_t flags,
1595 - uint8_t length, uint64_t timestamp)
1595 + uint8_t length, uint64_t timestamp,
1596 + bool has_maint_op_class, uint8_t maint_op_class,
1597 + bool has_maint_op_subclass,
1598 + uint8_t maint_op_subclass,
1599 + bool has_ld_id, uint16_t ld_id,
1600 + bool has_head_id, uint8_t head_id)
1601 {
1597 - st24_le_p(&hdr->flags, flags);
1602 hdr->length = length;
1603 memcpy(&hdr->id, uuid, sizeof(hdr->id));
1604 stq_le_p(&hdr->timestamp, timestamp);
1605 +
1606 + if (has_maint_op_class) {
1607 + hdr->maint_op_class = maint_op_class;
1608 + } else {
1609 + hdr->maint_op_class = 0;
1610 + }
1611 +
1612 + if (has_maint_op_subclass) {
1613 + flags |= CXL_EVENT_REC_FLAGS_MAINT_OP_SUBCLASS_VALID;
1614 + hdr->maint_op_subclass = maint_op_subclass;
1615 + }
1616 +
1617 + if (has_ld_id) {
1618 + flags |= CXL_EVENT_REC_FLAGS_LD_ID_VALID;
1619 + stw_le_p(&hdr->ld_id, ld_id);
1620 + }
1621 +
1622 + if (has_head_id) {
1623 + flags |= CXL_EVENT_REC_FLAGS_HEAD_ID_VALID;
1624 + hdr->head_id = head_id;
1625 + }
1626 +
1627 + st24_le_p(&hdr->flags, flags);
1628 }
1629
1630 static const QemuUUID gen_media_uuid = {
@@ -1637,7 +1664,13 @@ static int ct3d_qmp_cxl_event_log_enc(CxlEventLog log)
1664 }
1665 /* Component ID is device specific. Define this as a string. */
1666 void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
1640 - uint8_t flags, uint64_t dpa,
1667 + uint32_t flags, bool has_maint_op_class,
1668 + uint8_t maint_op_class,
1669 + bool has_maint_op_subclass,
1670 + uint8_t maint_op_subclass,
1671 + bool has_ld_id, uint16_t ld_id,
1672 + bool has_head_id, uint8_t head_id,
1673 + uint64_t dpa,
1674 uint8_t descriptor, uint8_t type,
1675 uint8_t transaction_type,
1676 bool has_channel, uint8_t channel,
@@ -1675,7 +1708,10 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
1708
1709 memset(&gem, 0, sizeof(gem));
1710 cxl_assign_event_header(hdr, &gen_media_uuid, flags, sizeof(gem),
1678 - cxl_device_get_timestamp(&ct3d->cxl_dstate));
1711 + cxl_device_get_timestamp(&ct3d->cxl_dstate),
1712 + has_maint_op_class, maint_op_class,
1713 + has_maint_op_subclass, maint_op_subclass,
1714 + has_ld_id, ld_id, has_head_id, head_id);
1715
1716 stq_le_p(&gem.phys_addr, dpa);
1717 gem.descriptor = descriptor;
@@ -1719,7 +1755,13 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
1755 #define CXL_DRAM_VALID_COLUMN BIT(6)
1756 #define CXL_DRAM_VALID_CORRECTION_MASK BIT(7)
1757
1722 -void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
1758 +void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
1759 + uint32_t flags,
1760 + bool has_maint_op_class, uint8_t maint_op_class,
1761 + bool has_maint_op_subclass,
1762 + uint8_t maint_op_subclass,
1763 + bool has_ld_id, uint16_t ld_id,
1764 + bool has_head_id, uint8_t head_id,
1765 uint64_t dpa, uint8_t descriptor,
1766 uint8_t type, uint8_t transaction_type,
1767 bool has_channel, uint8_t channel,
@@ -1762,7 +1804,10 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
1804
1805 memset(&dram, 0, sizeof(dram));
1806 cxl_assign_event_header(hdr, &dram_uuid, flags, sizeof(dram),
1765 - cxl_device_get_timestamp(&ct3d->cxl_dstate));
1807 + cxl_device_get_timestamp(&ct3d->cxl_dstate),
1808 + has_maint_op_class, maint_op_class,
1809 + has_maint_op_subclass, maint_op_subclass,
1810 + has_ld_id, ld_id, has_head_id, head_id);
1811 stq_le_p(&dram.phys_addr, dpa);
1812 dram.descriptor = descriptor;
1813 dram.type = type;
@@ -1822,7 +1867,13 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
1867 }
1868
1869 void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
1825 - uint8_t flags, uint8_t type,
1870 + uint32_t flags, bool has_maint_op_class,
1871 + uint8_t maint_op_class,
1872 + bool has_maint_op_subclass,
1873 + uint8_t maint_op_subclass,
1874 + bool has_ld_id, uint16_t ld_id,
1875 + bool has_head_id, uint8_t head_id,
1876 + uint8_t type,
1877 uint8_t health_status,
1878 uint8_t media_status,
1879 uint8_t additional_status,
@@ -1861,7 +1912,10 @@ void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
1912
1913 memset(&module, 0, sizeof(module));
1914 cxl_assign_event_header(hdr, &memory_module_uuid, flags, sizeof(module),
1864 - cxl_device_get_timestamp(&ct3d->cxl_dstate));
1915 + cxl_device_get_timestamp(&ct3d->cxl_dstate),
1916 + has_maint_op_class, maint_op_class,
1917 + has_maint_op_subclass, maint_op_subclass,
1918 + has_ld_id, ld_id, has_head_id, head_id);
1919
1920 module.type = type;
1921 module.health_status = health_status;
hw/mem/cxl_type3_stubs.c
+21 -3
@@ -14,7 +14,13 @@
14 #include "qapi/qapi-commands-cxl.h"
15
16 void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
17 - uint8_t flags, uint64_t dpa,
17 + uint32_t flags, bool has_maint_op_class,
18 + uint8_t maint_op_class,
19 + bool has_maint_op_subclass,
20 + uint8_t maint_op_subclass,
21 + bool has_ld_id, uint16_t ld_id,
22 + bool has_head_id, uint8_t head_id,
23 + uint64_t dpa,
24 uint8_t descriptor, uint8_t type,
25 uint8_t transaction_type,
26 bool has_channel, uint8_t channel,
@@ -23,7 +29,13 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
29 const char *component_id,
30 Error **errp) {}
31
26 -void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
32 +void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
33 + uint32_t flags,
34 + bool has_maint_op_class, uint8_t maint_op_class,
35 + bool has_maint_op_subclass,
36 + uint8_t maint_op_subclass,
37 + bool has_ld_id, uint16_t ld_id,
38 + bool has_head_id, uint8_t head_id,
39 uint64_t dpa, uint8_t descriptor,
40 uint8_t type, uint8_t transaction_type,
41 bool has_channel, uint8_t channel,
@@ -38,7 +50,13 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
50 Error **errp) {}
51
52 void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
41 - uint8_t flags, uint8_t type,
53 + uint32_t flags, bool has_maint_op_class,
54 + uint8_t maint_op_class,
55 + bool has_maint_op_subclass,
56 + uint8_t maint_op_subclass,
57 + bool has_ld_id, uint16_t ld_id,
58 + bool has_head_id, uint8_t head_id,
59 + uint8_t type,
60 uint8_t health_status,
61 uint8_t media_status,
62 uint8_t additional_status,
include/hw/cxl/cxl_device.h
+6 -1
@@ -723,7 +723,12 @@ bool ct3_test_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
723 uint64_t len);
724 void cxl_assign_event_header(CXLEventRecordHdr *hdr,
725 const QemuUUID *uuid, uint32_t flags,
726 - uint8_t length, uint64_t timestamp);
726 + uint8_t length, uint64_t timestamp,
727 + bool has_maint_op_class, uint8_t maint_op_class,
728 + bool has_maint_op_subclass,
729 + uint8_t maint_op_subclass,
730 + bool has_ld_id, uint16_t ld_id,
731 + bool has_head_id, uint8_t head_id);
732 void cxl_create_dc_event_records_for_extents(CXLType3Dev *ct3d,
733 CXLDCEventType type,
734 CXLDCExtentRaw extents[],
include/hw/cxl/cxl_events.h
+12 -3
@@ -29,9 +29,15 @@ typedef enum CXLEventLogType {
29
30 /*
31 * Common Event Record Format
32 - * CXL r3.1 section 8.2.9.2.1: Event Records; Table 8-43
32 + * CXL r3.2 section 8.2.10.2.1: Event Records; Table 8-55
33 */
34 -#define CXL_EVENT_REC_HDR_RES_LEN 0xf
34 +#define CXL_EVENT_REC_FLAGS_PERMANENT_COND BIT(2)
35 +#define CXL_EVENT_REC_FLAGS_MAINT_NEEDED BIT(3)
36 +#define CXL_EVENT_REC_FLAGS_PERF_DEGRADED BIT(4)
37 +#define CXL_EVENT_REC_FLAGS_HW_REPLACEMENT_NEEDED BIT(5)
38 +#define CXL_EVENT_REC_FLAGS_MAINT_OP_SUBCLASS_VALID BIT(6)
39 +#define CXL_EVENT_REC_FLAGS_LD_ID_VALID BIT(7)
40 +#define CXL_EVENT_REC_FLAGS_HEAD_ID_VALID BIT(8)
41 typedef struct CXLEventRecordHdr {
42 QemuUUID id;
43 uint8_t length;
@@ -40,7 +46,10 @@ typedef struct CXLEventRecordHdr {
46 uint16_t related_handle;
47 uint64_t timestamp;
48 uint8_t maint_op_class;
43 - uint8_t reserved[CXL_EVENT_REC_HDR_RES_LEN];
49 + uint8_t maint_op_subclass;
50 + uint16_t ld_id;
51 + uint8_t head_id;
52 + uint8_t reserved[0xb];
53 } QEMU_PACKED CXLEventRecordHdr;
54
55 #define CXL_EVENT_RECORD_DATA_LENGTH 0x50
qapi/cxl.json
+17 -4
@@ -33,20 +33,33 @@
33 ##
34 # @CXLCommonEventBase:
35 #
36 -# Common event base for a CXL Event (CXL r3.0 8.2.9.2.1
37 -# Table 8-42 Common Event Record Format).
36 +# Common event base for a CXL Event (CXL r3.2 8.2.10.2.1
37 +# Table 8-55 Common Event Record Format).
38 #
39 # @path: CXL type 3 device canonical QOM path
40 #
41 # @log: event log to add the event to
42 #
43 -# @flags: Event Record Flags. See CXL r3.0 Table 8-42 Common Event
43 +# @flags: Event Record Flags. See CXL r3.2 Table 8-55 Common Event
44 # Record Format, Event Record Flags for subfield definitions.
45 #
46 +# @maint-op-class: Maintenance operation class the device requests to
47 +# initiate.
48 +#
49 +# @maint-op-subclass: Maintenance operation subclass the device
50 +# requests to initiate.
51 +#
52 +# @ld-id: Logical Device (LD) ID of LD from where the event
53 +# originated.
54 +#
55 +# @head-id: ID of the device head from where the event originated.
56 +#
57 # Since: 8.1
58 ##
59 { 'struct': 'CXLCommonEventBase',
49 - 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint8' } }
60 + 'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint32',
61 + '*maint-op-class':'uint8', '*maint-op-subclass':'uint8',
62 + '*ld-id':'uint16', '*head-id':'uint8' } }
63
64 ##
65 # @CXLGeneralMediaEvent: