1. 机器检查架构

机器检查架构提供了探测和报告硬件 ( 机器 ) 错误的机制 , 这些错误包括 : 系统总线错误 , ECC 错误 , parity 错误 , cache 错误 , TLB 错误 .

处理器通过产生一个机器检查异常 ( #MC ) 报告无法纠正的机器检查错误 , 异常产生时 , 通常不允许处理器可靠地重新启动 . 异常处理函数可以从 MC MSR 收集错误相关的信息 .
处理器可以报告纠正过的 MC 错误信息 , 传递一个可编程的中断供软件回应 MC 错误 , 这个中断称作 MC 错误中断 ( CMCI ) .

Pentium 处理器可以报告下列 MC 错误 :

  • 读 cycle 期间的数据 parity 错误
  • 总线 cycle 没有成功完成

探测到错误时 , 记录到 P5_MC_TYPE 和 P5_MC_ADDR MSR , 处理器然后产生一个 #MC .

2. MC MSR

MC MSR 包括一组全局控制和状态寄存器 , 一些错误报告寄存器组 ; 每组错误报告寄存器都和特定的硬件单元关联 , 可以通过 RDMSRWRMSR 读写 .

2.1. MC 全局控制 MSR

MC 全局控制 MSR 包括 :

  • IA32_MCG_CAP , 只读 , 提供处理器的 MC 架构相关信息
  • IA32_MCG_STATUS , 描述 MC 异常发生后处理器的当前状态
  • IA32_MCG_CTL ( 可选 ) , 控制 MC 异常的报告
  • IA32_MCG_EXT_CTL ( 可选 ) , 控制硬件只报告一些 MCE 给单个逻辑处理器

2.2. 错误报告寄存器组

错误报告寄存器组可以包含 IA32_MCi_CTL , IA32_MCi_STATUS , IA32_MCi_ADDR 和 IA32_MCi_MISC MSR , 寄存器组数通过 IA32_MCG_CAP MSR bit 7:0 指明 .

  • IA32_MCi_CTL , 控制某个硬件单元产生的错误是否发出 #MC .
  • IA32_MCi_STATUS , 设置有效标志时 , 包含和 MC 错误相关的信息 .
    • 如果 IA32_MCi_STATUS 的有效标志已经设置 , 即 MC MSR 已经报告一个 MC 错误 , 新的事件需要报告时 , 需要遵照一定的规则覆盖写之前的 MC 错误 .
    • 如果一个新的事件覆盖写了前一个事件 , IA32_MCi_STATUS 中包含的信息都和新的事件相关 .
  • IA32_MCi_ADDR , 包含产生 MC 错误的代码或者数据的内存地址 .
  • IA32_MCi_MISC , 包含 MC 错误的额外信息 .
  • IA32_MCi_CTL2 , 设定一个阈值 , 如果纠正过的错误数量达到阈值 , 报告一个溢出事件给 APIC 中的 CMCI LVT 项 .
  • IA32_MCG_CAP 扩展 MC 状态 MSR , 检测到 MC 错误时 , 处理器保存通用寄存器 , EFLAGS , EIP 寄存器到这些 MC 状态 MSR , 供调试器使用 .
    软件可以读取这些 MSR , 但是只能向 MSR 写入 0 .

2.2.1. IOMCA

PCI-E 错误的记录和报告由 PCI-E 高级错误报告 ( AER , advanced error reporting ) 控制 ; PCI-E 架构将错误分成可修正的和不可修正的两种 ; 后者又分成致命的和非致命的 .
不可修正的 IO 错误通过 AER MSR 或平台相关的机制比如 NMI 报告给系统软件 . 一些处理器支持一种称作 IOMCA 模式的错误处理模式 , 不可修正的 PCI-E 错误以 MC 异常的形式报告 , 记录在 MC 寄存器组中 .

IOMCA 模式下 , 处理器将不可修正的 PCI-E 错误作为通用的 IO 错误保存到 IA32_MCi_STATUS 寄存器的 MCACOD 域 .

2.3. Pentium 处理器 MC 错误到 MC 架构的映射

Pentium 处理器使用两个寄存器 P5_MC_TYPE 和 P5_MC_ADDR 报告 MC 错误 , Pentium 4 , XEON 等处理器映射这些寄存器到 IA32_MCi_STATUS 和 IA32_MCi_ADDR , 但是错误信息的编码方式不一致 .

3. 增强的 cache 错误报告

较早的 cache 状态基于 cache 中发生的纠错事件的个数 , 增强的 cache 错误报告称作 “基于阈值的错误状态” , cache 状态基于 cache 中发生重复纠错的 cache 行数 ( ECC 块数 ) . 这个阈值由 Intel 基于多个因素选定 .

支持增强的 cache 错误报告的处理器包含记录 cache 运行状态的硬件 , 提供健康状况的指示器 .

4. 纠正的 MC 错误中断

纠正的 MC 错误中断 ( CMCI ) 提供了基于阈值的错误报告机制外的功能 . 基于阈值的错误报告, 软件被限制使用阶段性的轮训操作 , 查询硬件纠正的 MC 错误的状态 . CMCI 提供了基于软件可编程的阈值传递一个本地中断的机制 .

如果多个逻辑处理器都受到 MC 错误的影响 , CMCI 传递给多于一个逻辑处理器 .

5. 未纠正的可恢复 ( UCR ) 错误的恢复

系统软件可以尝试恢复的 architectural MCA 错误称作未纠正的可恢复错误 : 已经检测到并报告的未纠正错误 , 但是没有损坏处理器的上下文 . 一旦系统软件执行了某些恢复操作 , 可以继续在处理器执行程序 .

5.1. UCR 错误报告和记录

IA32_MCi_STATUS MSR 用于报告 UCR 错误和现有的已纠正的和未纠正错误 . 设置 IA32_MCG_CAP[24] 时 , 下列设置表明 UCR 错误 :

  • valid ( bit 63 ) = 1
  • UC ( bit 61 ) = 1
  • PCC ( bit 57 ) = 0

此外 , IA32_MCI_STATUS bit 55:56 项系统软件提供额外信息 , 确定 UCR 错误的必要恢复操作 :

  • bit 56 , S ( signaling ) 标志 , 设置表明报告了 UCR 错误 , 系统软件需要检查 AR 标志和 IA32_MCi_STATUS 的 MCA 错误代码域 ; 清除表明 UCR 错误作为一个纠正的 MC ( CMC ) 报告 , 系统软件不需要执行任何的恢复操作 .
  • bit 55 , AR ( action required ) 标志 , 设置表明系统软件必须在错误报告时执行 MCA 特定错误代码的恢复操作 , 恢复操作必须在处理器执行后续任务前完成 ; 如果恢复操作无法成功完成 , 系统软件必须关闭系统 . 清除时 , 系统软件仍然可以选择执行恢复操作 , 也可以安全的恢复执行保存在栈中的指令指针 .

两个标志都是 sticky , 设置后 , 处理器不会清除 , 只有软件和开机重置可以清除 .

5.1.1. UCR 错误分类

UCR 错误可以根据 S 和 AR 标志分类 :

  • 未纠正 , 不需要执行操作 ( uncorrected no action required , UCNA ) , UCR 错误没有作为 MC 异常报告 , 而是纠正的 MC 错误报告给系统软件 . 处理器状态依然有效 , 可以继续执行 , 不需要执行额外的操作 . UC = 1 , PCC = 0 , S = 0 , AR = 0 .

  • 可选的软件可恢复的操作 ( software recoverable action optional , SRAO ) , UCR 错误通过 MC 异常或 CMCI 报告 , 软件恢复操作可选 , 非必须 . 处理器状态依然有效 , 提供了执行恢复操作所需的额外错误信息 .
    通过 MC 报告时 , UC = 1 , PCC = 0 , S = 1 , EN = 1 , AR = 0 ; 通过 CMCI 报告时 , UC = 1 , PCC = 0 , S = 0 .

  • 必要的软件可恢复的操作 ( SRAR ) , UCR 错误需要软件执行其他指令流前进行恢复操作 , UC = 1 , PCC = 0 , S = 1 , EN = 1 , AR = 1 .

5.1.2. UCR 错误覆盖写规则

规则包括 :

  • UCR 错误覆盖纠正的错误
  • 未纠正的 ( PCC = 1 ) 错误覆盖 UCR 错误
  • UCR 错误不会覆盖前一个 UCR 错误
  • 纠正的错误不会覆盖写之前的 UCR 错误

不管是否保留第一个错误 , 或第二个错误覆盖了第一个错误 , 都会设置 IA32_MCi_STATUS 寄存器指明发生了溢出 .

6. 翻译 MCA 错误代码

处理器探测到 MC 错误时 , 写入一个 16-bit 错误代码到 IA32_MCi_STATUS 寄存器的 MCA 错误代码域 , 并设置寄存器的有效标志 .

MCA 错误代码分成两种 : 简单的错误代码和复合的错误代码 .

简单的错误代码描述全局的错误信息 ; 复合的错误代码描述和 TLB , cache , 内存 , 总线和互连逻辑 , 内部计时器关联的错误 , 错误代码指明具体的 TLB , cache , 内存等信息 .

6.1. 多个 MCA 错误

一个探测窗口内检测到多个 MCA 错误时 , 处理器可能在单个事件内报告这些错误 , 系统软件就会在不同的 MC 寄存器组发现多个记录的 MCA 错误 . 为了处理器单个 MC 事件报告的多个 UCR 错误 , 并从多个错误中恢复 , 系统软件需要考虑下列问题 :

  • 通过系统报告的最严重的错误判断是否可以从多个软件恢复 , 如果最严重的错误是一个不可恢复错误 , 系统软件就无法恢复 , 需要重置系统 .
  • 报告多个可恢复的错误 , 错误中没有发现致命条件 , 系统软件执行每个可恢复错误的恢复操作后 , 可能从错误恢复 .

6.2. MC 错误代码的翻译

16 章提供了翻译 MCA 错误代码的信息 .

7. 编写 MC 软件的准则

MCA 和错误日志可以用三种不同的方法使用 :

  • 使用 #MC 异常在正常的指令执行期间检测机器错误
  • 定期检查和记录机器错误
  • 通过一个 MC 异常处理函数或一个纠正的 MC 中断处理函数仔细检查可恢复的 UCR 错误 , 确定软件可恢复性 , 执行恢复操作

7.1. MC 异常处理函数

MC 异常对应向量 18 , 要服务机器检查异常 , 必须添加一个陷入门到 IDT .陷入门的指针必须执行一个 MC 异常处理函数 , 两种途径可以用于设计异常处理函数 :

  1. 处理函数只记录所有的机器状态和错误信息 , 然后调用调试器关闭系统 .
  2. 处理函数分析报告的错误信息 , 尝试修复错误 , 重启处理器 .

7.2. 记录可修正的 MC 错误

如果 MC 错误可以修正 , 处理器不会产生 MC 异常 . 要探测可修正的 MC 错误 , 需要一个软件工具读取每一个机器检查错误报告寄存器组 , 记录结果到统计文件或数据结构 . 软件工具可以按照以下方式之一实现 :

  • 一个系统守护进程不经常的轮训寄存器组 , 比如每小时或每天
  • 一个用户启动的应用 , 轮训寄存器组 , 记录异常 . 实际的轮训服务由 OS 驱动或者系统调用提供 .
  • 一个服务 CMCI 的中断服务例程 , 可以读取 MC 寄存器组 , 记录错误 .

7.3. MC 软件处理器函数错误恢复准则

错误恢复的 MC 异常处理函数和错误恢复的纠正的 MC 处理函数的编写需要根据寄存器中的标志位执行对应的操作 .