>-----Original Message-----
>From: Jonathan Cameron <jonathan.came...@huawei.com>
>Sent: 20 June 2025 15:04
>To: Shiju Jose <shiju.j...@huawei.com>
>Cc: qemu-devel@nongnu.org; linux-...@vger.kernel.org; tanxiaofei
><tanxiao...@huawei.com>; Zengtao (B) <prime.z...@hisilicon.com>; Linuxarm
><linux...@huawei.com>
>Subject: Re: [PATCH v2 1/7] hw/cxl/events: Update for rev3.2 common event
>record format
>
>On Thu, 19 Jun 2025 16:16:13 +0100
><shiju.j...@huawei.com> wrote:
>
>> From: Shiju Jose <shiju.j...@huawei.com>
>>
>> CXL spec 3.2 section 8.2.9.2.1 Table 8-55, Common Event Record format
>> has updated with Maintenance Operation Subclass, LD ID and ID of the
>> device head information.
>Hi Shiju,
>
>Wrap a little longer - this is sub 70 and should aim for about 75 for commit
>descriptions.
>
>>
>> Add updates for the above spec changes in the related CXL events
>> reporting and QMP command to inject CXL events.
>
>Main comment in here is we need to keep these new parameters as optional as
>we shouldn't go adding required stuff to qapi and perhaps more importantly
>they are actually optional for most events.
>

Hi Jonathan,

Thanks for the feedback. 
I will change these parameters as optional in qapi  as you suggested. 

Thanks,
Shiju

