RAS--APEI 报错解析流程(2)

RAS--APEI 报错解析流程(1)

除了APEI 中除了GHES会记录错误,在Post过程中的错误通常是通过BERT Table汇报

 

1.BERT

Boot Error Record Table is used to report unhandled errors that occurred in a previous boot,it is reported as a ‘one-time polled’type error source.

Bert 用于记录post 过程中产生的 error 以及UCE hang 重启 BIOS 错误状态未进行清除在下次重启扫描出的error

具体结构如图所示:

使用BERT 的header  通过section type 区分错误类型 对应到不同的错误结构 都是通过block error status addrss 链接

内存 pcie cpu的错误汇报信息结构体

 

 

使用IASL 解析BERT table:

BIOS 在Post 过程中去扫描pcie error 内存 error  CPU error

NBIOErrorDetection 检测到错误 addbert ->GENERIC_PCIE_AER_ERR_ENTRY

MCAErrorDetection 检测到MCA Bank UMC 错误  addbert ->GENERIC_MEM_ERR_ENTRY

MCAErrorDetection 检测到MCA Bank PIE  错误  addbert ->GENERIC_PRO_ERR_ENTRY

CPU BERT OS 解析

内存OS 解析

PCIE OS 解析

 

Post过程中检测到多个BERT :有内存和CPU bank 的错误状态

BIOS 日志:两个MCA Bank 读取到错误MCA_Status

 

BERT Table: BIOS 汇报和OS 解析通过Boot Error Region Address 联系

 

Boot Error Region Address 对应到结构体

///

/// Generic Error Status Definition

///

typedef struct {

  EFI_ACPI_6_2_ERROR_BLOCK_STATUS    BlockStatus;

  UINT32                             RawDataOffset;

  UINT32                             RawDataLength;

  UINT32                             DataLength;

  UINT32                             ErrorSeverity;

} EFI_ACPI_6_2_GENERIC_ERROR_STATUS_STRUCTURE;

 

对于OS去打印HardWare error 只需要参考GHES 中的Error Block status 就会去打印 错误的GHES Table中的错误信息

typedef struct {

  UINT32    UncorrectableErrorValid     : 1;

  UINT32    CorrectableErrorValid       : 1;

  UINT32    MultipleUncorrectableErrors : 1;

  UINT32    MultipleCorrectableErrors   : 1;

  UINT32    ErrorDataEntryCount         : 10;

  UINT32    Reserved                    : 18;

} EFI_ACPI_6_2_ERROR_BLOCK_STATUS;

也就是当扫描到BlockStatus 存在错误状态 OS就会上报Hardware error  然后清除错误状态

后面接着结构体,后面的结构体会根据SectionType 接着内存/CPU/PCIE 的结构体

typedef struct {

  UINT8     SectionType[16];

  UINT32    ErrorSeverity;

  UINT16    Revision;

  UINT8     ValidationBits;

  UINT8     Flags;

  UINT32    ErrorDataLength;

  UINT8     FruId[16];

  UINT8     FruText[20];

  UINT8     Timestamp[8];

} EFI_ACPI_6_2_GENERIC_ERROR_DATA_ENTRY_STRUCTURE;

 

/*

 * Section type definitions, used in section_type field in struct

 * cper_section_descriptor

 *

 * Processor Generic

 */

#define CPER_SEC_PROC_GENERIC                       \

    GUID_INIT(0x9876CCAD, 0x47B4, 0x4bdb, 0xB6, 0x5E, 0x16, 0xF1,   \

          0x93, 0xC4, 0xF3, 0xDB)

/* Processor Specific: X86/X86_64 */

#define CPER_SEC_PROC_IA                        \

    GUID_INIT(0xDC3EA0B0, 0xA144, 0x4797, 0xB9, 0x5B, 0x53, 0xFA,   \

          0x24, 0x2B, 0x6E, 0x1D)

/* Processor Specific: IA64 */

#define CPER_SEC_PROC_IPF                       \

    GUID_INIT(0xE429FAF1, 0x3CB7, 0x11D4, 0x0B, 0xCA, 0x07, 0x00,   \

          0x80, 0xC7, 0x3C, 0x88, 0x81)

/* Processor Specific: ARM */

