zoukankan      html  css  js  c++  java
  • 内核态发生非法地址访问是否会panic

    https://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652663676&idx=1&sn=b18ab57322594ebb8e7072e635e8bd1c&chksm=810f29e1b678a0f7238e8a71fd88f14c3c71e65556d149bbe851f08f775300bc7bb6ddbb503a&mpshare=1&scene=1&srcid=07302BR8M8OSgsym8wtFHNaB&sharer_sharetime=1564482704949&sharer_shareid=6a5d5f4082de4dfaafd2e3b24b69c271&pass_ticket=%2F5q07o1VYrDuvadEaasOzg9XP3sH%2B7O3W7boz%2BUgwgRPvsLYbzZpFyYQyGgBbiiB#rd

    如上链接是《宋宝华: Kernel Oops和Panic是一回事吗?》

    大概介绍了在未开启panic_on_oops,内核态非中断上下文 发生 访问0地址 时,kernel只会发oops,而不会panic。

    看完之后会有个疑问:缺页异常的上下文 是不是 中断上下文?

    答案是否。具体解析如下:

    1. 首先中断上下文是指当前HARDIRQ/NMI/softIRQ的计数不为0,code 如下:

    1 #define irq_count()    (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK 
    2                  | NMI_MASK))
    3 #define in_interrupt()        (irq_count())

      HARDIRQ 计数 在irq_enter()/irq_exit()接口中 做增减, 题外话:在irq_exit接口中通过invoke_softirq()触发软中断,一次执行时间限制在2ms或10次以内

      NMI 计数 在nmi_enter()/nmi_exit()接口中 做增减,ARM64貌似没有找到调用的地方?????

      softIRQ 计数 在__local_bh_disable_ip/__local_bh_enable接口中 做增减

    2. 对于ARM64, 异常向量表如下:

      1 // 文件:arch/arm64/kernel/entry.S
      2 
      3 // 向量表------------------------------------------------------------------------------------------------
      4     .align    11    //对齐2^7=128
      5 ENTRY(vectors)
      6     ventry    el1_sync_invalid        // Synchronous EL1t
      7     ventry    el1_irq_invalid            // IRQ EL1t
      8     ventry    el1_fiq_invalid            // FIQ EL1t
      9     ventry    el1_error_invalid        // Error EL1t
     10 
     11     ventry    el1_sync            // Synchronous EL1h 同步异常入口,缺页属于这一类
     12     ventry    el1_irq                // IRQ EL1h IRQ中断入口, HARDIRQ/SOFTIRQ 计数均在此入口增减
     13     ventry    el1_fiq_invalid            // FIQ EL1h FIQ入口,即NMI???? NMI计数应该在这个入口增减???
     14     ventry    el1_error_invalid        // Error EL1h
     15 
     16     ventry    el0_sync            // Synchronous 64-bit EL0
     17     ventry    el0_irq                // IRQ 64-bit EL0
     18     ventry    el0_fiq_invalid            // FIQ 64-bit EL0
     19     ventry    el0_error_invalid        // Error 64-bit EL0
     20 
     21 #ifdef CONFIG_COMPAT
     22     ventry    el0_sync_compat            // Synchronous 32-bit EL0
     23     ventry    el0_irq_compat            // IRQ 32-bit EL0
     24     ventry    el0_fiq_invalid_compat        // FIQ 32-bit EL0
     25     ventry    el0_error_invalid_compat    // Error 32-bit EL0
     26 #else
     27     ventry    el0_sync_invalid        // Synchronous 32-bit EL0
     28     ventry    el0_irq_invalid            // IRQ 32-bit EL0
     29     ventry    el0_fiq_invalid            // FIQ 32-bit EL0
     30     ventry    el0_error_invalid        // Error 32-bit EL0
     31 #endif
     32 END(vectors)
     33 
     34 // 同步异常:系统调用/数据abort/指令abort/未对齐/未定义/调试异常---------------------------------------------
     35     .align    6
     36 el1_sync:
     37     kernel_entry 1
     38     mrs    x1, esr_el1            // read the syndrome register
     39     lsr    x24, x1, #ESR_ELx_EC_SHIFT    // exception class
     40     cmp    x24, #ESR_ELx_EC_DABT_CUR    // data abort in EL1
     41     b.eq    el1_da
     42     cmp    x24, #ESR_ELx_EC_SYS64        // configurable trap
     43     b.eq    el1_undef
     44     cmp    x24, #ESR_ELx_EC_SP_ALIGN    // stack alignment exception
     45     b.eq    el1_sp_pc
     46     cmp    x24, #ESR_ELx_EC_PC_ALIGN    // pc alignment exception
     47     b.eq    el1_sp_pc
     48     cmp    x24, #ESR_ELx_EC_UNKNOWN    // unknown exception in EL1
     49     b.eq    el1_undef
     50     cmp    x24, #ESR_ELx_EC_BREAKPT_CUR    // debug exception in EL1
     51     b.ge    el1_dbg
     52     b    el1_inv
     53 // 数据abort
     54 el1_da:
     55     /*
     56      * Data abort handling
     57      */
     58     mrs    x0, far_el1
     59     enable_dbg
     60     // re-enable interrupts if they were enabled in the aborted context
     61     tbnz    x23, #7, 1f            // PSR_I_BIT
     62     enable_irq
     63 1:
     64     mov    x2, sp                // struct pt_regs
     65 // 跳往do_mem_abort->do_transation_fault->do_page_fault->do_kernel_fault->die->...
     66     bl    do_mem_abort
     67 
     68     // disable interrupts before pulling preserved data off the stack
     69     disable_irq
     70     kernel_exit 1
     71 el1_sp_pc:
     72     /*
     73      * Stack or PC alignment exception handling
     74      */
     75     mrs    x0, far_el1
     76     enable_dbg
     77     mov    x2, sp
     78     b    do_sp_pc_abort
     79 el1_undef:
     80     /*
     81      * Undefined instruction
     82      */
     83     enable_dbg
     84     mov    x0, sp
     85     b    do_undefinstr
     86 el1_dbg:
     87     /*
     88      * Debug exception handling
     89      */
     90     cmp    x24, #ESR_ELx_EC_BRK64        // if BRK64
     91     cinc    x24, x24, eq            // set bit '0'
     92     tbz    x24, #0, el1_inv        // EL1 only
     93     mrs    x0, far_el1
     94     mov    x2, sp                // struct pt_regs
     95     bl    do_debug_exception
     96     kernel_exit 1
     97 el1_inv:
     98     // TODO: add support for undefined instructions in kernel mode
     99     enable_dbg
    100     mov    x0, sp
    101     mov    x1, #BAD_SYNC
    102     mrs    x2, esr_el1
    103     b    bad_mode
    104 ENDPROC(el1_sync)
    105 
    106 // IRQ-------------------------------------------------------------------------------------------------------
    107     .align    6
    108 el1_irq:
    109     kernel_entry 1
    110     enable_dbg
    111 #ifdef CONFIG_TRACE_IRQFLAGS
    112     bl    trace_hardirqs_off
    113 #endif
    114 // 中断入口调用:handle_arch_irq->handle_irq
    115     irq_handler
    116 
    117 #ifdef CONFIG_PREEMPT
    118     get_thread_info tsk
    119     ldr    w24, [tsk, #TI_PREEMPT]        // get preempt count
    120     cbnz    w24, 1f                // preempt count != 0
    121     ldr    x0, [tsk, #TI_FLAGS]        // get flags
    122     tbz    x0, #TIF_NEED_RESCHED, 1f    // needs rescheduling?
    123 // 中断返回前执行抢占
    124     bl    el1_preempt    
    125 1:
    126 #endif
    127 #ifdef CONFIG_TRACE_IRQFLAGS
    128     bl    trace_hardirqs_on
    129 #endif
    130     kernel_exit 1
    131 ENDPROC(el1_irq)    

    3. HARDIRQ softIRQ 计数增减 的 代码流程,即缺页异常的流程 如下图:

    综上,在缺页的流程中:HARDIRQ/SOFTIRQ/NMI计数都没有增减,故in_interrupt()

  • 相关阅读:
    51Nod 1267 4个数和为0 二分
    51Nod 1090 3个数和为0 set 二分优化
    51Nod 1001 数组中和等于K的数对 Set
    Codeforces 890C
    Codeforces 890B
    Codeforces 890A
    51nod 1058 N的阶乘的长度 位数公式
    C#调用本机摄像头
    读取、写入excel数据
    数据库笔记--基本应用
  • 原文地址:https://www.cnblogs.com/zengjianrong/p/11280138.html
Copyright © 2011-2022 走看看