KVM: arm64: selftests: Add a test case for a linked watchpoint

Currently, the debug-exceptions test doesn't have a test case for
a linked watchpoint. Add a test case for the linked watchpoint to
the test. The new test case uses the highest numbered context-aware
breakpoint (for Context ID match), and the watchpoint#0, which is
linked to the context-aware breakpoint.

Signed-off-by: Reiji Watanabe <reijiw@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20221020054202.2119018-9-reijiw@google.com
This commit is contained in:
Reiji Watanabe 2022-10-19 22:42:01 -07:00 committed by Marc Zyngier
parent 142365932f
commit 5ced4e533b

View File

@ -22,6 +22,9 @@
#define DBGWCR_WR (0x2 << 3)
#define DBGWCR_EL1 (0x1 << 1)
#define DBGWCR_E (0x1 << 0)
#define DBGWCR_LBN_SHIFT 16
#define DBGWCR_WT_SHIFT 20
#define DBGWCR_WT_LINK (0x1 << DBGWCR_WT_SHIFT)
#define SPSR_D (1 << 9)
#define SPSR_SS (1 << 21)
@ -171,6 +174,28 @@ static void install_hw_bp(uint8_t bpn, uint64_t addr)
enable_monitor_debug_exceptions();
}
static void install_wp_ctx(uint8_t addr_wp, uint8_t ctx_bp, uint64_t addr,
uint64_t ctx)
{
uint32_t wcr;
uint64_t ctx_bcr;
/* Setup a context-aware breakpoint for Linked Context ID Match */
ctx_bcr = DBGBCR_LEN8 | DBGBCR_EXEC | DBGBCR_EL1 | DBGBCR_E |
DBGBCR_BT_CTX_LINK;
write_dbgbcr(ctx_bp, ctx_bcr);
write_dbgbvr(ctx_bp, ctx);
/* Setup a linked watchpoint (linked to the context-aware breakpoint) */
wcr = DBGWCR_LEN8 | DBGWCR_RD | DBGWCR_WR | DBGWCR_EL1 | DBGWCR_E |
DBGWCR_WT_LINK | ((uint32_t)ctx_bp << DBGWCR_LBN_SHIFT);
write_dbgwcr(addr_wp, wcr);
write_dbgwvr(addr_wp, addr);
isb();
enable_monitor_debug_exceptions();
}
void install_hw_bp_ctx(uint8_t addr_bp, uint8_t ctx_bp, uint64_t addr,
uint64_t ctx)
{
@ -306,6 +331,16 @@ static void guest_code(uint8_t bpn, uint8_t wpn, uint8_t ctx_bpn)
write_sysreg(0, contextidr_el1);
GUEST_ASSERT_EQ(hw_bp_addr, PC(hw_bp_ctx));
/* Linked watchpoint */
reset_debug_state();
install_wp_ctx(wpn, ctx_bpn, PC(write_data), ctx);
/* Set context id */
write_sysreg(ctx, contextidr_el1);
isb();
write_data = 'x';
GUEST_ASSERT_EQ(write_data, 'x');
GUEST_ASSERT_EQ(wp_data_addr, PC(write_data));
GUEST_DONE();
}