Memory Type virtualization in VT-x
已经介绍过了native下的Memory Type,那么,虚拟化下的Memory Type又是何般境地呢?
1. History
前辈们在影子页表时代探索过Memory Type的虚拟化。可以参考Maintaining cache coherency和Disheng Su: Cache Attribute Virtualization in Xen。我也看不明白细节,但是,需要知道的是:在影子页表时代,Memory Type的虚拟化需要软件做很多事情。当来到EPT页表时代,软件需要做的事情就没有那么多了。
2. 第一性原理
在native下,EMT(Effective Memory Type)由页表的PAT与MTRR设置的物理地址区间memory type来共同决定。在虚拟化下,EMT又是怎样的呢?
- 对于PAT,可以由guest的页表来设置
- MTRR的MSR肯定是不能pass-thru给guest的
- MTRR的功能是设置物理地址区间的memory type
- native下MTRR MSR设置的是HPA的属性,一般由bios来设置
- 在虚拟化场景下,当seabios或者OVMF设置MTRR时,会操作MTRR MSR,此时会发生VM Exit
- 所以hypervisor是可以感知guest设置的GPA区间的memory type的
如何模拟guest GPA区间中设置的memory type(guest 在MTRR设置的memory type)呢?EPT页表会将GPA转化为HPA的,将guest MTRR设置的memory type,在EPT memory type设置下即可完成guest GPA区间中设置的memory type的模拟。在Non-root mode下,EMT由guest page table的PAT与EPT的memory type共同决定,此时物理MTRR完全不起作用,这样可以做到guest与host的EMT的隔离性!
经过上述分析可以知道,在虚拟化的场景下,EPT memory type承接了MTRR的工作。当guest设置MTRR的memory type时,都会发生VM Exit,此时hypervisor将GPA区间的memory type设置在EPT memory type即可!
3. EPT and Memory Typing
EPT中的Memory Type在SDM Vol3的28.3.7 EPT and Memory Typing有详细的介绍。
中文翻译转载自Intel SDM Chapter 28: VMX Support for Address Translation。
涉及EPT的Memory Type有两个,首先是walk EPT时,访问EPT各级页表项所采用的Memory Type:
- 若
CR0.CD = 0
,则采用的Memory Type由EPTP的第0-2位决定,取0表示UC,取6表示WB - 若
CR0.CD = 1
,则采用的Memory Type为UC
其次是Guest访问内存时,采用的Memory Type,它由两个因素决定:
- EPT Memory Type:即EPT中最后一级页表项的第3-5位,起相当于MTRR的作用
- 取0表示UC,取1表示WC,取4表示WT,取5表示WP,取6表示WB,这与MTRR中Type的含义相同
- 此时MTRR完全不起作用
- PAT Memory Type:
- 若
CR0.PG = 0
,则PAT Memory Type为WB - 若
CR0.PG = 1
,则PAT Memory Type为Guest页表翻译时根据MSR[IA32_PAT]
确定的PAT Memory Type
- 若
最终产生的Memory Type如下:
- 若
CR0.CD = 0
- 若末级页表项的
IPAT = 0
,则Memory Type就是将EPT Memory Type当做MTRR Memory Type和PAT Memory Type合并后的结果 - 若末级页表项的
IPAT = 1
,则Memory Type就是EPT Memory Type
- 若末级页表项的
- 若
CR0.CD = 1
,则Memory Type为UC
IPAT即Ignore PAT(末级页表项的第6位),如下图标注所示:
EPT Memory Type(MTRR Memory Type)和PAT Memory Type合并后的结果: