@@ -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;
}
Add test cases that uses every breakpoint/watchpoint to the debug-exceptions test. Signed-off-by: Reiji Watanabe <reijiw@google.com> --- .../selftests/kvm/aarch64/debug-exceptions.c | 70 ++++++++++++++++--- 1 file changed, 59 insertions(+), 11 deletions(-)