# KVM内存管理

书接上回,看过了Qemu中的内存模型，这下该来看看KVM中的工作了。

## 从Qemu获得的信息

上文中我们停在了Qemu和KVM之间的握手上，那我们就先来看看这次交流之后KVM那头发生了什么。

说简单也简单，那就是把Qemu传递过来的信息记录了起来，保存在了一个叫kvm\_memory\_slot的结构体中。

```
struct kvm_memory_slot {
	gfn_t base_gfn;
	unsigned long npages;
	unsigned long *dirty_bitmap;
	struct kvm_arch_memory_slot arch;
	unsigned long userspace_addr;
	u32 flags;
	short id;
};
```

起始也就是记录下来了虚拟机中对应GPA的HVA。那记录下来是要干啥呢？

对了，构造EPT表。

## 逆向盗梦空间

先来看一张图

![ept](https://1838005143-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fq1T0mmRojL1RaCyUY15S%2Fuploads%2Fgit-blob-5a9b99dfa7193003c117a821677382f4d626d80e%2Fept.png?alt=media)

这张图描述了EPT的作用，**GPA->HPA的转换**。

当虚拟机中的系统访问虚拟机内的物理地址GPA时，系统就可以通过EPT找到真实的内存地址HPA。

是不是有点像盗梦空间中从梦中回到现实的感觉？

## EPT树

刚才看了EPT的原理图，接着我们看看在代码中是如何表示的。

在代码中，用kvm\_mmu\_page结构体来表示EPT结构中的一个节点。如果大家有过页表的概念，那么可以 将EPT想象为一个树形结构，而其中的每个节点就是用kvm\_mmu\_page结构来描述。

截取这棵树上的一个分叉，就像下图一样。

```
                                                          kvm_mmu_page     <---------+
                                                          +--------------------------|---+
                                              +-----------|parent_ptes               |   |
                                              |           |                          |   |
                                              |           |                          |   |
                                              |           |spt--+   one page         |   |
                                              v           |     |   page->private ---+   |
                                              +-----------|-->  +-->+--------------------+
                                              |           |         |                    |
                                              |           |         |                    |
                                              |           |         |                    |
    kvm_mmu_page     <---------+              |           |   512   |                    |
    +--------------------------|---+          |           | entries |                    |
    |                          |   |          |           |         |                    |
    |                          |   |          |           |         |                    |
    |                          |   |          |           |         |                    |
    |spt--+   one page         |   |          |           +---------+--------------------+
    |     |   page->private ---+   |          |
    |     +-->+--------------------+          |
    |         |                    |          |
    |         |                 ---|----------+
    |         |                    |
    |   512   |                    |
    | entries |                    |
    |         |                    |
    |         |                    |
    |         |                 ---|----------+
    +---------+--------------------+          |
                                              |
                                              |
                                              |
                                              |           kvm_mmu_page     <---------+
                                              |           +--------------------------|---+
                                              |<----------|parent_ptes               |   |
                                              |           |                          |   |
                                              |           |                          |   |
                                              |           |spt--+   one page         |   |
                                              |           |     |   page->private ---+   |
                                              +-----------|-->  +-->+--------------------+
                                                          |         |                    |
                                                          |         |                    |
                                                          |         |                    |
                                                          |   512   |                    |
                                                          | entries |                    |
                                                          |         |                    |
                                                          |         |                    |
                                                          |         |                    |
                                                          +---------+--------------------+
```

好了，简单的看内存虚拟化在KVM中就是这样的。

而真正复杂的内容隐藏于细节之中，待我悟到之后再来详述。
