* [RFC PATCH 0/7] Add CPER logging support for CRI
@ 2026-07-02 11:14 Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 1/7] drm/xe: Add error Signature IDs for RAS logging Badal Nilawar
` (6 more replies)
0 siblings, 7 replies; 11+ messages in thread
From: Badal Nilawar @ 2026-07-02 11:14 UTC (permalink / raw)
To: intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
riana.tauro, mallesh.koujalagi, aravind.iddamsetty
This patch series adds CPER (Common Platform Error Record) logging support
for Correctable errors reported by Intel Xe GPUs. CPER logging is done
through trace event.
In subsequent patches will add CPER logging support for Un-correctable errors.
Do not review patch "drm/xe: Add error Signature IDs for RAS logging" as
it is part of https://patchwork.freedesktop.org/series/168333/
Badal Nilawar (6):
drm/xe/xe_ras: Add support to retrieve info queue data for CRI
drm/xe/xe_ras: Refactor get_counter() to return response structure
drm/xe/cper: Add CPER structures and trace event
drm/xe/cper: APIs to prepare and log CPER record
drm/xe/cper: Prepare Intel CPER error info from info queue
drm/xe/cper: Log CPER record for correctable errors
Mallesh Koujalagi (1):
drm/xe: Add error Signature IDs for RAS logging
drivers/gpu/drm/xe/Makefile | 2 +
drivers/gpu/drm/xe/xe_cper.c | 215 ++++++++++++++
drivers/gpu/drm/xe/xe_cper.h | 30 ++
drivers/gpu/drm/xe/xe_cper_types.h | 186 ++++++++++++
drivers/gpu/drm/xe/xe_ras.c | 272 +++++++++++++++++-
drivers/gpu/drm/xe/xe_ras_types.h | 122 +++++++-
drivers/gpu/drm/xe/xe_sig_ids.h | 29 ++
drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h | 2 +
drivers/gpu/drm/xe/xe_trace_cper.c | 9 +
drivers/gpu/drm/xe/xe_trace_cper.h | 65 +++++
10 files changed, 921 insertions(+), 11 deletions(-)
create mode 100644 drivers/gpu/drm/xe/xe_cper.c
create mode 100644 drivers/gpu/drm/xe/xe_cper.h
create mode 100644 drivers/gpu/drm/xe/xe_cper_types.h
create mode 100644 drivers/gpu/drm/xe/xe_sig_ids.h
create mode 100644 drivers/gpu/drm/xe/xe_trace_cper.c
create mode 100644 drivers/gpu/drm/xe/xe_trace_cper.h
--
2.54.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [RFC PATCH 1/7] drm/xe: Add error Signature IDs for RAS logging
2026-07-02 11:14 [RFC PATCH 0/7] Add CPER logging support for CRI Badal Nilawar
@ 2026-07-02 11:14 ` Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 2/7] drm/xe/xe_ras: Add support to retrieve info queue data for CRI Badal Nilawar
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Badal Nilawar @ 2026-07-02 11:14 UTC (permalink / raw)
To: intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
riana.tauro, mallesh.koujalagi, aravind.iddamsetty
From: Mallesh Koujalagi <mallesh.koujalagi@intel.com>
Every GPU fault needs a stable numeric label so monitoring tools can
identify what went wrong without parsing log text. Add xe_sig_ids.h
which defines those labels, called SIG_IDs.
Signed-off-by: Mallesh Koujalagi <mallesh.koujalagi@intel.com>
---
drivers/gpu/drm/xe/xe_sig_ids.h | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 drivers/gpu/drm/xe/xe_sig_ids.h
diff --git a/drivers/gpu/drm/xe/xe_sig_ids.h b/drivers/gpu/drm/xe/xe_sig_ids.h
new file mode 100644
index 000000000000..7badd0d7ad72
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_sig_ids.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#ifndef _XE_SIG_IDS_H_
+#define _XE_SIG_IDS_H_
+
+/*
+ * Driver SIG_IDs
+ */
+#define XE_SIG_PROBE 1 /* FATAL: probe failed */
+#define XE_SIG_WEDGED 2 /* FATAL: device wedged */
+#define XE_SIG_SURVIVABILITY 3 /* FATAL: survivability mode */
+#define XE_SIG_FW 4 /* RECOVERABLE: GuC/HuC/UC/GSC/CSC/PCODE */
+#define XE_SIG_GT_TDR 5 /* RECOVERABLE: engine hang / reset */
+#define XE_SIG_MEM_FAULT 6 /* RECOVERABLE: VM bind, page fault, GTT */
+#define XE_SIG_IO_BUS 7 /* RECOVERABLE: runtime PCIe/IOMMU/MMIO */
+
+/*
+ * HW SIG_IDs
+ */
+#define XE_SIG_HW_DEVICE_MEMORY 8 /* Device memory errors (e.g. ECC) */
+#define XE_SIG_HW_CORE_COMPUTE 9 /* Compute/shader core errors */
+#define XE_SIG_HW_PCIE 10 /* PCIe interface errors */
+#define XE_SIG_HW_FABRIC 11 /* On-package fabric errors */
+#define XE_SIG_HW_SOC_INTERNAL 12 /* SoC-internal errors */
+
+#endif /* _XE_SIG_IDS_H_ */
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 2/7] drm/xe/xe_ras: Add support to retrieve info queue data for CRI
2026-07-02 11:14 [RFC PATCH 0/7] Add CPER logging support for CRI Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 1/7] drm/xe: Add error Signature IDs for RAS logging Badal Nilawar
@ 2026-07-02 11:14 ` Badal Nilawar
2026-07-07 12:29 ` Mallesh, Koujalagi
2026-07-02 11:14 ` [RFC PATCH 3/7] drm/xe/xe_ras: Refactor get_counter() to return response structure Badal Nilawar
` (4 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Badal Nilawar @ 2026-07-02 11:14 UTC (permalink / raw)
To: intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
riana.tauro, mallesh.koujalagi, aravind.iddamsetty
Add support to retrieve info queue data. It can be retrieved when
has_info_queue=1 and RAS_INFO_QUEUE_FLAG_MORE_DATA is set in
response of XE_SYSCTRL_CMD_GET_COUNTER.
Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
Assisted-by: Copilot:claude-sonnet-4.6
---
drivers/gpu/drm/xe/xe_ras.c | 34 ++++++
drivers/gpu/drm/xe/xe_ras_types.h | 112 +++++++++++++++++-
drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h | 2 +
3 files changed, 147 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c
index 44f4e1a3455b..85b0202467f6 100644
--- a/drivers/gpu/drm/xe/xe_ras.c
+++ b/drivers/gpu/drm/xe/xe_ras.c
@@ -270,6 +270,40 @@ int xe_ras_clear_counter(struct xe_device *xe, u8 severity, u8 component)
return 0;
}
+static int get_info_queue_data(struct xe_device *xe,
+ const struct xe_ras_get_info_queue_data_request *req,
+ struct xe_ras_get_info_queue_data_response *out)
+{
+ struct xe_ras_get_info_queue_data_response response = {0};
+ struct xe_sysctrl_mailbox_command command = {0};
+ size_t rlen;
+ int ret;
+
+ xe_sysctrl_create_command(&command, XE_SYSCTRL_GROUP_GFSP,
+ XE_SYSCTRL_CMD_GET_INFO_QUEUE_DATA,
+ (void *)req, sizeof(*req), &response, sizeof(response));
+
+ ret = xe_sysctrl_send_command(&xe->sc, &command, &rlen);
+ if (ret) {
+ xe_err(xe, "sysctrl: failed to get info queue data %d\n", ret);
+ return ret;
+ }
+
+ if (rlen != sizeof(response)) {
+ xe_err(xe, "sysctrl: unexpected get info queue data response length %zu (expected %zu)\n",
+ rlen, sizeof(response));
+ return -EIO;
+ }
+
+ xe_dbg(xe, "[RAS]: info queue data: status=%u chunk_size=%u flags=0x%x\n",
+ response.operation_status,
+ response.queue_response.queue_header.chunk_size,
+ response.queue_response.queue_header.flags);
+
+ *out = response;
+ return 0;
+}
+
/**
* xe_ras_init - Initialize Xe RAS
* @xe: xe device instance
diff --git a/drivers/gpu/drm/xe/xe_ras_types.h b/drivers/gpu/drm/xe/xe_ras_types.h
index 6688e11f57a8..fc496888b3f8 100644
--- a/drivers/gpu/drm/xe/xe_ras_types.h
+++ b/drivers/gpu/drm/xe/xe_ras_types.h
@@ -9,6 +9,12 @@
#include <linux/types.h>
#define XE_RAS_NUM_COUNTERS 16
+#define XE_RAS_INFO_QUEUE_MAX_CHUNK_SIZE 200
+#define XE_RAS_INFO_QUEUE_MAX_TOTAL_SIZE 5120
+#define XE_RAS_INFO_QUEUE_FLAG_AVAILABLE 0x01
+#define XE_RAS_INFO_QUEUE_FLAG_MORE_DATA 0x02
+#define XE_RAS_INFO_QUEUE_FLAG_OVERFLOW 0x04
+#define XE_RAS_INFO_QUEUE_FLAG_COMPRESSED 0x08
/**
* struct xe_ras_error_common - Error fields that are common across all products
@@ -71,7 +77,64 @@ struct xe_ras_threshold_crossed {
} __packed;
/**
- * struct xe_ras_get_counter_request - Request structure for get counter
+ * struct xe_ras_info_queue_header - Metadata for large info queue data transfers
+ *
+ * Provides chunk metadata for commands that support extended info queue
+ * functionality. Used when the total data exceeds a single mailbox response.
+ */
+struct xe_ras_info_queue_header {
+ /** @total_size: Total size of the complete info queue data in bytes */
+ u32 total_size;
+ /** @chunk_offset: Offset of this chunk within the total data in bytes */
+ u32 chunk_offset;
+ /** @chunk_size: Size of the data in this chunk in bytes */
+ u32 chunk_size;
+ /** @sequence_number: Sequence number for this chunk, starts at 0 */
+ u32 sequence_number;
+ /** @flags: Info queue control flags (RAS_INFO_QUEUE_FLAG_*) */
+ u32 flags:8;
+ /** @compression_type: Compression algorithm used; 0 = none */
+ u32 compression_type:4;
+ /** @num_headers: Number of detailed counter headers at start of queue_data */
+ u32 num_headers:5;
+ /** @reserved: Reserved for future use */
+ u32 reserved:15;
+ /** @checksum: CRC32 checksum of this chunk data */
+ u32 checksum;
+} __packed;
+
+/**
+ * struct xe_ras_info_queue_request - Request for a specific chunk of info queue data
+ *
+ * Allows the driver to request continuation of large info queue transfers
+ * by specifying an offset and size within the full data set.
+ */
+struct xe_ras_info_queue_request {
+ /** @requested_offset: Byte offset of the requested data chunk */
+ u32 requested_offset;
+ /** @requested_size: Maximum size of the requested chunk in bytes */
+ u32 requested_size;
+ /** @session_id: Session ID to correlate multi-chunk transfers */
+ struct xe_ras_error_class session_id;
+ /** @reserved: Reserved for future use */
+ u32 reserved;
+} __packed;
+
+/**
+ * struct xe_ras_info_queue_response - Generic response for commands with info queues
+ *
+ * Standard response format for any command that returns an info queue
+ * payload. May be embedded in a command-specific response structure.
+ */
+struct xe_ras_info_queue_response {
+ /** @queue_header: Info queue metadata for this chunk */
+ struct xe_ras_info_queue_header queue_header;
+ /** @queue_data: Info queue data for this chunk */
+ u8 queue_data[XE_RAS_INFO_QUEUE_MAX_CHUNK_SIZE];
+} __packed;
+
+/**
+ * struct xe_ras_get_counter_request - Request for get error counter
*/
struct xe_ras_get_counter_request {
/** @counter: Error counter to be queried */
@@ -121,4 +184,51 @@ struct xe_ras_clear_counter_response {
/** @reserved1: Reserved for future use */
u32 reserved1[3];
} __packed;
+
+/**
+ * struct xe_ras_info_queue_dynamic_counter_hdr - Aggregate counter header entry
+ *
+ * When a session requests aggregate counter data, one header per matching
+ * dynamic counter class is prepended to the queue data. The @counter field
+ * indicates how many subsequent error log entries belong to this class.
+ */
+struct xe_ras_info_queue_dynamic_counter_hdr {
+ /** @error_class: Error class associated with this counter group */
+ struct xe_ras_error_class error_class;
+ /** @counter: Number of error log entries that follow for this class */
+ u32 counter;
+} __packed;
+
+/**
+ * struct xe_ras_error_log - Single error log entry following dynamic counter headers
+ */
+struct xe_ras_error_log {
+ /** @timestamp: Timestamp when the error was recorded */
+ u64 timestamp;
+ /** @error_details: Error-specific details */
+ u32 error_details[16];
+} __packed;
+
+/**
+ * struct xe_ras_get_info_queue_data_request - Request for RAS_CMD_GET_INFO_QUEUE_DATA
+ */
+struct xe_ras_get_info_queue_data_request {
+ /** @queue_request: Info queue request parameters */
+ struct xe_ras_info_queue_request queue_request;
+ /** @source_command: Original command that generated the info queue */
+ u32 source_command;
+ /** @source_context: Context from original command, if applicable */
+ struct xe_ras_error_class source_context;
+} __packed;
+
+/**
+ * struct xe_ras_get_info_queue_data_response - Response for RAS_CMD_GET_INFO_QUEUE_DATA
+ */
+struct xe_ras_get_info_queue_data_response {
+ /** @operation_status: Status of the retrieval operation */
+ u32 operation_status;
+ /** @queue_response: Info queue data chunk */
+ struct xe_ras_info_queue_response queue_response;
+} __packed;
+
#endif
diff --git a/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h b/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h
index 6e3753554510..538d93352655 100644
--- a/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h
+++ b/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h
@@ -25,11 +25,13 @@ enum xe_sysctrl_group {
* @XE_SYSCTRL_CMD_GET_COUNTER: Get error counter value
* @XE_SYSCTRL_CMD_CLEAR_COUNTER: Clear error counter value
* @XE_SYSCTRL_CMD_GET_PENDING_EVENT: Retrieve pending event
+ * @XE_SYSCTRL_CMD_GET_INFO_QUEUE_DATA: Retrieve a chunk of info queue data
*/
enum xe_sysctrl_gfsp_cmd {
XE_SYSCTRL_CMD_GET_COUNTER = 0x03,
XE_SYSCTRL_CMD_CLEAR_COUNTER = 0x04,
XE_SYSCTRL_CMD_GET_PENDING_EVENT = 0x07,
+ XE_SYSCTRL_CMD_GET_INFO_QUEUE_DATA = 0x0D,
};
/**
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 3/7] drm/xe/xe_ras: Refactor get_counter() to return response structure
2026-07-02 11:14 [RFC PATCH 0/7] Add CPER logging support for CRI Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 1/7] drm/xe: Add error Signature IDs for RAS logging Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 2/7] drm/xe/xe_ras: Add support to retrieve info queue data for CRI Badal Nilawar
@ 2026-07-02 11:14 ` Badal Nilawar
2026-07-03 7:41 ` Tauro, Riana
2026-07-07 12:53 ` Mallesh, Koujalagi
2026-07-02 11:14 ` [RFC PATCH 4/7] drm/xe/cper: Add CPER structures and trace event Badal Nilawar
` (3 subsequent siblings)
6 siblings, 2 replies; 11+ messages in thread
From: Badal Nilawar @ 2026-07-02 11:14 UTC (permalink / raw)
To: intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
riana.tauro, mallesh.koujalagi, aravind.iddamsetty
Return the complete response structure from get_counter() instead of
only the counter value. This allows callers to access additional
response fields, such as has_info_queue for CPER record building.
Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
Assisted-by: Copilot:claude-sonnet-4.6
---
drivers/gpu/drm/xe/xe_ras.c | 23 +++++++++++++++--------
drivers/gpu/drm/xe/xe_ras_types.h | 10 ++++++++--
2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c
index 85b0202467f6..e594d4d3a23f 100644
--- a/drivers/gpu/drm/xe/xe_ras.c
+++ b/drivers/gpu/drm/xe/xe_ras.c
@@ -157,12 +157,12 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,
}
}
-static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter, u32 *value)
+static int get_counter(struct xe_device *xe, const struct xe_ras_error_class *counter,
+ struct xe_ras_get_counter_response *out)
{
struct xe_ras_get_counter_response response = {0};
struct xe_ras_get_counter_request request = {0};
struct xe_sysctrl_mailbox_command command = {0};
- struct xe_ras_error_common *common;
size_t rlen;
int ret;
@@ -183,12 +183,11 @@ static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter,
return -EIO;
}
- common = &response.counter.common;
- *value = response.value;
-
- xe_dbg(xe, "[RAS]: get counter %u for %s %s\n", *value, comp_to_str(common->component),
- sev_to_str(common->severity));
+ xe_dbg(xe, "[RAS]: get counter value %u for %s %s\n", response.value,
+ comp_to_str(response.counter.common.component),
+ sev_to_str(response.counter.common.severity));
+ *out = response;
return 0;
}
@@ -207,12 +206,20 @@ static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter,
int xe_ras_get_counter(struct xe_device *xe, u8 severity, u8 component, u32 *value)
{
struct xe_ras_error_class counter = {0};
+ struct xe_ras_get_counter_response response;
+ int ret;
counter.common.severity = drm_to_xe_ras_severity(severity);
counter.common.component = drm_to_xe_ras_component(component);
guard(xe_pm_runtime)(xe);
- return get_counter(xe, &counter, value);
+
+ ret = get_counter(xe, &counter, &response);
+ if (ret)
+ return ret;
+
+ *value = response.counter_value;
+ return 0;
}
/**
diff --git a/drivers/gpu/drm/xe/xe_ras_types.h b/drivers/gpu/drm/xe/xe_ras_types.h
index fc496888b3f8..befdaf297103 100644
--- a/drivers/gpu/drm/xe/xe_ras_types.h
+++ b/drivers/gpu/drm/xe/xe_ras_types.h
@@ -155,8 +155,14 @@ struct xe_ras_get_counter_response {
u64 timestamp;
/** @threshold: Threshold value for the counter */
u32 threshold;
- /** @reserved: Reserved */
- u32 reserved[57];
+ /** @reserved: Reserved for future use */
+ u32 reserved:9;
+ /** @has_info_queue: Set if info queue is available */
+ u32 has_info_queue:1;
+ /** @reserved1: Reserved for future use */
+ u32 reserved1:22;
+ /** @info_queue: Initial info queue data (first chunk) if available */
+ struct xe_ras_info_queue_response info_queue;
} __packed;
/**
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 4/7] drm/xe/cper: Add CPER structures and trace event
2026-07-02 11:14 [RFC PATCH 0/7] Add CPER logging support for CRI Badal Nilawar
` (2 preceding siblings ...)
2026-07-02 11:14 ` [RFC PATCH 3/7] drm/xe/xe_ras: Refactor get_counter() to return response structure Badal Nilawar
@ 2026-07-02 11:14 ` Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 5/7] drm/xe/cper: APIs to prepare and log CPER record Badal Nilawar
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Badal Nilawar @ 2026-07-02 11:14 UTC (permalink / raw)
To: intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
riana.tauro, mallesh.koujalagi, aravind.iddamsetty
Define packed data structures and Intel-specific GUID macros needed
to build Intel GPU CPER (Common Platform Error Record) non-standard
records.
Add xe_error_cper trace event to log the assembled CPER record bytes.
Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
Assisted-by: Copilot:claude-sonnet-4.6
---
drivers/gpu/drm/xe/Makefile | 1 +
drivers/gpu/drm/xe/xe_cper_types.h | 186 +++++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_trace_cper.c | 9 ++
drivers/gpu/drm/xe/xe_trace_cper.h | 65 ++++++++++
4 files changed, 261 insertions(+)
create mode 100644 drivers/gpu/drm/xe/xe_cper_types.h
create mode 100644 drivers/gpu/drm/xe/xe_trace_cper.c
create mode 100644 drivers/gpu/drm/xe/xe_trace_cper.h
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index e5a04253e73b..01e6711cce1c 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -134,6 +134,7 @@ xe-y += xe_bb.o \
xe_tlb_inval_job.o \
xe_trace.o \
xe_trace_bo.o \
+ xe_trace_cper.o \
xe_trace_guc.o \
xe_trace_lrc.o \
xe_ttm_stolen_mgr.o \
diff --git a/drivers/gpu/drm/xe/xe_cper_types.h b/drivers/gpu/drm/xe/xe_cper_types.h
new file mode 100644
index 000000000000..82167ea4eb16
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_cper_types.h
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#ifndef _XE_CPER_TYPES_H_
+#define _XE_CPER_TYPES_H_
+
+#include <linux/cper.h>
+#include <linux/types.h>
+#include <linux/uuid.h>
+
+/* Intel CPER GUID Namespace — RFC 9562 UUIDv5 (SHA-1 name-based)
+ *
+ * All values below are generated deterministically by the shell script
+ * in the [Generation Script] section. Re-run that script to verify.
+ * Do NOT hand-edit the byte values.
+ */
+
+/* Creator IDs */
+#define INTEL_CPER_CREATOR_XEKMD \
+ GUID_INIT(0x9a42070f, 0xdf9d, 0x555e, \
+ 0xba, 0x02, 0x7c, 0xbc, 0x86, 0x3d, 0x37, 0x1c)
+
+#define INTEL_CPER_CREATOR_AMC \
+ GUID_INIT(0x215803da, 0xfc7a, 0x5925, \
+ 0xb7, 0x8b, 0x1f, 0xc1, 0x19, 0x61, 0x58, 0xd1)
+
+/* Notification Types */
+#define INTEL_CPER_NOTIFY_GPU_ERROR \
+ GUID_INIT(0x4ae12aef, 0x8745, 0x5fc7, \
+ 0xb9, 0x96, 0x71, 0xee, 0xbb, 0x51, 0xf2, 0x23)
+
+#define INTEL_CPER_NOTIFY_DRV_ERROR \
+ GUID_INIT(0xcef7e934, 0x51e7, 0x535f, \
+ 0xa6, 0x78, 0x5a, 0x4c, 0xcc, 0xb6, 0x96, 0x09)
+
+/* Section Types */
+#define INTEL_CPER_SECTION_ACCEL_GENERIC \
+ GUID_INIT(0xea9d8f84, 0x4258, 0x5227, \
+ 0x80, 0x28, 0xb9, 0xb1, 0x3e, 0x6d, 0x58, 0xb0)
+
+#pragma pack(push, 1)
+
+/**
+ * struct xe_cper_sec_intel_err_hdr - Intel-specific CPER error section header
+ *
+ * Fixed-size header for the Intel GPU error section of a CPER record.
+ * All multi-byte fields are little-endian; the structure is packed.
+ */
+struct xe_cper_sec_intel_err_hdr {
+ /** @error_class: Error classification (type, component, location, cause) */
+ union {
+ struct {
+ /** @error_class.error_type: RAS error severity */
+ u8 error_type;
+ /** @error_class.error_component: IP block that raised the error */
+ u8 error_component;
+ /** @error_class.tile: Tile number */
+ u8 tile;
+ /** @error_class.instance: Instance within the tile */
+ u32 instance;
+ /** @error_class.cause: Error cause code */
+ u32 cause;
+ /** @error_class.reserved: Reserved, must be zero */
+ u8 reserved;
+ } error_class;
+ /** @class: Raw byte view of the error class */
+ u8 class[12];
+ };
+ /** @first_timestamp: Timestamp of the first occurrence of this error class */
+ u64 first_timestamp;
+ /** @sig_id: Aggregated error class SIG ID; set to U32_MAX if unknown */
+ u32 sig_id;
+ /** @error_count: Number of times this error has been observed */
+ u32 error_count;
+ /** @valid_bits: Bitmask indicating which header fields are populated */
+ union {
+ struct {
+ /** @valid_bits.location: @error_class field is valid */
+ u16 location : 1;
+ /** @valid_bits.first_timestamp: @first_timestamp field is valid */
+ u16 first_timestamp : 1;
+ /** @valid_bits.sig_id: @sig_id field is valid */
+ u16 sig_id : 1;
+ /** @valid_bits.pci_bdf: @pci_bdf field is valid */
+ u16 pci_bdf : 1;
+ /** @valid_bits.drv_version: @drv_version field is valid */
+ u16 drv_version : 1;
+ /** @valid_bits.fw_id: @fw_id field is valid */
+ u16 fw_id : 1;
+ /** @valid_bits.reserved: Reserved, must be zero */
+ u16 reserved : 10;
+ } valid_bits;
+ /** @validation_bits: Raw u16 view of all valid bits */
+ u16 validation_bits;
+ };
+ /** @pci_bdf: PCI location string, format "DDDD:bb:dd.f" */
+ char pci_bdf[16];
+ /** @drv_version: Driver source version string (THIS_MODULE->srcversion) */
+ char drv_version[25];
+ /** @fw_id: Firmware version string (GFSP+PCODE+CSC+GUC or MNG+NUC+RAS+GUC) */
+ char fw_id[256];
+ /** @reserved: Reserved for future use, must be zero */
+ u8 reserved[5];
+};
+
+/**
+ * struct xe_cper_sec_intel_error_info - Variable-length Intel GPU error payload
+ *
+ * Appended after &xe_cper_sec_intel_err_hdr when detailed per-event data
+ * is available. The @event_queue flexible array holds @event_queue_count
+ * packed &xe_intel_priv_event_entry records.
+ */
+struct xe_cper_sec_intel_error_info {
+ /** @error_class: Error classification (mirrors the header error_class) */
+ union {
+ struct {
+ u8 error_type;
+ u8 error_component;
+ u8 tile;
+ u32 instance;
+ u32 cause;
+ u8 reserved;
+ } error_class;
+ /** @class: Raw byte view of the error class */
+ u8 class[12];
+ };
+ /** @error_count: Total number of errors recorded */
+ u32 error_count;
+ /** @event_queue_length: Total byte size of the @event_queue array */
+ u32 event_queue_length;
+ /** @event_queue_count: Number of entries in @event_queue */
+ u32 event_queue_count;
+ /** @event_queue: Packed array of &xe_intel_priv_event_entry records */
+ u8 event_queue[];
+};
+
+/**
+ * struct xe_intel_priv_event_entry - Single error event in the event queue
+ *
+ * Each entry is variable-length; @entry_length gives the byte size of
+ * @metadata only (not including @entry_length or @timestamp).
+ */
+struct xe_intel_priv_event_entry {
+ /** @entry_length: Byte length of the @metadata payload */
+ u32 entry_length;
+ /** @timestamp: Hardware timestamp of this event */
+ u64 timestamp;
+ /** @metadata: Event-specific payload bytes */
+ u8 metadata[];
+};
+
+/**
+ * struct xe_cper_nonstd_record - Fixed-size portion of an Intel GPU CPER record
+ *
+ * Contains the standard CPER record header, section descriptor, and the
+ * Intel error section header. A &xe_cper_sec_intel_error_info payload
+ * (with its flexible @event_queue array) is appended dynamically.
+ */
+struct xe_cper_nonstd_record {
+ /** @record_hdr: Standard CPER record header (UEFI Appendix N.2.1) */
+ struct cper_record_header record_hdr;
+ /** @section_desc: CPER section descriptor */
+ struct cper_section_descriptor section_desc;
+ /** @intel_hdr: Intel-specific error section header */
+ struct xe_cper_sec_intel_err_hdr intel_hdr;
+};
+
+#pragma pack(pop)
+
+/**
+ * struct xe_platform_id_entry - Mapping from PCI device ID to CPER platform GUID
+ *
+ * Used to resolve the platform_id field in a CPER section descriptor.
+ * GUIDs are UUIDv5 (RFC 9562, SHA-1) derived from the Intel CPER namespace
+ * with name string "platform/8086:<dev_id_hex_lower>".
+ */
+struct xe_platform_id_entry {
+ /** @device_id: PCI device ID */
+ u16 device_id;
+ /** @platform_id: Corresponding UUIDv5 platform GUID */
+ guid_t platform_id;
+};
+
+#endif
diff --git a/drivers/gpu/drm/xe/xe_trace_cper.c b/drivers/gpu/drm/xe/xe_trace_cper.c
new file mode 100644
index 000000000000..caea8783ab7c
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_trace_cper.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#ifndef __CHECKER__
+#define CREATE_TRACE_POINTS
+#include "xe_trace_cper.h"
+#endif
diff --git a/drivers/gpu/drm/xe/xe_trace_cper.h b/drivers/gpu/drm/xe/xe_trace_cper.h
new file mode 100644
index 000000000000..45af86467616
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_trace_cper.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM xe
+
+#if !defined(_XE_TRACE_CPER_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _XE_TRACE_CPER_H_
+
+#include <linux/tracepoint.h>
+#include <linux/types.h>
+
+#include "xe_cper_types.h"
+#include "xe_device_types.h"
+
+#define __dev_name_xe(xe) dev_name((xe)->drm.dev)
+
+TRACE_EVENT(xe_error_cper,
+ TP_PROTO(struct xe_device *xe,
+ const guid_t *platform_id, const guid_t *fru_id,
+ const u8 severity,
+ const struct xe_cper_sec_intel_err_hdr *ihdr,
+ u32 cper_len, const u8 *cper),
+ TP_ARGS(xe, platform_id, fru_id, severity, ihdr, cper_len, cper),
+
+ TP_STRUCT__entry(
+ __string(dev, __dev_name_xe(xe))
+ __array(char, platform_id, UUID_SIZE)
+ __array(char, fru_id, UUID_SIZE)
+ __field(u8, sev)
+ __array(u8, ihdr_raw, sizeof(struct xe_cper_sec_intel_err_hdr))
+ __field(u32, cper_len)
+ __dynamic_array(u8, cper, cper_len)
+ ),
+
+ TP_fast_assign(
+ __assign_str(dev);
+ __entry->sev = severity;
+ memcpy(__entry->platform_id, platform_id, UUID_SIZE);
+ memcpy(__entry->fru_id, fru_id, UUID_SIZE);
+ memcpy(__entry->ihdr_raw, ihdr,
+ sizeof(struct xe_cper_sec_intel_err_hdr));
+ __entry->cper_len = cper_len;
+ memcpy(__get_dynamic_array(cper), cper, cper_len);
+ ),
+
+ TP_printk("dev=%s severity=%d platform_id=%pU fru_id=%pU "
+ "intel_err_hdr_raw=%s cper_len=%u cper_raw=%s",
+ __get_str(dev), __entry->sev,
+ __entry->platform_id, __entry->fru_id,
+ __print_hex(__entry->ihdr_raw, sizeof(struct xe_cper_sec_intel_err_hdr)),
+ __entry->cper_len,
+ __print_hex(__get_dynamic_array(cper), __entry->cper_len))
+);
+
+#endif
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/xe
+#define TRACE_INCLUDE_FILE xe_trace_cper
+#include <trace/define_trace.h>
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 5/7] drm/xe/cper: APIs to prepare and log CPER record
2026-07-02 11:14 [RFC PATCH 0/7] Add CPER logging support for CRI Badal Nilawar
` (3 preceding siblings ...)
2026-07-02 11:14 ` [RFC PATCH 4/7] drm/xe/cper: Add CPER structures and trace event Badal Nilawar
@ 2026-07-02 11:14 ` Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 6/7] drm/xe/cper: Prepare Intel CPER error info from info queue Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 7/7] drm/xe/cper: Log CPER record for correctable errors Badal Nilawar
6 siblings, 0 replies; 11+ messages in thread
From: Badal Nilawar @ 2026-07-02 11:14 UTC (permalink / raw)
To: intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
riana.tauro, mallesh.koujalagi, aravind.iddamsetty
Add APIs to initialize Intel-specific CPER metadata, build a
non-standard CPER record, and emit it via the xe_error_cper tracepoint.
Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
Assisted-by: Copilot:claude-sonnet-4.6
---
drivers/gpu/drm/xe/Makefile | 1 +
drivers/gpu/drm/xe/xe_cper.c | 215 +++++++++++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_cper.h | 30 +++++
3 files changed, 246 insertions(+)
create mode 100644 drivers/gpu/drm/xe/xe_cper.c
create mode 100644 drivers/gpu/drm/xe/xe_cper.h
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index 01e6711cce1c..37600de21a35 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -35,6 +35,7 @@ $(obj)/generated/%_device_wa_oob.c $(obj)/generated/%_device_wa_oob.h: $(obj)/xe
xe-y += xe_bb.o \
xe_bo.o \
xe_bo_evict.o \
+ xe_cper.o \
xe_dep_scheduler.o \
xe_devcoredump.o \
xe_device.o \
diff --git a/drivers/gpu/drm/xe/xe_cper.c b/drivers/gpu/drm/xe/xe_cper.c
new file mode 100644
index 000000000000..b46190601d98
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_cper.c
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#include <linux/cper.h>
+#include <linux/ktime.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <drm/drm_print.h>
+
+#include "xe_cper.h"
+#include "xe_cper_types.h"
+#include "xe_device_types.h"
+#include "xe_ras_types.h"
+#include "xe_trace_cper.h"
+
+static const struct xe_platform_id_entry xe_platform_ids[] = {
+ /* 0x674C platform/8086:674c */
+ { 0x674C, GUID_INIT(0x9046afe5, 0x9041, 0x5124,
+ 0x86, 0x14, 0x92, 0x55, 0x0d, 0x9e, 0x9d, 0xa6) },
+};
+
+/**
+ * fill_pci_bdf - populate pci_bdf in the Intel section header
+ * @xe: xe device instance
+ * @ihdr: Intel section header to update
+ *
+ * Writes the PCI domain:bus:device.function string into @ihdr->pci_bdf and
+ * sets the corresponding valid bit.
+ */
+static void fill_pci_bdf(struct xe_device *xe,
+ struct xe_cper_sec_intel_err_hdr *ihdr)
+{
+ struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
+
+ snprintf(ihdr->pci_bdf, sizeof(ihdr->pci_bdf), "%04x:%02x:%02x.%x",
+ pci_domain_nr(pdev->bus), pdev->bus->number,
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+ ihdr->valid_bits.pci_bdf = 1;
+}
+
+/**
+ * fill_drv_version - populate drv_version in the Intel section header
+ * @ihdr: Intel section header to update
+ *
+ * Copies the module's srcversion string into @ihdr->drv_version and sets the
+ * corresponding valid bit.
+ */
+static void fill_drv_version(struct xe_cper_sec_intel_err_hdr *ihdr)
+{
+ if (!THIS_MODULE->srcversion)
+ return;
+
+ strscpy(ihdr->drv_version, THIS_MODULE->srcversion,
+ sizeof(ihdr->drv_version));
+ ihdr->valid_bits.drv_version = 1;
+}
+
+/**
+ * lookup_platform_id - find the UUIDv5 platform_id for a PCI device ID
+ * @pdev: PCI device whose device ID is used as the lookup key
+ *
+ * Searches xe_platform_ids[] for an entry matching @pdev->device.
+ *
+ * Returns a pointer to the matching guid_t, or %NULL if not found.
+ */
+static const guid_t *lookup_platform_id(const struct pci_dev *pdev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(xe_platform_ids); i++)
+ if (xe_platform_ids[i].device_id == pdev->device)
+ return &xe_platform_ids[i].platform_id;
+ return NULL;
+}
+
+static void fill_fw_id(struct xe_device *xe,
+ struct xe_cper_sec_intel_err_hdr *ihdr)
+{
+ /* TODO: populate ihdr->fw_id from firmware version queries */
+}
+
+/**
+ * xe_cper_init_intel_err_hdr - Populate an Intel CPER section header
+ * @xe: xe device instance
+ * @location: 12-byte error classification blob (cast from the source
+ * error class struct); pass %NULL if not applicable
+ * @first_timestamp: timestamp of the first occurrence; pass 0 if not available
+ * @sig_id: signal identifier for the error; pass %U32_MAX if not applicable
+ * @error_count: number of times this error has occurred
+ * @ihdr: Intel section header to populate
+ *
+ * Fills in @ihdr with the provided error metadata and sets the corresponding
+ * valid bits.
+ */
+void xe_cper_init_intel_err_hdr(struct xe_device *xe,
+ const u8 location[12],
+ u64 first_timestamp,
+ u32 sig_id,
+ u64 error_count,
+ struct xe_cper_sec_intel_err_hdr *ihdr)
+{
+ if (location) {
+ memcpy(&ihdr->error_class, location, sizeof(ihdr->error_class));
+ ihdr->valid_bits.location = 1;
+ }
+
+ if (first_timestamp) {
+ ihdr->first_timestamp = first_timestamp;
+ ihdr->valid_bits.first_timestamp = 1;
+ }
+
+ if (sig_id != U32_MAX) {
+ ihdr->sig_id = sig_id;
+ ihdr->valid_bits.sig_id = 1;
+ }
+
+ ihdr->error_count = error_count;
+
+ fill_pci_bdf(xe, ihdr);
+ fill_drv_version(ihdr);
+ fill_fw_id(xe, ihdr);
+}
+
+/**
+ * xe_cper_record_emit - Build and emit a CPER record for an Intel GPU error
+ * @xe: xe device instance
+ * @fru_id: GUID identifying the field-replaceable unit
+ * @severity: CPER error severity (CPER_SEV_*)
+ * @ihdr: Intel-specific section header, fully populated by
+ * xe_cper_init_intel_err_hdr()
+ * @einfo: optional xe_cper_sec_intel_error_info payload; may be %NULL
+ * @einfo_size: byte size of @einfo, including any event_queue data
+ *
+ * The platform_id is resolved automatically from xe_platform_ids[] using
+ * the PCI device ID. If no entry matches, the field is left zeroed and
+ * the record is still emitted.
+ */
+void xe_cper_record_emit(struct xe_device *xe,
+ const guid_t *fru_id,
+ u8 severity,
+ guid_t notification_type,
+ struct xe_cper_sec_intel_err_hdr *ihdr,
+ const void *einfo,
+ u32 einfo_size)
+{
+ struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
+ const guid_t *platform_id = lookup_platform_id(pdev);
+ u32 total_len = sizeof(struct xe_cper_nonstd_record) + einfo_size;
+ struct cper_section_descriptor *sdesc;
+ struct cper_record_header *rhdr;
+ struct xe_cper_nonstd_record *rec;
+
+ rec = kzalloc(total_len, GFP_KERNEL);
+ if (!rec) {
+ drm_err(&xe->drm, "CPER: failed to allocate record buffer\n");
+ return;
+ }
+
+ rhdr = &rec->record_hdr;
+ sdesc = &rec->section_desc;
+
+ /* Assemble the CPER record header (UEFI Appendix N.2.1) */
+ memcpy(rhdr->signature, CPER_SIG_RECORD, CPER_SIG_SIZE);
+ rhdr->revision = CPER_RECORD_REV;
+ rhdr->signature_end = CPER_SIG_END;
+ rhdr->section_count = 1;
+ rhdr->error_severity = severity;
+ rhdr->validation_bits = CPER_VALID_TIMESTAMP;
+ rhdr->record_length = total_len;
+ rhdr->timestamp = ktime_get_real_ns();
+ if (platform_id) {
+ rhdr->platform_id = *platform_id;
+ rhdr->validation_bits |= CPER_VALID_PLATFORM_ID;
+ }
+ rhdr->creator_id = INTEL_CPER_CREATOR_XEKMD;
+ rhdr->notification_type = notification_type;
+ rhdr->record_id = cper_next_record_id();
+ rhdr->flags = 0;
+
+ /* Assemble the section descriptor (UEFI Appendix N.2.2) */
+ sdesc->section_offset = sizeof(struct cper_record_header) +
+ sizeof(struct cper_section_descriptor);
+ sdesc->section_length = sizeof(struct xe_cper_sec_intel_err_hdr) +
+ einfo_size;
+ sdesc->revision = CPER_RECORD_REV;
+ /* Set validation_bits using CPER_SEC_VALID_FRU_ID / CPER_SEC_VALID_FRU_TEXT
+ * when the corresponding fields are populated.
+ */
+ sdesc->validation_bits = 0;
+ sdesc->reserved = 0;
+ sdesc->flags = 0;
+ sdesc->section_type = INTEL_CPER_SECTION_ACCEL_GENERIC;
+ if (fru_id && !guid_is_null(fru_id)) {
+ sdesc->fru_id = *fru_id;
+ sdesc->validation_bits |= CPER_SEC_VALID_FRU_ID;
+ }
+ sdesc->section_severity = severity;
+
+ /* Copy the Intel-specific section header (updated with BDF/version) */
+ rec->intel_hdr = *ihdr;
+
+ /* Append optional variable-length error info */
+ if (einfo && einfo_size)
+ memcpy((u8 *)rec + sizeof(*rec), einfo, einfo_size);
+
+ trace_xe_error_cper(xe, platform_id, fru_id, severity,
+ &rec->intel_hdr, total_len, (u8 *)rec);
+
+ kfree(rec);
+}
diff --git a/drivers/gpu/drm/xe/xe_cper.h b/drivers/gpu/drm/xe/xe_cper.h
new file mode 100644
index 000000000000..7027e3f1be60
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_cper.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2026 Intel Corporation
+ */
+
+#ifndef _XE_CPER_H_
+#define _XE_CPER_H_
+
+#include <linux/types.h>
+#include <linux/uuid.h>
+
+struct xe_cper_sec_intel_err_hdr;
+struct xe_device;
+
+void xe_cper_record_emit(struct xe_device *xe,
+ const guid_t *fru_id,
+ u8 severity,
+ guid_t notification_type,
+ struct xe_cper_sec_intel_err_hdr *ihdr,
+ const void *einfo,
+ u32 einfo_size);
+
+void xe_cper_init_intel_err_hdr(struct xe_device *xe,
+ const u8 location[12],
+ u64 first_timestamp,
+ u32 sig_id,
+ u64 error_count,
+ struct xe_cper_sec_intel_err_hdr *ihdr);
+
+#endif /* _XE_CPER_H_ */
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 6/7] drm/xe/cper: Prepare Intel CPER error info from info queue
2026-07-02 11:14 [RFC PATCH 0/7] Add CPER logging support for CRI Badal Nilawar
` (4 preceding siblings ...)
2026-07-02 11:14 ` [RFC PATCH 5/7] drm/xe/cper: APIs to prepare and log CPER record Badal Nilawar
@ 2026-07-02 11:14 ` Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 7/7] drm/xe/cper: Log CPER record for correctable errors Badal Nilawar
6 siblings, 0 replies; 11+ messages in thread
From: Badal Nilawar @ 2026-07-02 11:14 UTC (permalink / raw)
To: intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
riana.tauro, mallesh.koujalagi, aravind.iddamsetty
Add prepare_cper_error_info() to xe_ras.c which assembles the raw info
queue data embedded in a GET_COUNTER response (and any subsequent chunks
fetched via GET_INFO_QUEUE_DATA) into a xe_cper_sec_intel_error_info
that can be passed directly to cper logging function.
Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
Assisted-by: Copilot:claude-sonnet-4.6
---
drivers/gpu/drm/xe/xe_ras.c | 142 +++++++++++++++++++++++++++++++++++-
1 file changed, 141 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c
index e594d4d3a23f..8579cde6a4bf 100644
--- a/drivers/gpu/drm/xe/xe_ras.c
+++ b/drivers/gpu/drm/xe/xe_ras.c
@@ -3,6 +3,8 @@
* Copyright © 2026 Intel Corporation
*/
+#include "xe_cper.h"
+#include "xe_cper_types.h"
#include "xe_device.h"
#include "xe_drm_ras.h"
#include "xe_pm.h"
@@ -218,7 +220,7 @@ int xe_ras_get_counter(struct xe_device *xe, u8 severity, u8 component, u32 *val
if (ret)
return ret;
- *value = response.counter_value;
+ *value = response.value;
return 0;
}
@@ -311,6 +313,144 @@ static int get_info_queue_data(struct xe_device *xe,
return 0;
}
+/**
+ * prepare_cper_error_info - Assemble info queue chunks and convert to CPER einfo
+ * @xe: xe device instance
+ * @counter_resp: counter response containing the first embedded chunk
+ * @error_class: RAS error class used to populate the einfo error_class fields
+ * @einfo_size_out: output size of the allocated einfo buffer
+ *
+ * Assembles the complete raw info queue data from the first chunk already
+ * embedded in @counter_resp and any additional chunks fetched via
+ * GET_INFO_QUEUE_DATA. The raw data layout is:
+ *
+ * [xe_ras_info_queue_dynamic_counter_hdr * num_headers]
+ * [xe_ras_error_log * N]
+ *
+ * Each xe_ras_error_log is translated into an xe_intel_priv_event_entry and
+ * appended to the returned xe_cper_sec_intel_error_info.event_queue[].
+ *
+ * Returns: allocated einfo on success (caller must kfree()), NULL on failure.
+ */
+static struct xe_cper_sec_intel_error_info *
+prepare_cper_error_info(struct xe_device *xe,
+ const struct xe_ras_get_counter_response *counter_resp,
+ const struct xe_ras_error_class *error_class,
+ u32 *einfo_size_out)
+{
+ const struct xe_ras_info_queue_header *first_qhdr =
+ &counter_resp->info_queue.queue_header;
+ struct xe_ras_get_info_queue_data_request iq_req = {0};
+ struct xe_ras_get_info_queue_data_response iq_response = {0};
+ struct xe_cper_sec_intel_error_info *einfo;
+ struct xe_intel_priv_event_entry *entry;
+ const struct xe_ras_error_log *logs;
+ u32 entry_size, einfo_size;
+ u32 num_logs;
+ u32 raw_total, iq_offset = 0;
+ u8 *raw_buf;
+ u32 i;
+
+ raw_buf = kzalloc(XE_RAS_INFO_QUEUE_MAX_TOTAL_SIZE, GFP_KERNEL);
+ if (!raw_buf)
+ return NULL;
+
+ /* Copy first chunk already embedded in the counter response */
+ if (first_qhdr->chunk_size &&
+ first_qhdr->chunk_offset + first_qhdr->chunk_size <=
+ XE_RAS_INFO_QUEUE_MAX_TOTAL_SIZE) {
+ memcpy(raw_buf + first_qhdr->chunk_offset,
+ counter_resp->info_queue.queue_data,
+ first_qhdr->chunk_size);
+ iq_offset = first_qhdr->chunk_size;
+ }
+
+ /* Fetch any remaining chunks */
+ if (first_qhdr->flags & XE_RAS_INFO_QUEUE_FLAG_MORE_DATA) {
+ iq_req.source_command = XE_SYSCTRL_CMD_GET_COUNTER;
+ iq_req.source_context = counter_resp->counter;
+ iq_req.queue_request.requested_size = XE_RAS_INFO_QUEUE_MAX_CHUNK_SIZE;
+ iq_req.queue_request.session_id = counter_resp->counter;
+
+ do {
+ struct xe_ras_info_queue_header *qhdr;
+ u32 end;
+
+ iq_req.queue_request.requested_offset = iq_offset;
+
+ if (get_info_queue_data(xe, &iq_req, &iq_response))
+ break;
+
+ qhdr = &iq_response.queue_response.queue_header;
+ end = qhdr->chunk_offset + qhdr->chunk_size;
+
+ if (end > XE_RAS_INFO_QUEUE_MAX_TOTAL_SIZE) {
+ xe_warn(xe, "[RAS]: CPER: info queue chunk out of bounds (offset=%u size=%u)\n",
+ qhdr->chunk_offset, qhdr->chunk_size);
+ break;
+ }
+
+ memcpy(raw_buf + qhdr->chunk_offset,
+ iq_response.queue_response.queue_data,
+ qhdr->chunk_size);
+
+ if (!qhdr->chunk_size)
+ break;
+
+ iq_offset += qhdr->chunk_size;
+ } while (iq_response.queue_response.queue_header.flags &
+ XE_RAS_INFO_QUEUE_FLAG_MORE_DATA);
+ }
+
+ raw_total = first_qhdr->total_size
+ ? min(first_qhdr->total_size, XE_RAS_INFO_QUEUE_MAX_TOTAL_SIZE)
+ : iq_offset;
+
+ num_logs = raw_total / sizeof(struct xe_ras_error_log);
+ if (!num_logs) {
+ kfree(raw_buf);
+ return NULL;
+ }
+
+ /*
+ * Each xe_intel_priv_event_entry holds:
+ * entry_length (u32) + timestamp (u64) + metadata[] (error_details)
+ */
+ entry_size = offsetof(struct xe_intel_priv_event_entry, metadata) +
+ sizeof_field(struct xe_ras_error_log, error_details);
+ einfo_size = sizeof(*einfo) + num_logs * entry_size;
+
+ einfo = kzalloc(einfo_size, GFP_KERNEL);
+ if (!einfo) {
+ kfree(raw_buf);
+ return NULL;
+ }
+
+ einfo->error_count = counter_resp->value;
+ einfo->event_queue_length = num_logs * entry_size;
+ einfo->event_queue_count = num_logs;
+ einfo->error_class.error_type = error_class->common.severity;
+ einfo->error_class.error_component = error_class->common.component;
+ einfo->error_class.tile = error_class->product.unit.tile;
+ einfo->error_class.instance = error_class->product.unit.instance;
+ einfo->error_class.cause = error_class->product.cause.cause;
+
+ logs = (const struct xe_ras_error_log *)raw_buf;
+ entry = (struct xe_intel_priv_event_entry *)einfo->event_queue;
+
+ for (i = 0; i < num_logs; i++) {
+ entry->entry_length = sizeof_field(struct xe_ras_error_log, error_details);
+ entry->timestamp = logs[i].timestamp;
+ memcpy(entry->metadata, logs[i].error_details,
+ sizeof(logs[i].error_details));
+ entry = (struct xe_intel_priv_event_entry *)((u8 *)entry + entry_size);
+ }
+
+ kfree(raw_buf);
+ *einfo_size_out = einfo_size;
+ return einfo;
+}
+
/**
* xe_ras_init - Initialize Xe RAS
* @xe: xe device instance
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 7/7] drm/xe/cper: Log CPER record for correctable errors
2026-07-02 11:14 [RFC PATCH 0/7] Add CPER logging support for CRI Badal Nilawar
` (5 preceding siblings ...)
2026-07-02 11:14 ` [RFC PATCH 6/7] drm/xe/cper: Prepare Intel CPER error info from info queue Badal Nilawar
@ 2026-07-02 11:14 ` Badal Nilawar
6 siblings, 0 replies; 11+ messages in thread
From: Badal Nilawar @ 2026-07-02 11:14 UTC (permalink / raw)
To: intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
riana.tauro, mallesh.koujalagi, aravind.iddamsetty
In xe_ras_counter_threshold_crossed(), emit a CPER record for each
correctable error reported via the counter threshold crossed event.
Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
Assisted-by: Copilot:claude-sonnet-4.6
---
drivers/gpu/drm/xe/xe_ras.c | 75 +++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c
index 8579cde6a4bf..53f192a2e97f 100644
--- a/drivers/gpu/drm/xe/xe_ras.c
+++ b/drivers/gpu/drm/xe/xe_ras.c
@@ -11,6 +11,7 @@
#include "xe_printk.h"
#include "xe_ras.h"
#include "xe_ras_types.h"
+#include "xe_sig_ids.h"
#include "xe_sysctrl.h"
#include "xe_sysctrl_event_types.h"
#include "xe_sysctrl_mailbox.h"
@@ -67,6 +68,10 @@ static const char *const xe_ras_components[] = {
};
static_assert(ARRAY_SIZE(xe_ras_components) == XE_RAS_COMP_MAX);
+static void emit_hw_error_cper(struct xe_device *xe,
+ const struct xe_ras_error_class *error_class,
+ u64 timestamp, u32 sig_id, u8 severity);
+
static u8 drm_to_xe_ras_severity(u8 severity)
{
switch (severity) {
@@ -133,6 +138,38 @@ static inline const char *comp_to_str(u8 component)
return xe_ras_components[component];
}
+static u32 ras_comp_to_hw_sigid(u8 component)
+{
+ switch (component) {
+ case XE_RAS_COMP_DEVICE_MEMORY:
+ return XE_SIG_HW_DEVICE_MEMORY;
+ case XE_RAS_COMP_CORE_COMPUTE:
+ return XE_SIG_HW_CORE_COMPUTE;
+ case XE_RAS_COMP_PCIE:
+ return XE_SIG_HW_PCIE;
+ case XE_RAS_COMP_FABRIC:
+ return XE_SIG_HW_FABRIC;
+ case XE_RAS_COMP_SOC_INTERNAL:
+ return XE_SIG_HW_SOC_INTERNAL;
+ default:
+ return U32_MAX;
+ }
+}
+
+static u8 ras_sev_to_cper_sev(u8 ras_sev)
+{
+ switch (ras_sev) {
+ case XE_RAS_SEV_CORRECTABLE:
+ return CPER_SEV_CORRECTED;
+ case XE_RAS_SEV_UNCORRECTABLE:
+ return CPER_SEV_RECOVERABLE;
+ case XE_RAS_SEV_INFORMATIONAL:
+ return CPER_SEV_INFORMATIONAL;
+ default:
+ return CPER_SEV_RECOVERABLE;
+ }
+}
+
void xe_ras_counter_threshold_crossed(struct xe_device *xe,
struct xe_sysctrl_event_response *response)
{
@@ -154,6 +191,9 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,
severity = errors[id].common.severity;
component = errors[id].common.component;
+ /* Emit a CPER record for this error */
+ emit_hw_error_cper(xe, &errors[id], 0, ras_comp_to_hw_sigid(component), severity);
+
xe_warn(xe, "[RAS]: %s %s detected\n",
comp_to_str(component), sev_to_str(severity));
}
@@ -451,6 +491,41 @@ prepare_cper_error_info(struct xe_device *xe,
return einfo;
}
+static void emit_hw_error_cper(struct xe_device *xe,
+ const struct xe_ras_error_class *error_class,
+ u64 timestamp, u32 sig_id, u8 severity)
+{
+ struct xe_ras_get_counter_response counter_response = {};
+ struct xe_cper_sec_intel_err_hdr ihdr = {};
+ struct xe_cper_sec_intel_error_info *einfo = NULL;
+ u32 einfo_size = 0;
+
+ if (get_counter(xe, error_class, &counter_response)) {
+ xe_err(xe, "[RAS]: CPER: failed to get counter, skipping record\n");
+ return;
+ }
+
+ xe_cper_init_intel_err_hdr(xe,
+ (const u8 *)error_class,
+ timestamp,
+ sig_id,
+ counter_response.value,
+ &ihdr);
+
+ if (counter_response.has_info_queue) {
+ einfo = prepare_cper_error_info(xe, &counter_response,
+ error_class, &einfo_size);
+ if (!einfo)
+ xe_err(xe, "[RAS]: CPER: failed to build einfo from info queue\n");
+ }
+
+ xe_cper_record_emit(xe, &guid_null,
+ ras_sev_to_cper_sev(severity),
+ INTEL_CPER_NOTIFY_GPU_ERROR,
+ &ihdr, einfo, einfo_size);
+ kfree(einfo);
+}
+
/**
* xe_ras_init - Initialize Xe RAS
* @xe: xe device instance
--
2.54.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 3/7] drm/xe/xe_ras: Refactor get_counter() to return response structure
2026-07-02 11:14 ` [RFC PATCH 3/7] drm/xe/xe_ras: Refactor get_counter() to return response structure Badal Nilawar
@ 2026-07-03 7:41 ` Tauro, Riana
2026-07-07 12:53 ` Mallesh, Koujalagi
1 sibling, 0 replies; 11+ messages in thread
From: Tauro, Riana @ 2026-07-03 7:41 UTC (permalink / raw)
To: Badal Nilawar, intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
mallesh.koujalagi, aravind.iddamsetty
On 02-07-2026 16:44, Badal Nilawar wrote:
> Return the complete response structure from get_counter() instead of
> only the counter value. This allows callers to access additional
> response fields, such as has_info_queue for CPER record building.
>
> Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
> Assisted-by: Copilot:claude-sonnet-4.6
> ---
> drivers/gpu/drm/xe/xe_ras.c | 23 +++++++++++++++--------
> drivers/gpu/drm/xe/xe_ras_types.h | 10 ++++++++--
> 2 files changed, 23 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c
> index 85b0202467f6..e594d4d3a23f 100644
> --- a/drivers/gpu/drm/xe/xe_ras.c
> +++ b/drivers/gpu/drm/xe/xe_ras.c
> @@ -157,12 +157,12 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,
> }
> }
>
> -static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter, u32 *value)
> +static int get_counter(struct xe_device *xe, const struct xe_ras_error_class *counter,
> + struct xe_ras_get_counter_response *out)
> {
> struct xe_ras_get_counter_response response = {0};
> struct xe_ras_get_counter_request request = {0};
> struct xe_sysctrl_mailbox_command command = {0};
> - struct xe_ras_error_common *common;
> size_t rlen;
> int ret;
>
> @@ -183,12 +183,11 @@ static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter,
> return -EIO;
> }
>
> - common = &response.counter.common;
> - *value = response.value;
> -
> - xe_dbg(xe, "[RAS]: get counter %u for %s %s\n", *value, comp_to_str(common->component),
> - sev_to_str(common->severity));
> + xe_dbg(xe, "[RAS]: get counter value %u for %s %s\n", response.value,
> + comp_to_str(response.counter.common.component),
> + sev_to_str(response.counter.common.severity));
Why the unnecessary change?
>
> + *out = response;
> return 0;
> }
>
> @@ -207,12 +206,20 @@ static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter,
> int xe_ras_get_counter(struct xe_device *xe, u8 severity, u8 component, u32 *value)
> {
> struct xe_ras_error_class counter = {0};
> + struct xe_ras_get_counter_response response;
> + int ret;
>
> counter.common.severity = drm_to_xe_ras_severity(severity);
> counter.common.component = drm_to_xe_ras_component(component);
>
> guard(xe_pm_runtime)(xe);
> - return get_counter(xe, &counter, value);
> +
> + ret = get_counter(xe, &counter, &response);
> + if (ret)
> + return ret;
> +
> + *value = response.counter_value;
Does this compile? I don't see a counter_value in response
Thanks
Riana
> + return 0;
> }
>
> /**
> diff --git a/drivers/gpu/drm/xe/xe_ras_types.h b/drivers/gpu/drm/xe/xe_ras_types.h
> index fc496888b3f8..befdaf297103 100644
> --- a/drivers/gpu/drm/xe/xe_ras_types.h
> +++ b/drivers/gpu/drm/xe/xe_ras_types.h
> @@ -155,8 +155,14 @@ struct xe_ras_get_counter_response {
> u64 timestamp;
> /** @threshold: Threshold value for the counter */
> u32 threshold;
> - /** @reserved: Reserved */
> - u32 reserved[57];
> + /** @reserved: Reserved for future use */
> + u32 reserved:9;
> + /** @has_info_queue: Set if info queue is available */
> + u32 has_info_queue:1;
> + /** @reserved1: Reserved for future use */
> + u32 reserved1:22;
> + /** @info_queue: Initial info queue data (first chunk) if available */
> + struct xe_ras_info_queue_response info_queue;
> } __packed;
>
> /**
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 2/7] drm/xe/xe_ras: Add support to retrieve info queue data for CRI
2026-07-02 11:14 ` [RFC PATCH 2/7] drm/xe/xe_ras: Add support to retrieve info queue data for CRI Badal Nilawar
@ 2026-07-07 12:29 ` Mallesh, Koujalagi
0 siblings, 0 replies; 11+ messages in thread
From: Mallesh, Koujalagi @ 2026-07-07 12:29 UTC (permalink / raw)
To: Badal Nilawar, intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
riana.tauro, aravind.iddamsetty
[-- Attachment #1: Type: text/plain, Size: 8580 bytes --]
On 02-07-2026 04:44 pm, Badal Nilawar wrote:
> Add support to retrieve info queue data. It can be retrieved when
> has_info_queue=1 and RAS_INFO_QUEUE_FLAG_MORE_DATA is set in
> response of XE_SYSCTRL_CMD_GET_COUNTER.
>
nit: Please change commit message, we haven't checked has_info_queue=1
>
> Signed-off-by: Badal Nilawar<badal.nilawar@intel.com>
> Assisted-by: Copilot:claude-sonnet-4.6
> ---
> drivers/gpu/drm/xe/xe_ras.c | 34 ++++++
> drivers/gpu/drm/xe/xe_ras_types.h | 112 +++++++++++++++++-
> drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h | 2 +
> 3 files changed, 147 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c
> index 44f4e1a3455b..85b0202467f6 100644
> --- a/drivers/gpu/drm/xe/xe_ras.c
> +++ b/drivers/gpu/drm/xe/xe_ras.c
> @@ -270,6 +270,40 @@ int xe_ras_clear_counter(struct xe_device *xe, u8 severity, u8 component)
> return 0;
> }
>
> +static int get_info_queue_data(struct xe_device *xe,
> + const struct xe_ras_get_info_queue_data_request *req,
> + struct xe_ras_get_info_queue_data_response *out)
> +{
Why we need info queue data? When we are going to use info queue data?
> + struct xe_ras_get_info_queue_data_response response = {0};
> + struct xe_sysctrl_mailbox_command command = {0};
> + size_t rlen;
> + int ret;
> +
> + xe_sysctrl_create_command(&command, XE_SYSCTRL_GROUP_GFSP,
> + XE_SYSCTRL_CMD_GET_INFO_QUEUE_DATA,
> + (void *)req, sizeof(*req), &response, sizeof(response));
> +
> + ret = xe_sysctrl_send_command(&xe->sc, &command, &rlen);
> + if (ret) {
> + xe_err(xe, "sysctrl: failed to get info queue data %d\n", ret);
> + return ret;
> + }
> +
> + if (rlen != sizeof(response)) {
> + xe_err(xe, "sysctrl: unexpected get info queue data response length %zu (expected %zu)\n",
> + rlen, sizeof(response));
> + return -EIO;
> + }
> +
> + xe_dbg(xe, "[RAS]: info queue data: status=%u chunk_size=%u flags=0x%x\n",
> + response.operation_status,
> + response.queue_response.queue_header.chunk_size,
> + response.queue_response.queue_header.flags);
> +
What happen when system control send corrupt data?
> + *out = response;
> + return 0;
> +}
> +
> /**
> * xe_ras_init - Initialize Xe RAS
> * @xe: xe device instance
> diff --git a/drivers/gpu/drm/xe/xe_ras_types.h b/drivers/gpu/drm/xe/xe_ras_types.h
> index 6688e11f57a8..fc496888b3f8 100644
> --- a/drivers/gpu/drm/xe/xe_ras_types.h
> +++ b/drivers/gpu/drm/xe/xe_ras_types.h
> @@ -9,6 +9,12 @@
> #include <linux/types.h>
>
> #define XE_RAS_NUM_COUNTERS 16
> +#define XE_RAS_INFO_QUEUE_MAX_CHUNK_SIZE 200
> +#define XE_RAS_INFO_QUEUE_MAX_TOTAL_SIZE 5120
> +#define XE_RAS_INFO_QUEUE_FLAG_AVAILABLE 0x01
> +#define XE_RAS_INFO_QUEUE_FLAG_MORE_DATA 0x02
> +#define XE_RAS_INFO_QUEUE_FLAG_OVERFLOW 0x04
> +#define XE_RAS_INFO_QUEUE_FLAG_COMPRESSED 0x08
>
What is use of XE_RAS_INFO_QUEUE_FLAG_COMPRESSED? When we are using it?
Thanks,
-/Mallesh
> /**
> * struct xe_ras_error_common - Error fields that are common across all products
> @@ -71,7 +77,64 @@ struct xe_ras_threshold_crossed {
> } __packed;
>
> /**
> - * struct xe_ras_get_counter_request - Request structure for get counter
> + * struct xe_ras_info_queue_header - Metadata for large info queue data transfers
> + *
> + * Provides chunk metadata for commands that support extended info queue
> + * functionality. Used when the total data exceeds a single mailbox response.
> + */
> +struct xe_ras_info_queue_header {
> + /** @total_size: Total size of the complete info queue data in bytes */
> + u32 total_size;
> + /** @chunk_offset: Offset of this chunk within the total data in bytes */
> + u32 chunk_offset;
> + /** @chunk_size: Size of the data in this chunk in bytes */
> + u32 chunk_size;
> + /** @sequence_number: Sequence number for this chunk, starts at 0 */
> + u32 sequence_number;
> + /** @flags: Info queue control flags (RAS_INFO_QUEUE_FLAG_*) */
> + u32 flags:8;
> + /** @compression_type: Compression algorithm used; 0 = none */
> + u32 compression_type:4;
> + /** @num_headers: Number of detailed counter headers at start of queue_data */
> + u32 num_headers:5;
> + /** @reserved: Reserved for future use */
> + u32 reserved:15;
> + /** @checksum: CRC32 checksum of this chunk data */
> + u32 checksum;
> +} __packed;
> +
> +/**
> + * struct xe_ras_info_queue_request - Request for a specific chunk of info queue data
> + *
> + * Allows the driver to request continuation of large info queue transfers
> + * by specifying an offset and size within the full data set.
> + */
> +struct xe_ras_info_queue_request {
> + /** @requested_offset: Byte offset of the requested data chunk */
> + u32 requested_offset;
> + /** @requested_size: Maximum size of the requested chunk in bytes */
> + u32 requested_size;
> + /** @session_id: Session ID to correlate multi-chunk transfers */
> + struct xe_ras_error_class session_id;
> + /** @reserved: Reserved for future use */
> + u32 reserved;
> +} __packed;
> +
> +/**
> + * struct xe_ras_info_queue_response - Generic response for commands with info queues
> + *
> + * Standard response format for any command that returns an info queue
> + * payload. May be embedded in a command-specific response structure.
> + */
> +struct xe_ras_info_queue_response {
> + /** @queue_header: Info queue metadata for this chunk */
> + struct xe_ras_info_queue_header queue_header;
> + /** @queue_data: Info queue data for this chunk */
> + u8 queue_data[XE_RAS_INFO_QUEUE_MAX_CHUNK_SIZE];
> +} __packed;
> +
> +/**
> + * struct xe_ras_get_counter_request - Request for get error counter
> */
> struct xe_ras_get_counter_request {
> /** @counter: Error counter to be queried */
> @@ -121,4 +184,51 @@ struct xe_ras_clear_counter_response {
> /** @reserved1: Reserved for future use */
> u32 reserved1[3];
> } __packed;
> +
> +/**
> + * struct xe_ras_info_queue_dynamic_counter_hdr - Aggregate counter header entry
> + *
> + * When a session requests aggregate counter data, one header per matching
> + * dynamic counter class is prepended to the queue data. The @counter field
> + * indicates how many subsequent error log entries belong to this class.
> + */
> +struct xe_ras_info_queue_dynamic_counter_hdr {
> + /** @error_class: Error class associated with this counter group */
> + struct xe_ras_error_class error_class;
> + /** @counter: Number of error log entries that follow for this class */
> + u32 counter;
> +} __packed;
> +
> +/**
> + * struct xe_ras_error_log - Single error log entry following dynamic counter headers
> + */
> +struct xe_ras_error_log {
> + /** @timestamp: Timestamp when the error was recorded */
> + u64 timestamp;
> + /** @error_details: Error-specific details */
> + u32 error_details[16];
> +} __packed;
> +
> +/**
> + * struct xe_ras_get_info_queue_data_request - Request for RAS_CMD_GET_INFO_QUEUE_DATA
> + */
> +struct xe_ras_get_info_queue_data_request {
> + /** @queue_request: Info queue request parameters */
> + struct xe_ras_info_queue_request queue_request;
> + /** @source_command: Original command that generated the info queue */
> + u32 source_command;
> + /** @source_context: Context from original command, if applicable */
> + struct xe_ras_error_class source_context;
> +} __packed;
> +
> +/**
> + * struct xe_ras_get_info_queue_data_response - Response for RAS_CMD_GET_INFO_QUEUE_DATA
> + */
> +struct xe_ras_get_info_queue_data_response {
> + /** @operation_status: Status of the retrieval operation */
> + u32 operation_status;
> + /** @queue_response: Info queue data chunk */
> + struct xe_ras_info_queue_response queue_response;
> +} __packed;
> +
> #endif
> diff --git a/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h b/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h
> index 6e3753554510..538d93352655 100644
> --- a/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h
> +++ b/drivers/gpu/drm/xe/xe_sysctrl_mailbox_types.h
> @@ -25,11 +25,13 @@ enum xe_sysctrl_group {
> * @XE_SYSCTRL_CMD_GET_COUNTER: Get error counter value
> * @XE_SYSCTRL_CMD_CLEAR_COUNTER: Clear error counter value
> * @XE_SYSCTRL_CMD_GET_PENDING_EVENT: Retrieve pending event
> + * @XE_SYSCTRL_CMD_GET_INFO_QUEUE_DATA: Retrieve a chunk of info queue data
> */
> enum xe_sysctrl_gfsp_cmd {
> XE_SYSCTRL_CMD_GET_COUNTER = 0x03,
> XE_SYSCTRL_CMD_CLEAR_COUNTER = 0x04,
> XE_SYSCTRL_CMD_GET_PENDING_EVENT = 0x07,
> + XE_SYSCTRL_CMD_GET_INFO_QUEUE_DATA = 0x0D,
> };
>
> /**
[-- Attachment #2: Type: text/html, Size: 9404 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 3/7] drm/xe/xe_ras: Refactor get_counter() to return response structure
2026-07-02 11:14 ` [RFC PATCH 3/7] drm/xe/xe_ras: Refactor get_counter() to return response structure Badal Nilawar
2026-07-03 7:41 ` Tauro, Riana
@ 2026-07-07 12:53 ` Mallesh, Koujalagi
1 sibling, 0 replies; 11+ messages in thread
From: Mallesh, Koujalagi @ 2026-07-07 12:53 UTC (permalink / raw)
To: Badal Nilawar, intel-xe
Cc: anshuman.gupta, rodrigo.vivi, daniele.ceraolospurio, raag.jadav,
riana.tauro, aravind.iddamsetty
On 02-07-2026 04:44 pm, Badal Nilawar wrote:
> Return the complete response structure from get_counter() instead of
> only the counter value. This allows callers to access additional
> response fields, such as has_info_queue for CPER record building.
>
> Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
> Assisted-by: Copilot:claude-sonnet-4.6
> ---
> drivers/gpu/drm/xe/xe_ras.c | 23 +++++++++++++++--------
> drivers/gpu/drm/xe/xe_ras_types.h | 10 ++++++++--
> 2 files changed, 23 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c
> index 85b0202467f6..e594d4d3a23f 100644
> --- a/drivers/gpu/drm/xe/xe_ras.c
> +++ b/drivers/gpu/drm/xe/xe_ras.c
> @@ -157,12 +157,12 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,
> }
> }
>
> -static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter, u32 *value)
> +static int get_counter(struct xe_device *xe, const struct xe_ras_error_class *counter,
> + struct xe_ras_get_counter_response *out)
> {
> struct xe_ras_get_counter_response response = {0};
response is not required, we can directly use "out".
> struct xe_ras_get_counter_request request = {0};
> struct xe_sysctrl_mailbox_command command = {0};
> - struct xe_ras_error_common *common;
> size_t rlen;
> int ret;
>
> @@ -183,12 +183,11 @@ static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter,
> return -EIO;
> }
>
> - common = &response.counter.common;
> - *value = response.value;
> -
> - xe_dbg(xe, "[RAS]: get counter %u for %s %s\n", *value, comp_to_str(common->component),
> - sev_to_str(common->severity));
> + xe_dbg(xe, "[RAS]: get counter value %u for %s %s\n", response.value,
> + comp_to_str(response.counter.common.component),
> + sev_to_str(response.counter.common.severity));
>
> + *out = response;
> return 0;
> }
>
> @@ -207,12 +206,20 @@ static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter,
> int xe_ras_get_counter(struct xe_device *xe, u8 severity, u8 component, u32 *value)
> {
> struct xe_ras_error_class counter = {0};
> + struct xe_ras_get_counter_response response;
Safe to initialized response = {0}.
> + int ret;
>
> counter.common.severity = drm_to_xe_ras_severity(severity);
> counter.common.component = drm_to_xe_ras_component(component);
>
> guard(xe_pm_runtime)(xe);
> - return get_counter(xe, &counter, value);
> +
> + ret = get_counter(xe, &counter, &response);
> + if (ret)
> + return ret;
> +
> + *value = response.counter_value;
counter_value is not member of response. should get compilation error.
Thanks,
-/Mallesh
> + return 0;
> }
>
> /**
> diff --git a/drivers/gpu/drm/xe/xe_ras_types.h b/drivers/gpu/drm/xe/xe_ras_types.h
> index fc496888b3f8..befdaf297103 100644
> --- a/drivers/gpu/drm/xe/xe_ras_types.h
> +++ b/drivers/gpu/drm/xe/xe_ras_types.h
> @@ -155,8 +155,14 @@ struct xe_ras_get_counter_response {
> u64 timestamp;
> /** @threshold: Threshold value for the counter */
> u32 threshold;
> - /** @reserved: Reserved */
> - u32 reserved[57];
> + /** @reserved: Reserved for future use */
> + u32 reserved:9;
> + /** @has_info_queue: Set if info queue is available */
> + u32 has_info_queue:1;
> + /** @reserved1: Reserved for future use */
> + u32 reserved1:22;
> + /** @info_queue: Initial info queue data (first chunk) if available */
> + struct xe_ras_info_queue_response info_queue;
> } __packed;
>
> /**
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-07-07 12:53 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-02 11:14 [RFC PATCH 0/7] Add CPER logging support for CRI Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 1/7] drm/xe: Add error Signature IDs for RAS logging Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 2/7] drm/xe/xe_ras: Add support to retrieve info queue data for CRI Badal Nilawar
2026-07-07 12:29 ` Mallesh, Koujalagi
2026-07-02 11:14 ` [RFC PATCH 3/7] drm/xe/xe_ras: Refactor get_counter() to return response structure Badal Nilawar
2026-07-03 7:41 ` Tauro, Riana
2026-07-07 12:53 ` Mallesh, Koujalagi
2026-07-02 11:14 ` [RFC PATCH 4/7] drm/xe/cper: Add CPER structures and trace event Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 5/7] drm/xe/cper: APIs to prepare and log CPER record Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 6/7] drm/xe/cper: Prepare Intel CPER error info from info queue Badal Nilawar
2026-07-02 11:14 ` [RFC PATCH 7/7] drm/xe/cper: Log CPER record for correctable errors Badal Nilawar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox