1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2026 Intel Corporation 4 */ 5 6 #include "xe_device.h" 7 #include "xe_drm_ras.h" 8 #include "xe_pm.h" 9 #include "xe_printk.h" 10 #include "xe_ras.h" 11 #include "xe_survivability_mode.h" 12 #include "xe_sysctrl.h" 13 #include "xe_sysctrl_event_types.h" 14 #include "xe_sysctrl_mailbox.h" 15 #include "xe_sysctrl_mailbox_types.h" 16 17 #define CORE_COMPUTE_UNCORR_TYPE GENMASK(26, 25) 18 /* 19 * Uncorrectable error type for core compute errors. 20 * 0 - Correctable Error 21 * 1 - Local Uncorrectable Error 22 * 2 - Global Uncorrectable Error 23 * 3 - Informational Error 24 */ 25 #define GLOBAL_UNCORR_ERROR 2 26 27 /* Severity of detected errors */ 28 enum xe_ras_severity { 29 XE_RAS_SEV_NOT_SUPPORTED = 0, 30 XE_RAS_SEV_CORRECTABLE, 31 XE_RAS_SEV_UNCORRECTABLE, 32 XE_RAS_SEV_INFORMATIONAL, 33 XE_RAS_SEV_MAX 34 }; 35 36 /* Major IP blocks/components where errors can originate */ 37 enum xe_ras_component { 38 XE_RAS_COMP_NOT_SUPPORTED = 0, 39 XE_RAS_COMP_DEVICE_MEMORY, 40 XE_RAS_COMP_CORE_COMPUTE, 41 XE_RAS_COMP_RESERVED, 42 XE_RAS_COMP_PCIE, 43 XE_RAS_COMP_FABRIC, 44 XE_RAS_COMP_SOC_INTERNAL, 45 XE_RAS_COMP_MAX 46 }; 47 48 /* RAS response status codes */ 49 enum xe_ras_response_status { 50 XE_RAS_STATUS_SUCCESS = 0, 51 XE_RAS_STATUS_INVALID_PARAM, 52 XE_RAS_STATUS_OP_NOT_SUPPORTED, 53 XE_RAS_STATUS_TIMEOUT, 54 XE_RAS_STATUS_HARDWARE_FAILURE, 55 XE_RAS_STATUS_INSUFFICIENT_RESOURCES, 56 XE_RAS_STATUS_MAX 57 }; 58 59 /* GPU health values */ 60 enum xe_ras_health { 61 XE_RAS_HEALTH_OK = 0, 62 XE_RAS_HEALTH_WARNING, 63 XE_RAS_HEALTH_CRITICAL, 64 XE_RAS_HEALTH_MAX 65 }; 66 67 static const char *const xe_ras_severities[] = { 68 [XE_RAS_SEV_NOT_SUPPORTED] = "Not Supported", 69 [XE_RAS_SEV_CORRECTABLE] = "Correctable Error", 70 [XE_RAS_SEV_UNCORRECTABLE] = "Uncorrectable Error", 71 [XE_RAS_SEV_INFORMATIONAL] = "Informational Error", 72 }; 73 static_assert(ARRAY_SIZE(xe_ras_severities) == XE_RAS_SEV_MAX); 74 75 static const char *const xe_ras_components[] = { 76 [XE_RAS_COMP_NOT_SUPPORTED] = "Not Supported", 77 [XE_RAS_COMP_DEVICE_MEMORY] = "Device Memory", 78 [XE_RAS_COMP_CORE_COMPUTE] = "Core Compute", 79 [XE_RAS_COMP_RESERVED] = "Reserved", 80 [XE_RAS_COMP_PCIE] = "PCIe", 81 [XE_RAS_COMP_FABRIC] = "Fabric", 82 [XE_RAS_COMP_SOC_INTERNAL] = "SoC Internal", 83 }; 84 static_assert(ARRAY_SIZE(xe_ras_components) == XE_RAS_COMP_MAX); 85 86 static const char * const gpu_health_states[] = { 87 [XE_RAS_HEALTH_OK] = "ok", 88 [XE_RAS_HEALTH_WARNING] = "warning", 89 [XE_RAS_HEALTH_CRITICAL] = "critical", 90 }; 91 static_assert(ARRAY_SIZE(gpu_health_states) == XE_RAS_HEALTH_MAX); 92 93 static u8 drm_to_xe_ras_severity(u8 severity) 94 { 95 switch (severity) { 96 case DRM_XE_RAS_ERR_SEV_CORRECTABLE: 97 return XE_RAS_SEV_CORRECTABLE; 98 case DRM_XE_RAS_ERR_SEV_UNCORRECTABLE: 99 return XE_RAS_SEV_UNCORRECTABLE; 100 default: 101 return XE_RAS_SEV_NOT_SUPPORTED; 102 } 103 } 104 105 static u8 drm_to_xe_ras_component(u8 component) 106 { 107 switch (component) { 108 case DRM_XE_RAS_ERR_COMP_CORE_COMPUTE: 109 return XE_RAS_COMP_CORE_COMPUTE; 110 case DRM_XE_RAS_ERR_COMP_SOC_INTERNAL: 111 return XE_RAS_COMP_SOC_INTERNAL; 112 case DRM_XE_RAS_ERR_COMP_DEVICE_MEMORY: 113 return XE_RAS_COMP_DEVICE_MEMORY; 114 case DRM_XE_RAS_ERR_COMP_PCIE: 115 return XE_RAS_COMP_PCIE; 116 case DRM_XE_RAS_ERR_COMP_FABRIC: 117 return XE_RAS_COMP_FABRIC; 118 default: 119 return XE_RAS_COMP_NOT_SUPPORTED; 120 } 121 } 122 123 static int ras_status_to_errno(u32 status) 124 { 125 switch (status) { 126 case XE_RAS_STATUS_SUCCESS: 127 return 0; 128 case XE_RAS_STATUS_INVALID_PARAM: 129 return -EINVAL; 130 case XE_RAS_STATUS_OP_NOT_SUPPORTED: 131 return -EOPNOTSUPP; 132 case XE_RAS_STATUS_TIMEOUT: 133 return -ETIMEDOUT; 134 case XE_RAS_STATUS_HARDWARE_FAILURE: 135 return -EIO; 136 case XE_RAS_STATUS_INSUFFICIENT_RESOURCES: 137 return -ENOSPC; 138 default: 139 return -EPROTO; 140 } 141 } 142 143 static inline const char *sev_to_str(u8 severity) 144 { 145 if (severity >= XE_RAS_SEV_MAX) 146 severity = XE_RAS_SEV_NOT_SUPPORTED; 147 148 return xe_ras_severities[severity]; 149 } 150 151 static inline const char *comp_to_str(u8 component) 152 { 153 if (component >= XE_RAS_COMP_MAX) 154 component = XE_RAS_COMP_NOT_SUPPORTED; 155 156 return xe_ras_components[component]; 157 } 158 159 static struct pci_dev *find_usp_dev(struct pci_dev *pdev) 160 { 161 struct pci_dev *vsp; 162 163 /* 164 * Device Hierarchy: 165 * 166 * Upstream Switch Port (USP) --> Virtual Switch Port (VSP) --> SGunit (GPU endpoint) 167 */ 168 vsp = pci_upstream_bridge(pdev); 169 if (!vsp) 170 return NULL; 171 172 return pci_upstream_bridge(vsp); 173 } 174 175 static void ras_usp_aer_init(struct xe_device *xe) 176 { 177 struct pci_dev *pdev = to_pci_dev(xe->drm.dev); 178 struct pci_dev *usp; 179 u16 aer_cap; 180 u32 status; 181 182 usp = find_usp_dev(pdev); 183 if (!usp) 184 return; 185 186 aer_cap = pci_find_ext_capability(usp, PCI_EXT_CAP_ID_ERR); 187 if (!aer_cap) { 188 dev_warn(&usp->dev, "AER capability unavailable\n"); 189 return; 190 } 191 192 /* 193 * Clear any stale Uncorrectable Internal Error Status event in Uncorrectable Error 194 * Status Register. 195 */ 196 pci_read_config_dword(usp, aer_cap + PCI_ERR_UNCOR_STATUS, &status); 197 if (status & PCI_ERR_UNC_INTN) 198 pci_write_config_dword(usp, aer_cap + PCI_ERR_UNCOR_STATUS, PCI_ERR_UNC_INTN); 199 200 /* 201 * All errors are steered to USP which is a PCIe AER Compliant device. 202 * Downgrade all the errors to non-fatal to prevent PCIe bus driver 203 * from triggering a Secondary Bus Reset (SBR). This allows error 204 * detection, containment and recovery in the driver. 205 * 206 * The Uncorrectable Error Severity Register has the 'Uncorrectable 207 * Internal Error Severity' set to fatal by default. Set this to 208 * non-fatal and unmask the error. 209 */ 210 211 /* Downgrade Uncorrectable Internal Error to non-fatal */ 212 pci_clear_and_set_config_dword(usp, aer_cap + PCI_ERR_UNCOR_SEVER, PCI_ERR_UNC_INTN, 0); 213 214 /* Unmask Uncorrectable Internal Error */ 215 pci_clear_and_set_config_dword(usp, aer_cap + PCI_ERR_UNCOR_MASK, PCI_ERR_UNC_INTN, 0); 216 217 pci_save_state(usp); 218 dev_dbg(&usp->dev, "Uncorrectable Internal Errors downgraded and unmasked\n"); 219 } 220 221 static u8 handle_core_compute_errors(struct xe_ras_error_array *arr) 222 { 223 struct xe_ras_compute_error *error_info = (void *)arr->details; 224 u8 uncorr_type; 225 226 uncorr_type = FIELD_GET(CORE_COMPUTE_UNCORR_TYPE, error_info->log_header); 227 228 /* Request a reset if error is global */ 229 if (uncorr_type == GLOBAL_UNCORR_ERROR) 230 return XE_RAS_RECOVERY_ACTION_RESET; 231 232 /* 233 * No action needed for other errors. 234 * Local errors are recovered using an engine reset by GuC. 235 */ 236 return XE_RAS_RECOVERY_ACTION_RECOVERED; 237 } 238 239 static u8 handle_soc_internal_errors(struct xe_device *xe, struct xe_ras_error_array *arr) 240 { 241 struct xe_ras_soc_error *info = (void *)arr->details; 242 struct xe_ras_soc_error_source *source = &info->source; 243 struct xe_ras_error_class *counter = &arr->counter; 244 245 if (source->csc) { 246 struct xe_ras_csc_error *csc_error = (void *)info->details; 247 248 /* 249 * CSC uncorrectable errors are classified as hardware errors and firmware errors. 250 * CSC firmware errors are critical errors that can be recovered only by firmware 251 * update via SPI driver. On a CSC firmware error, PCODE enables FDO mode and sets 252 * the bit in the capability register. On receiving this error, the driver enables 253 * runtime survivability mode which notifies userspace that a firmware update 254 * is required. 255 */ 256 if (csc_error->hec_fw_error) { 257 xe_err(xe, "[RAS]: CSC %s detected: 0x%x\n", 258 sev_to_str(counter->common.severity), 259 csc_error->hec_fw_error); 260 xe_survivability_mode_runtime_enable(xe); 261 return XE_RAS_RECOVERY_ACTION_DISCONNECT; 262 } 263 } else if (source->ieh) { 264 struct xe_ras_ieh_error *ieh_error = (void *)info->details; 265 266 if (ieh_error->global_error_status & XE_RAS_SOC_IEH_PUNIT) { 267 xe_err(xe, "[RAS]: PUNIT %s detected: 0x%x\n", 268 sev_to_str(counter->common.severity), 269 ieh_error->global_error_status); 270 /* TODO: Add PUNIT error handling */ 271 return XE_RAS_RECOVERY_ACTION_DISCONNECT; 272 } 273 } 274 275 /* For other SoC internal errors, request a reset as recovery mechanism */ 276 return XE_RAS_RECOVERY_ACTION_RESET; 277 } 278 279 static u8 handle_device_memory_errors(struct xe_device *xe, struct xe_ras_error_array *arr) 280 { 281 struct xe_ras_memory_error *info = (void *)arr->details; 282 283 /* 284 * For memory errors, the recovery action depends on the error category 285 * 286 * TODO: Double-bit ECC errors: Page offlining 287 * Poison and data parity errors: Log only 288 * For any other memory errors, request a reset as recovery mechanism 289 */ 290 switch (info->category) { 291 case XE_RAS_MEMORY_POISON: 292 xe_info(xe, "[RAS]: Poison error detected\n"); 293 break; 294 case XE_RAS_MEMORY_DATA_PARITY: 295 xe_info(xe, "[RAS]: Data parity error detected\n"); 296 break; 297 case XE_RAS_MEMORY_DB_ECC: 298 xe_info(xe, "[RAS]: Double-bit ECC error detected at sw address 0x%llx\n", 299 info->sw_address); 300 /* TODO: Add page offlining for Double-bit ECC error */ 301 fallthrough; 302 default: 303 return XE_RAS_RECOVERY_ACTION_RESET; 304 } 305 306 return XE_RAS_RECOVERY_ACTION_RECOVERED; 307 } 308 309 void xe_ras_counter_threshold_crossed(struct xe_device *xe, 310 struct xe_sysctrl_event_response *response) 311 { 312 struct xe_ras_threshold_crossed *pending = (void *)&response->data; 313 struct xe_ras_error_class *errors = pending->counters; 314 u32 id, ncounters = pending->ncounters; 315 316 BUILD_BUG_ON(sizeof(response->data) < sizeof(*pending)); 317 xe_device_assert_mem_access(xe); 318 319 if (!ncounters || ncounters > XE_RAS_NUM_COUNTERS) 320 xe_err(xe, "sysctrl: unexpected counter threshold crossed %u\n", ncounters); 321 else 322 xe_warn(xe, "[RAS]: counter threshold crossed, %u new errors\n", ncounters); 323 324 for (id = 0; id < ncounters && id < XE_RAS_NUM_COUNTERS; id++) { 325 u8 severity, component; 326 327 severity = errors[id].common.severity; 328 component = errors[id].common.component; 329 330 xe_warn(xe, "[RAS]: %s %s detected\n", 331 comp_to_str(component), sev_to_str(severity)); 332 } 333 } 334 335 static int get_counter(struct xe_device *xe, struct xe_ras_error_class *counter, u32 *value) 336 { 337 struct xe_ras_get_counter_response response = {0}; 338 struct xe_ras_get_counter_request request = {0}; 339 struct xe_sysctrl_mailbox_command command = {0}; 340 struct xe_ras_error_common *common; 341 size_t rlen; 342 int ret; 343 344 request.counter = *counter; 345 346 xe_sysctrl_create_command(&command, XE_SYSCTRL_GROUP_GFSP, XE_SYSCTRL_CMD_GET_COUNTER, 347 &request, sizeof(request), &response, sizeof(response)); 348 349 ret = xe_sysctrl_send_command(&xe->sc, &command, &rlen); 350 if (ret) { 351 xe_err(xe, "sysctrl: failed to get counter %d\n", ret); 352 return ret; 353 } 354 355 if (rlen != sizeof(response)) { 356 xe_err(xe, "sysctrl: unexpected get counter response length %zu (expected %zu)\n", 357 rlen, sizeof(response)); 358 return -EIO; 359 } 360 361 common = &response.counter.common; 362 *value = response.value; 363 364 xe_dbg(xe, "[RAS]: get counter %u for %s %s\n", *value, comp_to_str(common->component), 365 sev_to_str(common->severity)); 366 367 return 0; 368 } 369 370 /** 371 * xe_ras_process_errors() - Process and contain hardware errors 372 * @xe: xe device instance 373 * 374 * Get error details from system controller and return recovery 375 * method. 376 * 377 * Returns: recovery action to be taken 378 */ 379 enum xe_ras_recovery_action xe_ras_process_errors(struct xe_device *xe) 380 { 381 struct xe_sysctrl_mailbox_command command = {0}; 382 enum xe_ras_recovery_action final_action; 383 u32 remaining = XE_SYSCTRL_FLOOD_LIMIT; 384 struct xe_ras_get_soc_error response; 385 size_t rlen; 386 int ret; 387 388 if (!xe->info.has_sysctrl) 389 return XE_RAS_RECOVERY_ACTION_RESET; 390 391 /* Default action */ 392 final_action = XE_RAS_RECOVERY_ACTION_RECOVERED; 393 394 xe_sysctrl_create_command(&command, XE_SYSCTRL_GROUP_GFSP, XE_SYSCTRL_CMD_GET_SOC_ERROR, 395 NULL, 0, &response, sizeof(response)); 396 397 do { 398 memset(&response, 0, sizeof(response)); 399 400 ret = xe_sysctrl_send_command(&xe->sc, &command, &rlen); 401 if (ret) { 402 xe_err(xe, "sysctrl: failed to get soc error %d\n", ret); 403 goto err; 404 } 405 406 if (rlen != sizeof(response)) { 407 xe_err(xe, "sysctrl: unexpected get soc error response length %zu (expected %zu)\n", 408 rlen, sizeof(response)); 409 goto err; 410 } 411 412 /* Report if number of errors exceeds the maximum errors supported */ 413 if (response.num_errors > XE_RAS_NUM_ERROR_ARR) 414 xe_err(xe, "sysctrl: number of errors received %d out of bound (%d)\n", 415 response.num_errors, XE_RAS_NUM_ERROR_ARR); 416 417 for (int i = 0; i < response.num_errors && i < XE_RAS_NUM_ERROR_ARR; i++) { 418 struct xe_ras_error_array *arr = &response.arr[i]; 419 enum xe_ras_recovery_action action; 420 u8 component, severity; 421 422 component = arr->counter.common.component; 423 severity = arr->counter.common.severity; 424 425 xe_info(xe, "[RAS]: %s %s detected\n", comp_to_str(component), 426 sev_to_str(severity)); 427 428 switch (component) { 429 case XE_RAS_COMP_CORE_COMPUTE: 430 action = handle_core_compute_errors(arr); 431 break; 432 case XE_RAS_COMP_SOC_INTERNAL: 433 action = handle_soc_internal_errors(xe, arr); 434 break; 435 case XE_RAS_COMP_DEVICE_MEMORY: 436 action = handle_device_memory_errors(xe, arr); 437 break; 438 default: 439 /* For any other component, reset */ 440 action = XE_RAS_RECOVERY_ACTION_RESET; 441 break; 442 } 443 444 /* Process and log all errors and then trigger highest recovery action */ 445 if (action > final_action) 446 final_action = action; 447 } 448 449 /* Treat flooding as a system controller error */ 450 if (!--remaining) { 451 xe_err(xe, "[RAS]: sysctrl: get soc error response flooding\n"); 452 goto err; 453 } 454 455 } while (response.additional_errors); 456 457 return final_action; 458 459 err: 460 return XE_RAS_RECOVERY_ACTION_RESET; 461 } 462 463 /** 464 * xe_ras_get_counter() - Get error counter value 465 * @xe: Xe device instance 466 * @severity: Error severity to be queried (&enum drm_xe_ras_error_severity) 467 * @component: Error component to be queried (&enum drm_xe_ras_error_component) 468 * @value: Counter value 469 * 470 * This function retrieves the value of a specific error counter based on 471 * the error severity and component. 472 * 473 * Return: 0 on success, negative error code on failure. 474 */ 475 int xe_ras_get_counter(struct xe_device *xe, u8 severity, u8 component, u32 *value) 476 { 477 struct xe_ras_error_class counter = {0}; 478 479 counter.common.severity = drm_to_xe_ras_severity(severity); 480 counter.common.component = drm_to_xe_ras_component(component); 481 482 guard(xe_pm_runtime)(xe); 483 return get_counter(xe, &counter, value); 484 } 485 486 /** 487 * xe_ras_clear_counter() - Clear error counter value 488 * @xe: Xe device instance 489 * @severity: Error severity to be cleared (&enum drm_xe_ras_error_severity) 490 * @component: Error component to be cleared (&enum drm_xe_ras_error_component) 491 * 492 * This function clears the value of a specific error counter based on 493 * the error severity and component. 494 * 495 * Return: 0 on success, negative error code on failure. 496 */ 497 int xe_ras_clear_counter(struct xe_device *xe, u8 severity, u8 component) 498 { 499 struct xe_ras_clear_counter_response response = {0}; 500 struct xe_ras_clear_counter_request request = {0}; 501 struct xe_sysctrl_mailbox_command command = {0}; 502 struct xe_ras_error_class *counter; 503 size_t rlen; 504 int ret; 505 506 counter = &request.counter; 507 counter->common.severity = drm_to_xe_ras_severity(severity); 508 counter->common.component = drm_to_xe_ras_component(component); 509 510 xe_sysctrl_create_command(&command, XE_SYSCTRL_GROUP_GFSP, XE_SYSCTRL_CMD_CLEAR_COUNTER, 511 &request, sizeof(request), &response, sizeof(response)); 512 513 guard(xe_pm_runtime)(xe); 514 ret = xe_sysctrl_send_command(&xe->sc, &command, &rlen); 515 if (ret) { 516 xe_err(xe, "sysctrl: failed to clear counter %d\n", ret); 517 return ret; 518 } 519 520 if (rlen != sizeof(response)) { 521 xe_err(xe, "sysctrl: unexpected clear counter response length %zu (expected %zu)\n", 522 rlen, sizeof(response)); 523 return -EIO; 524 } 525 526 ret = ras_status_to_errno(response.status); 527 if (ret) { 528 xe_err(xe, "sysctrl: clear counter command failed with status %#x\n", 529 response.status); 530 return ret; 531 } 532 533 counter = &response.counter; 534 535 xe_dbg(xe, "[RAS]: clear counter for %s %s\n", comp_to_str(counter->common.component), 536 sev_to_str(counter->common.severity)); 537 538 return 0; 539 } 540 541 static ssize_t gpu_health_show(struct device *dev, struct device_attribute *attr, char *buf) 542 { 543 struct xe_ras_get_health_response response = {0}; 544 struct xe_sysctrl_mailbox_command command = {0}; 545 struct xe_ras_get_health_request request = {0}; 546 struct xe_device *xe = kdev_to_xe_device(dev); 547 const char *health; 548 size_t rlen; 549 int ret; 550 551 xe_sysctrl_create_command(&command, XE_SYSCTRL_GROUP_GFSP, XE_SYSCTRL_CMD_GET_HEALTH, 552 &request, sizeof(request), &response, sizeof(response)); 553 guard(xe_pm_runtime)(xe); 554 ret = xe_sysctrl_send_command(&xe->sc, &command, &rlen); 555 if (ret) { 556 xe_err(xe, "sysctrl: failed to get health %d\n", ret); 557 return ret; 558 } 559 560 if (rlen != sizeof(response)) { 561 xe_err(xe, "sysctrl: unexpected get health response length %zu (expected %zu)\n", 562 rlen, sizeof(response)); 563 return -EIO; 564 } 565 if (response.health >= XE_RAS_HEALTH_MAX) { 566 xe_err(xe, "sysctrl: invalid health state %u\n", 567 response.health); 568 return -EIO; 569 } 570 571 health = gpu_health_states[response.health]; 572 573 xe_dbg(xe, "[RAS]: get health: %s\n", health); 574 575 return sysfs_emit(buf, "%s\n", health); 576 } 577 578 static ssize_t gpu_health_store(struct device *dev, struct device_attribute *attr, 579 const char *buf, size_t count) 580 { 581 struct xe_ras_set_health_response response = {0}; 582 struct xe_sysctrl_mailbox_command command = {0}; 583 struct xe_ras_set_health_request request = {0}; 584 struct xe_device *xe = kdev_to_xe_device(dev); 585 const char *health; 586 size_t rlen; 587 int state; 588 int ret; 589 590 state = sysfs_match_string(gpu_health_states, buf); 591 if (state < 0) 592 return -EINVAL; 593 594 request.health = state; 595 596 xe_sysctrl_create_command(&command, XE_SYSCTRL_GROUP_GFSP, XE_SYSCTRL_CMD_SET_HEALTH, 597 &request, sizeof(request), &response, sizeof(response)); 598 guard(xe_pm_runtime)(xe); 599 ret = xe_sysctrl_send_command(&xe->sc, &command, &rlen); 600 if (ret) { 601 xe_err(xe, "sysctrl: failed to set health %d\n", ret); 602 return ret; 603 } 604 605 if (rlen != sizeof(response)) { 606 xe_err(xe, "sysctrl: unexpected set health response length %zu (expected %zu)\n", 607 rlen, sizeof(response)); 608 return -EIO; 609 } 610 611 ret = ras_status_to_errno(response.status); 612 if (ret) { 613 xe_err(xe, "sysctrl: set health command failed with status %#x\n", 614 response.status); 615 return ret; 616 } 617 618 if (response.health >= XE_RAS_HEALTH_MAX) { 619 xe_err(xe, "sysctrl: invalid health state %u\n", 620 response.health); 621 return -EIO; 622 } 623 624 health = gpu_health_states[response.health]; 625 626 xe_dbg(xe, "[RAS]: set health: %s\n", health); 627 628 return count; 629 } 630 static DEVICE_ATTR_RW(gpu_health); 631 632 static struct attribute *gpu_health_attrs[] = { 633 &dev_attr_gpu_health.attr, 634 NULL 635 }; 636 637 /** 638 * DOC: GPU Health Indicator 639 * 640 * On Intel Xe platforms that support the gpu health indicator interface, 641 * the driver exposes this sysfs attribute for in-band access to the gpu 642 * health state:: 643 * 644 * /sys/bus/pci/devices/<device>/gpu_health 645 * 646 * Reading the attribute is available to all users and returns a single 647 * line containing the current gpu health state, whereas writing is 648 * restricted to administrative users and updates the state to one of the 649 * valid values. 650 * 651 * Management tools and administrators use this interface to query the 652 * current gpu health state (e.g. for telemetry/monitoring) and to 653 * update it - for example, to mark the gpu as ``warning`` or ``critical`` 654 * after diagnostics, or reset it back to ``ok`` once remediated. 655 * 656 * The valid values for the gpu health state are: 657 * 658 * - ``ok`` 659 * The gpu is healthy and operating within normal parameters. 660 * 661 * - ``warning`` 662 * The gpu is experiencing minor issues but remains operational. 663 * 664 * - ``critical`` 665 * The gpu is in a critical state and may not be operational. 666 * 667 * See Documentation/ABI/testing/sysfs-driver-intel-xe-ras for the ABI 668 * specification. 669 */ 670 static const struct attribute_group gpu_health_group = { 671 .attrs = gpu_health_attrs, 672 }; 673 674 /** 675 * xe_ras_init - Initialize Xe RAS 676 * @xe: xe device instance 677 * 678 * Initialize Xe RAS 679 */ 680 void xe_ras_init(struct xe_device *xe) 681 { 682 int ret; 683 684 xe_drm_ras_init(xe); 685 686 if (!xe->info.has_sysctrl) 687 return; 688 689 if (IS_ENABLED(CONFIG_PCIEAER)) 690 ras_usp_aer_init(xe); 691 692 ret = devm_device_add_group(xe->drm.dev, &gpu_health_group); 693 if (ret) 694 xe_err(xe, "Failed to create GPU health sysfs, err=%d\n", ret); 695 } 696