“训练”分支预测变量是什么意思?

时间:2018-08-08 12:28:37

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

我正在读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

分支预测器是否基于先前的预测/错误预测使用权重对预测进行偏向或偏向?

2 个答案:

答案 0 :(得分:4)

这意味着创建一个分支来别名您要攻击的分支(通过将其置于特定地址,也许与另一个进程中的虚拟地址相同,或者使用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“小工具”。

答案 1 :(得分:1)

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

“培训”只是填充该内存。对于简单的(一值)预测变量,这意味着一次选择您希望使用的分支。对于复杂的预测器,这将意味着多次执行优先分支,直到处理器可靠地预测出所需的结果为止。