Test the migration of single-step state. Setup single-stepping, migrate, and check that we are actually single-stepping. Signed-off-by: Ricardo Koller <ricarkol@xxxxxxxxxx> --- arm/debug.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ arm/unittests.cfg | 12 ++++++++++++ 2 files changed, 59 insertions(+) diff --git a/arm/debug.c b/arm/debug.c index b2240d7..54f059d 100644 --- a/arm/debug.c +++ b/arm/debug.c @@ -23,8 +23,10 @@ #define DBGWCR_E (0x1 << 0) #define SPSR_D (1 << 9) +#define SPSR_SS (1 << 21) #define ESR_EC_HW_BP_CURRENT 0x31 +#define ESR_EC_SSTEP_CURRENT 0x33 #define ESR_EC_WP_CURRENT 0x35 #define ID_AA64DFR0_BRPS_SHIFT 12 @@ -34,6 +36,7 @@ static volatile uint64_t hw_bp_idx, hw_bp_addr[16]; static volatile uint64_t wp_idx, wp_data_addr[16]; +static volatile uint64_t ss_addr[4], ss_idx; static void hw_bp_handler(struct pt_regs *regs, unsigned int esr) { @@ -47,6 +50,12 @@ static void wp_handler(struct pt_regs *regs, unsigned int esr) regs->pstate |= SPSR_D; } +static void ss_handler(struct pt_regs *regs, unsigned int esr) +{ + ss_addr[ss_idx++] = regs->pc; + regs->pstate |= SPSR_SS; +} + static int get_num_hw_bp(void) { uint64_t reg = read_sysreg(id_aa64dfr0_el1); @@ -344,6 +353,36 @@ static void test_wp(bool migrate) } } +static void test_ss(bool migrate) +{ + extern unsigned char ss_start; + uint32_t mdscr; + + install_exception_handler(EL1H_SYNC, ESR_EC_SSTEP_CURRENT, ss_handler); + + reset_debug_state(); + + ss_idx = 0; + + mdscr = read_sysreg(mdscr_el1) | MDSCR_KDE | MDSCR_SS; + write_sysreg(mdscr, mdscr_el1); + isb(); + + if (migrate) { + do_migrate(); + } + + asm volatile("msr daifclr, #8"); + + asm volatile("ss_start:\n" + "mrs x0, esr_el1\n" + "add x0, x0, #1\n" + "msr daifset, #8\n" + : : : "x0"); + + report(ss_addr[0] == (uint64_t)&ss_start, "single step"); +} + int main(int argc, char **argv) { if (argc < 2) @@ -365,6 +404,14 @@ int main(int argc, char **argv) report_prefix_push(argv[1]); test_wp(true); report_prefix_pop(); + } else if (strcmp(argv[1], "ss") == 0) { + report_prefix_push(argv[1]); + test_ss(false); + report_prefix_pop(); + } else if (strcmp(argv[1], "ss-migration") == 0) { + report_prefix_push(argv[1]); + test_ss(true); + report_prefix_pop(); } else { report_abort("Unknown subtest '%s'", argv[1]); } diff --git a/arm/unittests.cfg b/arm/unittests.cfg index bca2fad..c8c51d2 100644 --- a/arm/unittests.cfg +++ b/arm/unittests.cfg @@ -266,3 +266,15 @@ file = debug.flat arch = arm64 extra_params = -append 'wp-migration' groups = debug migration + +[debug-sstep] +file = debug.flat +arch = arm64 +extra_params = -append 'ss' +groups = debug + +[debug-sstep-migration] +file = debug.flat +arch = arm64 +extra_params = -append 'ss-migration' +groups = debug migration -- 2.34.1.173.g76aa8bc2d0-goog