fault exc_page_fault
2026/9/23 16:05:18 网站建设 项目流程

DEFINE_IDTENTRY_RAW_ERRORCODE是 Linux 内核 x86 架构中用于定义原始异常入口函数的宏,它封装了硬件异常处理入口的底层汇编粘合逻辑,使开发者能直接编写 C 语言处理函数。

宏的核心作用

这个宏展开后,会定义一个带有struct pt_regs *regsunsigned long error_code参数的函数,并自动生成对应的汇编入口代码。它的关键特性是“原始”(RAW):调用者不会自动执行idtentry_enter/exit()辅助函数,这意味着中断是禁用的,且需要调用者在函数体内自行处理进入/退出逻辑。

宏定义与展开

#define DEFINE_IDTENTRY_RAW_ERRORCODE(func) \ __visible noinstr void func(struct pt_regs *regs, \ unsigned long error_code)

关键属性说明:

  • __visible:确保符号对汇编代码可见,因为汇编入口桩需要跳转到这个函数。

  • noinstr:禁止在函数中插入任何插桩代码(如 kprobe、ftrace),因为此时内核环境尚未完全就绪。

exc_page_fault的关系

exc_page_fault正是通过这个宏定义的:

DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault)

它在arch/x86/include/asm/idtentry.h中通过DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF, exc_page_fault)声明。当 CPU 触发缺页异常(向量 14)时,硬件会将错误码压栈,然后跳转到汇编入口桩,汇编桩再调用exc_page_fault

为什么缺页异常需要 “RAW” 模式?

缺页异常的处理路径非常特殊:

  1. 需要访问用户内存:处理缺页时可能需要读取用户态指令(如is_prefetch检测),而标准的idtentry_enter()会改变某些状态,可能干扰这一过程。

  2. 中断状态敏感:缺页处理中需要精确控制中断的启用/禁用时机,因此不能由宏自动处理。

  3. FRED 兼容性:在支持 FRED(Flexible Return and Event Delivery)的新架构上,exc_page_fault会被替换为fred_exc_page_fault,但两者最终都调用相同的page_fault_common逻辑。

调用链概览

CPU 触发缺页异常 (向量 14) ↓ 汇编入口桩 (asm_exc_page_fault) ↓ DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault) ↓ page_fault_common(regs, error_code, read_cr2()) ↓ handle_page_fault() 或 do_user_addr_fault() / do_kern_addr_fault()

read_cr2()用于获取触发异常的地址,因为缺页异常的错误码中不包含地址信息,必须从 CR2 寄存器读取。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询