1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
// SPDX-License-Identifier: MIT
/*
* Copyright © 2026 Intel Corporation
*/
#include "xe_device.h"
#include "xe_printk.h"
#include "xe_ras.h"
#include "xe_ras_types.h"
#include "xe_sysctrl.h"
#include "xe_sysctrl_event_types.h"
/* Severity of detected errors */
enum xe_ras_severity {
XE_RAS_SEV_NOT_SUPPORTED = 0,
XE_RAS_SEV_CORRECTABLE,
XE_RAS_SEV_UNCORRECTABLE,
XE_RAS_SEV_INFORMATIONAL,
XE_RAS_SEV_MAX
};
/* Major IP blocks/components where errors can originate */
enum xe_ras_component {
XE_RAS_COMP_NOT_SUPPORTED = 0,
XE_RAS_COMP_DEVICE_MEMORY,
XE_RAS_COMP_CORE_COMPUTE,
XE_RAS_COMP_RESERVED,
XE_RAS_COMP_PCIE,
XE_RAS_COMP_FABRIC,
XE_RAS_COMP_SOC_INTERNAL,
XE_RAS_COMP_MAX
};
static const char *const xe_ras_severities[] = {
[XE_RAS_SEV_NOT_SUPPORTED] = "Not Supported",
[XE_RAS_SEV_CORRECTABLE] = "Correctable Error",
[XE_RAS_SEV_UNCORRECTABLE] = "Uncorrectable Error",
[XE_RAS_SEV_INFORMATIONAL] = "Informational Error",
};
static_assert(ARRAY_SIZE(xe_ras_severities) == XE_RAS_SEV_MAX);
static const char *const xe_ras_components[] = {
[XE_RAS_COMP_NOT_SUPPORTED] = "Not Supported",
[XE_RAS_COMP_DEVICE_MEMORY] = "Device Memory",
[XE_RAS_COMP_CORE_COMPUTE] = "Core Compute",
[XE_RAS_COMP_RESERVED] = "Reserved",
[XE_RAS_COMP_PCIE] = "PCIe",
[XE_RAS_COMP_FABRIC] = "Fabric",
[XE_RAS_COMP_SOC_INTERNAL] = "SoC Internal",
};
static_assert(ARRAY_SIZE(xe_ras_components) == XE_RAS_COMP_MAX);
static inline const char *sev_to_str(u8 severity)
{
if (severity >= XE_RAS_SEV_MAX)
severity = XE_RAS_SEV_NOT_SUPPORTED;
return xe_ras_severities[severity];
}
static inline const char *comp_to_str(u8 component)
{
if (component >= XE_RAS_COMP_MAX)
component = XE_RAS_COMP_NOT_SUPPORTED;
return xe_ras_components[component];
}
void xe_ras_counter_threshold_crossed(struct xe_device *xe,
struct xe_sysctrl_event_response *response)
{
struct xe_ras_threshold_crossed *pending = (void *)&response->data;
struct xe_ras_error_class *errors = pending->counters;
u32 id, ncounters = pending->ncounters;
BUILD_BUG_ON(sizeof(response->data) < sizeof(*pending));
xe_device_assert_mem_access(xe);
if (!ncounters || ncounters > XE_RAS_NUM_COUNTERS)
xe_err(xe, "sysctrl: unexpected counter threshold crossed %u\n", ncounters);
else
xe_warn(xe, "[RAS]: counter threshold crossed, %u new errors\n", ncounters);
for (id = 0; id < ncounters && id < XE_RAS_NUM_COUNTERS; id++) {
u8 severity, component;
severity = errors[id].common.severity;
component = errors[id].common.component;
xe_warn(xe, "[RAS]: %s %s detected\n",
comp_to_str(component), sev_to_str(severity));
}
}
|