新闻详情

新闻详情

首页 / 资讯中心 / 详情

cr4_init_shadow

发布时间:2026/8/22 9:04:28
cr4_init_shadow
/* * cr4_init_shadow */ 0xffffffff82376403 x86_64_start_kernel8 mov %cr4,%rax 0xffffffff82376406 x86_64_start_kernel11 mov %rax,%gs:0x7dcb0cca(%rip) # 0x270d8 cpu_tlbstate24cr4_init_shadow()是 Linux 内核中一个用于初始化当前 CPU 的 CR4 寄存器“影子副本”的内联函数。这个机制的核心目的是优化性能避免在内核中频繁读取 CR4 寄存器时产生的高昂开销。实现原理与数据结构cr4_init_shadow()函数的实现非常简洁它只是读取硬件 CR4 寄存器的当前值并将其保存到 per-CPU 变量cpu_tlbstate.cr4中。static inline void cr4_init_shadow(void) { this_cpu_write(cpu_tlbstate.cr4, __read_cr4()); }这个 “影子” 是一个软件拷贝存在于内核为每个 CPU 核心维护的tlb_state结构体中。它使得内核后续对 CR4 状态的读取可以直接从内存中的 shadow 副本获取无需再执行开销较大的rdmsr或mov指令去访问硬件寄存器。核心用途高效地读取与更新 CR4一旦 shadow 副本被正确初始化内核中的相关函数就会围绕它来工作以实现更高效的 CR4 访问读取 CR4内核使用cr4_read_shadow()函数来获取当前值它只是直接读取 per-CPU 变量非常快。更新 CR4内核在修改 CR4 时例如通过cr4_set_bits()或cr4_clear_bits()会遵循“修改影子副本 - 将新值写入硬件 CR4”的模式。这能确保软件副本和硬件状态始终保持一致。关键作用保证启动早期初始化顺序cr4_init_shadow()必须在任何可能读取 CR4 shadow 副本的代码之前被调用。内核开发者对此非常重视并进行了多项修正主CPUBSP启动在 64 位内核中cr4_init_shadow()会在x86_64_start_reservations()之前被调用。在 32 位内核中则是在i386_start_kernel()内部完成。其他CPUAP启动对于系统中其他的 CPU 核心AP需要在它们开始执行任何可能引用 shadow 的 TLB 刷新操作如__flush_tlb_all()之前在start_secondary()函数的开头显式调用cr4_init_shadow()。中断处理依赖早期版本的代码中cr4_init_shadow()被放在idt_setup_early_handler()之前。这会导致在像 486 这样不支持 CR4 的旧 CPU 上因读取 CR4 产生异常而此时中断描述符表IDT尚未初始化导致系统崩溃。因此启动顺序修正为必须先在cr4_init_shadow()之前调用idt_setup_early_handler()以确保异常能被正确处理。兼容性处理为了兼容像 486 这样不支持 CR4 寄存器的老旧 CPUcr4_init_shadow()的实现特意使用了__read_cr4_safe()而非__read_cr4()。前者在硬件不支持 CR4 时能优雅地返回 0而不是触发异常导致内核崩溃。
网站建设 高端定制 企业官网