#define CPER_SEC_PROC_ARM                       \

    GUID_INIT(0xE19E3D16, 0xBC11, 0x11E4, 0x9C, 0xAA, 0xC2, 0x05,   \

          0x1D, 0x5D, 0x46, 0xB0)

/* Platform Memory */

#define CPER_SEC_PLATFORM_MEM                       \

    GUID_INIT(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83,   \

          0xED, 0x7C, 0x83, 0xB1)

#define CPER_SEC_PCIE                           \

    GUID_INIT(0xD995E954, 0xBBC1, 0x430F, 0xAD, 0x91, 0xB4, 0x4D,   \

          0xCB, 0x3C, 0x6F, 0x35)

/* Firmware Error Record Reference */

Section Type=CPER_SEC_PROC_GENERIC 对应到 CPU 的错误结构体

 

 

对于GHES 的错误OS需要使用定时器,BERT 只需要在Kernel 加载时跑一边即可。

OS 下错误解析  ghes.c bert.c  cper.c

GHES 驱动:

static struct platform_driver ghes_platform_driver = {

    .driver     = {

        .name   = "GHES",

    },

    .probe      = ghes_probe,

    .remove     = ghes_remove,

};

ghes_init 加载GHES的驱动 ,系统下的解析策略和Notify 的结构体相关联,BIOS中会设置Notify Type ,Pollinterval

系统下扫描GHES 的驱动 是通过定时器周期性去扫描错误状态,Pollinterval 是定时器的参考时间

 

    switch (generic->notify.type) {

    case ACPI_HEST_NOTIFY_POLLED:

    case ACPI_HEST_NOTIFY_EXTERNAL:

    case ACPI_HEST_NOTIFY_SCI:

    case ACPI_HEST_NOTIFY_GSIV:

    case ACPI_HEST_NOTIFY_GPIO:

        break;

    case ACPI_HEST_NOTIFY_SEA:

        if (!IS_ENABLED(CONFIG_ACPI_APEI_SEA)) {

            pr_warn(GHES_PFX "Generic hardware error source: %d notified via SEA is not supported\n",

                generic->header.source_id);

            rc = -ENOTSUPP;

            goto err;

        }

        break;

    case ACPI_HEST_NOTIFY_NMI:

        if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_NMI)) {

            pr_warn(GHES_PFX "Generic hardware error source: %d notified via NMI interrupt is not supported!\n",

                generic->header.source_id);

            goto err;

        }

        break;

    case ACPI_HEST_NOTIFY_LOCAL:

        pr_warning(GHES_PFX "Generic hardware error source: %d notified via local interrupt is not supported!\n",

               generic->header.source_id);

        goto err;

 

 

timer_setup(&ghes->timer, ghes_poll_func, TIMER_DEFERRABLE);

ghes_proc(ghes);

    ghes_read_estatus(ghes, 0);//-->apei_read(&buf_paddr, &g->error_status_address);

    ghes_print_estatus

    cper_estatus_print(pfx_seq, estatus);

 

 

这就对应到Dmesg 中的HardWare error 错误,就可以识别到错误的source id ,既可以大致定位错误信息来源 Source id = 512 对应到PCIE 错误

后续通过Section error type 定位到更加详细的信息

前面的信息都是来自于固定结构体

///

/// Generic Error Data Entry Definition

///

typedef struct {

  UINT8     SectionType[16];

  UINT32    ErrorSeverity;

  UINT16    Revision;

  UINT8     ValidationBits;

  UINT8     Flags;

  UINT32    ErrorDataLength;

  UINT8     FruId[16];

  UINT8     FruText[20];

  UINT8     Timestamp[8];

} EFI_ACPI_6_2_GENERIC_ERROR_DATA_ENTRY_STRUCTURE;

static void

cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata,

               int sec_no)

{

    guid_t *sec_type = (guid_t *)gdata->section_type;

    __u16 severity;

    char newpfx[64];

    if (acpi_hest_get_version(gdata) >= 3)

        cper_print_tstamp(pfx, (struct acpi_hest_generic_data_v300 *)gdata);

    severity = gdata->error_severity;

    printk("%s""Error %d, type: %s\n", pfx, sec_no,

           cper_severity_str(severity));

    if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)

        printk("%s""fru_id: %pUl\n", pfx, gdata->fru_id);

    if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)

        printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text);

}

 

