hw_breakpoint :watchpointhandler

    static void watchpoint_handler(unsigned long addr, unsigned int fsr,
                               struct pt_regs *regs)
{
        int i, access;
        u32 val, ctrl_reg, alignment_mask;
        struct perf_event *wp, **slots;
        struct arch_hw_breakpoint *info;
        struct arch_hw_breakpoint_ctrl ctrl;

        slots = (struct perf_event **)__get_cpu_var(wp_on_reg);

        for (i = 0; i < core_num_wrps; ++i) {
                rcu_read_lock();

                wp = slots[i];

                if (wp == NULL)
                   goto unlock;

                info = counter_arch_bp(wp);
                /*
                 * The DFAR is an unknown value on debug architectures prior
                 * to 7.1. Since we only allow a single watchpoint on these
                 * older CPUs, we can set the trigger to the lowest possible
                 * faulting address.
                 */
                if (debug_arch < ARM_DEBUG_ARCH_V7_1) {
                        BUG_ON(i > 0);
                        info->trigger = wp->attr.bp_addr;
                } else {
                        if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
                                alignment_mask = 0x7;
                        else
                                alignment_mask = 0x3;

                        /* Check if the watchpoint value matches. */
                        val = read_wb_reg(ARM_BASE_WVR + i);
                        if (val != (addr & ~alignment_mask))
                                goto unlock;

                        /* Possible match, check the byte address select. */
                        ctrl_reg = read_wb_reg(ARM_BASE_WCR + i);
                        decode_ctrl_reg(ctrl_reg, &ctrl);
                        if (!((1 << (addr & alignment_mask)) & ctrl.len))
                                goto unlock;

                        /* Check that the access type matches. */
                        access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W :
                                 HW_BREAKPOINT_R;
                        if (!(access & hw_breakpoint_type(wp)))
                                goto unlock;

                        /* We have a winner. */
                        info->trigger = addr;
                }

                pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);

                perf_bp_event(wp, regs);

       /*
                 * If no overflow handler is present, insert a temporary
                 * mismatch breakpoint so we can single-step over the
                 * watchpoint trigger.
                 */
                if (!wp->overflow_handler)
                        enable_single_step(wp, instruction_pointer(regs));

unlock:
                rcu_read_unlock();
        }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值