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.
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
qapi/cxl.json | 20 ++++++++---
include/hw/cxl/cxl_device.h | 7 +++-
include/hw/cxl/cxl_events.h | 15 ++++++--
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 +++++++++++--
7 files changed, 121 insertions(+), 21 deletions(-)
diff --git a/qapi/cxl.json b/qapi/cxl.json
index d5b86159f1..b3c2ac9575 100644
--- a/qapi/cxl.json
+++ b/qapi/cxl.json
@@ -33,20 +33,32 @@
##
# @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: 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:
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 165355baf9..e461a824b6 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -723,7 +723,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 758b075a64..4d9cfdb621 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/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 6cfdd98168..e9528da70c 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -3458,7 +3458,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 6eb20137a0..371bd4dc6a 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -1592,12 +1592,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 = {
@@ -1637,7 +1664,13 @@ static int ct3d_qmp_cxl_event_log_enc(CxlEventLog log)
}
/* 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,
@@ -1675,7 +1708,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;
@@ -1719,7 +1755,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,
@@ -1762,7 +1804,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;
@@ -1822,7 +1867,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,
@@ -1861,7 +1912,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,
--
2.48.1
Jonathan Cameron <Jonathan.Cameron@huawei.com> writes:
> 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.
>
> Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
> qapi/cxl.json | 20 ++++++++---
> include/hw/cxl/cxl_device.h | 7 +++-
> include/hw/cxl/cxl_events.h | 15 ++++++--
> 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 +++++++++++--
> 7 files changed, 121 insertions(+), 21 deletions(-)
>
> diff --git a/qapi/cxl.json b/qapi/cxl.json
> index d5b86159f1..b3c2ac9575 100644
> --- a/qapi/cxl.json
> +++ b/qapi/cxl.json
> @@ -33,20 +33,32 @@
> ##
> # @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: LD ID of LD from where the event originated.
What's an LD?
> +#
> +# @head-id: ID of the device head from where the event originated.
Are these identifiers taken from the CXL spec?
> +#
> # 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:
[...]
On Mon, 12 Jan 2026 13:16:05 +0100
Markus Armbruster <armbru@redhat.com> wrote:
> Jonathan Cameron <Jonathan.Cameron@huawei.com> writes:
>
> > 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.
> >
> > Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Hi Markus,
Thanks for taking a look!
> > ---
> > qapi/cxl.json | 20 ++++++++---
> > include/hw/cxl/cxl_device.h | 7 +++-
> > include/hw/cxl/cxl_events.h | 15 ++++++--
> > 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 +++++++++++--
> > 7 files changed, 121 insertions(+), 21 deletions(-)
> >
> > diff --git a/qapi/cxl.json b/qapi/cxl.json
> > index d5b86159f1..b3c2ac9575 100644
> > --- a/qapi/cxl.json
> > +++ b/qapi/cxl.json
> > @@ -33,20 +33,32 @@
> > ##
> > # @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: LD ID of LD from where the event originated.
Logical Device. I'll spell it out the first time. From the glossary:
"LD: Logical Device. Entity that represents a CXL Endpoint that is bound to
a VCS. An SLD contains one LD. An MLD contains multiple LDs."
So what does that actually mean? It's a number that identifies the
bit of a device that is presented to a given host at a particular
point in the PCI topology that we are faking from the underlying CXL
one.
I think best I can do is just spell out the acronyms. If people
want more they need to look at the spec :(
Time for a deeper explanation that probably no one ever wanted :)
From a physical topology point of view think of something like:
vPPDs are virtual downstream ports that assign an LD ID.
HOST 0 HOST 1 Host 3
| | |
RP RP RP
| | |
| | |
__|_________________|______ |
| | SWITCH | | |
| _|_____ _____|_ | |
|| | | | | |
|| | | | | |
|vPPD0 vPPD1 VPPD2 VPPD3 | |
|| | | | | |
||_____________| | | |
| | | | |
|___________DSP0________DSP1| |
| | |
| Some other dev |
Traffic tagged |
with an LD_ID associated with |
a given vPPD (so 2 tags here) |
| |
________________|__________________________|______
| (CXL Device) HEAD0 HEAD1 |
| Now splits up based Only one LD|
| on LD_ID |
|__________________________________________________|
Hosts see:
Used letters for down stream port numbers to avoid
any explicit mapping to the physical ports above.
HOST 0 Host 1 Host3
| | |
RP RP RP
| | |
________|_________ _________|_________ |
| | | | | | |
| ____|____ | | ______|______ | |
| | | | | | | | |
|__DSPA______DSPB__| |__DSPA________DSPB_| |
| | | | |
___|______ Nothing _____|_____ Other dev ___|______
|CXL Type3 | |CXL Type3 | |CXL Type3 |
| (H0, LD0)| | (H0, LD1)| | (H1, LD0)|
|__________| |__________| |__________|
These IDs should only be reported for events that are isolated
(as appropriate) to a head and/or LD and as you can see the hosts
don't actually know these IDs even exist hence there is no need to
report them via in band path. If they don't take the values
that reflect the LD we are actually talking to, then we are
reporting someone else's error! Via out of band / switch CCI we
see the top diagram where we definitely need LD_ID and HEAD_ID
to make any sense of errors, particularly as the memory addresses
in the records are specific to Head/LD pair.
The recommendation of the spec is don't set them for simple reporting
over inband mailboxes. Now you might think we don't have out of band
support upstream yet (my staging CXL tree does have both MCTP over
I2C and USB) but we do have the switch CCI and that can tunnel to
out of band interfaces (technically it's over PCI Vendor defined
messages but in practice it ends up the same from a 'what can I talk
to' point of view as something truely out of band like an I2C bus.
We don't actually have event queues on those yet though... When
we do we'll want this command to queue events there as well as on
for inband path.
So we are adding them now for 2 reasons.
1) The spec allows it even for boring inband event reporting
(recommendation only to not do so) so we need to check the kernel stack
reports correctly.
2) We will want to add event queues on the out of band interfaces and
for those we'll need these IDs.
>
> What's an LD?
>
> > +#
> > +# @head-id: ID of the device head from where the event originated.
>
> Are these identifiers taken from the CXL spec?
Yes. Though feels odd to reference the glossary for the definitions.
>
> > +#
> > # 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:
>
> [...]
>
>
Jonathan Cameron <jonathan.cameron@huawei.com> writes:
> On Mon, 12 Jan 2026 13:16:05 +0100
> Markus Armbruster <armbru@redhat.com> wrote:
>
>> Jonathan Cameron <Jonathan.Cameron@huawei.com> writes:
>>
>> > 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.
>> >
>> > Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
>> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
>
> Hi Markus,
> Thanks for taking a look!
You're welcome!
>> > ---
>> > qapi/cxl.json | 20 ++++++++---
>> > include/hw/cxl/cxl_device.h | 7 +++-
>> > include/hw/cxl/cxl_events.h | 15 ++++++--
>> > 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 +++++++++++--
>> > 7 files changed, 121 insertions(+), 21 deletions(-)
>> >
>> > diff --git a/qapi/cxl.json b/qapi/cxl.json
>> > index d5b86159f1..b3c2ac9575 100644
>> > --- a/qapi/cxl.json
>> > +++ b/qapi/cxl.json
>> > @@ -33,20 +33,32 @@
>> > ##
>> > # @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: LD ID of LD from where the event originated.
>>
>> What's an LD?
>
> Logical Device. I'll spell it out the first time.
Yes, please.
> From the glossary:
> "LD: Logical Device. Entity that represents a CXL Endpoint that is bound to
> a VCS. An SLD contains one LD. An MLD contains multiple LDs."
A line of acronyms marching ponderously across the page... made me laugh
:)
> So what does that actually mean? It's a number that identifies the
> bit of a device that is presented to a given host at a particular
> point in the PCI topology that we are faking from the underlying CXL
> one.
>
> I think best I can do is just spell out the acronyms. If people
> want more they need to look at the spec :(
Fair!
> Time for a deeper explanation that probably no one ever wanted :)
>
> From a physical topology point of view think of something like:
>
> vPPDs are virtual downstream ports that assign an LD ID.
>
> HOST 0 HOST 1 Host 3
> | | |
> RP RP RP
> | | |
> | | |
> __|_________________|______ |
> | | SWITCH | | |
> | _|_____ _____|_ | |
> || | | | | |
> || | | | | |
> |vPPD0 vPPD1 VPPD2 VPPD3 | |
> || | | | | |
> ||_____________| | | |
> | | | | |
> |___________DSP0________DSP1| |
> | | |
> | Some other dev |
> Traffic tagged |
> with an LD_ID associated with |
> a given vPPD (so 2 tags here) |
> | |
> ________________|__________________________|______
> | (CXL Device) HEAD0 HEAD1 |
> | Now splits up based Only one LD|
> | on LD_ID |
> |__________________________________________________|
>
>
> Hosts see:
> Used letters for down stream port numbers to avoid
> any explicit mapping to the physical ports above.
>
>
> HOST 0 Host 1 Host3
> | | |
> RP RP RP
> | | |
> ________|_________ _________|_________ |
> | | | | | | |
> | ____|____ | | ______|______ | |
> | | | | | | | | |
> |__DSPA______DSPB__| |__DSPA________DSPB_| |
> | | | | |
> ___|______ Nothing _____|_____ Other dev ___|______
> |CXL Type3 | |CXL Type3 | |CXL Type3 |
> | (H0, LD0)| | (H0, LD1)| | (H1, LD0)|
> |__________| |__________| |__________|
>
> These IDs should only be reported for events that are isolated
> (as appropriate) to a head and/or LD and as you can see the hosts
> don't actually know these IDs even exist hence there is no need to
> report them via in band path. If they don't take the values
> that reflect the LD we are actually talking to, then we are
> reporting someone else's error! Via out of band / switch CCI we
> see the top diagram where we definitely need LD_ID and HEAD_ID
> to make any sense of errors, particularly as the memory addresses
> in the records are specific to Head/LD pair.
>
> The recommendation of the spec is don't set them for simple reporting
> over inband mailboxes. Now you might think we don't have out of band
> support upstream yet (my staging CXL tree does have both MCTP over
> I2C and USB) but we do have the switch CCI and that can tunnel to
> out of band interfaces (technically it's over PCI Vendor defined
> messages but in practice it ends up the same from a 'what can I talk
> to' point of view as something truely out of band like an I2C bus.
> We don't actually have event queues on those yet though... When
> we do we'll want this command to queue events there as well as on
> for inband path.
Truly more than I ever wanted ;)
> So we are adding them now for 2 reasons.
> 1) The spec allows it even for boring inband event reporting
> (recommendation only to not do so) so we need to check the kernel stack
> reports correctly.
> 2) We will want to add event queues on the out of band interfaces and
> for those we'll need these IDs.
Makes sense. Thanks!
>> > +#
>> > +# @head-id: ID of the device head from where the event originated.
>>
>> Are these identifiers taken from the CXL spec?
> Yes. Though feels odd to reference the glossary for the definitions.
Since they are from the CXL spec, I don't need to think about names that
are more in line with established QAPI naming conventions. That's why I
asked. We're good there.
>> > +#
>> > # 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:
>>
>> [...]
© 2016 - 2026 Red Hat, Inc.