如何在aarch64中设置硬件断点?

问题描述 投票:0回答:2

我有兴趣在arm64(aarch64)中生成断点异常,使用LiteOS作为工作操作系统。为了不不清楚,每当处理器元素尝试从特定地址执行指令时,就会生成断点异常(这不应与“断点指令异常”混淆,即指令

bkpt
int
,如 中所示)这个问题)。

AARCH64手册的断点异常部分处理了我想要实现的目标(以及这个问题,但它没有解决我的问题)。

在解释我的问题之前,让我说我验证了我的CPU支持硬件断点:寄存器

ID_AA64DFR0_EL1

(手册
这里)的位[15:12]是0b1010
 = 5-1 = 
4
断点支持.

在我的用户空间中,我有一个简单的功能:

void justAFunction() { printf("justAFunction has been called, did you block?\n"); }
在调用该函数之前,用户态进程“设置断点”:

[...] setBreakpoint((void *)justAFunction); /* this is a system call to the kernel */ [...] justAFunction(); [...]

setBreakpoint

是一个系统调用,我实现的内核代码如下(如kvm代码,我在这方面找到的唯一参考,
这里):

void setBreakpoint(void *addr) { AARCH64_SYSREG_WRITE(DBGBVR0_EL1, addr); AARCH64_SYSREG_WRITE(DBGBCR0_EL1, (AARCH64_SYSREG_READ(DBGBCR0_EL1) | DBGBCR_E | DBGBCR_LEN8 | DBGBCR_EXEC | DBGBCR_EL1)); isb(); asm volatile("msr daifclr, #8"); AARCH64_SYSREG_WRITE(mdscr_el1, (AARCH64_SYSREG_READ(mdscr_el1) | MDSCR_KDE | MDSCR_MDE)); isb(); }

DBGBCR0_EL1

DBGBVR0_EL1
的说明:
这里

具体:

#define DBGBCR_LEN8 (0xff << 5) #define DBGBCR_EXEC (0x0 << 3) #define DBGBCR_EL1 (0x1 << 1) #define DBGBCR_E (0x1 << 0) #define MDSCR_KDE (1 << 13) #define MDSCR_MDE (1 << 15)
尝试将

addr

(即
justAFunction
虚拟地址)写入
DBGBVR0_EL1
后,我尝试重新读取相同的寄存器,内容是正确的。

我期望的是一旦用户态进程尝试执行

bkpt

,就会引发调试异常(在我的内核中启用,因为我能够引发像
justAFunction
这样的断点指令或单步执行我的应用程序)。

不幸的是,什么也没发生。

justAFunction

被执行并且异常向量没有被触发(我已经用gdb验证过)。

我的感觉是我错过了一些东西,但我找不到什么。

linux-kernel arm arm64
2个回答
1
投票
您希望断点命中 EL0,但您将其配置为 EL1。放下

DBGBCR_EL1

 旗帜。

此外,您可能不想读取

DBGBCR0_EL1

 的当前内容,而是完全覆盖它们。

替换这个:

AARCH64_SYSREG_WRITE(DBGBCR0_EL1, (AARCH64_SYSREG_READ(DBGBCR0_EL1) | DBGBCR_E | DBGBCR_LEN8 | DBGBCR_EXEC | DBGBCR_EL1));
这样:

AARCH64_SYSREG_WRITE(DBGBCR0_EL1, (DBGBCR_E | DBGBCR_LEN8 | DBGBCR_EXEC));
    

0
投票
您需要根据您的问题将 PMC(特权模式控制)位 [2:1] 设置为

0b10

 而不是 
0b01
(而不是 
0b00
,因为这些位符合 Siguza 的建议)。

因此,再加一个定义,

#define DBGBCR_EL0 (0x2 << 1)
对控制寄存器的正确写入是

AARCH64_SYSREG_WRITE(DBGBCR0_EL1, (DBGBCR_E | DBGBCR_LEN8 | DBGBCR_EL0));
注意,我放弃了 

DBGBCR_EXEC

,因为它是 0。

架构参考手册中,它指出HMC、SSCE、SSC和PMC位都需要一起考虑,但我认为对于这种情况,我们可以在其他字段中保留零。

HMC | SSCE | SSC | PMC || EL3 | EL2 | EL1 | EL0 ----------------------------------------------- 0 | 0 | 00 | 01 || - | - | Y | - 0 | 0 | 00 | 10 || - | - | - | Y 0 | 0 | 00 | 11 || - | - | Y | Y ...
完整表格请参见

D2.8.4 断点生成断点异常的执行条件

© www.soinside.com 2019 - 2024. All rights reserved.