【问题标题】:What does it mean to "train" a branch predictor?“训练”分支预测器是什么意思?
【发布时间】:2019-01-15 17:23:11
【问题描述】:

我正在阅读 this article 关于类似于 Spectre 的理论上的 CPU 漏洞,它指出:

"攻击者需要训练分支预测器,使其 可靠地错误预测了分支。”

我大致了解什么是分支预测以及它是如何工作的,但是“训练”一个分支预测器意味着什么?这是否意味着偏向一个分支,使其在计算上比另一个更昂贵,还是意味着(在一个循环中)不断地让 CPU 在继续下一个预测错误的分支之前正确预测一个特定的分支?

例如,

// Train branch predictor
for (int i = 0; i < 512; i++)
{
    if (true){
        // Do some instructions
    } else {
        // Do some other instruction
    }
}

// The branch predictor is now "trained"/biased to predict the first branch?

// Proceed to attack

分支预测器是使用权重来偏置预测还是基于先前的预测/错误预测的一种或另一种方式?

【问题讨论】:

    标签: security cpu cpu-architecture cpu-cache branch-prediction


    【解决方案1】:

    这意味着创建一个分支,为您正在攻击的分支提供别名(通过将其放在特定地址,可能与另一个进程中的虚拟地址相同,或者 4k 或其他 2 的幂偏移可能有效),并多次运行它以使预测器产生偏差。

    这样当你用 Spectre 攻击的分支实际运行时,它就会按照你想要的方式进行预测。 (或者对于间接分支,会跳转到你想要的虚拟地址)。


    现代 TAGE 分支预测器索引基于分支历史(导致该分支的动态指令流中的其他分支),因此正确的训练可能很复杂......

    但在最简单的层面上,是的,具有超过 1 位状态的分支预测器记住的不仅仅是最后一个分支方向。 Wikipedia has a big article 关于分支预测的许多不同实现,从简单的 2 级饱和计数器开始。

    训练他们需要让你控制的分支重复以同样的方式运行。


    具体来说,您可以将这样的 asm 放在一个循环中(在一个已知地址),然后重复运行它。

    xor   eax,eax    ; eax=0 and thus set ZF
    jnz   .target    ; always not-taken
    

    然后目标分支将通过并运行您想要的 Spectre“小工具”,即使它通常已被占用。

    【讨论】:

      【解决方案2】:

      分支预测器通过记住最近的分支目标来工作。最简单的预测形式只是记住最后一次命中哪个分支;存在更复杂的预测变量并且很常见。

      “训练”只是填充记忆。对于简单的(1 值)预测器,这意味着采用您想要支持的分支一次。对于复杂的预测器,这将意味着多次执行偏好分支,直到处理器可靠地预测出所需的结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-29
        • 2020-01-03
        • 1970-01-01
        • 1970-01-01
        • 2017-10-22
        • 2019-04-02
        • 2018-09-21
        • 2016-04-06
        相关资源
        最近更新 更多