v3 2026-10-26

修复vmap失败PTE残留 · v3

__vmap_pages_range_noflush() 失败前可能安装部分 PTE 且调用方清理责任不一致,重映射会命中残留并 BUG/WARN;统一失败回滚并清理已映射范围。

原始补丁链接

子 Patch(10)

1/10
mm/kmsan: undo the shadow mapping when the origin mapping fails
kmsan_vmap_pages_range_noflush() 在 origin 映射失败时调用 __vunmap_range_noflush() 撤销已建 shadow 映射,避免残留 PTE 使后续同范围 vmap 触发 BUG 或 -EBUSY;仅清 PTE 无需 TLB flush。
2/10
mm/kmsan: skip vunmap_range_noflush when KMSAN is disabled
kmsan_vunmap_range_noflush() 增加 kmsan_enabled 为 false 的提前返回,与 vmap 侧一致,避免 KMSAN 未启用时仍遍历 shadow/origin 页表做无意义 unmap。
3/10
mm/vmalloc: clamp an unaligned range in vunmap_pte_range()
vunmap_pte_range() 增加非页对齐范围截断:把 end 向下对齐到最后一个完整页,空范围直接跳过,避免循环无法命中 end 而越界清 PTE。
4/10
mm/vmalloc: propagate errors in vmap_pages_p*d_range()
让 vmap_pages_pmd_range()/pud_range()/p4d_range() 原样向上传递下层错误,保留 vmap_pages_pte_range() 返回的 -EINVAL、-EBUSY,而非统一改成 -ENOMEM。
5/10
mm/vmalloc: reject an unaligned range in vmap_pages_pte_range()
在 vmap_pages_pte_range() 增加 PAGE_SIZE 对齐检查并拒绝非对齐范围,防止循环越过 end 继续映射后续页表,作为下层映射路径的兜底保护。
6/10
mm/vmalloc: reject empty and unaligned ranges in __vmap_pages_range_noflush()
__vmap_pages_range_noflush() 入口校验 [addr,end) 非空且页对齐,违者返回 -EINVAL,避免空范围触发 BUG_ON、非对齐范围在 huge-page 路径从下方页边界开始映射。
7/10
mm/vmalloc: only flush the cache after the vmap succeeded
vmap_page_range() 和 __vmap_pages_range() 改为映射成功后才 flush_cache_vmap(),避免失败映射触发无谓 flush;UML 上这可防止半安装 PTE 被同步到 host 后残留。
8/10
mm/vmalloc: undo partial mappings inside the mapping functions
vmap 入口在失败时用 __vunmap_range_noflush() 回滚已安装的 PTE,并丢弃失败映射的 KMSAN 元数据,避免调用者重试同范围时遇到残留映射而 BUG/WARN。
9/10
powerpc: drop redundant unmaps of failed vmap mappings
vmap_page_range()/ioremap_page_range() 失败时已清理 PTE,删除 remap_isa_base() 和 ioremap_phb() 中多余的 vunmap_range(),避免重复 unmap。
10/10
mm/percpu: stop unmapping the CPU that failed to map
__pcpu_map_pages() 失败时已清掉自身 PTE,pcpu_map_pages() 只需回滚失败 CPU 之前已映射的 CPU,去掉对失败 CPU 的重复 unmap。