高级平台错误接口在 Linux 平台上的应用(5)
- UID
- 1066743
|
高级平台错误接口在 Linux 平台上的应用(5)
表 1. 解析之后的 HEST 实例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
| /*
* Disassembly of HEST.dat
* ACPI Data Table [HEST]
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
*/
[000h 0000 4] Signature : "HEST" /* Hardware Error Source Table */
[004h 0004 4] Table Length : 000000A8
[008h 0008 1] Revision : 01
[009h 0009 1] Checksum : E2
[00Ah 0010 6] Oem ID : "xxxxxx"
[010h 0016 8] Oem Table ID : "xxxxxx"
[018h 0024 4] Oem Revision : 00000001
[01Ch 0028 4] Asl Compiler ID : "xxxxxx"
[020h 0032 4] Asl Compiler Revision : 00000001
[024h 0036 4] Error Source Count : 00000002
[000h 0000 4] Signature : "HEST" /* Hardware Error Source Table */
[004h 0004 4] Table Length : 000000A8
[008h 0008 1] Revision : 01
[009h 0009 1] Checksum : E2
[00Ah 0010 6] Oem ID : "xxxxxx"
[010h 0016 8] Oem Table ID : "xxxxxx"
[018h 0024 4] Oem Revision : 00000001
[01Ch 0028 4] Asl Compiler ID : "xxxxxx"
[020h 0032 4] Asl Compiler Revision : 00000001
[024h 0036 4] Error Source Count : 00000002
[028h 0040 2] Subtable Type : 0009 (Generic Hardware Error Source)
[02Ah 0042 2] Source Id : 0000
[02Ch 0044 2] Related Source Id : FFFF
[02Eh 0046 1] Reserved : 00
[02Fh 0047 1] Enabled : 01
[030h 0048 4] Records To Preallocate : 00000001
[034h 0052 4] Max Sections Per Record : 00000001
[038h 0056 4] Max Raw Data Length : 00001000
[03Ch 0060 12] Error Status Address : <Generic Address Structure>
[03Ch 0060 1] Space ID : 00 (SystemMemory)
[03Dh 0061 1] Bit Width : 40
[03Eh 0062 1] Bit Offset : 00
[03Fh 0063 1] Encoded Access Width : 04 (QWord Access:64)
[040h 0064 8] Address : 000000007BE17018
[048h 0072 28] Notify : <Hardware Error Notification Structure>
[048h 0072 1] Notify Type : 03 (SCI)
[049h 0073 1] Notify Length : 1C
[04Ah 0074 2] Configuration Write Enable : 0000
[04Ch 0076 4] PollInterval : 00000000
[050h 0080 4] Vector : 00000000
[054h 0084 4] Polling Threshold Value : 00000000
[058h 0088 4] Polling Threshold Window : 00000000
[05Ch 0092 4] Error Threshold Value : 00000000
[060h 0096 4] Error Threshold Window : 00000000
[064h 0100 4] Error Status Block Length : 00001000
[068h 0104 2] Subtable Type : 0009 (Generic Hardware Error Source)
[06Ah 0106 2] Source Id : 0001
[06Ch 0108 2] Related Source Id : FFFF
[06Eh 0110 1] Reserved : 00
[06Fh 0111 1] Enabled : 01
[070h 0112 4] Records To Preallocate : 00000001
[074h 0116 4] Max Sections Per Record : 00000001
[078h 0120 4] Max Raw Data Length : 00001000
[07Ch 0124 12] Error Status Address : <Generic Address Structure>
[07Ch 0124 1] Space ID : 00 (SystemMemory)
[07Dh 0125 1] Bit Width : 40
[07Eh 0126 1] Bit Offset : 00
[07Fh 0127 1] Encoded Access Width : 04 (QWord Access:64)
[080h 0128 8] Address : 000000007BE18020
[088h 0136 28] Notify : <Hardware Error Notification Structure>
[088h 0136 1] Notify Type : 04 (NMI)
[089h 0137 1] Notify Length : 1C
[08Ah 0138 2] Configuration Write Enable : 0000
[08Ch 0140 4] PollInterval : 00000000
[090h 0144 4] Vector : 00000000
[094h 0148 4] Polling Threshold Value : 00000000
[098h 0152 4] Polling Threshold Window : 00000000
[09Ch 0156 4] Error Threshold Value : 00000000
[0A0h 0160 4] Error Threshold Window : 00000000
[0A4h 0164 4] Error Status Block Length : 00001000
|
从上表中可以得知:这是一个 HEST 类型的表(Signature = "HEST");包含着 2 个错误源(Error Source Count = 2);这两个错误源都是 GHES 类型(Subtable Type = 9),一个是 SCI(Notify Type = 3),另一个是 NMI(Notify Type = 4)。错误类型为 SCI 的 GHES 中的 GAS 寄存器地址为 0x000000007BE17018,寄存器宽度为 8 个字节(Bit Width = 0x40),寄存器类型为 MMIO(Space ID = 0);错误类型为 NMI 的 GHES 中的 GAS 寄存器地址为 0x000000007BE18020,寄存器宽度为 8 个字节(Bit Width = 0x40),寄存器类型为 MMIO(Space ID = 0)。
在 FFM 使能的情况下,当系统中发生一个 UC/Fatal 类型的硬件错误时,CPU 首先进入 SMM 模式,将控制权交给底层的 firmware。在 firmware 处理结束后,产生 NMI 中断,由上可知,这个中断最终会调用注册在 NMI 通知链上的 GHES 回调函数,也就是 ghes_notify_nmi。
清单 11. NMI 类型错误的处理过程:第一部分1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| 在 drivers/acpi/apei/ghes.c 中
static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
{
struct ghes *ghes, *ghes_global = NULL;
int sev, sev_global = -1;
int ret = NMI_DONE;
raw_spin_lock(&ghes_nmi_lock);
list_for_each_entry_rcu(ghes, &ghes_nmi, list) {
if (ghes_read_estatus(ghes, 1)) {
ghes_clear_estatus(ghes);
continue;
}
sev = ghes_severity(ghes->estatus->error_severity);
if (sev > sev_global) {
sev_global = sev;
ghes_global = ghes;
}
ret = NMI_HANDLED;
}
if (ret == NMI_DONE)
goto out;
|
ghes_notify_nmi 函数的第一部分首先检查相应的 GHES 错误源,判断当前产生 NMI 的错误源以及相应的错误严重级别。这个错误严重级别关系到最终采取的处理方式,是尝试恢复错误,还是重启系统。
清单 12. NMI 类型错误的处理过程:第二部分1
2
3
4
5
6
7
8
9
| if (sev_global >= GHES_SEV_PANIC) {
oops_begin();
__ghes_print_estatus(KERN_EMERG HW_ERR, ghes_global->generic,
ghes_global->estatus);
/* reboot to log the error! */
if (panic_timeout == 0)
panic_timeout = ghes_panic_timeout;
panic("Fatal hardware error!");
}
|
这部分代码用来对严重错误进行先行处理。当错误的严重程度超过了一定限度后,无法进行错误恢复,或者说无法进行容错处理,而只能通过重启系统的方式来恢复当前不可靠的系统环境。 |
|
|
|
|
|