# 22.3 Speculative execution(2)

![](/files/-MYZrO2juNK0QIr_cO4h)

如果r0中的内存地址是无效的，且在Page Table中完全没有映射关系，那么我也不知道会发生什么。如果r0中的内存地址在Page Table中存在映射关系，只是现在权限不够，比如说pte\_u标志位为0，那么Intel的CPU会加载内存地址对应的数据，并存储在r2寄存器的临时版本中。之后r2寄存器的临时版本可以被代码第5行使用。所以尽管r0中的内存地址是我们没有权限的内存，比如说一个内核地址，它的数据还是会被加载到r2，之后再加1并存储在r3中。之后，当代码第4行Retired时，CPU会发现这是一个无效的读内存地址行为，因为PTE不允许读取这个内存地址。这时CPU会产生Page Fault取消执行后续指令，并回撤对于r2和r3寄存器的修改。

所以，在这里的例子中，CPU进行了两个推测：一个是CPU推测了if分支的走向，并选择了一个分支提前执行；除此之外，CPU推测了代码第4行能够成功完成。对于load指令，如果数据在CPU缓存中且相应的PTE存在于Page Table，不论当前代码是否有权限，Intel CPU总是能将数据取出。如果没有权限，只有在代码第4行Retired的时候，才会生成Page Fault，并导致预测执行被取消。

> 学生提问：我对CPU的第二个预测，也就是从r0中保存的内存地址加载数据有一些困惑，这是不是意味着r0对应的数据先被加载到了r2，然后再检查PTE的标志位？
>
> Robert教授：完全正确。在预测的阶段，不论r0指向了什么地址，只要它指向了任何东西，内存中的数据会被加载到r2中。之后，当load指令Retired时才会检查权限。如果我们并没有权限做操作，所有的后续指令的效果会被取消，也就是对于寄存器的所有修改会回滚。同时，Page Fault会被触发，同时寄存器的状态就像是预测执行的指令没有执行过一样。
>
> 学生提问：难道不能限制CPU在Speculative execution的时候，先检查权限，再执行load指令吗？看起来我们现在的问题就是我们在不知道权限的情况下读取了内存，如果我们能先知道权限，那么Speculative execution能不能提前取消？
>
> Robert教授：这里有两个回答。首先，Intel芯片并不是这样工作的。其次，是的，我相信对于Intel来说如果先做权限检查会更简单，这样的话，在上面的例子中，r2寄存器就不会被修改。
>
> 你们或许注意到论文中提到，尽管AMD CPU的手册与Intel的一样，它们有相同的指令集，Meltdown Attack并不会在AMD CPU上生效。普遍接受的观点是，AMD CPU在Speculative execution时，如果没有权限读取内存地址，是不会将内存地址中的数据读出。这就是为什么Meltdown Attack在AMD CPU上不生效的原因。最近的Intel CPU明显也采用了这种方法，如果程序没有权限，在Speculative execution的时候也不会加载内存数据。
>
> 这里使用哪种方式对于性能来说没有明显区别，或许在指令Retired的时候再检查权限能省一些CPU的晶体管吧。这里我要提醒一下，这里有很多内容都是猜的，不过我认为我说的都是对的。Intel和AMD并没有太披露具体的细节。

这里有一些重要的术语。你可以从CPU手册中读到的，比如说一个add指令接收两个寄存器作为参数，并将结果存放在第三个寄存器，这一类设计被称为CPU的Architectural，或者通告的行为。如果你读取一个你没有权限的内存地址，你会得到一个Page Fault，你不允许读取这个内存地址，这就是一种通告的行为。CPU的实际行为被称作Micro-Architectural，CPU的通告行为与实际行为是模糊不清的。比如说CPU会悄悄的有Speculative execution。

![](/files/-MYbZDXyL8yYuviU1NcT)

CPU设计者在设计Micro-Architectural时的初衷是为了让它是透明的。的确有很多行为都发生在CPU内部，但是结果看起来就像是CPU完全按照手册在运行。举个例子，在上面代码的第4行，或许Intel的CPU在读取内存时没有检查权限，但是如果权限有问题的话，在指令Retired的时候，所有的效果都会回滚，你永远也看不到你不该看到的内存内容。所以看起来就跟CPU的手册一样，你不允许读取你没有权限的内存地址。这里Architectural和Micro-Architectural的区别是Meltdown Attack的主要攻击点。这里的攻击知道CPU内部是如何工作的。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mit-public-courses-cn-translatio.gitbook.io/mit6-s081/lec22-meltdown-robert/22.3-speculative-execution-2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
