内核 6.6.0-24-generic(#0ok1-KYLINOS)IEE 子系统在 fork/slab 路径触发 double fault,导致随机死机重启

这个问题困扰了我很久,平均3天死机一次,现象为:鼠标键盘不能操作,Caps灯狅闪

以下报告为本地agent调查之后生成:

内核崩溃调查报告:IEE 子系统在 slab/巨页路径触发 double fault

项目 内容
报告日期 2026-09-24
严重级别 严重(Kernel Panic / 系统崩溃自动重启)
受影响内核 6.6.0-24-generic #0ok1-KYLINOS(CONFIG_IEE=y)
崩溃组件 arch/x86/kernel/iee/(麒麟定制内核子系统 IEE)
是否已定位崩溃路径 是(iee_set_token_page_valid → do_split_huge_pmd → allocate_slab)
是否与 GPU/显卡相关 否(推翻前期假设)
是否为硬件故障 现有证据指向软件缺陷;硬件未证实有问题

1. 概述

本机在运行中会随机卡死约 10 秒后自动重启。通过 ramoops/pstore 捕获到一次真实 panic 现场,完整调用链落在麒麟定制内核子系统 IEE(arch/x86/kernel/iee/)上:

dpkg 进程 fork/clone
  → dup_task_struct → slab 分配
  → iee_set_token_page_valid
  → do_split_huge_pmd   ← WARNING(arch/x86/kernel/iee/iee-func.c:77)
  → iee_rw_gate         ← PANIC: double fault(RSP=0,内核栈损坏)

崩溃发生在 dpkg 安装软件、产生大量 fork/clone 期间;路径涉及 slab 分配器与 透明巨页(THP)分裂(IEE 内部操作 IEE_OP_SPLIT_HUGE_PMD)。

结论:这是一处软件缺陷,而非显卡/显存问题。 前期围绕 Intel i915(Iris Xe)"GPU hang → hard lockup"的排查方向应予修正。


2. 环境信息

项目 值
机型 HUAWEI BoDE-WXX9 / M1010(华为笔记本,QUANTA 代工)
BIOS 1.20(2023-07-05)
CPU 11th Gen Intel Core i7-1195G7 @ 2.90GHz(Tiger Lake,8 线程)
集成显卡 Intel Iris Xe Graphics(PCI 8086:9a49)
内存 ~15.8 GiB,无 ECC
存储 NVMe SSD(1987:5013,PCI 0000:01:00.0)
操作系统 openKylin / KYLINOS(Kylin V10 系)
内核 6.6.0-24-generic #0ok1-KYLINOS SMP PREEMPT_DYNAMIC,构建于 Mon Jun 22 14:28:34 UTC 2026,编译器 gcc (Openkylin 12.3.0-1ok3) 12.3.0
内核配置(关键) CONFIG_IEE=y、CONFIG_TRANSPARENT_HUGEPAGE=y、CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y、CONFIG_SLUB=y、CONFIG_HARDENED_USERCOPY=y
取证机制 ramoops(固件 Reserved 区 0x70e00000,2MB)+ pstore

3. 问题现象

  • 随机死机:界面定格、无 panic 文本上屏,约 10 秒后自动重启(与 panic=10 行为一致)。
  • 部分事件进入固件自检/冷复位,导致内存被清空、ramoops 丢失现场。
  • 本次捕获到热重启(panic → 10 秒后重启)的完整现场。
  • 崩溃前 uptime 约 81653 秒,其中约 21 小时为 s2idle 休眠(见 §7)。
  • 崩溃时正在执行 dpkg(安装/升级软件),存在大量 fork/clone。

4. 取证过程与证据

4.1 证据文件

文件 说明 SHA-256
/var/lib/systemd/pstore/dmesg-ramoops-0 头部 Oops#1 Part1(1150 行) 944490f631ee5688f1cde4a71dc9b50a39bfd73df16d524f92c0ceed135d0a99
/var/lib/systemd/pstore/dmesg-ramoops-1 头部 Panic#2 Part1(1164 行) 6c700602e9167e090df9728922ec071bbe35fcb75ea6471a2527d331e345b70b

两份文件是同一次崩溃:pstore 在 WARN 时写 “Oops” 记录、panic 时写 “Panic” 记录,内容除末尾收尾行外完全相同。即本次只捕获到一次 panic。

4.2 崩溃调用链(自内向外,调用者在下)

WARNING: ... at arch/x86/kernel/iee/iee-func.c:77
        do_split_huge_pmd+0x21d/0x2d0
  ↑ iee_set_token_page_valid+0x30d/0x370
  ↑ allocate_slab+0x41e/0x5d0
  ↑ ? get_any_partial+0x11b/0x190
  ↑ ___slab_alloc+0x603/0xb00
  ↑ kmem_cache_alloc_node_noprof+0x2dd/0x3a0
  ↑ dup_task_struct+0x48/0x1d0
  ↑ copy_process+0x1e4/0x1680
  ↑ kernel_clone+0xc3/0x460
  ↑ __do_sys_clone+0x66/0x90
  ↑ do_syscall_64+0x7d/0x1e0
  ↑ entry_SYSCALL_64_after_hwframe+0x76/0xe0

WARN 上下文:

CPU: 1  PID: 42357  Comm: dpkg
Tainted: G     U  W
RIP: 0010:do_split_huge_pmd+0x21d/0x2d0
RAX: 80000000000001e1   RBX: ffff88847f8e3060   RDI: ffffea0005060000 (struct page)
RSI: ffff88821ef81000   RBP: ffff88821ef81000   CR2: 000000001e7a2418
CR4: 0000000000672ee0

WARN 之后立即:

traps: PANIC: double fault, error_code: 0x0
CPU: 7  PID: 42385  Comm: dpkg
RIP: 0010:iee_rw_gate+0x37/0x70
RSP: 0018:0000000000000000        ← 内核栈指针为 0(栈已损坏)
CR2: fffffffffffffff8            ← 访问 -8 偏移
Kernel panic - not syncing: Fatal exception in interrupt
Kernel Offset: disabled

4.3 时间线

内核时间 事件
~0.068s IEE 初始化异常(见 §5.3)
383s PM: suspend entry (s2idle) 进入休眠
76486s ACPI: EC: interrupt unblocked 唤醒(休眠约 21.1 小时)
76539–76555s kylin-vpn 反复 general protection fault(用户态)
76619s 起 PCIe AER Corrected 错误(NVMe 链路)
80283–80470s stack_test / v3 程序反复 segfault(用户态)
81653s IEE WARN → double fault → kernel panic

5. IEE 子系统分析

5.1 IEE 是什么

IEE 是麒麟定制内核功能,源码位于 arch/x86/kernel/iee/,编译进内核(CONFIG_IEE=y,非模块)。从符号与操作码看,它围绕页表级访问控制 / 内存隔离 / 令牌(token)机制构建,深度挂钩内存管理与 slab 分配:

  • 源文件:iee.c、iee-func.c、page-slab.c、stack-slab.c
  • 关键函数(部分,共 104 个 IEE 符号):
    init_iee_offset、iee_rw_gate、iee_rwx_gate、iee_read_token_stack、iee_read_tmp_page、iee_read_freeptr、set_iee_page、unset_iee_page、iee_set_logical_mem_ro、set_iee_page_valid/invalid、iee_set_token_page_valid/invalid、set_iee_stack_page、get_iee_stack、free_iee_stack、iee_free_task_struct_slab、iee_free_slab、kernel_physical_mapping_init_for_iee、init_memory_mapping_for_iee、iee_get_oo_objects
  • 操作码枚举:IEE_OP_INIT_TOKEN、IEE_OP_INVALIDATE_TOKEN、IEE_OP_SET_TOKEN、IEE_OP_UNSET_TOKEN、IEE_OP_VALIDATE_TOKEN、IEE_OP_SET_TOKEN_PGD、IEE_OP_SPLIT_HUGE_PMD、IEE_OP_READ_*、IEE_OP_MEMCPY/MEMSET、IEE_OP_SET_FREEPTR、IEE_OP_TEST_CLEAR_BIT

其中 IEE_OP_SPLIT_HUGE_PMD 与崩溃点 do_split_huge_pmd 直接对应,说明 IEE 会在其令牌/页管理流程中主动分裂巨页 PMD。

5.2 与崩溃的关系

  • 崩溃路径为 allocate_slab → iee_set_token_page_valid → do_split_huge_pmd,即 IEE 在为 slab 页建立/校验令牌时,走到了巨页 PMD 分裂逻辑。
  • 该路径上的 WARNING(iee-func.c:77)触发后,紧接着 iee_rw_gate 发生 double fault,且 RSP=0,表明 IEE 的门(gate)机制在异常后破坏了内核栈。

5.3 IEE 初始化异常(每次开机均出现)

<3>[0.067] IBT selftest: Failed!
<3>[0.068] IEE SI disabled because SMAP or SMEP is not available
<3>[0.068] IEE: testing iee_exec_entry si_test...
<3>[0.068] IEE: testing iee_exec_entry si_test...        ← 重复两次

5.4 关于 SMEP/SMAP 的重要观察

  • /proc/cpuinfo 明确报告 CPU 支持 smap、smep。
  • 但崩溃现场 CR4 = 0x0000000000672ee0:其中 bit20(SMEP)= 0,bit21(SMAP)= 1,即内核运行在 SMEP 已关闭的状态。
  • IEE 启动时也报告 “SMAP or SMEP is not available”,并据此禁用了 IEE SI。

推断(待厂商确认):内核/或 IEE 自身以 SMEP 关闭的方式运行(例如 IEE 的 rwx_gate/可执行门机制可能与 SMEP 冲突,或探测时机早于 SMEP 启用),导致 IEE SI 在半残状态下运行——但其 slab/巨页钩子仍在生效,形成不一致状态,这很可能就是崩溃的土壤。


6. 根因分析

已确证:

  1. 崩溃是内核 panic(double fault),非用户态、非 GPU。
  2. 崩溃调用栈完整,根节点在 IEE 的 iee_set_token_page_valid / do_split_huge_pmd。
  3. 触发者是 fork/clone(dup_task_struct 走 slab 分配),由 dpkg 的大规模进程创建放大。
  4. 崩溃路径与 IEE 的 IEE_OP_SPLIT_HUGE_PMD(巨页分裂)强相关。

推断(根因假设):

  • IEE 在 IEE SI 被禁用(SMEP 不可用 / 探测异常)的状态下,仍执行令牌页校验与巨页分裂;两者状态不一致,在 do_split_huge_pmd 内触发 WARN,随后 iee_rw_gate 门机制在异常处理中使内核栈失效(RSP=0),升级为 double fault → panic。
  • THP 默认 always 使巨页广泛存在,提供了该路径的触发条件。

佐证:

  • 新版内核 6.6.0.ok25.0 的 IEE 符号集合与 ok24 完全一致(44 项),两版 vmlinuz 体积仅差 252 字节 → 新版未修复该 IEE 逻辑,升级内核不能解决。

7. 关于"运行 22 小时"的更正

日志显示 383s 进入 s2idle 休眠、76486s 才唤醒,约 21 小时为休眠,唤醒后仅约 86 分钟即崩溃。崩溃与"长时间运行导致的老化/过热"无必然关系,而是休眠唤醒后的 slab/fork 负载触发了 IEE 缺陷。


8. 影响面

  • 任意触发 slab 分配 + 巨页分裂的负载(尤其大量进程创建,如 dpkg、编译、容器 churn)都可能触发。
  • 系统会无预警 panic 重启,可能丢失未保存数据;冷复位事件还会清空 ramoops 现场,增加排查难度。
  • 崩溃后 EFI/FAT 分区出现"未正常卸载"告警,长期可能累积损坏。
  • 属于可用性问题(DoS),且在 SMEP 关闭状态下运行存在安全隐患。

9. 建议

9.1 用户侧缓解(立即可用)

  1. 禁用透明巨页(THP):内核参数 transparent_hugepage=never,并在 /etc/grub.d 持久化、update-grub。目的:使巨页不产生,从根源绕开 IEE_OP_SPLIT_HUGE_PMD 路径。(详见本机 死机调查.md §11)
  2. 保留 ramoops/kdump 取证通道,改后持续观察是否仍崩溃。
  3. 持续观察 NVMe PCIe AER 可纠正错误;择机对 EFI/FAT 分区 fsck。

9.2 厂商侧修复建议(麒麟/openKylin)

  1. 修复 IEE 在 IEE SI disabled(SMEP 不可用)状态下仍执行 token page 校验/巨页分裂的逻辑不一致问题。
  2. 审查 iee-func.c:77 处 WARN 之后 iee_rw_gate 导致内核栈损坏(RSP=0)的异常处理路径。
  3. 提供运行时/启动参数关闭 IEE 的开关(当前 CONFIG_IEE=y 且无任何开关,用户无法规避)。
  4. 核查为何内核在 CPU 支持 SMEP 的情况下以 SMEP 关闭运行,及 IEE SI disabled 的判定是否与被自身关闭 SMEP 互相矛盾。
  5. 评估 6.6.0.ok25.0:目前已确认其 IEE 代码与 ok24 无差异,未包含本问题修复。

10. 附录

10.1 关键日志原文(崩溃段)

<4>[81653.756177] ------------[ cut here ]------------
<4>[81653.756180] WARNING: CPU: 1 PID: 42357 at arch/x86/kernel/iee/iee-func.c:77 do_split_huge_pmd+0x21d/0x2d0
<4>[81653.756280] CPU: 1 PID: 42357 Comm: dpkg Tainted: G     U  W   6.6.0-24-generic #0ok1-KYLINOS
<4>[81653.756284] RIP: 0010:do_split_huge_pmd+0x21d/0x2d0
<4>[81653.756288] RAX: 80000000000001e1 RBX: ffff88847f8e3060 RCX: 0000000141800000
<4>[81653.756289] RDX: 0000000000000040 RSI: ffff88821ef81000 RDI: ffffea0005060000
<4>[81653.756295] CR2: 000000001e7a2418 CR3: 00000002cdbb4003 CR4: 0000000000672ee0
<4>[81653.756302]  iee_set_token_page_valid+0x30d/0x370
<4>[81653.756306]  allocate_slab+0x41e/0x5d0
<4>[81653.756312]  ___slab_alloc+0x603/0xb00
<4>[81653.756323]  kmem_cache_alloc_node_noprof+0x2dd/0x3a0
<4>[81653.756326]  dup_task_struct+0x48/0x1d0
<4>[81653.756329]  copy_process+0x1e4/0x1680
<4>[81653.756332]  kernel_clone+0xc3/0x460
<4>[81653.756336]  __do_sys_clone+0x66/0x90
<0>[81653.756786] traps: PANIC: double fault, error_code: 0x0
<4>[81653.756788] double fault: 0000 [#1] PREEMPT SMP NOPTI
<4>[81653.756790] CPU: 7 PID: 42385 Comm: dpkg Tainted: G     U  W
<4>[81653.756792] RIP: 0010:iee_rw_gate+0x37/0x70
<4>[81653.756795] RSP: 0018:0000000000000000 EFLAGS: 00010082
<4>[81653.756800] CR2: fffffffffffffff8 CR3: 000000025fa50001 CR4: 0000000000672ee0
<0>[81653.759105] Kernel panic - not syncing: Fatal exception in interrupt
<0>[81653.759125] Kernel Offset: disabled

10.2 IEE 初始化日志

<3>[0.067519] IBT selftest: Failed!
<3>[0.068486] IEE SI disabled because SMAP or SMEP is not available
<3>[0.068486] IEE: testing iee_exec_entry si_test...
<3>[0.068486] IEE: testing iee_exec_entry si_test...

10.3 IEE 符号表(节选,/boot/System.map-6.6.0-24-generic)

ffffffff8103ef50 T init_iee_offset
ffffffff81099370 T iee_rw_gate
ffffffff810993f0 T iee_read_token_stack
ffffffff81099450 T iee_read_tmp_page
ffffffff810994b0 T iee_read_freeptr
ffffffff81099510 T iee_rwx_gate_inner
ffffffff810995b0 T iee_rwx_gate
ffffffff810998d0 T set_iee_page
ffffffff81099a90 T unset_iee_page
ffffffff81099c00 T iee_set_logical_mem_ro
ffffffff81099d70 T set_iee_page_valid
ffffffff81099d90 T set_iee_page_invalid
ffffffff81099db0 T iee_set_token_page_valid          ← 崩溃调用链
ffffffff8109a130 T iee_set_token_page_invalid
ffffffff8109a4e0 T set_iee_stack_page
ffffffff8109a500 T unset_iee_stack_page
ffffffff8109a520 T get_iee_stack
ffffffff8109a5c0 T free_iee_stack
ffffffff8109a610 T iee_free_task_struct_slab
ffffffff8109a740 T iee_free_slab
ffffffff8109f270 T kernel_physical_mapping_init_for_iee
ffffffff8140a4e0 T iee_get_oo_objects
ffffffff81ff9590 T init_memory_mapping_for_iee

10.4 相关配置文件

  • /etc/default/grub 第 11 行(当前内核命令行)
  • /etc/modules-load.d/ramoops.conf(加载 ramoops)
  • 取证存档:/var/lib/systemd/pstore/dmesg-ramoops-{0,1}

10.5 术语

  • IEE:麒麟定制内核子系统(arch/x86/kernel/iee/),本报告分析对象;内部缩写含义以厂商定义为准。
  • THP:Transparent Huge Pages,透明巨页。
  • PMD:Page Middle Directory,页中间目录(巨页分裂的对象)。
  • ramoops/pstore:将内核日志直写保留内存、跨重启留存的取证机制。
  • SMEP/SMAP:Supervisor Mode Execution/Access Prevention,内核执行/访问用户页的硬件保护。

11. 补充说明

11.1 可复现性与影响范围(是否单机问题)

  • 不是单机硬件问题。 崩溃代码 arch/x86/kernel/iee/ 编译进内核(CONFIG_IEE=y),与硬件无关;任何安装同一麒麟内核(6.6.0-24-generic #0ok1-KYLINOS)的设备运行的都是同一份有缺陷代码。

  • 触发路径通用:fork/clone → slab 分配 → IEE 令牌页校验 → 巨页分裂(IEE_OP_SPLIT_HUGE_PMD)。任何 Linux 都在做 fork/slab,因此同类内核设备普遍存在隐患。

  • 是否实际崩溃取决于以下条件(概率性):

    条件 本机情况
    内核含 IEE 是(CONFIG_IEE=y)
    THP 开启 是(TRANSPARENT_HUGEPAGE_ALWAYS=y,内核默认)
    IEE 处于半残但生效状态 是(IEE SI disabled 但仍运行 slab/巨页钩子)
    负载/时序命中 dpkg 装包时命中(休眠唤醒后 ~86 分钟)
  • 因此表现为偶发死机:可能数小时或数天一次,也可能长期未碰到。

  • 待确认:内核运行于 SMEP 关闭状态(见 §5.4)是"该内核普遍如此"还是"本机型/固件特有"。若普遍,则风险面更广;建议在其它同版本设备上对比(命令见 §11.5)。

  • 建议在报 bug 时明确声明:位于内核 IEE 代码、理论影响所有同版本内核设备、非单机硬件问题、且 ok25 未修复。

11.2 禁用 THP 的影响与权衡

缓解手段 transparent_hugepage=never 的副作用(功能/数据安全无影响,完全可逆):

方面 影响
内存密集负载性能 可能略降(数据库/VM/大型程序,几个百分点~约 10%);日常桌面/浏览器/办公基本无感
内存占用 可能更省(THP 按 2MB 粒度、易内部碎片)
延迟/抖动 通常更好(去掉 khugepaged 合并与 defrag 造成的停顿)
HugeTLB 不受影响(另一套机制;本机 HugePages_Total=0)
可逆性 完全可逆(改回 always/madvise 或删除参数)
  • 多数发行版默认 madvise,本内核编译为 always;改为 never 是更保守的一步。
  • 折中方案 madvise:保留按需巨页,但不一定足以规避本崩溃(只要有程序申请巨页,IEE_OP_SPLIT_HUGE_PMD 仍可能触发),故取证阶段建议先用 never。

11.3 排查中已确认/排除的因素

因素 结论 依据
i915 / GPU / 显存 已排除(前期方向走偏) 崩溃栈与 GPU 无关;kern.log 无 GPU HANG/rcs0 reset
硬件内存 未证实有问题 崩溃为软件缺陷;本机无 ECC,但仍未见内存错误证据
IEE 可否运行时关闭 否 CONFIG_IEE=y、无启动参数、无 sysfs/proc 开关
升级 ok25 内核 不能解决 IEE 符号集合与 ok24 完全相同(44 项)、vmlinuz 仅差 252 字节
efi_pstore 变砖风险 无 内置且 pstore_disable=Y,backend=ramoops,efivarfs 无 dmesg-efi-*
kdump/crashkernel 已暂停,ramoops 为主取证通道 见 死机调查.md §9.6
显卡相关内核参数(i915.enable_*) 保留未动(一次只改一个变量) GPU 假设虽已推翻,但暂不改动

11.4 复现与验证建议

给用户(复现验证):

  1. 重启后确认 THP 已关闭:cat /sys/kernel/mm/transparent_hugepage/enabled → [never]。
  2. 制造 fork/slab 压力(如 apt 安装/升级一批包,或重复运行大栈复现程序),观察是否仍崩。
  3. 若再崩,检查 /var/lib/systemd/pstore/,确认是否仍落在 iee_set_token_page_valid/do_split_huge_pmd。

给厂商(定位):

  1. 审阅 arch/x86/kernel/iee/iee-func.c:77 处 WARN 及其后 iee_rw_gate 的异常处理。
  2. 审阅 iee_set_token_page_valid 在 IEE SI disabled 状态下为何仍执行 IEE_OP_SPLIT_HUGE_PMD。
  3. 核查内核为何在 CPU 支持 SMEP 时以 SMEP 关闭运行,及其与 IEE SI disabled 的因果关系。
  4. 在带 CONFIG_IEE=y 的内核上以 THP 开启 + 高 fork 压力复现。

11.5 相关命令速查

# 环境核对
uname -r
zcat /proc/config.gz 2>/dev/null | grep -E 'CONFIG_IEE|TRANSPARENT_HUGEPAGE'
dmesg | grep -iE 'IEE SI disabled|si_test|IBT selftest'

# 当前 THP 状态
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag

# 取证
ls -la /var/lib/systemd/pstore/
sudo sha256sum /var/lib/systemd/pstore/dmesg-ramoops-*
grep -nE 'WARNING|do_split_huge_pmd|iee_|panic|double fault' /var/lib/systemd/pstore/dmesg-ramoops-0

# 其它设备对比(判断是否共性)
#   看 IEE 与 THP 是否与本机一致

11.6 排查时间线纪要

  • 早期:误判为 Intel i915 “GPU hang → hard lockup”,围绕 i915 加参数(i915.enable_psr/dc/guc)。
  • 2026-09-23:建立 ramoops 取证;efi_pstore 实测不可用并禁用;kdump 尝试后回退。
  • 2026-09-24:捕获真实 panic 现场 → 定位 IEE;核对配置与符号,确认 ok25 未修复;确认 SMEP 关闭与 IEE SI disabled;实施 transparent_hugepage=never;产出本报告。

*报告完。证据文件哈希见 §4.1,原始日志见 §10,补充说明见 §11。

以下为AI的补充报告:

[源码仓库]
linux: openKylin linux内核项目维护工作已经迁移至 AtomGit平台,PR请提交到:https://gitcode.com/openkylin/linux (维护已迁移至 AtomGit:linux:基于 Linux 技术的内核项目 - AtomGit )
分支:linux-6.6-next(= devel/6.6.0-23.0ok2,iee-func.c blob sha ca4652b14b499d3f1ee9664236a944f89d2ce9a3)

[1] mm/slub.c:2657-2664(allocate_slab 内,每次 task_struct slab 分配都触发 IEE):
if (s == task_struct_cachep) {
void *token_addr = (void *)__phys_to_iee(page_to_phys(…));
void *alloc_token = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
iee_set_token_page_valid(token_addr, alloc_token, order); // ← line 2664
}

[2] arch/x86/kernel/iee/iee-func.c:179-190(iee_set_token_page_valid,双分裂无锁无二次校验):
if (pmd_leaf(*token_pmdp) && order < 9) {
do_split_huge_pmd(token_pmdp);
do_split_huge_pmd(token_page_pmdp); // ← line 186
}

[3] arch/x86/kernel/iee/iee-func.c:62-96(do_split_huge_pmd,起始无锁保护):
pte_t *pgtable = pte_alloc_one_kernel(&init_mm);
…
for (i = 0; i < PMD_SIZE / PAGE_SIZE; i++, ptep++) {
entry = mk_pte(page + i, pmd_pgprot(*pmdp));
WRITE_ONCE(*ptep, entry);
}
spinlock_t *ptl = pmd_lock(&init_mm, pmdp);
if (pmd_leaf(READ_ONCE(*pmdp))) { smp_wmb(); pmd_populate_kernel(…); pgtable = NULL; }
spin_unlock(ptl);

[说明]

  1. 现场崩溃发生在 do_split_huge_pmd+0x21d 的 BUG 指令(ud2),触发条件为“pmd 为大页(PSE)且 RW 位已被清除(只读/sensitive)”;
    与本机二进制一致。双 CPU 并发 fork(PID 42357 / 42385)同时分裂同一 2MB 大页→第二次到达时已是敏感只读大页→BUG→#UD 期间 double fault。
  2. 注意:装机版(6.6.0-24.0ok1)二进制中的 WARN/ud2 守卫及 IEE 包装在以上公开源码分支中均不存在——
    即“发布的二进制内核”与“公开源码分支 linux-6.6-next / linux-6.6-stable / openkylin/nile / devel/6.6.0-23.0ok2”不一致(二进制较源码多出未公开的守卫代码)。
  3. 请核对生产树(6.6.0-24.0ok1 的构建分支/补丁)是否在 iee-func.c 加入了该守卫,并修复 iee_set_token_page_valid 的双分裂竞态。
  4. 引用源码为 GPL-2.0,摘录自 openKylin 公开仓库。
1 个赞