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.