# 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](/files/-LcGhg8piniwnDNHkHY_)

这张图描述了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中就是这样的。

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


---

# 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://richardweiyang-2.gitbook.io/kernel-exploring/00-kvm/01-memory_virtualization/01_2-kvm_memory_manage.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.
