【19】怎么禁止PCIEAER的firmware first mode

pcie aer howto
https://github.com/torvalds/linux/blob/master/Documentation/PCI/pcieaer-howto.txt

pcieaer-howto.txt里面有一句话,比较有意思。
有些系统的firmware支持AER功能,如果linux使能AER的同时,firmware也来处理AER,将可能导致无法预知的行为。因此,linux不会处理AER事件,除非firmware确保有OS来控制AER,firmware和OS交接AER控制权是通过APCI的_OSC的方式实现的。
在这里插入图片描述
我们就需要研究一下PCI FW 的spec,看看怎么禁止firmware first mode来处理AER,简单说就是专业的人干专业的事儿,PCIe这个领域不存在一统江湖的人。ACPI的HEST既然干不了AER这么专业的事儿(至少现在干不了,相信以后也干不了,自己的的aer driver的需要根据不同设备发生的不同做成做深度定制化的处理,才能保证PCIe设备出现异常时,OS尽量不死,业务尽量不断),就应该让贤。
在这里插入图片描述
linux PCIEAER driver的作者写了一篇文章,enable pci express advance error report in kernel,
enable pci express advance report in kernel
感兴趣的可以自己下载。指出在2.6.18内核之前由于没有AER服务,BIOS做了一些基础的错误处理机制,但是这种机制不能配合相应设备得到更详细的错误信息,更重要的没有recovery的功能,因此linux kernel引入的AER driver
在这里插入图片描述
大部分的BIOS提供了非标准的错误处理机制,AER driver为了防止处理PCIe错误时与BIOS冲突,必须要通过APCI 的**_OSC机制**,从BIOS那里获取PCIE AER的控制权。
在这里插入图片描述
一旦PCIEAER driver获取了PCIe错误的控制权,BIOS必须停止PCIE错误处理。
在这里插入图片描述
在这里插入图片描述
如果BIOS不遵循 PCI FW 3.0规定的ACPI _OSC。PCIE AER driver有一种规避措施就是在bootgrub中加入aerdriver.forceload=y,不过这个aerdriver.forceload已经被移除了
https://lore.kernel.org/patchwork/patch/714628/
在这里插入图片描述
intel的白皮书
A Tour beyond BIOS Implementing the ACPI Platform Error Interface with the Unified Extensible Firmware Interface
Intel BIOS APCI白皮书
APEI提供了两种方式,Firmware first model(FFM)和OS native model。
FFM
所有的错误都通过SMI中断或者GPI中断通知到host firmware。然后Firmware分析错误,最后创建详细的有FRU信息的APEI 错误log(实际上firmware是很难做到的)。最后firmware通SCI、NMI或者其他中断通知OS。
OS native model
OS或者OS级别的软件提供直接访问hardware reg和分析错误的机制。这需要标准的硬件标准架构提供错误信息和上报功能。例如AER 和MCA(MCE architecture)
硬件平台可以使用并发模式,即FFM和OS native都存在,也就是某些错误使用FFM,某些错误使用OS native model(个人建议是PCIEAER 用OS native mode)
在这里插入图片描述
在X86架构下,错误通过硬件pin脚、硬件错误寄存器或者error msg通知host firmware。这些错误通常会触发SMI,这种host firmware就可以在SMM环境处理错误了。
error也可以通过X86架构下的中断通知OS,包括MCE/CMC或者AER MSI/INTx(基本上没有人再使用了)或者平台级的NMI/ACPI SCI。
在这里插入图片描述
前面说了很多理论,下面我们看看intel的框图
在这里插入图片描述
intel平台
下面介绍的比较详细,把MISCCTRLSTS 这个reg可以覆盖标准配置空间Root ctrl reg的system error enable bit的设置,因此在intel平台上要关闭firmware first model,首先把MISCCTRLSTS的bit35-33清零。防止MISCCTRLSTS覆盖了root ctrl reg对应bit。
ROOT CNT和其他一些AER reg(这些reg都不用手动操作,OS的AER driver和pci_enable_msi函数会帮你搞定,具体见linux 的AER driver)就可以了

/**
 * aer_enable_rootport - enable Root Port's interrupts when receiving messages
 * @rpc: pointer to a Root Port data structure
 *
 * Invoked when PCIe bus loads AER service driver.
 */
static void aer_enable_rootport(struct aer_rpc *rpc)
{
	struct pci_dev *pdev = rpc->rpd;
	int aer_pos;
	u16 reg16;
	u32 reg32;

	/* Clear PCIe Capability's Device Status */
	pcie_capability_read_word(pdev, PCI_EXP_DEVSTA, &reg16);
	pcie_capability_write_word(pdev, PCI_EXP_DEVSTA, reg16);

	/* Disable system error generation in response to error messages */
	pcie_capability_clear_word(pdev, PCI_EXP_RTCTL,
				   SYSTEM_ERROR_INTR_ON_MESG_MASK);

	aer_pos = pdev->aer_cap;
	/* Clear error status */
	pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
	pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
	pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, &reg32);
	pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32);
	pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, &reg32);
	pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32);

	/*
	 * Enable error reporting for the root port device and downstream port
	 * devices.
	 */
	set_downstream_devices_error_reporting(pdev, true);

	/* Enable Root Port's interrupt in response to error messages */
	pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, &reg32);
	reg32 |= ROOT_PORT_INTR_ON_MESG_MASK;
	pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, reg32);
}

在这里插入图片描述
在这里插入图片描述
AMD 平台
IOHCRASx0000017C (IOHC::PCIE0PortASerr_ACTION_CONTROL)到IOHCRASx00000378 (IOHC::PCIE1PortHParityErr_ACTION_CONTROL)清零,就可以关闭firmware first model了。

下面是OS的一下patch
https://patchwork.kernel.org/patch/10871703/
https://patchwork.ozlabs.org/cover/998635/
https://patchwork.kernel.org/patch/10871705/

发布了33 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/linjiasen/article/details/89215943