Add test cases that uses every breakpoint/watchpoint to the debug-exceptions test. Signed-off-by: Reiji Watanabe <reijiw@xxxxxxxxxx> --- .../selftests/kvm/aarch64/debug-exceptions.c | 70 ++++++++++++++++--- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c index 4e00100b9aa1..829fad6c7d58 100644 --- a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c +++ b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c @@ -701,7 +701,7 @@ static void check_debug_regs(struct kvm_vm *vm, uint32_t vcpu, } } -int main(int argc, char *argv[]) +void run_test(uint8_t bpn, uint8_t wpn, uint8_t ctx_bpn) { struct kvm_vm *vm; struct ucall uc; @@ -710,6 +710,8 @@ int main(int argc, char *argv[]) uint8_t nbps, nwps; bool debug_reg_test = false; + pr_debug("%s bpn:%d, wpn:%d, ctx_bpn:%d\n", __func__, bpn, wpn, ctx_bpn); + vm = vm_create_default(VCPU_ID, 0, guest_code); ucall_init(vm, NULL); @@ -717,11 +719,6 @@ int main(int argc, char *argv[]) vcpu_init_descriptor_tables(vm, VCPU_ID); get_reg(vm, VCPU_ID, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &aa64dfr0); - if (cpuid_extract_uftr(aa64dfr0, ID_AA64DFR0_DEBUGVER_SHIFT) < 6) { - print_skip("Armv8 debug architecture not supported."); - kvm_vm_free(vm); - exit(KSFT_SKIP); - } vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT, ESR_EC_BRK_INS, guest_sw_bp_handler); @@ -742,11 +739,7 @@ int main(int argc, char *argv[]) nwps = cpuid_extract_uftr(aa64dfr0, ID_AA64DFR0_WRPS_SHIFT) + 1; TEST_ASSERT(nwps >= 2, "Number of watchpoints must be >= 2"); - /* - * Test with breakpoint#0 and watchpoint#0, and the higiest - * numbered breakpoint (the context aware breakpoint). - */ - vcpu_args_set(vm, VCPU_ID, 4, &debug_regs, 0, 0, nbps - 1); + vcpu_args_set(vm, VCPU_ID, 4, &debug_regs, bpn, wpn, ctx_bpn); for (stage = 0; stage < 13; stage++) { /* First two stages are sanity debug regs read/write check */ @@ -783,5 +776,60 @@ int main(int argc, char *argv[]) done: kvm_vm_free(vm); +} + +/* + * Run debug testing using the various breakpoint#, watchpoint# and + * context-aware breakpoint# with the given ID_AA64DFR0_EL1 configuration. + */ +void test_debug(uint64_t aa64dfr0) +{ + uint8_t brps, wrps, ctx_cmps; + uint8_t normal_brp_num, wrp_num, ctx_brp_base, ctx_brp_num; + int b, w, c; + + brps = cpuid_extract_uftr(aa64dfr0, ID_AA64DFR0_BRPS_SHIFT); + wrps = cpuid_extract_uftr(aa64dfr0, ID_AA64DFR0_WRPS_SHIFT); + ctx_cmps = cpuid_extract_uftr(aa64dfr0, ID_AA64DFR0_CTX_CMPS_SHIFT); + + pr_debug("%s brps:%d, wrps:%d, ctx_cmps:%d\n", __func__, + brps, wrps, ctx_cmps); + + /* Number of normal (non-context aware) breakpoints */ + normal_brp_num = brps - ctx_cmps; + + /* Number of watchpoints */ + wrp_num = wrps + 1; + + /* Number of context aware breakpoints */ + ctx_brp_num = ctx_cmps + 1; + + /* Lowest context aware breakpoint number */ + ctx_brp_base = normal_brp_num; + + for (c = ctx_brp_base; c < ctx_brp_base + ctx_brp_num; c++) { + for (b = 0; b < normal_brp_num; b++) { + for (w = 0; w < wrp_num; w++) + run_test(b, w, c); + } + } +} + +int main(int argc, char *argv[]) +{ + struct kvm_vm *vm; + uint64_t aa64dfr0; + + vm = vm_create_default(VCPU_ID, 0, guest_code); + get_reg(vm, VCPU_ID, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &aa64dfr0); + kvm_vm_free(vm); + + if (cpuid_extract_uftr(aa64dfr0, ID_AA64DFR0_DEBUGVER_SHIFT) < 6) { + print_skip("Armv8 debug architecture not supported."); + exit(KSFT_SKIP); + } + + /* Run debug tests with the default configuration */ + test_debug(aa64dfr0); return 0; } -- 2.36.0.rc0.470.gd361397f0d-goog