1 .. SPDX-License-Identifier: GPL-2.0 2 .. include:: ../disclaimer-zh_CN.rst 3 4 :Original: Documentation/mm/vmalloced-kernel-s 5 6 :翻译: 7 8 司延腾 Yanteng Si <siyanteng@loongson.cn> 9 10 :校译: 11 12 ==================== 13 支持虚拟映射的内核栈 14 ==================== 15 16 :作者: Shuah Khan <skhan@linuxfoundation.org> 17 18 .. contents:: :local: 19 20 概览 21 ---- 22 23 这是介绍 `虚拟映射内核栈功能 <htt 24 和原始补丁系列的信息汇总。 25 26 简介 27 ---- 28 29 内核堆栈溢出通常难以调试,并使 30 隔离和究其根本原因。 31 32 带有保护页的虚拟映射内核堆栈如 33 坏。 34 35 HAVE_ARCH_VMAP_STACK和VMAP_STACK配置选项 36 当堆栈溢出时,这个特性会引发可 37 响应取决于架构。 38 39 .. note:: 40 截至本文撰写时, arm64, powerp 41 42 HAVE_ARCH_VMAP_STACK 43 -------------------- 44 45 能够支持虚拟映射内核栈的架构应 46 47 - vmalloc空间必须大到足以容纳许多 48 - vmalloc空间的堆栈需要可靠地工作 49 具有未填充页表的虚拟地址时, 50 switch_mm(),很可能)需要确保堆栈 51 充。 52 - 如果堆栈溢出到一个保护页,就 53 在没有记录任何东西的情况下立 54 55 VMAP_STACK 56 ---------- 57 58 VMAP_STACK bool配置选项在启用时分配 59 HAVE_ARCH_VMAP_STACK。 60 61 - 如果你想使用带有保护页的虚拟 62 被立即捕获,而不是难以诊断的 63 64 .. note:: 65 66 使用KASAN的这个功能需要架构 67 必须启用KASAN_VMALLOC。 68 69 .. note:: 70 71 启用VMAP_STACK时,无法在堆栈 72 73 内核配置选项和依赖性不断变化。 74 75 `Kconfig <https://git.kernel.org/pub/scm/linux 76 77 分配方法 78 -------- 79 80 当一个新的内核线程被创建时,线 81 些页面被映射到有PAGE_KERNEL保护的 82 83 alloc_thread_stack_node()调用__vmalloc_node_ 84 保护的栈。 85 86 - 分配的堆栈被缓存起来,以后会 87 进行memcg核算。因此,__vmalloc_node_ 88 - vm_struct被缓存起来,以便能够找 89 可以在中断上下文中调用。 90 - 在arm64上,所有VMAP的堆栈都需要 91 工作。架构特定的vmap堆栈分配器 92 - 这并不涉及中断堆栈--参考原始补 93 94 线程栈分配是由clone()、fork()、vfork( 95 启动的。留点提示在这,以便搜索 96 97 大量的代码是在: 98 `kernel/fork.c <https://git.kernel.org/pub/scm 99 100 task_struct中的stack_vm_area指针可以跟 101 指针可以表明虚拟映射的内核堆栈 102 103 :: 104 105 struct vm_struct *stack_vm_area; 106 107 堆栈溢出处理 108 ------------ 109 110 前守护页和后守护页有助于检测堆 111 次溢出堆栈。当处理程序被调用时 112 113 在x86上,这是通过处理表明内核堆 114 115 用守护页测试VMAP分配 116 -------------------- 117 118 我们如何确保VMAP_STACK在分配时确实 119 可以帮助检测任何回归。 120 121 :: 122 123 void lkdtm_STACK_GUARD_PAGE_LEADING() 124 void lkdtm_STACK_GUARD_PAGE_TRAILING() 125 126 结论 127 ---- 128 129 - vmalloced堆栈的percpu缓存似乎比高 130 - THREAD_INFO_IN_TASK完全摆脱了arch-speci 131 thread_info(仅包含标志)和'int cpu' 132 - 一旦任务死亡,线程栈就可以被 133 可以将整个栈缓存起来,以便在
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.