1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2026 Intel Corporation 4 */ 5 6 #include <linux/bitmap.h> 7 8 #include <drm/drm_managed.h> 9 #include <drm/drm_print.h> 10 #include <drm/drm_ras.h> 11 12 #include "xe_device_types.h" 13 #include "xe_drm_ras.h" 14 #include "xe_ras.h" 15 16 static const char * const error_components[] = DRM_XE_RAS_ERROR_COMPONENT_NAMES; 17 static const char * const error_severity[] = DRM_XE_RAS_ERROR_SEVERITY_NAMES; 18 19 static int query_error_counter(struct xe_device *xe, 20 enum drm_xe_ras_error_severity severity, 21 u32 error_id, const char **name, u32 *val) 22 { 23 struct xe_drm_ras *ras = &xe->ras; 24 struct xe_drm_ras_counter *info = ras->info[severity]; 25 26 if (!info || !info[error_id].name) 27 return -ENOENT; 28 29 *name = info[error_id].name; 30 31 /* Fetch counter from system controller if supported */ 32 if (xe->info.has_sysctrl) 33 return xe_ras_get_counter(xe, severity, error_id, val); 34 35 *val = atomic_read(&info[error_id].counter); 36 37 return 0; 38 } 39 40 static int clear_error_counter(struct xe_device *xe, 41 enum drm_xe_ras_error_severity severity, 42 u32 error_id) 43 { 44 struct xe_drm_ras *ras = &xe->ras; 45 struct xe_drm_ras_counter *info = ras->info[severity]; 46 47 if (!info || !info[error_id].name) 48 return -ENOENT; 49 50 /* Clear counter from system controller if supported */ 51 if (xe->info.has_sysctrl) 52 return xe_ras_clear_counter(xe, severity, error_id); 53 54 atomic_set(&info[error_id].counter, 0); 55 56 return 0; 57 } 58 59 static int query_uncorrectable_error_counter(struct drm_ras_node *ep, u32 error_id, 60 const char **name, u32 *val) 61 { 62 struct xe_device *xe = ep->priv; 63 64 return query_error_counter(xe, DRM_XE_RAS_ERR_SEV_UNCORRECTABLE, error_id, name, val); 65 } 66 67 static int clear_uncorrectable_error_counter(struct drm_ras_node *node, u32 error_id) 68 { 69 struct xe_device *xe = node->priv; 70 71 return clear_error_counter(xe, DRM_XE_RAS_ERR_SEV_UNCORRECTABLE, error_id); 72 } 73 74 static int query_correctable_error_counter(struct drm_ras_node *ep, u32 error_id, 75 const char **name, u32 *val) 76 { 77 struct xe_device *xe = ep->priv; 78 79 return query_error_counter(xe, DRM_XE_RAS_ERR_SEV_CORRECTABLE, error_id, name, val); 80 } 81 82 static int clear_correctable_error_counter(struct drm_ras_node *node, u32 error_id) 83 { 84 struct xe_device *xe = node->priv; 85 86 return clear_error_counter(xe, DRM_XE_RAS_ERR_SEV_CORRECTABLE, error_id); 87 } 88 89 static struct xe_drm_ras_counter *allocate_and_copy_counters(struct xe_device *xe) 90 { 91 struct xe_drm_ras_counter *counter; 92 int i; 93 94 counter = drmm_kcalloc(&xe->drm, DRM_XE_RAS_ERR_COMP_MAX, sizeof(*counter), GFP_KERNEL); 95 if (!counter) 96 return ERR_PTR(-ENOMEM); 97 98 for (i = DRM_XE_RAS_ERR_COMP_CORE_COMPUTE; i < DRM_XE_RAS_ERR_COMP_MAX; i++) { 99 if (!error_components[i]) 100 continue; 101 102 counter[i].name = error_components[i]; 103 atomic_set(&counter[i].counter, 0); 104 } 105 106 return counter; 107 } 108 109 static int assign_node_params(struct xe_device *xe, struct drm_ras_node *node, 110 const enum drm_xe_ras_error_severity severity) 111 { 112 struct pci_dev *pdev = to_pci_dev(xe->drm.dev); 113 struct xe_drm_ras *ras = &xe->ras; 114 const char *device_name; 115 116 device_name = kasprintf(GFP_KERNEL, "%04x:%02x:%02x.%d", 117 pci_domain_nr(pdev->bus), pdev->bus->number, 118 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); 119 120 if (!device_name) 121 return -ENOMEM; 122 123 node->device_name = device_name; 124 node->node_name = error_severity[severity]; 125 node->type = DRM_RAS_NODE_TYPE_ERROR_COUNTER; 126 node->error_counter_range.first = DRM_XE_RAS_ERR_COMP_CORE_COMPUTE; 127 node->error_counter_range.last = DRM_XE_RAS_ERR_COMP_MAX - 1; 128 node->priv = xe; 129 130 ras->info[severity] = allocate_and_copy_counters(xe); 131 if (IS_ERR(ras->info[severity])) 132 return PTR_ERR(ras->info[severity]); 133 134 if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE) { 135 node->query_error_counter = query_correctable_error_counter; 136 node->clear_error_counter = clear_correctable_error_counter; 137 } else { 138 node->query_error_counter = query_uncorrectable_error_counter; 139 node->clear_error_counter = clear_uncorrectable_error_counter; 140 } 141 142 return 0; 143 } 144 145 static void cleanup_node_param(struct drm_ras_node *node) 146 { 147 kfree(node->device_name); 148 node->device_name = NULL; 149 } 150 151 static void cleanup_node(struct drm_device *drm, void *node) 152 { 153 drm_ras_node_unregister(node); 154 cleanup_node_param(node); 155 } 156 157 static int register_nodes(struct xe_device *xe) 158 { 159 struct xe_drm_ras *ras = &xe->ras; 160 struct drm_ras_node *node; 161 int i, ret; 162 163 for_each_error_severity(i) { 164 node = &ras->node[i]; 165 166 ret = assign_node_params(xe, node, i); 167 if (ret) 168 goto free_param; 169 170 ret = drm_ras_node_register(node); 171 if (ret) 172 goto free_param; 173 174 ret = drmm_add_action_or_reset(&xe->drm, cleanup_node, node); 175 if (ret) 176 goto null_info; 177 } 178 179 return 0; 180 181 free_param: 182 cleanup_node_param(node); 183 null_info: 184 ras->info[i] = NULL; 185 return ret; 186 } 187 188 /** 189 * xe_drm_ras_init() - Initialize DRM RAS 190 * @xe: xe device instance 191 * 192 * Allocate and register DRM RAS nodes per device 193 * 194 * Return: 0 on success, negative error code otherwise. 195 */ 196 int xe_drm_ras_init(struct xe_device *xe) 197 { 198 struct xe_drm_ras *ras = &xe->ras; 199 struct drm_ras_node *node; 200 int err; 201 202 if (!xe->info.has_drm_ras) 203 return 0; 204 205 node = drmm_kcalloc(&xe->drm, DRM_XE_RAS_ERR_SEV_MAX, sizeof(*node), GFP_KERNEL); 206 if (!node) 207 return -ENOMEM; 208 209 ras->node = node; 210 211 err = register_nodes(xe); 212 if (err) { 213 drm_err(&xe->drm, "Failed to register DRM RAS nodes (%pe)\n", ERR_PTR(err)); 214 return err; 215 } 216 217 return 0; 218 } 219