热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

KernelOops和Panic是一回事吗?在未开启panic_on_oops,内核态非中断上下文发生访问0地址时,kernel只会发oops,而不会panic。

帐号已迁移如上链接是《宋宝华:KernelOops和Panic是一回事吗?》大概介绍了在未开启panic_on_oops,内核态非中断

帐号已迁移

如上链接是《宋宝华: 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.S2 3 // 向量表------------------------------------------------------------------------------------------------4 .align 11 //对齐2^7=1285 ENTRY(vectors)6 ventry el1_sync_invalid // Synchronous EL1t7 ventry el1_irq_invalid // IRQ EL1t8 ventry el1_fiq_invalid // FIQ EL1t9 ventry el1_error_invalid // Error EL1t10 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 EL1h15 16 ventry el0_sync // Synchronous 64-bit EL017 ventry el0_irq // IRQ 64-bit EL018 ventry el0_fiq_invalid // FIQ 64-bit EL019 ventry el0_error_invalid // Error 64-bit EL020 21 #ifdef CONFIG_COMPAT22 ventry el0_sync_compat // Synchronous 32-bit EL023 ventry el0_irq_compat // IRQ 32-bit EL024 ventry el0_fiq_invalid_compat // FIQ 32-bit EL025 ventry el0_error_invalid_compat // Error 32-bit EL026 #else27 ventry el0_sync_invalid // Synchronous 32-bit EL028 ventry el0_irq_invalid // IRQ 32-bit EL029 ventry el0_fiq_invalid // FIQ 32-bit EL030 ventry el0_error_invalid // Error 32-bit EL031 #endif32 END(vectors)33 34 // 同步异常:系统调用/数据abort/指令abort/未对齐/未定义/调试异常---------------------------------------------35 .align 636 el1_sync:37 kernel_entry 138 mrs x1, esr_el1 // read the syndrome register39 lsr x24, x1, #ESR_ELx_EC_SHIFT // exception class40 cmp x24, #ESR_ELx_EC_DABT_CUR // data abort in EL141 b.eq el1_da42 cmp x24, #ESR_ELx_EC_SYS64 // configurable trap43 b.eq el1_undef44 cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception45 b.eq el1_sp_pc46 cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception47 b.eq el1_sp_pc48 cmp x24, #ESR_ELx_EC_UNKNOWN // unknown exception in EL149 b.eq el1_undef50 cmp x24, #ESR_ELx_EC_BREAKPT_CUR // debug exception in EL151 b.ge el1_dbg52 b el1_inv53 // 数据abort54 el1_da:55 /*56 * Data abort handling57 */58 mrs x0, far_el159 enable_dbg60 // re-enable interrupts if they were enabled in the aborted context61 tbnz x23, #7, 1f // PSR_I_BIT62 enable_irq63 1:64 mov x2, sp // struct pt_regs65 // 跳往do_mem_abort->do_transation_fault->do_page_fault->do_kernel_fault->die->...66 bl do_mem_abort67 68 // disable interrupts before pulling preserved data off the stack69 disable_irq70 kernel_exit 171 el1_sp_pc:72 /*73 * Stack or PC alignment exception handling74 */75 mrs x0, far_el176 enable_dbg77 mov x2, sp78 b do_sp_pc_abort79 el1_undef:80 /*81 * Undefined instruction82 */83 enable_dbg84 mov x0, sp85 b do_undefinstr86 el1_dbg:87 /*88 * Debug exception handling89 */90 cmp x24, #ESR_ELx_EC_BRK64 // if BRK6491 cinc x24, x24, eq // set bit '0'92 tbz x24, #0, el1_inv // EL1 only93 mrs x0, far_el194 mov x2, sp // struct pt_regs95 bl do_debug_exception96 kernel_exit 197 el1_inv:98 // TODO: add support for undefined instructions in kernel mode99 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()

内核态发生非法地址访问是否会panic - black_man - 博客园


推荐阅读
author-avatar
UU常璐图_302
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有