| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/20 09:39 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch adds a netlink multicast notification (`error-event`) sent from the kernel to userspace when hardware RAS errors occur. It does not introduce any new userspace-triggerable code paths or input parsing logic, as the event generation is driven by hardware events and the multicast subscription is handled by generic netlink code.",
"WorthFuzzing": false
} |
| 1/1 | 2026/07/20 09:39 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 965af2f9528fbaebf14b773515cb899409b6b5a8\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Mon Jul 20 09:39:21 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/Documentation/gpu/drm-ras.rst b/Documentation/gpu/drm-ras.rst\nindex 83c21853b74b60..406e4c49bac1fd 100644\n--- a/Documentation/gpu/drm-ras.rst\n+++ b/Documentation/gpu/drm-ras.rst\n@@ -56,6 +56,7 @@ User space tools can:\n ``node-id`` and ``error-id`` as parameters.\n * Clear specific error counters with the ``clear-error-counter`` command, using both\n ``node-id`` and ``error-id`` as parameters.\n+* Subscribe to the ``error-report`` multicast group to receive ``error-event``.\n \n YAML-based Interface\n --------------------\n@@ -111,3 +112,23 @@ Example: Clear an error counter for a given node\n \n sudo ynl --family drm_ras --do clear-error-counter --json '{\"node-id\":0, \"error-id\":1}'\n None\n+\n+Example: Subscribe to ``error-report`` multicast group\n+\n+.. code-block:: bash\n+\n+ sudo ynl --family drm_ras --output-json --subscribe error-report\n+\n+.. code-block:: json\n+\n+ {\n+ \"name\": \"error-event\",\n+ \"msg\": {\n+ \"device-name\": \"0000:03:00.0\",\n+ \"node-id\": 1,\n+ \"node-name\": \"uncorrectable-errors\",\n+ \"error-id\": 1,\n+ \"error-name\": \"error_name1\",\n+ \"error-value\": 1\n+ }\n+ }\ndiff --git a/Documentation/netlink/specs/drm_ras.yaml b/Documentation/netlink/specs/drm_ras.yaml\nindex e113056f8c016c..8aed3d4515e5af 100644\n--- a/Documentation/netlink/specs/drm_ras.yaml\n+++ b/Documentation/netlink/specs/drm_ras.yaml\n@@ -69,6 +69,33 @@ attribute-sets:\n name: error-value\n type: u32\n doc: Current value of the requested error counter.\n+ -\n+ name: error-event-attrs\n+ attributes:\n+ -\n+ name: device-name\n+ type: string\n+ doc: Device (PCI BDF, UUID) that reported the error.\n+ -\n+ name: node-id\n+ type: u32\n+ doc: ID of the node that reported the error.\n+ -\n+ name: node-name\n+ type: string\n+ doc: Name of the node that reported the error.\n+ -\n+ name: error-id\n+ type: u32\n+ doc: ID of the error counter.\n+ -\n+ name: error-name\n+ type: string\n+ doc: Name of the error.\n+ -\n+ name: error-value\n+ type: u32\n+ doc: Current value of the error counter.\n \n operations:\n list:\n@@ -124,3 +151,24 @@ operations:\n do:\n request:\n attributes: *id-attrs\n+ -\n+ name: error-event\n+ doc: \u003e-\n+ Report an error event to userspace.\n+ The event includes the device, node and error information\n+ of the error that triggered the event.\n+ attribute-set: error-event-attrs\n+ mcgrp: error-report\n+ event:\n+ attributes:\n+ - device-name\n+ - node-id\n+ - node-name\n+ - error-id\n+ - error-name\n+ - error-value\n+\n+mcast-groups:\n+ list:\n+ -\n+ name: error-report\ndiff --git a/drivers/gpu/drm/drm_ras.c b/drivers/gpu/drm/drm_ras.c\nindex d6eab29a1394ca..0b77e4358ea8f6 100644\n--- a/drivers/gpu/drm/drm_ras.c\n+++ b/drivers/gpu/drm/drm_ras.c\n@@ -41,6 +41,11 @@\n * Userspace must provide Node ID, Error ID.\n * Clears specific error counter of a node if supported.\n *\n+ * 4. ERROR_REPORT: Subscribe to this multicast group to receive error events\n+ *\n+ * 5. ERROR_EVENT: Report an error event to userspace. The event contains device, node\n+ * and error information that triggered the event.\n+ *\n * Node registration:\n *\n * - drm_ras_node_register(): Registers a new node and assigns\n@@ -186,6 +191,34 @@ static int msg_reply_value(struct sk_buff *msg, u32 error_id,\n \t\t\t value);\n }\n \n+static int msg_put_error_event_attrs(struct sk_buff *msg, struct drm_ras_node *node,\n+\t\t\t\t u32 error_id, const char *error_name, u32 value)\n+{\n+\tint ret;\n+\n+\tret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME, node-\u003edevice_name);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, node-\u003eid);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, node-\u003enode_name);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, error_id);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, error_name);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, value);\n+}\n+\n static int doit_reply_value(struct genl_info *info, u32 node_id,\n \t\t\t u32 error_id)\n {\n@@ -222,6 +255,57 @@ static int doit_reply_value(struct genl_info *info, u32 node_id,\n \treturn genlmsg_reply(msg, info);\n }\n \n+/**\n+ * drm_ras_nl_error_event() - Report an error event\n+ * @node: Node structure\n+ * @error_id: ID of the error\n+ * @error_name: Name of the error\n+ * @value: Value associated with the error\n+ *\n+ * Report an error-event to userspace using the error-report multicast group.\n+ *\n+ * Return: 0 on success, or negative errno on failure.\n+ */\n+int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name,\n+\t\t\t u32 value)\n+{\n+\tstruct genl_info info;\n+\tstruct sk_buff *msg;\n+\tstruct nlattr *hdr;\n+\tint ret;\n+\n+\tif (!error_name)\n+\t\treturn -EINVAL;\n+\n+\tgenl_info_init_ntf(\u0026info, \u0026drm_ras_nl_family, DRM_RAS_CMD_ERROR_EVENT);\n+\n+\tmsg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);\n+\tif (!msg)\n+\t\treturn -ENOMEM;\n+\n+\thdr = genlmsg_iput(msg, \u0026info);\n+\tif (!hdr) {\n+\t\tret = -EMSGSIZE;\n+\t\tgoto free_msg;\n+\t}\n+\n+\tret = msg_put_error_event_attrs(msg, node, error_id, error_name, value);\n+\tif (ret)\n+\t\tgoto cancel_msg;\n+\n+\tgenlmsg_end(msg, hdr);\n+\tgenlmsg_multicast_allns(\u0026drm_ras_nl_family, msg, 0, DRM_RAS_NLGRP_ERROR_REPORT);\n+\n+\treturn 0;\n+\n+cancel_msg:\n+\tgenlmsg_cancel(msg, hdr);\n+free_msg:\n+\tnlmsg_free(msg);\n+\treturn ret;\n+}\n+EXPORT_SYMBOL(drm_ras_nl_error_event);\n+\n /**\n * drm_ras_nl_get_error_counter_dumpit() - Dump all Error Counters\n * @skb: Netlink message buffer\ndiff --git a/drivers/gpu/drm/drm_ras_nl.c b/drivers/gpu/drm/drm_ras_nl.c\nindex dea1c1b2494e81..9d3123cc9f9caa 100644\n--- a/drivers/gpu/drm/drm_ras_nl.c\n+++ b/drivers/gpu/drm/drm_ras_nl.c\n@@ -58,6 +58,10 @@ static const struct genl_split_ops drm_ras_nl_ops[] = {\n \t},\n };\n \n+static const struct genl_multicast_group drm_ras_nl_mcgrps[] = {\n+\t[DRM_RAS_NLGRP_ERROR_REPORT] = { \"error-report\", },\n+};\n+\n struct genl_family drm_ras_nl_family __ro_after_init = {\n \t.name\t\t= DRM_RAS_FAMILY_NAME,\n \t.version\t= DRM_RAS_FAMILY_VERSION,\n@@ -66,4 +70,6 @@ struct genl_family drm_ras_nl_family __ro_after_init = {\n \t.module\t\t= THIS_MODULE,\n \t.split_ops\t= drm_ras_nl_ops,\n \t.n_split_ops\t= ARRAY_SIZE(drm_ras_nl_ops),\n+\t.mcgrps\t\t= drm_ras_nl_mcgrps,\n+\t.n_mcgrps\t= ARRAY_SIZE(drm_ras_nl_mcgrps),\n };\ndiff --git a/drivers/gpu/drm/drm_ras_nl.h b/drivers/gpu/drm/drm_ras_nl.h\nindex a398643572a5a0..03ec275aca9292 100644\n--- a/drivers/gpu/drm/drm_ras_nl.h\n+++ b/drivers/gpu/drm/drm_ras_nl.h\n@@ -21,6 +21,10 @@ int drm_ras_nl_get_error_counter_dumpit(struct sk_buff *skb,\n int drm_ras_nl_clear_error_counter_doit(struct sk_buff *skb,\n \t\t\t\t\tstruct genl_info *info);\n \n+enum {\n+\tDRM_RAS_NLGRP_ERROR_REPORT,\n+};\n+\n extern struct genl_family drm_ras_nl_family;\n \n #endif /* _LINUX_DRM_RAS_GEN_H */\ndiff --git a/drivers/gpu/drm/xe/xe_drm_ras.c b/drivers/gpu/drm/xe/xe_drm_ras.c\nindex 7937d8ba0ed9ce..0287594e102650 100644\n--- a/drivers/gpu/drm/xe/xe_drm_ras.c\n+++ b/drivers/gpu/drm/xe/xe_drm_ras.c\n@@ -185,6 +185,48 @@ static int register_nodes(struct xe_device *xe)\n \treturn ret;\n }\n \n+/**\n+ * xe_drm_ras_event() - Report drm_ras error event to userspace\n+ * @xe: xe device structure\n+ * @component: error component (see \u0026enum drm_xe_ras_error_component)\n+ * @severity: error severity (see \u0026enum drm_xe_ras_error_severity)\n+ * @value: value of error counter\n+ *\n+ * Report an error-event to userspace.\n+ */\n+void xe_drm_ras_event(struct xe_device *xe, u8 component, u8 severity, u32 value)\n+{\n+\tstruct xe_drm_ras *ras = \u0026xe-\u003eras;\n+\tstruct xe_drm_ras_counter *info;\n+\tstruct drm_ras_node *node;\n+\tint ret;\n+\n+\t/* Event is supported only if drm_ras is enabled */\n+\tif (!xe-\u003einfo.has_drm_ras)\n+\t\treturn;\n+\n+\tif (component \u003e= DRM_XE_RAS_ERR_COMP_MAX) {\n+\t\tdrm_warn(\u0026xe-\u003edrm, \"unsupported component %u\\n\", component);\n+\t\treturn;\n+\t}\n+\n+\tif (severity \u003e= DRM_XE_RAS_ERR_SEV_MAX) {\n+\t\tdrm_warn(\u0026xe-\u003edrm, \"unsupported severity %u\\n\", severity);\n+\t\treturn;\n+\t}\n+\n+\tnode = \u0026ras-\u003enode[severity];\n+\tinfo = ras-\u003einfo[severity];\n+\n+\tif (!info || !info[component].name)\n+\t\treturn;\n+\n+\tret = drm_ras_nl_error_event(node, component, info[component].name, value);\n+\tif (ret)\n+\t\tdrm_err_ratelimited(\u0026xe-\u003edrm, \"drm_ras error-event failed: %d for %s %s\\n\", ret,\n+\t\t\t\t info[component].name, error_severity[severity]);\n+}\n+\n /**\n * xe_drm_ras_init() - Initialize DRM RAS\n * @xe: xe device instance\ndiff --git a/drivers/gpu/drm/xe/xe_drm_ras.h b/drivers/gpu/drm/xe/xe_drm_ras.h\nindex 365c70e93e82fd..add96bf1a7abd6 100644\n--- a/drivers/gpu/drm/xe/xe_drm_ras.h\n+++ b/drivers/gpu/drm/xe/xe_drm_ras.h\n@@ -5,11 +5,14 @@\n #ifndef _XE_DRM_RAS_H_\n #define _XE_DRM_RAS_H_\n \n+#include \u003clinux/types.h\u003e\n+\n struct xe_device;\n \n #define for_each_error_severity(i)\t\\\n \tfor (i = 0; i \u003c DRM_XE_RAS_ERR_SEV_MAX; i++)\n \n int xe_drm_ras_init(struct xe_device *xe);\n+void xe_drm_ras_event(struct xe_device *xe, u8 component, u8 severity, u32 value);\n \n #endif\ndiff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c\nindex ed609912fda140..462cbb548f07ba 100644\n--- a/drivers/gpu/drm/xe/xe_ras.c\n+++ b/drivers/gpu/drm/xe/xe_ras.c\n@@ -89,6 +89,8 @@ static const char * const gpu_health_states[] = {\n };\n static_assert(ARRAY_SIZE(gpu_health_states) == XE_RAS_HEALTH_MAX);\n \n+static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter, u32 *value);\n+\n static u8 drm_to_xe_ras_severity(u8 severity)\n {\n \tswitch (severity) {\n@@ -101,6 +103,18 @@ static u8 drm_to_xe_ras_severity(u8 severity)\n \t}\n }\n \n+static u8 xe_to_drm_ras_severity(u8 severity)\n+{\n+\tswitch (severity) {\n+\tcase XE_RAS_SEV_CORRECTABLE:\n+\t\treturn DRM_XE_RAS_ERR_SEV_CORRECTABLE;\n+\tcase XE_RAS_SEV_UNCORRECTABLE:\n+\t\treturn DRM_XE_RAS_ERR_SEV_UNCORRECTABLE;\n+\tdefault:\n+\t\treturn DRM_XE_RAS_ERR_SEV_MAX;\n+\t}\n+}\n+\n static u8 drm_to_xe_ras_component(u8 component)\n {\n \tswitch (component) {\n@@ -119,6 +133,24 @@ static u8 drm_to_xe_ras_component(u8 component)\n \t}\n }\n \n+static u8 xe_to_drm_ras_component(u8 component)\n+{\n+\tswitch (component) {\n+\tcase XE_RAS_COMP_DEVICE_MEMORY:\n+\t\treturn DRM_XE_RAS_ERR_COMP_DEVICE_MEMORY;\n+\tcase XE_RAS_COMP_CORE_COMPUTE:\n+\t\treturn DRM_XE_RAS_ERR_COMP_CORE_COMPUTE;\n+\tcase XE_RAS_COMP_PCIE:\n+\t\treturn DRM_XE_RAS_ERR_COMP_PCIE;\n+\tcase XE_RAS_COMP_FABRIC:\n+\t\treturn DRM_XE_RAS_ERR_COMP_FABRIC;\n+\tcase XE_RAS_COMP_SOC_INTERNAL:\n+\t\treturn DRM_XE_RAS_ERR_COMP_SOC_INTERNAL;\n+\tdefault:\n+\t\treturn DRM_XE_RAS_ERR_COMP_MAX;\n+\t}\n+}\n+\n static int ras_status_to_errno(u32 status)\n {\n \tswitch (status) {\n@@ -217,6 +249,26 @@ static void ras_usp_aer_init(struct xe_device *xe)\n \tdev_dbg(\u0026usp-\u003edev, \"Uncorrectable Internal Errors downgraded and unmasked\\n\");\n }\n \n+static void ras_send_error_event(struct xe_device *xe, u8 severity, u8 component)\n+{\n+\tstruct xe_ras_error_class counter = {0};\n+\tu8 drm_severity, drm_component;\n+\tu32 value;\n+\tint ret;\n+\n+\tcounter.common.severity = severity;\n+\tcounter.common.component = component;\n+\n+\tret = get_counter(xe, \u0026counter, \u0026value);\n+\tif (ret)\n+\t\treturn;\n+\n+\tdrm_severity = xe_to_drm_ras_severity(severity);\n+\tdrm_component = xe_to_drm_ras_component(component);\n+\n+\txe_drm_ras_event(xe, drm_component, drm_severity, value);\n+}\n+\n static u8 handle_core_compute_errors(struct xe_ras_error_array *arr)\n {\n \tstruct xe_ras_compute_error *error_info = (void *)arr-\u003edetails;\n@@ -241,8 +293,10 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,\n \tstruct xe_ras_threshold_crossed *pending = (void *)\u0026response-\u003edata;\n \tstruct xe_ras_error_class *errors = pending-\u003ecounters;\n \tu32 id, ncounters = pending-\u003encounters;\n+\tu8 sent = 0;\n \n \tBUILD_BUG_ON(sizeof(response-\u003edata) \u003c sizeof(*pending));\n+\tBUILD_BUG_ON(BITS_PER_TYPE(sent) \u003c XE_RAS_COMP_MAX);\n \txe_device_assert_mem_access(xe);\n \n \tif (!ncounters || ncounters \u003e XE_RAS_NUM_COUNTERS)\n@@ -256,8 +310,21 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,\n \t\tseverity = errors[id].common.severity;\n \t\tcomponent = errors[id].common.component;\n \n+\t\tif (severity != XE_RAS_SEV_CORRECTABLE) {\n+\t\t\txe_warn(xe, \"sysctrl: unexpected severity %s (%u)\\n\", sev_to_str(severity),\n+\t\t\t\tseverity);\n+\t\t\tcontinue;\n+\t\t}\n+\n \t\txe_warn(xe, \"[RAS]: %s %s detected\\n\",\n \t\t\tcomp_to_str(component), sev_to_str(severity));\n+\n+\t\t/* Send event once per component */\n+\t\tif (sent \u0026 BIT(component))\n+\t\t\tcontinue;\n+\t\tsent |= BIT(component);\n+\n+\t\tras_send_error_event(xe, severity, component);\n \t}\n }\n \n@@ -311,6 +378,7 @@ enum xe_ras_recovery_action xe_ras_process_errors(struct xe_device *xe)\n \tenum xe_ras_recovery_action final_action;\n \tu32 remaining = XE_SYSCTRL_FLOOD_LIMIT;\n \tstruct xe_ras_get_soc_error response;\n+\tu8 sent = 0;\n \tsize_t rlen;\n \tint ret;\n \n@@ -354,6 +422,12 @@ enum xe_ras_recovery_action xe_ras_process_errors(struct xe_device *xe)\n \t\t\txe_info(xe, \"[RAS]: %s %s detected\\n\", comp_to_str(component),\n \t\t\t\tsev_to_str(severity));\n \n+\t\t\t/* Send event once per component */\n+\t\t\tif (!(sent \u0026 BIT(component))) {\n+\t\t\t\tsent |= BIT(component);\n+\t\t\t\tras_send_error_event(xe, severity, component);\n+\t\t\t}\n+\n \t\t\tswitch (component) {\n \t\t\tcase XE_RAS_COMP_CORE_COMPUTE:\n \t\t\t\taction = handle_core_compute_errors(arr);\ndiff --git a/include/drm/drm_ras.h b/include/drm/drm_ras.h\nindex 0beede3ddc4e4b..ee2caa0edc6f92 100644\n--- a/include/drm/drm_ras.h\n+++ b/include/drm/drm_ras.h\n@@ -80,9 +80,14 @@ struct drm_device;\n #if IS_ENABLED(CONFIG_DRM_RAS)\n int drm_ras_node_register(struct drm_ras_node *node);\n void drm_ras_node_unregister(struct drm_ras_node *node);\n+int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name,\n+\t\t\t u32 value);\n #else\n static inline int drm_ras_node_register(struct drm_ras_node *node) { return 0; }\n static inline void drm_ras_node_unregister(struct drm_ras_node *node) { }\n+static inline int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id,\n+\t\t\t\t\t const char *error_name, u32 value)\n+{ return 0; }\n #endif\n \n #endif\ndiff --git a/include/uapi/drm/drm_ras.h b/include/uapi/drm/drm_ras.h\nindex 218a3ee8680527..eab8231aa87cbf 100644\n--- a/include/uapi/drm/drm_ras.h\n+++ b/include/uapi/drm/drm_ras.h\n@@ -38,13 +38,28 @@ enum {\n \tDRM_RAS_A_ERROR_COUNTER_ATTRS_MAX = (__DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX - 1)\n };\n \n+enum {\n+\tDRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME = 1,\n+\tDRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID,\n+\tDRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME,\n+\tDRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID,\n+\tDRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME,\n+\tDRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE,\n+\n+\t__DRM_RAS_A_ERROR_EVENT_ATTRS_MAX,\n+\tDRM_RAS_A_ERROR_EVENT_ATTRS_MAX = (__DRM_RAS_A_ERROR_EVENT_ATTRS_MAX - 1)\n+};\n+\n enum {\n \tDRM_RAS_CMD_LIST_NODES = 1,\n \tDRM_RAS_CMD_GET_ERROR_COUNTER,\n \tDRM_RAS_CMD_CLEAR_ERROR_COUNTER,\n+\tDRM_RAS_CMD_ERROR_EVENT,\n \n \t__DRM_RAS_CMD_MAX,\n \tDRM_RAS_CMD_MAX = (__DRM_RAS_CMD_MAX - 1)\n };\n \n+#define DRM_RAS_MCGRP_ERROR_REPORT\t\"error-report\"\n+\n #endif /* _UAPI_LINUX_DRM_RAS_H */\n"
} |
| 2/1 | 2026/07/20 09:39 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch adds a netlink multicast notification (`error-event`) sent from the kernel to userspace when hardware RAS errors occur. It does not introduce any new userspace-triggerable code paths or input parsing logic, as the event generation is driven by hardware events and the multicast subscription is handled by generic netlink code.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 965af2f9528fbaebf14b773515cb899409b6b5a8
Author: syz-cluster <triage@syzkaller.com>
Date: Mon Jul 20 09:39:21 2026 +0000
syz-cluster: applied patch under review
diff --git a/Documentation/gpu/drm-ras.rst b/Documentation/gpu/drm-ras.rst
index 83c21853b74b60..406e4c49bac1fd 100644
--- a/Documentation/gpu/drm-ras.rst
+++ b/Documentation/gpu/drm-ras.rst
@@ -56,6 +56,7 @@ User space tools can:
``node-id`` and ``error-id`` as parameters.
* Clear specific error counters with the ``clear-error-counter`` command, using both
``node-id`` and ``error-id`` as parameters.
+* Subscribe to the ``error-report`` multicast group to receive ``error-event``.
YAML-based Interface
--------------------
@@ -111,3 +112,23 @@ Example: Clear an error counter for a given node
sudo ynl --family drm_ras --do clear-error-counter --json '{"node-id":0, "error-id":1}'
None
+
+Example: Subscribe to ``error-report`` multicast group
+
+.. code-block:: bash
+
+ sudo ynl --family drm_ras --output-json --subscribe error-report
+
+.. code-block:: json
+
+ {
+ "name": "error-event",
+ "msg": {
+ "device-name": "0000:03:00.0",
+ "node-id": 1,
+ "node-name": "uncorrectable-errors",
+ "error-id": 1,
+ "error-name": "error_name1",
+ "error-value": 1
+ }
+ }
diff --git a/Documentation/netlink/specs/drm_ras.yaml b/Documentation/netlink/specs/drm_ras.yaml
index e113056f8c016c..8aed3d4515e5af 100644
--- a/Documentation/netlink/specs/drm_ras.yaml
+++ b/Documentation/netlink/specs/drm_ras.yaml
@@ -69,6 +69,33 @@ attribute-sets:
name: error-value
type: u32
doc: Current value of the requested error counter.
+ -
+ name: error-event-attrs
+ attributes:
+ -
+ name: device-name
+ type: string
+ doc: Device (PCI BDF, UUID) that reported the error.
+ -
+ name: node-id
+ type: u32
+ doc: ID of the node that reported the error.
+ -
+ name: node-name
+ type: string
+ doc: Name of the node that reported the error.
+ -
+ name: error-id
+ type: u32
+ doc: ID of the error counter.
+ -
+ name: error-name
+ type: string
+ doc: Name of the error.
+ -
+ name: error-value
+ type: u32
+ doc: Current value of the error counter.
operations:
list:
@@ -124,3 +151,24 @@ operations:
do:
request:
attributes: *id-attrs
+ -
+ name: error-event
+ doc: >-
+ Report an error event to userspace.
+ The event includes the device, node and error information
+ of the error that triggered the event.
+ attribute-set: error-event-attrs
+ mcgrp: error-report
+ event:
+ attributes:
+ - device-name
+ - node-id
+ - node-name
+ - error-id
+ - error-name
+ - error-value
+
+mcast-groups:
+ list:
+ -
+ name: error-report
diff --git a/drivers/gpu/drm/drm_ras.c b/drivers/gpu/drm/drm_ras.c
index d6eab29a1394ca..0b77e4358ea8f6 100644
--- a/drivers/gpu/drm/drm_ras.c
+++ b/drivers/gpu/drm/drm_ras.c
@@ -41,6 +41,11 @@
* Userspace must provide Node ID, Error ID.
* Clears specific error counter of a node if supported.
*
+ * 4. ERROR_REPORT: Subscribe to this multicast group to receive error events
+ *
+ * 5. ERROR_EVENT: Report an error event to userspace. The event contains device, node
+ * and error information that triggered the event.
+ *
* Node registration:
*
* - drm_ras_node_register(): Registers a new node and assigns
@@ -186,6 +191,34 @@ static int msg_reply_value(struct sk_buff *msg, u32 error_id,
value);
}
+static int msg_put_error_event_attrs(struct sk_buff *msg, struct drm_ras_node *node,
+ u32 error_id, const char *error_name, u32 value)
+{
+ int ret;
+
+ ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME, node->device_name);
+ if (ret)
+ return ret;
+
+ ret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, node->id);
+ if (ret)
+ return ret;
+
+ ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, node->node_name);
+ if (ret)
+ return ret;
+
+ ret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, error_id);
+ if (ret)
+ return ret;
+
+ ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, error_name);
+ if (ret)
+ return ret;
+
+ return nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, value);
+}
+
static int doit_reply_value(struct genl_info *info, u32 node_id,
u32 error_id)
{
@@ -222,6 +255,57 @@ static int doit_reply_value(struct genl_info *info, u32 node_id,
return genlmsg_reply(msg, info);
}
+/**
+ * drm_ras_nl_error_event() - Report an error event
+ * @node: Node structure
+ * @error_id: ID of the error
+ * @error_name: Name of the error
+ * @value: Value associated with the error
+ *
+ * Report an error-event to userspace using the error-report multicast group.
+ *
+ * Return: 0 on success, or negative errno on failure.
+ */
+int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name,
+ u32 value)
+{
+ struct genl_info info;
+ struct sk_buff *msg;
+ struct nlattr *hdr;
+ int ret;
+
+ if (!error_name)
+ return -EINVAL;
+
+ genl_info_init_ntf(&info, &drm_ras_nl_family, DRM_RAS_CMD_ERROR_EVENT);
+
+ msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ hdr = genlmsg_iput(msg, &info);
+ if (!hdr) {
+ ret = -EMSGSIZE;
+ goto free_msg;
+ }
+
+ ret = msg_put_error_event_attrs(msg, node, error_id, error_name, value);
+ if (ret)
+ goto cancel_msg;
+
+ genlmsg_end(msg, hdr);
+ genlmsg_multicast_allns(&drm_ras_nl_family, msg, 0, DRM_RAS_NLGRP_ERROR_REPORT);
+
+ return 0;
+
+cancel_msg:
+ genlmsg_cancel(msg, hdr);
+free_msg:
+ nlmsg_free(msg);
+ return ret;
+}
+EXPORT_SYMBOL(drm_ras_nl_error_event);
+
/**
* drm_ras_nl_get_error_counter_dumpit() - Dump all Error Counters
* @skb: Netlink message buffer
diff --git a/drivers/gpu/drm/drm_ras_nl.c b/drivers/gpu/drm/drm_ras_nl.c
index dea1c1b2494e81..9d3123cc9f9caa 100644
--- a/drivers/gpu/drm/drm_ras_nl.c
+++ b/drivers/gpu/drm/drm_ras_nl.c
@@ -58,6 +58,10 @@ static const struct genl_split_ops drm_ras_nl_ops[] = {
},
};
+static const struct genl_multicast_group drm_ras_nl_mcgrps[] = {
+ [DRM_RAS_NLGRP_ERROR_REPORT] = { "error-report", },
+};
+
struct genl_family drm_ras_nl_family __ro_after_init = {
.name = DRM_RAS_FAMILY_NAME,
.version = DRM_RAS_FAMILY_VERSION,
@@ -66,4 +70,6 @@ struct genl_family drm_ras_nl_family __ro_after_init = {
.module = THIS_MODULE,
.split_ops = drm_ras_nl_ops,
.n_split_ops = ARRAY_SIZE(drm_ras_nl_ops),
+ .mcgrps = drm_ras_nl_mcgrps,
+ .n_mcgrps = ARRAY_SIZE(drm_ras_nl_mcgrps),
};
diff --git a/drivers/gpu/drm/drm_ras_nl.h b/drivers/gpu/drm/drm_ras_nl.h
index a398643572a5a0..03ec275aca9292 100644
--- a/drivers/gpu/drm/drm_ras_nl.h
+++ b/drivers/gpu/drm/drm_ras_nl.h
@@ -21,6 +21,10 @@ int drm_ras_nl_get_error_counter_dumpit(struct sk_buff *skb,
int drm_ras_nl_clear_error_counter_doit(struct sk_buff *skb,
struct genl_info *info);
+enum {
+ DRM_RAS_NLGRP_ERROR_REPORT,
+};
+
extern struct genl_family drm_ras_nl_family;
#endif /* _LINUX_DRM_RAS_GEN_H */
diff --git a/drivers/gpu/drm/xe/xe_drm_ras.c b/drivers/gpu/drm/xe/xe_drm_ras.c
index 7937d8ba0ed9ce..0287594e102650 100644
--- a/drivers/gpu/drm/xe/xe_drm_ras.c
+++ b/drivers/gpu/drm/xe/xe_drm_ras.c
@@ -185,6 +185,48 @@ static int register_nodes(struct xe_device *xe)
return ret;
}
+/**
+ * xe_drm_ras_event() - Report drm_ras error event to userspace
+ * @xe: xe device structure
+ * @component: error component (see &enum drm_xe_ras_error_component)
+ * @severity: error severity (see &enum drm_xe_ras_error_severity)
+ * @value: value of error counter
+ *
+ * Report an error-event to userspace.
+ */
+void xe_drm_ras_event(struct xe_device *xe, u8 component, u8 severity, u32 value)
+{
+ struct xe_drm_ras *ras = &xe->ras;
+ struct xe_drm_ras_counter *info;
+ struct drm_ras_node *node;
+ int ret;
+
+ /* Event is supported only if drm_ras is enabled */
+ if (!xe->info.has_drm_ras)
+ return;
+
+ if (component >= DRM_XE_RAS_ERR_COMP_MAX) {
+ drm_warn(&xe->drm, "unsupported component %u\n", component);
+ return;
+ }
+
+ if (severity >= DRM_XE_RAS_ERR_SEV_MAX) {
+ drm_warn(&xe->drm, "unsupported severity %u\n", severity);
+ return;
+ }
+
+ node = &ras->node[severity];
+ info = ras->info[severity];
+
+ if (!info || !info[component].name)
+ return;
+
+ ret = drm_ras_nl_error_event(node, component, info[component].name, value);
+ if (ret)
+ drm_err_ratelimited(&xe->drm, "drm_ras error-event failed: %d for %s %s\n", ret,
+ info[component].name, error_severity[severity]);
+}
+
/**
* xe_drm_ras_init() - Initialize DRM RAS
* @xe: xe device instance
diff --git a/drivers/gpu/drm/xe/xe_drm_ras.h b/drivers/gpu/drm/xe/xe_drm_ras.h
index 365c70e93e82fd..add96bf1a7abd6 100644
--- a/drivers/gpu/drm/xe/xe_drm_ras.h
+++ b/drivers/gpu/drm/xe/xe_drm_ras.h
@@ -5,11 +5,14 @@
#ifndef _XE_DRM_RAS_H_
#define _XE_DRM_RAS_H_
+#include <linux/types.h>
+
struct xe_device;
#define for_each_error_severity(i) \
for (i = 0; i < DRM_XE_RAS_ERR_SEV_MAX; i++)
int xe_drm_ras_init(struct xe_device *xe);
+void xe_drm_ras_event(struct xe_device *xe, u8 component, u8 severity, u32 value);
#endif
diff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c
index ed609912fda140..462cbb548f07ba 100644
--- a/drivers/gpu/drm/xe/xe_ras.c
+++ b/drivers/gpu/drm/xe/xe_ras.c
@@ -89,6 +89,8 @@ static const char * const gpu_health_states[] = {
};
static_assert(ARRAY_SIZE(gpu_health_states) == XE_RAS_HEALTH_MAX);
+static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter, u32 *value);
+
static u8 drm_to_xe_ras_severity(u8 severity)
{
switch (severity) {
@@ -101,6 +103,18 @@ static u8 drm_to_xe_ras_severity(u8 severity)
}
}
+static u8 xe_to_drm_ras_severity(u8 severity)
+{
+ switch (severity) {
+ case XE_RAS_SEV_CORRECTABLE:
+ return DRM_XE_RAS_ERR_SEV_CORRECTABLE;
+ case XE_RAS_SEV_UNCORRECTABLE:
+ return DRM_XE_RAS_ERR_SEV_UNCORRECTABLE;
+ default:
+ return DRM_XE_RAS_ERR_SEV_MAX;
+ }
+}
+
static u8 drm_to_xe_ras_component(u8 component)
{
switch (component) {
@@ -119,6 +133,24 @@ static u8 drm_to_xe_ras_component(u8 component)
}
}
+static u8 xe_to_drm_ras_component(u8 component)
+{
+ switch (component) {
+ case XE_RAS_COMP_DEVICE_MEMORY:
+ return DRM_XE_RAS_ERR_COMP_DEVICE_MEMORY;
+ case XE_RAS_COMP_CORE_COMPUTE:
+ return DRM_XE_RAS_ERR_COMP_CORE_COMPUTE;
+ case XE_RAS_COMP_PCIE:
+ return DRM_XE_RAS_ERR_COMP_PCIE;
+ case XE_RAS_COMP_FABRIC:
+ return DRM_XE_RAS_ERR_COMP_FABRIC;
+ case XE_RAS_COMP_SOC_INTERNAL:
+ return DRM_XE_RAS_ERR_COMP_SOC_INTERNAL;
+ default:
+ return DRM_XE_RAS_ERR_COMP_MAX;
+ }
+}
+
static int ras_status_to_errno(u32 status)
{
switch (status) {
@@ -217,6 +249,26 @@ static void ras_usp_aer_init(struct xe_device *xe)
dev_dbg(&usp->dev, "Uncorrectable Internal Errors downgraded and unmasked\n");
}
+static void ras_send_error_event(struct xe_device *xe, u8 severity, u8 component)
+{
+ struct xe_ras_error_class counter = {0};
+ u8 drm_severity, drm_component;
+ u32 value;
+ int ret;
+
+ counter.common.severity = severity;
+ counter.common.component = component;
+
+ ret = get_counter(xe, &counter, &value);
+ if (ret)
+ return;
+
+ drm_severity = xe_to_drm_ras_severity(severity);
+ drm_component = xe_to_drm_ras_component(component);
+
+ xe_drm_ras_event(xe, drm_component, drm_severity, value);
+}
+
static u8 handle_core_compute_errors(struct xe_ras_error_array *arr)
{
struct xe_ras_compute_error *error_info = (void *)arr->details;
@@ -241,8 +293,10 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,
struct xe_ras_threshold_crossed *pending = (void *)&response->data;
struct xe_ras_error_class *errors = pending->counters;
u32 id, ncounters = pending->ncounters;
+ u8 sent = 0;
BUILD_BUG_ON(sizeof(response->data) < sizeof(*pending));
+ BUILD_BUG_ON(BITS_PER_TYPE(sent) < XE_RAS_COMP_MAX);
xe_device_assert_mem_access(xe);
if (!ncounters || ncounters > XE_RAS_NUM_COUNTERS)
@@ -256,8 +310,21 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,
severity = errors[id].common.severity;
component = errors[id].common.component;
+ if (severity != XE_RAS_SEV_CORRECTABLE) {
+ xe_warn(xe, "sysctrl: unexpected severity %s (%u)\n", sev_to_str(severity),
+ severity);
+ continue;
+ }
+
xe_warn(xe, "[RAS]: %s %s detected\n",
comp_to_str(component), sev_to_str(severity));
+
+ /* Send event once per component */
+ if (sent & BIT(component))
+ continue;
+ sent |= BIT(component);
+
+ ras_send_error_event(xe, severity, component);
}
}
@@ -311,6 +378,7 @@ enum xe_ras_recovery_action xe_ras_process_errors(struct xe_device *xe)
enum xe_ras_recovery_action final_action;
u32 remaining = XE_SYSCTRL_FLOOD_LIMIT;
struct xe_ras_get_soc_error response;
+ u8 sent = 0;
size_t rlen;
int ret;
@@ -354,6 +422,12 @@ enum xe_ras_recovery_action xe_ras_process_errors(struct xe_device *xe)
xe_info(xe, "[RAS]: %s %s detected\n", comp_to_str(component),
sev_to_str(severity));
+ /* Send event once per component */
+ if (!(sent & BIT(component))) {
+ sent |= BIT(component);
+ ras_send_error_event(xe, severity, component);
+ }
+
switch (component) {
case XE_RAS_COMP_CORE_COMPUTE:
action = handle_core_compute_errors(arr);
diff --git a/include/drm/drm_ras.h b/include/drm/drm_ras.h
index 0beede3ddc4e4b..ee2caa0edc6f92 100644
--- a/include/drm/drm_ras.h
+++ b/include/drm/drm_ras.h
@@ -80,9 +80,14 @@ struct drm_device;
#if IS_ENABLED(CONFIG_DRM_RAS)
int drm_ras_node_register(struct drm_ras_node *node);
void drm_ras_node_unregister(struct drm_ras_node *node);
+int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name,
+ u32 value);
#else
static inline int drm_ras_node_register(struct drm_ras_node *node) { return 0; }
static inline void drm_ras_node_unregister(struct drm_ras_node *node) { }
+static inline int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id,
+ const char *error_name, u32 value)
+{ return 0; }
#endif
#endif
diff --git a/include/uapi/drm/drm_ras.h b/include/uapi/drm/drm_ras.h
index 218a3ee8680527..eab8231aa87cbf 100644
--- a/include/uapi/drm/drm_ras.h
+++ b/include/uapi/drm/drm_ras.h
@@ -38,13 +38,28 @@ enum {
DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX = (__DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX - 1)
};
+enum {
+ DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME = 1,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE,
+
+ __DRM_RAS_A_ERROR_EVENT_ATTRS_MAX,
+ DRM_RAS_A_ERROR_EVENT_ATTRS_MAX = (__DRM_RAS_A_ERROR_EVENT_ATTRS_MAX - 1)
+};
+
enum {
DRM_RAS_CMD_LIST_NODES = 1,
DRM_RAS_CMD_GET_ERROR_COUNTER,
DRM_RAS_CMD_CLEAR_ERROR_COUNTER,
+ DRM_RAS_CMD_ERROR_EVENT,
__DRM_RAS_CMD_MAX,
DRM_RAS_CMD_MAX = (__DRM_RAS_CMD_MAX - 1)
};
+#define DRM_RAS_MCGRP_ERROR_REPORT "error-report"
+
#endif /* _UAPI_LINUX_DRM_RAS_H */
|
| 3/2 | 2026/07/20 09:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 7920 output: 23 thoughts: 1022 Thoughts: **Analysis of the New Netlink Multicast Event for DRM RAS** Okay, so I'm looking at this patch and immediately, it's about adding an `error-event` netlink multicast event to the existing `drm_ras` netlink family. My initial thoughts are that it's good that we're expanding our error reporting capabilities, but let's see where the risks lie. The patch touches a bunch of files, mostly in the DRM and specifically the `xe` driver areas, along with related header and documentation files, which is expected for something like this. The core of it seems to be `drm_ras_nl_error_event`, which is responsible for sending the actual netlink multicast event. It modifies the `xe` driver to call this function through `xe_drm_ras_event` and subsequently through `ras_send_error_event`, eventually originating from hardware error handlers like `xe_ras_counter_threshold_crossed` and `xe_ras_process_errors`. Now, the main question is always: *is this reachable from userspace?* The documentation is pretty clear about `error-event` being *to* userspace. The patch introduces a multicast group, `error-report`, to which userspace can subscribe. It seems the event itself is triggered by the kernel, specifically by the `xe` driver when RAS errors happen. A quick double-check: is there any way for userspace to trigger `xe_ras_counter_threshold_crossed` or `xe_ras_process_errors` directly? These appear to be hardware error handlers, so it seems unlikely. I quickly check the netlink part: It merely defines the multicast group and the event attributes. There's no new `doit` or `dumpit` operation for userspace to call, nothing that could trigger an event other than subscribing to the multicast group. Looking at the definition of `DRM_RAS_CMD_ERROR_EVENT` in the `include/uapi/drm/drm_ras.h`, along with the `drm_ras.yaml` file, it confirms this is an event *sent to* userspace, with information like device name, node ID, and error details. I'm verifying by examining `drivers/gpu/drm/drm_ras.c`. `drm_ras_nl_error_event` clearly creates and sends the netlink notification. The `msg_put_error_event_attrs` is solely about populating the event data. The `xe` driver changes are only about calling this function when hardware errors are encountered. So, since it's only an outbound netlink notification, and no new code paths triggered *by* userspace, the risk of fuzzing is minimal... unless, of course, there's some sort of implicit vulnerability in the netlink infrastructure itself, or, as a more remote possibility, if these hardware events triggered by some other means like debugfs or sysfs. I would now use `grepper` to search for injection or triggering of those error events. Given my understanding of the system, this feels like it will be a low priority for fuzzing, unless `grepper` reveals some hidden interaction. |
| 4/2 | 2026/07/20 09:39 | tool | grepper |
0mArgs:{
"Expression": "xe_ras_counter_threshold_crossed"
}Results: {
"Output": "drivers/gpu/drm/xe/xe_ras.c=272=static u8 handle_core_compute_errors(struct xe_ras_error_array *arr)\n--\ndrivers/gpu/drm/xe/xe_ras.c-289-\ndrivers/gpu/drm/xe/xe_ras.c:290:void xe_ras_counter_threshold_crossed(struct xe_device *xe,\ndrivers/gpu/drm/xe/xe_ras.c-291-\t\t\t\t struct xe_sysctrl_event_response *response)\n--\ndrivers/gpu/drm/xe/xe_ras.h=13=struct xe_sysctrl_event_response;\ndrivers/gpu/drm/xe/xe_ras.h-14-\ndrivers/gpu/drm/xe/xe_ras.h:15:void xe_ras_counter_threshold_crossed(struct xe_device *xe,\ndrivers/gpu/drm/xe/xe_ras.h-16-\t\t\t\t struct xe_sysctrl_event_response *response);\n--\ndrivers/gpu/drm/xe/xe_sysctrl_event.c=15=static void get_pending_event(struct xe_sysctrl *sc, struct xe_sysctrl_mailbox_command *command)\n--\ndrivers/gpu/drm/xe/xe_sysctrl_event.c-38-\t\tif (response-\u003eevent == XE_SYSCTRL_EVENT_THRESHOLD_CROSSED)\ndrivers/gpu/drm/xe/xe_sysctrl_event.c:39:\t\t\txe_ras_counter_threshold_crossed(xe, response);\ndrivers/gpu/drm/xe/xe_sysctrl_event.c-40-\t\telse\n"
} |
| 5/2 | 2026/07/20 09:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 10054 output: 21 thoughts: 46 Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue: **Investigating the RAS Error Flow** Alright, let's see... so `xe_ras_counter_threshold_crossed` gets triggered from `xe_sysctrl_event.c`. Makes sense, that's where the hardware event handling lives. That tells me this function is a key part of the real-time response to a RAS event. What I need to understand now is the relationship of that function to others. I'm especially interested in understanding the flow of this code. Where does it fit into the bigger picture of error handling? I'm starting to think about this... how does that threshold crossing relate to the other RAS error handling functions? What happens next? Where is `xe_ras_process_errors` used? I'll need to go find where `xe_ras_process_errors` is called. It's probably invoked either from here directly, or from somewhere deeper in the call stack. This threshold crossed event has to feed into some kind of error processing, right? The key now is tracking down that connection, figuring out how the data flows from one to the next, and what the overall error handling state machine looks like. I'll need to dig into the call graphs. |
| 6/2 | 2026/07/20 09:39 | tool | grepper |
0mArgs:{
"Expression": "xe_ras_process_errors"
}Results: {
"Output": "drivers/gpu/drm/xe/xe_pci_error.c=78=static pci_ers_result_t xe_pci_error_mmio_enabled(struct pci_dev *pdev)\n--\ndrivers/gpu/drm/xe/xe_pci_error.c-83-\txe_info(xe, \"PCI error: MMIO enabled\\n\");\ndrivers/gpu/drm/xe/xe_pci_error.c:84:\taction = xe_ras_process_errors(xe);\ndrivers/gpu/drm/xe/xe_pci_error.c-85-\n--\ndrivers/gpu/drm/xe/xe_ras.c=331=static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter, u32 *value)\n--\ndrivers/gpu/drm/xe/xe_ras.c-366-/**\ndrivers/gpu/drm/xe/xe_ras.c:367: * xe_ras_process_errors() - Process and contain hardware errors\ndrivers/gpu/drm/xe/xe_ras.c-368- * @xe: xe device instance\n--\ndrivers/gpu/drm/xe/xe_ras.c-374- */\ndrivers/gpu/drm/xe/xe_ras.c:375:enum xe_ras_recovery_action xe_ras_process_errors(struct xe_device *xe)\ndrivers/gpu/drm/xe/xe_ras.c-376-{\n--\ndrivers/gpu/drm/xe/xe_ras.c=677=void xe_ras_init(struct xe_device *xe)\n--\ndrivers/gpu/drm/xe/xe_ras.c-696-\t */\ndrivers/gpu/drm/xe/xe_ras.c:697:\txe_ras_process_errors(xe);\ndrivers/gpu/drm/xe/xe_ras.c-698-\tret = devm_device_add_group(xe-\u003edrm.dev, \u0026gpu_health_group);\n--\ndrivers/gpu/drm/xe/xe_ras.h=19=void xe_ras_init(struct xe_device *xe);\ndrivers/gpu/drm/xe/xe_ras.h:20:enum xe_ras_recovery_action xe_ras_process_errors(struct xe_device *xe);\ndrivers/gpu/drm/xe/xe_ras.h-21-\n"
} |
| 7/2 | 2026/07/20 09:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 10995 output: 96 thoughts: 564 Thoughts: **Fuzzing Analysis: No New Userspace Attack Surface** Okay, let's break this down. My analysis focuses on identifying new attack surfaces introduced by this patch – specifically, anything reachable by userspace that could be fuzzed. I've traced the flow. `xe_ras_process_errors` is triggered internally – by `xe_pci_error_mmio_enabled` and `xe_ras_init`. Nothing here seems directly exposed to userspace except, perhaps, during initialisation or error recovery. The critical change is the addition of a netlink notification. This immediately triggers my suspicion; is there any new parsing of userspace-provided input? I see that `drm_ras` netlink family is already established. This patch introduces `error-event` to `drm_ras.yaml` and `drm_ras.c`. That’s my primary concern. However, upon inspection, `drm_ras_nl_error_event` is *exported* and called from the driver, but the patch doesn't add any code to parse incoming userspace input. The new code is `msg_put_error_event_attrs`, which constructs the netlink message *sent* to userspace. The userspace interaction is solely subscribing to the multicast group. That’s generic netlink territory. `drm_ras` is only concerned with the *sending* side. Thus, there is *no* new userspace-reachable code introduced. This is just a notification channel, kernel to userspace. I'm double-checking the documentation changes for `drm_ras.yaml`. Ah, it's adding `error-event-attrs` and an `error-event` operation, along with an `error-report` multicast group. The `event:` designation for `error-event` confirms it's a notification – there are no `do:` or `dump:` commands here. My conclusion is clear: this patch doesn't add any new userspace-triggerable code paths. `drm_ras_nl_error_event`, `xe_drm_ras_event` and `ras_send_error_event` are simply formatting and transmitting error information. There are no new ioctls, sysfs entries, debugfs files, or netlink commands that userspace can initiate. Therefore, WorthFuzzing=false. I am confident in that assessment. |
| 8/2 | 2026/07/20 09:39 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch adds a netlink multicast notification (`error-event`) sent from the kernel to userspace when hardware RAS errors occur. It does not introduce any new userspace-triggerable code paths or input parsing logic, as the event generation is driven by hardware events and the multicast subscription is handled by generic netlink code.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch adds a netlink multicast notification (`error-event`) sent from the kernel to userspace when hardware RAS errors occur. It does not introduce any new userspace-triggerable code paths or input parsing logic, as the event generation is driven by hardware events and the multicast subscription is handled by generic netlink code.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|