/* * CPU initialisation. */ static void hw_breakpoint_reset(void *unused) { int i; struct perf_event **slots; /* * When a CPU goes through cold-boot, it does not have any installed * slot, so it is safe to share the same function for restoring and * resetting breakpoints; when a CPU is hotplugged in, it goes * through the slots, which are all empty, hence it just resets control * and value for debug registers. * When this function is triggered on warm-boot through a CPU PM * notifier some slots might be initialized; if so they are * reprogrammed according to the debug slots content. */ for (slots = this_cpu_ptr(bp_on_reg), i = 0; i < core_num_brps; ++i) { if (slots[i]) { hw_breakpoint_control(slots[i], HW_BREAKPOINT_RESTORE); } else { write_wb_reg(AARCH64_DBG_REG_BCR, i, 0UL); write_wb_reg(AARCH64_DBG_REG_BVR, i, 0UL); } } for (slots = this_cpu_ptr(wp_on_reg), i = 0; i < core_num_wrps; ++i) { if (slots[i]) { hw_breakpoint_control(slots[i], HW_BREAKPOINT_RESTORE); } else { write_wb_reg(AARCH64_DBG_REG_WCR, i, 0UL); write_wb_reg(AARCH64_DBG_REG_WVR, i, 0UL); } } }
static void hw_breakpoint_restore(void) { int i; struct perf_event **slots; for (slots = __get_cpu_var(bp_on_reg), i = 0; i < core_num_brps; ++i) { if (slots[i]) { hw_breakpoint_control(slots[i], HW_BREAKPOINT_RESTORE); } else { write_wb_reg(AARCH64_DBG_REG_BCR, i, 0UL); write_wb_reg(AARCH64_DBG_REG_BVR, i, 0UL); } } for (slots = __get_cpu_var(wp_on_reg), i = 0; i < core_num_wrps; ++i) { if (slots[i]) { hw_breakpoint_control(slots[i], HW_BREAKPOINT_RESTORE); } else { write_wb_reg(AARCH64_DBG_REG_WCR, i, 0UL); write_wb_reg(AARCH64_DBG_REG_WVR, i, 0UL); } } }
void arch_uninstall_hw_breakpoint(struct perf_event *bp) { hw_breakpoint_control(bp, HW_BREAKPOINT_UNINSTALL); }
/* * Install a perf counter breakpoint. */ int arch_install_hw_breakpoint(struct perf_event *bp) { return hw_breakpoint_control(bp, HW_BREAKPOINT_INSTALL); }