Add test cases that uses every breakpoint/watchpoint with various combination of ID_AA64DFR0_EL1.BRPs, WRPs, and CTX_CMPs configuration to the debug-exceptions test. Signed-off-by: Reiji Watanabe <reijiw@xxxxxxxxxx> --- .../selftests/kvm/aarch64/debug-exceptions.c | 52 ++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c index 829fad6c7d58..d8ebbb7985da 100644 --- a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c +++ b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c @@ -701,18 +701,19 @@ static void check_debug_regs(struct kvm_vm *vm, uint32_t vcpu, } } -void run_test(uint8_t bpn, uint8_t wpn, uint8_t ctx_bpn) +void run_test(uint64_t aa64dfr0, uint8_t bpn, uint8_t wpn, uint8_t ctx_bpn) { struct kvm_vm *vm; struct ucall uc; int stage; - uint64_t aa64dfr0; 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); - + pr_debug("%s aa64dfr0:0x%lx, bpn:%d, wpn:%d, ctx_bpn:%d\n", __func__, + aa64dfr0, bpn, wpn, ctx_bpn); vm = vm_create_default(VCPU_ID, 0, guest_code); + set_reg(vm, VCPU_ID, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), aa64dfr0); + ucall_init(vm, NULL); vm_init_descriptor_tables(vm); @@ -810,15 +811,33 @@ void test_debug(uint64_t aa64dfr0) 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); + run_test(aa64dfr0, b, w, c); } } } +uint64_t update_aa64dfr0_bwrp(uint64_t dfr0, uint8_t brps, uint8_t wrps, + uint8_t ctx_brps) +{ + /* Clear brps/wrps/ctx_cmps fields */ + dfr0 &= ~(ARM64_FEATURE_MASK(ID_AA64DFR0_BRPS) | + ARM64_FEATURE_MASK(ID_AA64DFR0_WRPS) | + ARM64_FEATURE_MASK(ID_AA64DFR0_CTX_CMPS)); + + /* Set new brps/wrps/ctx_cmps fields */ + dfr0 |= ((uint64_t)brps << ID_AA64DFR0_BRPS_SHIFT) | + ((uint64_t)wrps << ID_AA64DFR0_WRPS_SHIFT) | + ((uint64_t)ctx_brps << ID_AA64DFR0_CTX_CMPS_SHIFT); + + return dfr0; +} + int main(int argc, char *argv[]) { struct kvm_vm *vm; - uint64_t aa64dfr0; + uint64_t aa64dfr0, test_aa64dfr0; + uint8_t max_brps, max_wrps, max_ctx_brps; + int bs, ws, cs; vm = vm_create_default(VCPU_ID, 0, guest_code); get_reg(vm, VCPU_ID, KVM_ARM64_SYS_REG(SYS_ID_AA64DFR0_EL1), &aa64dfr0); @@ -831,5 +850,26 @@ int main(int argc, char *argv[]) /* Run debug tests with the default configuration */ test_debug(aa64dfr0); + + if (!kvm_check_cap(KVM_CAP_ARM_ID_REG_CONFIGURABLE)) + return 0; + + /* + * Run debug tests with various number of breakpoints/watchpoints + * configuration. + */ + max_brps = cpuid_extract_uftr(aa64dfr0, ID_AA64DFR0_BRPS_SHIFT); + max_wrps = cpuid_extract_uftr(aa64dfr0, ID_AA64DFR0_WRPS_SHIFT); + max_ctx_brps = cpuid_extract_uftr(aa64dfr0, ID_AA64DFR0_CTX_CMPS_SHIFT); + for (cs = 0; cs <= max_ctx_brps; cs++) { + for (bs = cs + 1; bs <= max_brps; bs++) { + for (ws = 1; ws <= max_wrps; ws++) { + test_aa64dfr0 = update_aa64dfr0_bwrp(aa64dfr0, + bs, ws, cs); + test_debug(test_aa64dfr0); + } + } + } + return 0; } -- 2.36.0.rc0.470.gd361397f0d-goog