zoukankan      html  css  js  c++  java
  • struct arch_hw_breakpoint结构体

    struct arch_hw_breakpoint结构体

    watchpoint or breakpoint(type)、watchpoint监测的数据长度、监测的地址,这些信息都保存在arch_hw_breakpoint结构体里

    struct arch_hw_breakpoint {
        u64 address;
        u64 trigger;
        struct arch_hw_breakpoint_ctrl ctrl;
    };

    在arch_build_bp_info()里设置这个结构体:

    对于设置watchpoint时,attr->bp_type值为HW_BREAKPOINT_W(2),然后将attr->bp_addr的值赋值给arch_hw_breakpoint结构类型的address成员。

    attr->bp_len表示watchpoint监视的地址要监视多少个byte,比如值为8时,表示监视连续的8个字节,将这个len赋值给arch_hw_breakpoint里的ctrl.len成员,赋值给ctrl.len的len的含义用一个8bit的byte来表示某一个byte是否监视,比如bp_len是8时,赋值给ctrl.len的值为0xff,如果为7,则为0x7f。

    dbgwcrx_el1 register bitfield描述如下,这里的ctrl.len即是BAS field,[12:5],一共8bit:

    Figure 11.3. DBGWCRn_EL1 bit assignments

    Figure 11.3. DBGWCR

    4.19/arch/arm64/kernel/hw_breakpoint.c

    static int arch_build_bp_info(struct perf_event *bp,
                      const struct perf_event_attr *attr,
                      struct arch_hw_breakpoint *hw)
    {
        /* Type */
        switch (attr->bp_type) {
        case HW_BREAKPOINT_X:
            hw->ctrl.type = ARM_BREAKPOINT_EXECUTE;
            break;
        case HW_BREAKPOINT_R:
            hw->ctrl.type = ARM_BREAKPOINT_LOAD;
            break;
        case HW_BREAKPOINT_W:
            hw->ctrl.type = ARM_BREAKPOINT_STORE;
            break;
        case HW_BREAKPOINT_RW:
            hw->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
            break;
        default:
            return -EINVAL;
        }
    
        /* Len */
        switch (attr->bp_len) {
        case HW_BREAKPOINT_LEN_1:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_1;
            break;
        case HW_BREAKPOINT_LEN_2:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_2;
            break;
        case HW_BREAKPOINT_LEN_3:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_3;
            break;
        case HW_BREAKPOINT_LEN_4:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
            break;
        case HW_BREAKPOINT_LEN_5:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_5;
            break;
        case HW_BREAKPOINT_LEN_6:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_6;
            break;
        case HW_BREAKPOINT_LEN_7:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_7;
            break;
        case HW_BREAKPOINT_LEN_8:
            hw->ctrl.len = ARM_BREAKPOINT_LEN_8;
            break;
        default:
            return -EINVAL;
        }
    
        /*
         * On AArch64, we only permit breakpoints of length 4, whereas
         * AArch32 also requires breakpoints of length 2 for Thumb.
         * Watchpoints can be of length 1, 2, 4 or 8 bytes.
         */
        if (hw->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
            if (is_compat_bp(bp)) {
                if (hw->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
                    hw->ctrl.len != ARM_BREAKPOINT_LEN_4)
                    return -EINVAL;
            } else if (hw->ctrl.len != ARM_BREAKPOINT_LEN_4) {
                /*
                 * FIXME: Some tools (I'm looking at you perf) assume
                 *      that breakpoints should be sizeof(long). This
                 *      is nonsense. For now, we fix up the parameter
                 *      but we should probably return -EINVAL instead.
                 */
                hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
            }
        }
    
        /* Address */
        hw->address = attr->bp_addr;

    下面的hw_breakpoint_arch_parse()对于watchpoint,alignment_mask为0x7,如果address本身没有8对齐,则会将address向下对齐到8,同时ctrl.len也会左移对应的bit,比如address为0x5,则它会对齐到0x0,len为8(对应ctrl.len为0xff),offset为5,将0xff左移5bit得到0xe0,即只有最高3bit为1,表示只监视地址5/6/7,低位地址0-4不监视:

    setup watchpoint时,调用hw_breakpoint_control(),在这个函数里ops参数值为0,即HW_BREAKPOINT_INSTALL:

    [   21.943510] hw-breakpoint: ops: 0, reg_enable: 1.
    [   21.948240] CPU: 1 PID: 34 Comm: kworker/1:1 Tainted: P           O      4.19.116+ #19
    [   21.956172] Hardware name: test_mach(DT)
    [   21.959855] Workqueue: events watch_point_delayed_work_func
    [   21.965433] Call trace:
    [   21.967899]  dump_backtrace+0x0/0x4
    [   21.971414]  dump_stack+0xf4/0x134
    [   21.974829]  hw_breakpoint_control+0x184/0x29c
    [   21.979280]  hw_breakpoint_add+0x80/0x8c
    [   21.983210]  event_sched_in+0x44c/0x718
    [   21.987049]  group_sched_in+0x6c/0x218
    [   21.990816]  pinned_sched_in+0x158/0x264
    [   21.994749]  visit_groups_merge+0x140/0x1fc
    [   21.998947]  ctx_sched_in+0x1a4/0x1ec
    [   22.002631]  ctx_resched+0xdc/0x1e4
    [   22.006142]  __perf_event_enable+0x1d0/0x2c4
    [   22.010420]  event_function.9234+0x128/0x224
    [   22.014695]  remote_function+0x74/0xb4
    [   22.018469]  generic_exec_single+0x7c/0x1a4
    [   22.022679]  smp_call_function_single+0xc0/0x1e8
    [   22.027320]  event_function_call+0x84/0x274
    [   22.031512]  perf_event_enable+0xec/0x158
    [   22.035527]  _register_wp_bp+0x408/0x4b8
    [   22.039456]  watch_point_delayed_work_func+0x68/0xcc
    [   22.044443]  process_one_work+0x3c0/0x670
    [   22.048478]  worker_thread+0x32c/0x6d0
    [   22.052236]  kthread+0x130/0x140
    [   22.055468]  ret_from_fork+0x10/0x18
  • 相关阅读:
    c#实现MD5加密
    AJAX学习笔记 一:简单的XMLHTTPRequest示例和asp.net异步更新。
    客户端JS验证fileupload控件,设置只允许特定的文件类型。
    三层架构下的用户登录检测。
    常用用户注册页面客户端验证脚本。
    Android Debug Bridge 技术实现原理
    Android反编译与防止反编译
    android用sharepreference保存输入框中的内容
    android include 控件详解
    android程序排序算法实现
  • 原文地址:https://www.cnblogs.com/aspirs/p/15651684.html
Copyright © 2011-2022 走看看