对于后续的结构体包括内存PCIE CPU 有着不同的结构体主要包括三个函数打印错误信息,通过匹配Section type Guid 判断

  cper_print_proc_generic(); cper_print_mem(); cper_print_pcie()

if (guid_equal(sec_type, &CPER_SEC_PROC_GENERIC)) {

        struct cper_sec_proc_generic *proc_err = acpi_hest_get_payload(gdata);

        printk("%s""section_type: general processor error\n", newpfx);

        if (gdata->error_data_length >= sizeof(*proc_err))

            cper_print_proc_generic(newpfx, proc_err);

        else

            goto err_section_too_small;

    } else if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {

        struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);

        printk("%s""section_type: memory error\n", newpfx);

        if (gdata->error_data_length >=

            sizeof(struct cper_sec_mem_err_old))

            cper_print_mem(newpfx, mem_err,

                       gdata->error_data_length);

        else

            goto err_section_too_small;

    } else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {

        struct cper_sec_pcie *pcie = acpi_hest_get_payload(gdata);

        printk("%s""section_type: PCIe error\n", newpfx);

        if (gdata->error_data_length >= sizeof(*pcie))

            cper_print_pcie(newpfx, pcie, gdata);

        else

            goto err_section_too_small;

#if defined(CONFIG_ARM64) || defined(CONFIG_ARM)

    } else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {

        struct cper_sec_proc_arm *arm_err = acpi_hest_get_payload(gdata);

        printk("%ssection_type: ARM processor error\n", newpfx);

        if (gdata->error_data_length >= sizeof(*arm_err))

            cper_print_proc_arm(newpfx, arm_err);

        else

            goto err_section_too_small;

 

CPU错误信息结构体:

typedef struct _PLATFORM_PROC_ERR_SEC {

  PROC_ERR_VALID_BIT    ValidBits;              ///< Validation Bits

  UINT64                LocalApicID;            ///< Processor APIC ID

  UINT64                CpuIdInfo_EAX;          ///< CPUID Information output value from EAX

  UINT64                CpuIdInfo_EBX;          ///< CPUID Information output value from EBX

  UINT64                CpuIdInfo_ECX;          ///< CPUID Information output value from ECX

  UINT64                CpuIdInfo_EDX;          ///< CPUID Information output value from EDX

  UINT64                CpuIdInfo_PD1;          ///< CPUID Information Padding 1

  UINT64                CpuIdInfo_PD2;          ///< CPUID Information Padding 2

} PLATFORM_PROC_ERR_SEC;

内存错误信息结构体:

typedef struct _PLATFORM_MEM_ERR_SEC {

  MEM_ERR_VALID_BIT    ValidBits;   ///< Valid bits Bitmp

  UINT64               ErrStatus;   ///< Error Status

  UINT64               PhyAddr;     ///< Physical memory address of detected error

  UINT64               PhyAddrMask; ///< Physical Error Address mask

  UINT16               Node;        ///< Node Number

  UINT16               Card;        ///< Card Number

  UINT16               Module;      ///< Module Number

  UINT16               Bank;        ///< Bank Number

  UINT16               Device;      ///< Device Number

  UINT16               Row;         ///< Row Number

  UINT16               Column;      ///< Column Number

  UINT16               BitPosition; ///< Bit Position

  UINT64               RequestorID; ///< Requestor ID

  UINT64               ResponderID; ///< Responder ID

  UINT64               TargetID;    ///< Target ID

  UINT8                MemErrType;  ///< Memory Error Type

  UINT8                Extend;      ///< Extened

  UINT16               RankNumber;  ///< Rank Number

  UINT16               CardHandle;  ///< Card Number

  UINT16               ModuleHandle;///< Module Number

} PLATFORM_MEM_ERR_SEC;

 

PCIE 错误信息结构体:

///

/// PCIE Error Section

///

typedef struct {

  PCIE_ERR_VALID_BIT    Validation;                                  ///< Validation Bits

  UINT32                PortType;                                    ///< Port Type

  UINT32                Revision;                                    ///< Revision

  UINT32                CommandStatus;                               ///< Command Status

  UINT32                Reserved;                                    ///< Reserved

  DEVICE_ID             DeviceId;                                    ///< Device Id

  UINT8                 SerialNum[8];                                ///< Serial Num

  UINT32                BridgeCtrlStatus;                            ///< Bridge Control Status

  CAP_STRUCTURE         CapabilityStructure;                         ///< Capability Structure

  AER_INFO              AerInfo;                                     ///< AER Info

} PCIE_ERROR_SECTION;

 

对于BERT 错误不需要使用定时器在Kernel 加载的时候会去初始化一遍BERT

BERT   \drivers\acpi\apei\bert.c

bert_init  -->

pr_info_once("Error records from previous boot:\n");

bert_print_all(boot_error_region, region_len);

cper_estatus_print(KERN_INFO HW_ERR, estatus);

错误解析和HEST GHES 类似

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/50055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS Next 省市区级联(三级联动)筛选框

效果图 完整代码 实例对象 export class ProvinceBean {id?: stringpid?: stringisSelect?: booleandeep?: objectextName?: stringchildren?: ProvinceBean[] }级联代码 import { MMKV } from tencent/mmkv/src/main/ets/utils/MMKV import { ProvinceBean } from ..…

基于 HTML+ECharts 实现智慧运维数据可视化大屏(含源码)

智慧运维数据可视化大屏&#xff1a;基于 HTML 和 ECharts 的实现 在现代企业中&#xff0c;运维管理是确保系统稳定运行的关键环节。随着数据量的激增&#xff0c;如何高效地监控和分析运维数据成为了一个重要课题。本文将介绍如何利用 HTML 和 ECharts 实现一个智慧运维数据可…

深入理解 Java NIO:ByteBuffer和MappedByteBuffer的特性与使用

目录 前言 ByteBuffer是什么 重要特点 分配缓冲区 读写模式切换 操作文本数据 操作基本数据类型 案例解析-循环输出数据 MappedByteBuffer是什么 MappedByteBuffer 的工作机制 刷盘时机 总结 前言 在深入学习 RocketMQ 这款高性能消息队列框架的源码时&#xff0c…

醒醒,别睡了...讲《数据分析pandas库》了—/—<1>

一、了解pandas No.1 Pandas 是 Python 语言的一个扩展程序库&#xff0c;用于数据分析&#xff0c;是一个强大的分析结构化数据的工具集&#xff0c;基础是Numpy库&#xff0c;可以去参考前面所讲的课。&#xff08;提供高性能的矩阵运算&#xff09; No.2 应用 &#xff1a;P…

vue上传Excel文件并直接点击文件列表进行预览

本文主要内容&#xff1a;用elementui的Upload 组件上传Excel文件&#xff0c;上传后的列表采用xlsx插件实现点击预览表格内容效果。 在项目中可能会有这样的需求&#xff0c;有很多种方法实现。但是不想要跳转外部地址&#xff0c;所以用了xlsx插件来解析表格&#xff0c;并展…

Docker安装kkFileView实现在线文件预览

kkFileView为文件文档在线预览解决方案,该项目使用流行的spring boot搭建,易上手和部署,基本支持主流办公文档的在线预览,如doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,图片,视频,音频等等 官方文档地址:https://kkview.cn/zh-cn/docs/production.html 一、拉取镜像 do…

1 深度学习网络DNN

代码来自B站up爆肝杰哥 测试版本 import torch import torchvisiondef print_hi(name):print(fHi, {name}) if __name__ __main__:print_hi(陀思妥耶夫斯基)print("HELLO pytorch {}".format(torch.__version__))print("torchvision.version:", torchvi…

用在ROS2系统中保持差速轮方向不变的PID程序

在ROS 2中&#xff0c;为了保持差速轮机器人的方向不变&#xff0c;通常需要使用PID&#xff08;Proportional Integral Derivative&#xff09;控制器来控制机器人的角速度。PID控制器可以帮助调整机器人的角速度&#xff0c;以维持其朝向不变。 下面是一个简单的ROS 2节点示…

使用el-table的案例小结——包含跨页多选、双击行、分页器、编辑\删除行、动态根据分页生成序号

首先看一下业务需求 需要实现跨页多选&#xff0c;双击行的时候弹出编辑对话框&#xff0c;对每行可以进行编辑和删除&#xff0c;实现分页器。 如果还没在项目中配置element-plus的可以参考文章 从零开始创建vue3项目——包含项目初始化、element-plus、eslint、axios、router…

vue import from

vue import from 导入文件&#xff0c;从XXXX路径&#xff1b;引入文件 import xxxx from “./minins/resize” import xxxx from “./minins/resize.js” vue.config.js 定义 : resolve(src)&#xff1b;就是指src 目录 import xxxx from “/utils/auth” im…

【C++初阶】string类

【C初阶】string类 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. 为什么学习string类&#xff1f; 1.1 C语言中的字符串 1.2 实际中 2. 标准库中的string类 2.1 string类 2.…

Web响应式设计———1、Grid布局

1、网格布局 Grid布局 流动网格布局是响应式设计的基础。它通过使用百分比而不是固定像素来定义网格和元素的宽度。这样&#xff0c;页面上的元素可以根据屏幕宽度自动调整大小&#xff0c;适应不同设备和分辨率。 <!DOCTYPE html> <html lang"en"> &l…

Mysql-索引视图

目录 1.视图 1.1什么是视图 1.2为什么需要视图 1.3视图的作用和优点 1.4创建视图 1.5更新视图 1.6视图使用规则 1.7修改视图 1.8删除视图 2.索引 2.1什么是索引 2.2索引特点 2.3索引分类 2.4索引优缺点 2.5创建索引 2.6查看索引 2.7删除索引 1.视图 1.1什么是…

go中map

文章目录 Map简介哈希表与Map的概念Go语言内建的Map类型Map的声明Map的初始化Map的访问Map的添加和修改Map的删除Map的遍历 Map的基本使用Map的声明与初始化Map的访问与操作Map的删除Map的遍历Map的并发问题实现线程安全的Map 3. Map的访问与操作3.1 访问Map元素代码示例&#…

释疑 803-(1)概述 精炼提纯版

目录 习题 1-01计算机网络可以向用户提供哪些服务? 1-02 试简述分组交换的要点。 1-03 试从多个方面比较电路交换、报文交换和分组交换的主要优缺点。 1-05 互联网基础结构的发展大致分为哪几个阶段?请指出这几个阶段最主要的特点。 1-06 简述互联网标准制定的几个阶段…

web网站组成

web网站由四部分组成&#xff1a;浏览器 前端服务器 后端服务器 数据库服务器 流程&#xff1a; 1.浏览器输入网站后&#xff0c;向前端服务器发送请求&#xff0c;前端服务器响应&#xff0c;静态的数据给浏览器。 2.前端代码中script中有url,这个是向后台发送请求的网…

手撕数据结构---------顺序表和链表

1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中⼴泛使 ⽤的数据结构&#xff0c;常⻅的线性表&#xff1a;顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构&#xff0c;也就说是连续的⼀条直…

Python研究生毕业设计,数据挖掘、情感分析、机器学习

最近在学校毕业了&#xff0c;其中有很多毕业论文使用到的代码&#xff0c;如数据挖掘、情感分析、机器学习、数据预测处理、划分数据集和测试集&#xff0c;绘制分类任务&#xff0c;词汇表示&#xff1a;使用TF-IDF向量化器&#xff0c;线性回归、多元线性回归、SVR回归模型&…

ecshop网站部署

目录 步骤1 ecshop网站的部署 一、安装环境 二、设置开机启动 ​三、 测试php ​四、上传安装包 五、安装ecshop 步骤1 ecshop网站的部署 一、安装环境 yum install -y httpd mariadb-server php php-devel php-mysql 浏览器访问&#xff1a;192.168.30.2 二、设置开机启…

LeetCode 415.字符串相加 C++写法

LeetCode 415.字符串相加 C写法 思路&#x1f914;&#xff1a; 首先不能用stoi和tostring来做&#xff0c;如果给一个很大的数那一定存不下。我们可以从后往前一位一位的取&#xff0c;创建一个变量存储进位用于计算下一位数&#xff0c;之后取模得到当前数字&#xff0c;每一…