AArch64 Linux 中的活动监视器单元 (AMU) 扩展¶
作者:Ionela Voinescu <ionela.voinescu@arm.com>
日期:2019-09-10
本文档简要描述了 AArch64 Linux 中活动监视器单元的支持。
架构概述¶
活动监视器扩展是 ARMv8.4 CPU 架构引入的可选扩展。
活动监视器单元实现在每个 CPU 中,提供用于系统管理的性能计数器。 AMU 扩展提供了一个系统寄存器接口来访问计数器寄存器,并且还支持可选的外部内存映射接口。
活动监视器架构的第 1 版实现了一个计数器组,该组包含四个固定的、架构定义的 64 位事件计数器。
CPU 周期计数器:以 CPU 的频率递增。
常量计数器:以系统时钟的固定频率递增。
已退役指令:每次执行架构指令时递增。
内存停顿周期:计算由时钟域内最后一级缓存中的未命中导致的指令分派停顿周期。
当处于 WFI 或 WFE 状态时,这些计数器不会递增。
活动监视器架构为最多 16 个架构事件计数器提供空间。架构的未来版本可能会使用此空间来实现其他架构事件计数器。
此外,第 1 版还实现了一个包含多达 16 个辅助 64 位事件计数器的计数器组。
在冷复位时,所有计数器都会重置为 0。
基本支持¶
内核可以安全地运行混合 CPU,无论是否支持活动监视器扩展。 因此,当选择 CONFIG_ARM64_AMU_EXTN 时,我们会无条件地启用该功能,以允许任何后来的 CPU(辅助或热插拔)检测和使用该功能。
当在 CPU 上检测到该功能时,我们会标记该功能的可用性,但这并不保证计数器的正确功能,仅保证扩展的存在。
固件(在更高的异常级别运行的代码,例如 arm-tf)需要
允许较低的异常级别(EL2 和 EL1)访问 AMU 寄存器。
启用计数器。 如果未启用,这些计数器将读取为 0。
在 CPU 从“关闭”电源状态启动/唤醒之前/之后,保存/恢复计数器。
当使用启用此功能的内核但使用损坏的固件启动时,用户在访问计数器寄存器时可能会遇到崩溃或死锁。 即使未观察到这些症状,寄存器读取返回的值也可能无法正确反映实际情况。 最常见的是,计数器将读取为 0,表明它们未启用。
如果固件中未提供适当的支持,最好禁用 CONFIG_ARM64_AMU_EXTN。 需要注意的是,出于安全原因,这不会绕过将 AMUSERENR_EL0 设置为捕获从 EL0(用户空间)到 EL1(内核)的访问。 因此,固件仍应确保对 AMU 寄存器的访问不会在 EL2/EL3 中被捕获。
AMUv1 的固定计数器可以通过以下系统寄存器定义访问
SYS_AMEVCNTR0_CORE_EL0
SYS_AMEVCNTR0_CONST_EL0
SYS_AMEVCNTR0_INST_RET_EL0
SYS_AMEVCNTR0_MEM_STALL_EL0
可以使用 SYS_AMEVCNTR1_EL0(n) 访问辅助平台特定的计数器,其中 n 是介于 0 和 15 之间的值。
详细信息可以在:arch/arm64/include/asm/sysreg.h 中找到。
用户空间访问¶
目前,由于以下原因,禁止从用户空间访问 AMU 寄存器
安全原因:它们可能会暴露有关以安全模式执行的代码的信息。
目的:AMU 计数器旨在用于系统管理。
此外,用户空间看不到该功能的存在。
虚拟化¶
目前,由于以下原因,禁止从 KVM 客户机端的用户空间 (EL0) 和内核空间 (EL1) 访问
安全原因:它们可能会暴露有关其他客户机或主机执行的代码的信息。
任何访问 AMU 寄存器的尝试都将导致将 UNDEFINED 异常注入到客户机中。