英特尔的 Peter Zijlstra就提出了“呼叫深度跟踪”作为处理 Retbleed并避免间接分支限制推测 (IBRS) 使用的“性能恐怖秀”的缓解方法。今天发布的是最新版本的呼叫深度跟踪代码,性能基准测试结果看起来非常有希望减轻Retbleed CPU 缓解性能影响的痛苦。
至于 Peter 一直在用这个 Call Depth Tracking 代码做什么,他在 v2 补丁系列中解释了:
此版本与上一个版本有很大不同,因为它不再使用从模块空间分配的外部调用 thunk。相反,每个函数都对齐到 16 个字节并获得 16 个字节的(符号前)
填充。(这个填充也可以用于其他事情,比如 kCFI/FineIBT 工作。)在这些补丁之前,函数对齐基本上是不存在的,因此对于函数的第一条指令的任何指令提取都会(平均)有一半的提取窗口被之前的任何内容填充。通过将对齐提高到 16 字节,这改善了恰好具有 16 字节 i-fetch 窗口大小的芯片(英特尔)的问题,而对于具有更大 32 字节 i-fetch 窗口的芯片(AMD Zen)来说,情况不会变得更糟。事实上,它将 Zen 的最坏情况从 31 字节垃圾提高到 16 字节垃圾。
因此,该系列的前许多补丁修复了许多对齐怪癖。
第二个大区别是struct pcpu_hot的引入。因为编译器设法将两个相邻的(在代码中)DEFINE_PER_CPU() 变量放在随机缓存行中(这样做是完全免费的),per-cpu x86_call_depth 变量的引入有时会引入显着的额外缓存压力,而其他时候它会坐与 preempt_count 很好地位于同一行,根本不显示。
为了缓解这个问题;引入 struct pcpu_hot 并以编译器不会弄乱的方式收集许多热的 per-cpu 变量。
有关缓解 Retbleed 的呼叫深度跟踪的更多背景信息:
除了这些变化;深度跟踪的核心还是一样的。
– objtool 创建(函数)调用站点的列表。
– 每次通话;用记帐 thunk 覆盖目标函数的填充(如果尚未完成)并调整调用站点以定位此 thunk。
– retbleed 返回 thunk 机制用于自定义返回 thunk,其中包括返回记帐并在需要时进行 RSB 填充。
这确保了不需要新的编译器,并避免了几乎所有未受影响机器的开销。仍然可以使用 内核命令行上的
“retbleed=stuff” 来选择这个新选项。…
Return-Stack-Buffer (RSB) 是一个 16 深的堆栈,每次调用都会填充。在返回路径上,推测将“弹出”一个条目并将其作为返回目标。一旦 RSB 为空,CPU 就会退回到其他预测器,例如分支历史缓冲区,它可能会被用户空间误导并误导(返回)推测路径到您选择的披露小工具 – 如 rebleed 论文中所述.
调用深度跟踪旨在通过在 RSB 运行低时将推测陷阱调用填充到 RSB 来打破这种推测路径。这样,投机就停止了,永远不会回到其他预测指标。
假设是第 12 次回报的填充足以在它遇到下溢和回退到其他预测变量之前打破投机。测试证实它有效。Johannes 是 rebleed 的研究人员之一,他试图攻击这种方法,并证实它可以将信噪比降低到水晶球水平。
基准测试结果看起来非常有希望:
原创文章,作者:校长,如若转载,请注明出处:https://www.yundongfang.com/Yun186480.html