[PATCH v7 38/38] KVM: arm64: selftests: Test breakpoint/watchpoint changing ID_AA64DFR0_EL1

Reiji Watanabe reijiw at google.com
Mon Apr 18 23:55:44 PDT 2022


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 at google.com>
---
 .../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




More information about the linux-arm-kernel mailing list