On Mon, Jan 19, 2026 at 3:16 AM Jonathan Cameron
<[email protected]> wrote:
>
> From: Shiju Jose <[email protected]>
>
> 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 <[email protected]>
> Signed-off-by: Jonathan Cameron <[email protected]>
> ---
> v3: Expand the LD acronym (Markus)
> ---
>  qapi/cxl.json               | 21 ++++++++---
>  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, 122 insertions(+), 21 deletions(-)
>
> diff --git a/qapi/cxl.json b/qapi/cxl.json
> index 55a088586e53..82001c0591d8 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:
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index 165355baf9da..e461a824b692 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 758b075a64b9..4d9cfdb621ea 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 7583dd9162f6..5356dfb5b300 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 6cfdd98168f9..e9528da70cc4 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 6eb20137a04f..371bd4dc6ab2 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 c1a5e4a7c193..91b1478114d9 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
>
>
No comments.

Reviewed-by: Ravi Jonnalagadda <[email protected]>

Reply via email to