>Jonathan
>
>>
>> Signed-off-by: Shiju Jose <shiju.j...@huawei.com>
>
>> diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index
>> b5482f58a3..0787a9bfca 100644
>> --- a/hw/mem/cxl_type3.c
>> +++ b/hw/mem/cxl_type3.c
>> @@ -1780,12 +1780,18 @@ 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,
>> +                             uint8_t maint_class, uint8_t maint_subclass,
>> +                             uint16_t ld_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);
>> +    hdr->maint_op_class = maint_class;
>> +    hdr->maint_op_subclass = maint_subclass;
>> +    hdr->ld_id = ld_id;
>2 bytes so
>
>       stw_le_p(&hdr->ld_id, ld_id);
>
>> +    hdr->head_id = head_id;
>>  }
>>
>>  static const QemuUUID gen_media_uuid = { @@ -1825,7 +1831,9 @@ 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, uint8_t class,
>> +                                        uint8_t subclass, uint16_t ld_id,
>> +                                        uint8_t head_id, uint64_t
>> + dpa,
>>                                          uint8_t descriptor, uint8_t type,
>>                                          uint8_t transaction_type,
>>                                          bool has_channel, uint8_t
>> channel, @@ -1863,7 +1871,8 @@ 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),
>> +                            class, subclass, ld_id, head_id);
>>
>>      stq_le_p(&gem.phys_addr, dpa);
>>      gem.descriptor = descriptor;
>> @@ -1907,7 +1916,9 @@ 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,
>> +                               uint8_t class, uint8_t subclass,
>> +                               uint16_t ld_id, uint8_t head_id,
>>                                 uint64_t dpa, uint8_t descriptor,
>>                                 uint8_t type, uint8_t transaction_type,
>>                                 bool has_channel, uint8_t channel, @@
>> -1950,7 +1961,8 @@ 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),
>> +                            class, subclass, ld_id, head_id);
>>      stq_le_p(&dram.phys_addr, dpa);
>>      dram.descriptor = descriptor;
>>      dram.type = type;
>> @@ -2010,7 +2022,9 @@ 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, uint8_t class,
>> +                                        uint8_t subclass, uint16_t ld_id,
>> +                                        uint8_t head_id, uint8_t
>> + type,
>>                                          uint8_t health_status,
>>                                          uint8_t media_status,
>>                                          uint8_t additional_status, @@
>> -2049,7 +2063,8 @@ 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),
>> +                            class, subclass, ld_id, head_id);
>>
>>      module.type = type;
>>      module.health_status = health_status; @@ -2284,7 +2299,8 @@
>> static void qmp_cxl_process_dynamic_capacity_prescriptive(const char *path,
>>       * Event Log.
>>       */
>>      cxl_assign_event_header(hdr, &dynamic_capacity_uuid, flags, 
>> sizeof(dCap),
>> -                            cxl_device_get_timestamp(&dcd->cxl_dstate));
>> +                            cxl_device_get_timestamp(&dcd->cxl_dstate),
>> +                            0, 0, 0, 0);
>As below - we'll need to pass in the validity flags as well for subclass, 
>ld-id and
>head-id  as we don't really want to do that bit of computing 'flags' at each 
>caller.
>
>>
>>      dCap.type = type;
>>      /* FIXME: for now, validity flag is cleared */ diff --git
>> a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c index
>> c1a5e4a7c1..263d8b4609 100644
>> --- a/hw/mem/cxl_type3_stubs.c
>> +++ b/hw/mem/cxl_type3_stubs.c
>> @@ -14,7 +14,9 @@
>>  #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, uint8_t class,
>> +                                        uint8_t subclass, uint16_t ld_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 +25,9 @@ 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,
>> +                               uint8_t class, uint8_t subclass,
>> +                               uint16_t ld_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 +42,9 @@ 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, uint8_t class,
>> +                                        uint8_t subclass, uint16_t ld_id,
>> +                                        uint8_t head_id, uint8_t
>> + type,
>>                                          uint8_t health_status,
>>                                          uint8_t media_status,
>>                                          uint8_t additional_status,
>With suggestion below, this will gain bool has_xxx parameters like
>qmp_cxl_inject_general_media already has.
>
>> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
>> index 831fdefbac..fc6ec82670 100644
>> --- a/include/hw/cxl/cxl_device.h
>> +++ b/include/hw/cxl/cxl_device.h
>> @@ -827,7 +827,9 @@ 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,
>> +                             uint8_t maint_class, uint8_t maint_subclass,
>> +                             uint16_t ld_id, uint8_t head_id);
>
>I think we need to add bools for the presence of maint_subclass, ld_id and
>head_id or we have to modify flags at each caller which is rather ugly.
>It's fine to just fill maint_class in with 0 if not set though as that has no 
>valid bit.
>
>>  bool cxl_extents_overlaps_dpa_range(CXLDCExtentList *list,
>>                                      uint64_t dpa, uint64_t len);
>> bool cxl_extent_groups_overlaps_dpa_range(CXLDCExtentGroupList *list,
>> 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)
>As below - here we have the 3 valid bits.
>
>>  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 8f2e9237b1..c38585d3c8 100644
>> --- a/qapi/cxl.json
>> +++ b/qapi/cxl.json
>> @@ -42,6 +42,18 @@
>>  # @flags: Event Record Flags.  See CXL r3.0 Table 8-42 Common Event
>>  #     Record Format, Event Record Flags for subfield definitions.
>>  #
>> +# @class: Maintenance operation class the device requests to initiate.
>> +#     See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>> +# @subclass: Maintenance operation subclass the device requests to
>> +#     initiate. See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>> +# @ld-id: LD ID of LD from where the event originated.
>> +#     See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>> +# @head-id: ID of the device head from where the event originated.
>> +#     See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>>  # @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.
>> @@ -73,7 +85,9 @@
>>  # Since: 8.1
>>  ##
>>  { 'command': 'cxl-inject-general-media-event',
>> -  'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint8',
>> +  'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint32',
>> +        'class':'uint8', 'subclass':'uint8',
>> +        'ld-id':'uint16', 'head-id':'uint8',
>
>This is a bit of a problem as we should maintain backwards compatibility.
>
>ld-id, head-id etc are optional anyway so should be "*ld-id" and we should then
>check has_ld_id and set the valid bits appropriately.
>
>For class and subclass we should make them optional in this interface and 
>follow
>the guidance to set them to 0 if they aren't explicitly set.
>Actually on closer inspection subclass is also optional and has a valid flag 
>so the
>only one we are making optional in this interface that isn't in the spec is 
>class.
>
>Also good to use fuller name to make it clear these are about maintenance
>classes.  Maybe maint-op-class and maint-op-subclass
>
>Similar comments apply to the other cases.
>
>
>>              'dpa': 'uint64', 'descriptor': 'uint8',
>>              'type': 'uint8', 'transaction-type': 'uint8',
>>              '*channel': 'uint8', '*rank': 'uint8', @@ -93,6 +107,18
>> @@  # @flags: Event Record Flags.  See CXL r3.0 Table 8-42 Common
>> Event
>>  #     Record Format, Event Record Flags for subfield definitions.
>>  #
>> +# @class: Maintenance operation class the device requests to initiate.
>> +#     See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>> +# @subclass: Maintenance operation subclass the device requests to
>> +#     initiate. See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>> +# @ld-id: LD ID of LD from where the event originated.
>> +#     See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>> +# @head-id: ID of the device head from where the event originated.
>> +#     See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>>  # @dpa: Device Physical Address (relative to @path device).  Note
>>  #     lower bits include some flags.  See CXL r3.0 Table 8-44 DRAM
>>  #     Event Record, Physical Address.
>> @@ -132,7 +158,9 @@
>>  # Since: 8.1
>>  ##
>>  { 'command': 'cxl-inject-dram-event',
>> -  'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint8',
>> +  'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags': 'uint32',
>> +        'class':'uint8', 'subclass':'uint8',
>> +        'ld-id':'uint16', 'head-id':'uint8',
>
>>              'dpa': 'uint64', 'descriptor': 'uint8',
>>              'type': 'uint8', 'transaction-type': 'uint8',
>>              '*channel': 'uint8', '*rank': 'uint8', '*nibble-mask':
>> 'uint32', @@ -154,6 +182,18 @@  # @flags: Event Record Flags.  See CXL
>> r3.0 Table 8-42 Common Event
>>  #     Record Format, Event Record Flags for subfield definitions.
>>  #
>> +# @class: Maintenance operation class the device requests to initiate.
>> +#     See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>> +# @subclass: Maintenance operation subclass the device requests to
>> +#     initiate. See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>> +# @ld-id: LD ID of LD from where the event originated.
>> +#     See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>> +# @head-id: ID of the device head from where the event originated.
>> +#     See CXL r3.2 Table 8-55 Common Event Record Format.
>> +#
>>  # @type: Device Event Type.  See CXL r3.0 Table 8-45 Memory Module
>>  #     Event Record for bit definitions for bit definiions.
>>  #
>> @@ -184,7 +224,9 @@
>>  # Since: 8.1
>>  ##
>>  { 'command': 'cxl-inject-memory-module-event',
>> -  'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags' : 'uint8',
>> +  'data': { 'path': 'str', 'log': 'CxlEventLog', 'flags' : 'uint32',
>> +        'class':'uint8', 'subclass':'uint8',
>> +        'ld-id':'uint16', 'head-id':'uint8',
>>              'type': 'uint8', 'health-status': 'uint8',
>>              'media-status': 'uint8', 'additional-status': 'uint8',
>>              'life-used': 'uint8', 'temperature' : 'int16',


Reply via email to