@@ -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;
}
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@google.com> --- .../selftests/kvm/aarch64/debug-exceptions.c | 52 ++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-)