I am interested in generating a breakpoint exception in arm64 (aarch64), using LiteOS as working OS. To not be unclear, a Breakpoint exception is generated whenever the processor element tries to execute an instruction from a particular address (this shouldn't be confused with "breakpoint instruction exceptions", i.e. instruction bkpt
or int
, like in this question).
The section BREAKPOINT EXCEPTION of AARCH64 manual treats what I want to achieve (and this question as well, but it didn't solve my problem).
Before explaining my problem, let me say that I verified that my CPU supports hardware breakpoints: bits [15:12] of register ID_AA64DFR0_EL1
(manual here) are 0b1010
= 5-1 = 4
breakpoint supported.
In my userspace, I have a simple function:
void justAFunction()
{
printf("justAFunction has been called, did you block?\n");
}
Before calling this function, the userland process "set a breakpoint":
[...]
setBreakpoint((void *)justAFunction); /* this is a system call to the kernel */
[...]
justAFunction();
[...]
setBreakpoint
is a system call, and I implemented the kernel code as follow (like kvm code, the only reference I found in this respect, here):
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();
}
Description for DBGBCR0_EL1
and DBGBVR0_EL1
: here.
Specifically:
#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)
After trying to write addr
(namely justAFunction
virtual address) to DBGBVR0_EL1
, I tried to re-read the same register, and the content was correct.
What I expected is to raise a debug exception (which are enabled in my kernel because I am able to raise a breakpoint instruction like bkpt
or to single-step my application) once the userland process tried to execute justAFunction
.
Unfortunately, nothing happens. justAFunction
is executed and the exception vector is not triggered (I have verified with gdb).
My feeling is that I missed something, but I can't find what.