Linux 内核 x86 架构中用于计算 swap 文件最大允许大小的函数。它的核心逻辑是在通用限制的基础上如果 CPU 受L1TFL1 Terminal Fault漏洞影响且缓解措施开启就进一步收紧 swap 大小以堵住该漏洞的利用路径。核心作用L1TF 缓解下的 swap 大小限制L1TF 漏洞允许攻击者通过推测执行读取 L1 缓存中不属于自己的数据。内核的缓解措施之一是确保物理内存中不存在“无效”的 PTE页表项因为攻击者可以利用这些无效 PTE 的物理地址信息来推测数据。Swap 文件是这个问题的高危区域。当 swap 文件被映射到物理内存时如果其大小超过了某个限制就可能产生无效 PTE。因此arch_max_swapfile_size()会在 L1TF 缓解开启时主动限制 swap 文件的最大页数。代码逐段解析unsigned long arch_max_swapfile_size(void) { unsigned long pages; pages generic_max_swapfile_size(); // 1. 获取通用上限1. 通用上限generic_max_swapfile_size()返回一个与架构无关的、基于 swap 条目格式swp_entry_t的最大页数。这个值通常很大受限于 swap 偏移量的位数。if (boot_cpu_has_bug(X86_BUG_L1TF) l1tf_mitigation ! L1TF_MITIGATION_OFF) {2. 条件判断只有当 CPU 存在 L1TF 漏洞X86_BUG_L1TF且L1TF 缓解措施未关闭l1tf_mitigation ! L1TF_MITIGATION_OFF时才执行限制。unsigned long long l1tf_limit l1tf_pfn_limit();3. 计算 L1TF 限制l1tf_pfn_limit()返回一个页帧号PFN上限。这个值通常是物理内存最大地址的一半MAX_PA/2因为 L1TF 缓解要求内核不能使用高于此地址的物理内存来存储敏感数据。#if CONFIG_PGTABLE_LEVELS 2 l1tf_limit PAGE_SHIFT - SWP_OFFSET_FIRST_BIT; #endif4. 对齐到 swap 偏移格式这是一个关键的位运算调整。Swap 条目swp_entry_t的偏移量字段有特定的位布局其中低几位SWP_OFFSET_FIRST_BIT不用于存储 PFN。通过左移PAGE_SHIFT - SWP_OFFSET_FIRST_BIT位将l1tf_limit从“页帧号”转换为“swap 条目偏移量”的尺度从而让限制值在正确的量纲上比较。pages min_t(unsigned long long, l1tf_limit, pages);5. 取最小值最终swap 的最大页数取 L1TF 限制和通用限制中的较小值。return pages; }调用位置与流程arch_max_swapfile_size()主要在swapfile_init()函数中被调用。这个调用发生在内核初始化的后期具体路径如下start_kernel └─ arch_call_rest_init └─ rest_init └─ kernel_init └─ kernel_init_freeable └─ do_basic_setup └─ do_initcalls // 在此处调用 swapfile_init()swapfile_init()是一个initcall初始化调用它在第 4 级初始化调用时被执行。在swapfile_init()内部会调用arch_max_swapfile_size()来计算并缓存该架构支持的最大 swap 文件大小。为什么要在此时调用这个时间点很关键。对于 x86 架构arch_max_swapfile_size()的返回值依赖于L1TF 漏洞状态X86_BUG_L1TF和L1TF 缓解措施l1tf_mitigation。这些信息在更早的启动阶段setup_arch和check_bugs就已经确定好了所以到swapfile_init()执行时所有相关配置都已就绪可以安全地计算并缓存这个最大值。设计意图这个函数体现了内核对安全漏洞的精细化缓解不是简单地禁用 swap 或大幅限制内存而是精确地计算出在 L1TF 缓解框架下swap 文件最大能有多大而不产生安全风险。通过min_t取最小值它既尊重了通用的格式限制又叠加了安全约束确保系统在安全与可用性之间取得平衡。