Hypervisor(五):Cache 类型与管理

😄

1 Cache

1.0 处理器缓存结构

Intel 64 and IA-32 架构支持 Cache、TLBs、Store buffer(临时存储指令和数据)。

65.png

66.png

1.1 Cache 类型

处理器允许将系统内存的任何区域缓存在 L1、L2 和 L3 缓存中。 在系统内存的单个页面或一片区域中,它允许指定缓存类型(也称为内存类型)。 目前为Intel 64和IA-32架构定义的内存类型有(见表11-2):

62.png

缓存(Cache)类型:

内存类型 简写 解释
Strong Uncacheable,不缓存系统内存 UC 内存读写都不缓存到 Cache 中。
Uncacheable UC- 特性与 UC 相似,不同的是,这种类型的 Memory,可以通过修改 MTRR 来把它改变成 WC。
Write Combining,写组合 WC 特性与UC 相似,不同的是,写入可能会延迟数据会写入组合缓冲区(write combining buffer, WC buffer)中以减少内存访问。
写入组合缓冲区(Write Combining Buffer,WC buffer):该缓冲区与内部 L1、L2 和 L3 缓存以及存储缓冲区(Store buffer)区别开(不同)。写入数据时,虽然数据不会缓存到高速缓存上,但是数据会被写入到 WC buffer,等 WC buffer 写满之后才会将 WC buffer 的数据写入到内存中。
Write-through ,直写 WT 对系统内存的写入和读取都会被缓存。如数据写入到内存时,必须同步缓存至 Cache。它强制处理器中的缓存和系统内存之间的一致性。
Write-back,回写 WB 对系统内存的写入和读取都被缓存。只是数据写入时会先写到高速缓存,并不会修改内存。等 Cache 写满后,才会将 Cache 的内容写入到内存中,然后新的内容写入到 Cache 中。
Write protected,写保护 WP 读的时候,数据会被缓存。写的时候,数据不会被缓存。

其他概念:

专业术语 解释
cache line fill(缓存行填充) 当处理器识别出从内存读取的操作数是可缓存的时,处理器会将整个缓存行读入相应的缓存(L1、L2、L3 或全部)。 This operation is called a cache line fill.
cache hit(缓存命中) 如果下次处理器尝试访问上述的操作数时,包含该操作数的内存位置已经被缓存,则处理器可以从缓存中读取该操作数,而不是从内存读取。 This operation is called a cache hit.
write hit(写入命中) 当处理器尝试将操作数写入可缓存的内存时,它首先检查缓存中是否存在该内存位置的缓存行。 如果确实存在有效的缓存行,则处理器(取决于当前有效的写入策略)可以将操作数写入缓存,而不是将其写出到系统内存。 This operation is called a write hit.

1.2 缓存控制

内存的缓存由以下两方面控制:

  1. 控制寄存器和分页条目中的位。
  2. 一些控制指令预取、数据写入时缓存的指令

第一方面,控制寄存器和分页条目中的位。

63.png

第二方面,控制缓存的指令。

指令 权限级别 解释
INVD 特权指令 使 L1、L2 和 L3 缓存的内容失效。应谨慎使用 INVD 指令,如果内存类型为 WB,则使用该指令后高速缓存中的数据不会再写入到内存中,会造成数据丢失造成错误。
WBINVD 特权指令 WBINVD 指令首先写回所有内部缓存中任何修改的行(写到内存),然后使 L1、L2 和 L3 缓存的内容失效。它确保无论有效的写入策略(即直写或回写)如何,都能保持与主内存的缓存一致性。
prefetch 非特权指令 允许处理器将内存中的指令预取到高速缓存中。
CLFLUSH、CLFLUSHOPT 非特权指令 根据内存刷新其对应的高速缓存,使缓存失效。
非临时移动指令(MOVNTI、MOVNTQ、MOVNTDQ、MOVNTPS 和 MOVNTPD) 非特权指令 允许将数据从处理器的寄存器直接移动到系统内存中,而无需同时写入 L1、L2 和/或 L3 缓存。

1.3 缓存类型优先级

  1. 当 page-level(页面级) 和 MTRR 对应的缓存控制不一致时,则有“阻止”功能的缓存控制优先。如 page-level 控制是 Uncacheable,MTRR 对应区域控制是 Cacheable,最终该区域内存类型为 Uncacheable。
  2. 当某个内存区域和页面缓存类型冲突时,有优先级:WC > WT > WBUncacheable > Cacheable(最小缓存权限原则)。

page-level 页面级的缓存,指的是分页条目上的缓存控制位(PAT、PCD、PWT)。

64.png

阻止内存缓存:

如果要将所有内存类型设置为 Uncacheable,仅通过设置 CR0.CD = 1 是不够的,因为不同的处理器对物理内存的缓存控制策略不同。若要在所有物理内存上强制使用 UC 内存类型和严格内存排序,只需将所有物理内存的 MTRR 编程为 UC 内存类型或禁用所有 MTRR 即可。

参考内容:

  • Chapter 11 Memory Cache Control

1.4 使 TLB 失效

以下操作会使所有 TLB 条目失效,无论 G 标志的设置如何(此外,大多数细节可参考 4.10.4 “Invalidation of TLBs and Paging-Structure Caches.”):

  1. 激活或取消激活 FLUSH# pin 引脚。
  2. 写入 MTRR(使用 WRMSR 指令)(仅限 Pentium 4 Intel Xeon 和更高版本的处理器)。
  3. 写入控制寄存器 CR0 以修改 PG 或 PE 标志。
  4. 写入控制寄存器 CR4 以修改 PSE、PGE 或 PAE 标志(仅限 Pentium 4 Intel Xeon 和更高版本的处理器)。
  5. 写入控制寄存器 CR4 以将 PCIE 标志从 1 更改为 0。

刷新某内存所在页面的 TLB 指令:INVLPG

1.5 Store Buffer

处理器会将每一次写入到内存的数据临时缓存至 Store buffer。存储缓冲区通过允许处理器继续执行指令而不必等到对存储器和/或高速缓存的写入完成来提高处理器性能。 它还允许延迟写入以更有效地使用内存访问总线周期。

处理器确保写入操作始终按顺序执行。 它还确保在以下情况下始终将存储缓冲区的内容写到内存中:

  1. 当产生异常或中断时。
  2. 执行序列化指令时(仅限 P6 和更新的处理器系列)。
  3. 执行 I/O 指令时。
  4. 执行 LOCK 操作时。
  5. 执行 BINIT 操作时(仅限 P6 和更新的处理器系列)。
  6. 当使用 SFENCE 指令对存储进行排序时(仅限 Pentium Ⅲ 和更新的处理器系列)。
  7. 使用 MFENCE 指令对存储进行排序时(仅限 Pentium 4 和更新的处理器系列)。

The discussion of write ordering in Section 9.2, “Memory Ordering,” gives a detailed description of the operation of the store buffer.

2 MTRR

2.1 MTRR 介绍

内存类型范围寄存器 (Memory Type Range Registers, MTRRs) :它可以将物理内存不同区域指定为不同的缓存类型。MTRR 设置内存的范围类型

MTRR 是在系统初始化时,在 BIOS 中初始化的。

MTRR 将内存缓存类型进行编号,如表12-8 。

67.png

MTRR 将物理内存划分为 3 种区域:Fixed(固定的)、Variable(可变的)、Default(默认的)。如图 12-4。3 种区域内存由 the fixed-range MTRRsthe variable range MTRRsIA32_MTRR_DEF_TYPE MSR 寄存器控制。

Fixed、Variable 区域之外的内存就是 Default 区域内存。

68.png

MTTR 支持和开启控制

MTRR 的支持是特定于处理器型号的,可以通过 CPUID.01:EDX[12]= 1 来获得处理器是否支持 MTRR 功能。如果支持 MTRR 功能,则可以通过只读的 IA32_MTRRCAP MSR 获取关于 MTRR 的相关信息(如图12-5)。

  • IA32_MTRRCAP(0xFE) MSR 寄存器控制有几个可变范围内存、是否支持 Fixed MTRR、是否支持 WC 类型、是否支持 SMRR(SMM 模式下使用)。
  • IA32_MTRR_DEF_TYPE(0x2FF) MSR 寄存器控制 Default 区域的内存类型、是否启用 Fixed MTRR、是否启用 MTRRs 寄存器。

69.png

70.png

WC 内存类型是通过 MTRR 寄存器指定的,所以是否支持该内存类型也将从 IA32_MTRRCAP MSR 获取。

1
2
3
4
kd> rdmsr 0xFE
msr[fe] = 00000000`00000508
kd> rdmsr 0x2FF
msr[2ff] = 00000000`00000c06

2.2 Fixed Range MTRRs

Fixed-区域只能定义在物理内存的最低 1M 空间(从 00000HFFFFFH)里,由 11 个 IA32_MTRR_FIXmK_xxxx 的 MTRR 来映射(每个 64 bits),每个 Fixed MTTR 以 8 bits 为单位得到 8 个子区域,如下表所示。

71.png

每个寄存器固定映射 8个区城,那么共有 88 个 Fixed-range 可以映射,如下图。

72.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
kd> !mtrr
MTRR: Var 8, Fixed-support enabled, USWC-supported, Default: WB
WB:00000-0ffff WB:10000-1ffff WB:20000-2ffff WB:30000-3ffff
WB:40000-4ffff WB:50000-5ffff WB:60000-6ffff WB:70000-7ffff
WB:80000-83fff WB:84000-87fff WB:88000-8bfff WB:8c000-8ffff
WB:90000-93fff WB:94000-97fff WB:98000-9bfff WB:9c000-9ffff
UC:a0000-a3fff UC:a4000-a7fff UC:a8000-abfff UC:ac000-affff
UC:b0000-b3fff UC:b4000-b7fff UC:b8000-bbfff UC:bc000-bffff
WP:c0000-c0fff WP:c1000-c1fff WP:c2000-c2fff WP:c3000-c3fff
WP:c4000-c4fff WP:c5000-c5fff WP:c6000-c6fff WP:c7000-c7fff
UC:c8000-c8fff UC:c9000-c9fff UC:ca000-cafff UC:cb000-cbfff
UC:cc000-ccfff UC:cd000-cdfff UC:ce000-cefff UC:cf000-cffff
UC:d0000-d0fff UC:d1000-d1fff UC:d2000-d2fff UC:d3000-d3fff
UC:d4000-d4fff UC:d5000-d5fff UC:d6000-d6fff UC:d7000-d7fff
UC:d8000-d8fff UC:d9000-d9fff UC:da000-dafff UC:db000-dbfff
UC:dc000-dcfff UC:dd000-ddfff UC:de000-defff UC:df000-dffff
UC:e0000-e0fff UC:e1000-e1fff UC:e2000-e2fff UC:e3000-e3fff
UC:e4000-e4fff UC:e5000-e5fff UC:e6000-e6fff UC:e7000-e7fff
UC:e8000-e8fff UC:e9000-e9fff UC:ea000-eafff UC:eb000-ebfff
UC:ec000-ecfff UC:ed000-edfff UC:ee000-eefff UC:ef000-effff
WP:f0000-f0fff WP:f1000-f1fff WP:f2000-f2fff WP:f3000-f3fff
WP:f4000-f4fff WP:f5000-f5fff WP:f6000-f6fff WP:f7000-f7fff
WP:f8000-f8fff WP:f9000-f9fff WP:fa000-fafff WP:fb000-fbfff
WP:fc000-fcfff WP:fd000-fdfff WP:fe000-fefff WP:ff000-fffff
Variable: Base Mask Length
0. WB: 00000000:00000000 0000000f:80000000 00000000:80000000
1.
2.
3.
4.
5.
6.
7.

如下单个输出看一下,以 8 bits 为单位来显示该 MSR 对应的固定内存区域的内存类型。

1
2
3
4
5
6
7
8
msr[250] = 06060606`06060606	// WB, IA32_MTRR_FIX64K_0000
kd> rdmsr 0x258
msr[258] = 06060606`06060606 // WB, IA32_MTRR_FIX16K_8000
kd> rdmsr 0x259
msr[259] = 00000000`00000000 // UC, IA32_MTRR_FIX16K_A000
kd> rdmsr 0x268
msr[268] = 05050505`05050505 // WP, IA32_MTRR_FIX4K_C000
...

2.3 Variable Range MTRRs

目前 Intel 只实现了 10 个内存大小可变的区域,每个区域使用一对 PHYSBASE/PHYSMASK MSR 寄存器来描述。Variable Range 区域的个数由 IA32_MTRRCAP[7:0](0xFE) 决定,有多少个可变范围的区域,就有几对 PHYSBASE/PHYSMASK 寄存器。

这 10 对 PHYSBASE/PHYSMASK 寄存器是:IA32_MTRR_PHYSBASEnIA32_MTRR_PHYSMASKnnIA32_MTRRCAP[7:0] 决定,n 取值为 0 → (vcnt - 1)

73.png

每一对 PHYSBASE/PHYSMASK 寄存器格式如下:

74.png

  • Type[7:0]:指定该可变范围内存的类型(0/1/4/5/6)。
  • PhysBase[MAXPHYADDR:12]:指定这个可变范围的物理基址,低 12 位清 0 以使得内存在 4-KByte 边界上对齐。
  • PhysMask[MAXPHYADDR:12]:是一个掩码 mask,该值用来确定可变区域的范围。实际上就是用这一对 MSR 寄存器来计算出他们所表示的物理内存的起始、终止地址
    • 有这样的关系:Address_Within_Range AND PhysMask = PhysBase AND PhysMask
    • 使用 mask 值时,低 12 位为 0 。
  • Valid[11]:标志着该对 MSR 寄存器是否启用。

根据一对 PHYSBASE/PHYSMASK 寄存器,计算他们所描述的内存的起始、终止地址:

1
2
3
4
5
6
7
8
9
10
11
12
13
Descriptor = &EptState->MemoryRanges[EptState->NumberOfEnabledMemoryRanges++];

// Calculate the base address in bytes
PhysicalBaseAddress = PhysBase * PAGE_SIZE;

// Calculate the total size of the range
// The lowest bit of the mask that is set to 1 specifies the size of the range
// The MaskIndex begin from 1, not 0.
// https://learn.microsoft.com/zh-cn/cpp/intrinsics/bitscanforward-bitscanforward64?view=msvc-170
_BitScanForward64(&MaskIndex, PhysMask * PAGE_SIZE); // Not include Valid

// Size of the range in bytes + Base Address
PhysicalEndAddress = PhysicalBaseAddress + ((1ULL << MaskIndex) - 1ULL);

举例如下:

1
2
3
4
5
6
7
8
9
10
kd> rdmsr 0x200
msr[200] = 00000000`00000006
kd> rdmsr 0x201
msr[201] = 0000000f`80000800

// MAXPHYADDR - PhysMask = Size_of_the_range
// PhysMask = MAXPHYADDR - Size_of_the_range
0xF`FFFFFFFF - 0xF`80000000 = 0x7FFFFFFF;
// 等价于
(1 << MaskIndex) - 1 = Size_of_the_range;

关于 Variable Range 区域 PhysBase 对齐的问题(Intel SDM 3,12.11.4 Range Size and Alignment Requirement):

  1. 可变区域最小范围是 1 个 Page(4-KByte),最小的 PhysBase 也必须在 4-KByte 边界上对齐。
  2. 如果可变区域范围大小 >= 4KByte,对齐值不能小于范围值。如某个可变区域大小为 8-KByte,则该区域的 PhysBase 必须至少在 8-KByte 边界上对齐。

2.4 IA32_MTRR_DEF_TYPE MSR

当不对内存区域进行任何的划分映射时,就是 Default 的区域,Memory type 在 IA32_MTRR_DEF_TYPE(0x2FF) MSR 寄存器里设置。

70.png

  • Type[7:0]:Default 区域的内存类型(0/1/4/5/6)。
  • FE[10]:是否启用 Fixed MTRR 寄存器,是否启用固定内存区域。
  • E[11]:是否启用 MTRR 功能。

2.5 MTRR 优先级

优先级如下:

  1. 如果 IA32_MTRR_DEF_TYPE.E = 0,则所有的内存缓存类型为 UC。
  2. 如果最低 1 MByte 内存被 fixed-range MTRR 描述了,则该区域就是固定区域(即使 Variable-range MTRR 的起始地址为 0,也是 fixed MTRR 有效)。
  3. 对于 Variable-range 区域,UC > WT >WB。
  4. 没有被 Fixed、Variable MTRR 描述的内存,就是 Default 区域。

3 PAT

页面属性表(Page Attribute Table, PAT)。内存的缓存类型由 MTRR 和页表条目的 PAT、PCD、PWT 共同来决定。MTRR 是在物理页面上进行内存类型的定义,PAT 则实是在线性地址层面对内存类型进行控制。MTRR 和 PAT 共同决定内存的类型。

The Page Attribute Table (PAT) extends the IA-32 architecture’s page-table format to allow memory types to be assigned to regions of physical memory based on linear address mappings. the MTRRs allow mapping of memory types to regions of the physical address space, where the PAT allows mapping of memory types to pages within the linear address space.

——Intel SDM 3,12.12 PAGE ATTRIBUTE TABLE (PAT).

通过 CPUID.01H:EDX[16] = 1 来检测 CPU 是否支持 PAT 功能,如果支持的话则 CPU 就自动启用 PAT 功能,没有其他控制器来控制 PAT 的启用。这时候就可以使用 IA32_PAT(0x277) MSR 来指定内存的类型。

3.1 IA32_PAT

IA32_PAT(0x277) MSR 用来指定内存的类型(该寄存器可读写),包含 PAT0~PAT7,其格式如下:

75.png

  • IA32_PAT 拆成 8 bytes。
  • 每个字节低 3 位指定内存类型,高 5 位保留为 0。

IA32_PAT 寄存器的作用:将 PATn 和表12-10 编码的内存类型对应起来(见表12-12)。

低 3 位指定的内存类型和 MTTR 指定的内存类型稍有点区别,PAT 可用的内存类型如图 12-10:

76.png

  • MTRR 可使用的内存类型为:0/1/4/5/6。
  • PAT 可使用的内存类型为:0/1/4/5/6/7

查看 IA32_PAT 如下:

1
2
3
4
5
6
7
8
9
10
11
12
kd> rdmsr 0x277
msr[277] = 00070106`00070106
kd> .formats 0x00070106`00070106
Evaluate expression:
Hex: 00070106`00070106
Decimal: 1971450118865158
Octal: 0000070020300001600406
Binary: 00000000 00000111 00000001 00000110 00000000 00000111 00000001 00000110
Chars: ........
Time: Mon Apr 2 02:30:11.886 1607 (UTC + 8:00)
Float: low 6.43216e-040 high 6.43216e-040
Double: 9.74026e-309

3.2 PAT 内存类型控制

PAT 内存类型的控制由分页结构条目中的 PAT、PCD、PWT 共同决定。PAT 标志只存在于 Page Frame 上,即指向内存页面的页表条目(1-GByte PDPTE、2-MByte PDE、4-KByte PTE)。而 PCD、PWT 存在每级分页条目上,4-KByte 大小页面有如下控制顺序:

  1. CR3 上的 PCD、PWT 控制 PLM4T 的 Cache 类型。
  2. PLM4E 上的 PCD、PWT 控制 PDPT 的 Cache 类型。
  3. PDPTE 上的 PCD、PWT 控制 PDT 的 Cache 类型。
  4. PDE 上的 PCD、PWT 控制 PTT 的 Cache 类型。
  5. PTE 的 PAT、PCD 和 PWT 标志将控制 4K page frame 的 cache 类型。
  • PCD:Page Cache Disable,标志着 Page 是否可以被 Cache。1-禁止缓存,0-可缓存(Uncacheable)。
  • PWT:Page Write Through,标志 Page 是 Write Through 还是 WriteBack 的 Cache 类型。1-WT,0-WB。

PAT、PCD、PWT 共同决定缓存类型如下:

77.png

PATn 和 PAT Encoding 内存初始的对应关系如下(在计算机上电或重启时,系统初始化过程中可能会重写 IA32_PAT MSR,所以该图的参考意义不大):

78.png

举例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
kd> !process 0 0 notepad.exe
PROCESS ffffbd8e736ec340
SessionId: 1 Cid: 1588 Peb: 6061bac000 ParentCid: 0d50
DirBase: 4acc8002 ObjectTable: ffff9706df18ed00 HandleCount: 237.
Image: notepad.exe

kd> .process ffffbd8e736ec340
Implicit process is now ffffbd8e`736ec340
WARNING: .cache forcedecodeuser is not enabled

kd> !vtop 4acc8000 23504472A70
Amd64VtoP: Virt 0000023504472a70, pagedir 000000004acc8000
Amd64VtoP: PML4E 000000004acc8020
Amd64VtoP: PDPE 0000000076aed6a0
Amd64VtoP: PDE 0000000050dee110
Amd64VtoP: PTE 0000000044552390
Amd64VtoP: Mapped phys 0000000039912a70
Virtual address 23504472a70 translates to physical address 39912a70.

kd> !du 39912a70
#39912a70 "20240205"
  1. 内存属性由 PTE 控制,PTE 0000000044552390PAT = 1, PCD = 1, PWT = 0,对应上面的 PAT6。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    kd> .formats 44552390
    Evaluate expression:
    Hex: 00000000`44552390
    Decimal: 1146430352
    Octal: 0000000000010425221620
    Binary: 00000000 00000000 00000000 00000000 01000100 01010101 00100011 10010000
    Chars: ....DU#.
    Time: Mon May 1 04:52:32 2006
    Float: low 852.556 high 0
    Double: 5.66412e-315
  2. 根据 IA32_PAT MSR 找到 PAT6 的值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    kd> rdmsr 0x277
    msr[277] = 00070106`00070106

    kd> .formats 00070106`00070106
    Evaluate expression:
    Hex: 00070106`00070106
    Decimal: 1971450118865158
    Octal: 0000070020300001600406
    Binary: 00000000 00000111 00000001 00000110 00000000 00000111 00000001 00000110
    Chars: ........
    Time: Mon Apr 2 02:30:11.886 1607 (UTC + 8:00)
    Float: low 6.43216e-040 high 6.43216e-040
    Double: 9.74026e-309

    得到 PAT6 = 111h = 7,再根据 table 12-10 ,7 对应的内存类型为 UC-

    76.png

4 EPT Cache 管理

4.1 EPT 缓存信息分类

  • 未启用 EPT:linear mapping(线性映射)。
  • 启用 EPT:guest-physical mapping(guest 物理映射)、combined mapping (合并映射)。

概念说明:

分类 说明
linear page number 如 IA-32e 模式下:
使用 4K 页面时:page number = [47:12]
使用 2M 页面时:page number = [47:21]
使用 1G 页面时:page number = [47:30]
guest-physical page number GPA 地址,在 IA-32e 模式下:
EPT 使用 4K 页面时:page number = GPA[47:12]
EPT 使用 2M 页面时:page number = GPA[47:21]
EPT 使用 1G 页面时:page number = GPA[47:30]
physical page frame 物理地址去除低 12 位属性后的其余位,如 MXAPHYADDR = 36 时,physical page frame = [36:12]
当开启 EPT 机制时,处理器不会缓存由线性映射产生的 cache 信息,而是使用 guest-physical mapping(guest 物理映射)、combined mapping (合并映射)。
映射分类 缓存信息
linear mapping(线性映射) 当 EPT 未启用,或处于 VMX-root operation 中,采用该映射。
1、TLB:缓存 linear page number 和对应的物理内存 page frame、page frame 合成后的访问权限与内存类型。
2、paging-structure cache:缓存分页目录项的内容。注意:paging-structure cache 并不缓存提供 page frame 的表项(即 4K 页面时的 PTE, 2M 与4M 页面时的 PDE 及1G 页面时的 PDPTE)。在使用 4K 页面时,paging-structure cache 缓存以下信息:
linear PMLAE number(线性地址的 bits 47:39)对应的 PML4E。
linear PDPTE number(线性地址的 bits 47:30)对应的 PDPTE。
linear PDE number (线性地址的 bits 47:21) 对应的 PDE。
guest-physical mapping(guest 物理映射) 当 EPT 启用后,将使用 guest-physical mapping、combined mapping。
1、EPT TLB:缓存 guest-physical page number 和对应物理内存的 page frame。
2、EPT paging-structure cache:缓存转换 GPA 的 EPT 分页结构(不缓存提供 page frame 的表项)。EPT 使用 4K 页面时,缓存下面的 EPT 表项信息:
PML4E number(GPA 的 bits 47:39) 对应的 PMLAE。
PDPTE number(GPA 的 bits 47:30)对应的 PDPTE。
PDE number(GPA 的 bits 47:21)对应的 PDE。
combined mapping (合并映射) 当 EPT 启用后,将使用 guest-physical mapping、combined mapping。
1、combined TLB:缓存 linear page number 和对应的物理内存 page frame、page frame 合成后的访问权限与内存类型。
2、combined paging-structure cache:缓存线性地址对应的 guest-paging structure(GPS) 分页结构条目的物理内存值。
用 4K 页面时,缓存下面的信息:
linear PMLAE number(线性地址的 bits 47:39)对应的 GPS 分页结构中 PML4E 物理内存值。
linear PDPTE number(线性地址的 bits 47:30)对应的 GPS 分页结构中 PDPTE 物理内存值。
linear PDE number (线性地址的 bits 47:21) 对应的 GPS 分页结构中 PDE 物理内存值。

combined mapping (合并映射):合并了 linear mapping 与 guest-physical mapping 这两种映射 cache 的结果。其中 combined TLB 直接缓存由 guest-linear address 到 host-physical address 的转换结果。

80.png

4.2 EPT 内存类型

VMX 架构中,可以为 VMM 和 VM 所使用的的内存指定 Cache 类型。

  • VMM:VMCS region、EPT paging structure。仅支持 UC、WB。
  • VM:每一个 guest-physical address 对应的物理页面。可支持 UC、WC、WT、WB、WP。
区域 内存类型 描述
VMM EPT paging structure CR0.CD = 0 时,EPTP[2:0] 就是 EPT paging structure 内存类型。
CR0.CD = 1 时,EPT paging structure 内存类型只能为 UC。
VM guest-physical address 由 EPT、PAT、CR0.CD 共同决定。
guest-physical address 页面内存类型:
1、CR0.CD = 1 时,guest-physical address 内存类型只能为 UC。
2、CR0.CD = 0 时,EPT paging structure 提供 page frame 基址表项的 IPAT 位决定着内存类型:
(1) IAPT = 1,忽略 PAT 内存类型,guest-physical address 内存类型 = EPT 内存类型(提供 page frame 条目 [5:3] MemoryType)。
(2) IPAT = 0,guest-physical address 内存类型 = PAT 内存类型组合 EPT 内存类型

PAT 内存类型
CR0.PG = 0 时,PAT 内存类型固定位 WB。
CR0.PG = 1 时,PAT 内存类型由分页结构页表条目的 PAT、PCD、PWT 共同决定。

备注:MTRR 不影响 EPT paging structure、guest-physical address 页面内存类型。

4.3 Cache 的所属信息

处理器在建立 cache 信息时,也必须维护 Cache 的归属信息,也就是 Cache 所属的域。另一方面,在刷新(invalidate)Cache 操作时,也需要指明刷新哪份 Cache 信息(哪个域的 Cache)。

当前处理器支持三个归属标识,分别为 PCID, VPID 及 EP4TA。

Cache 归属域 描述
PCID 进程上下文ID,是和进程 CR3 关联的,每个进程 CR3 低 12 位即为 PCID 值(12 bits)。有了 PCID 之后,不同进程切换时 TLB 无需刷新。使用 PCID 的 2 个条件如下:
只能在 IA-32e 模式下使用(IA32_EFER_LMA = 1)。
CPUID.01H:ECX[17] = 1 时,软件才可以置 CR4.PCIDE = 1,开启 PCID 功能。

注意:处理器用 PCID 来维护与线性地址转换相关的 cache 信息,即 linear mapping 及 combined mapping。
EP4TA EPT4A = EPTP[N:12],N = MAXPHYADDR。在 EPT 机制中,一个 EP4TA 值也被作为 ID 标识符,用来标识由 EPT paging structure 所映射的 guest-physical address space。

注意:处理器用 EP4TA 来维护与 guest-physical address 转换相关的 cache 信息,包括 guest-physical mapping 与 combined mapping 所产生的 cache 信息。
VPID 虚拟处理器 ID,VPID 用来为每个虚拟处理器提供一个 ID 值。每个 VMCS 拥有一个非 0 值的 VPID(16 bits)。
常用的用法:VMM.VPID = 000h、每个虚拟处理器使用的 VMCS 对应不同的非零 VPID 值。

处理器用 VPID 来维护与线性地址转换相关的 cache 信息:
(1)没有 EPT 机制时(或者在 host 里):处理器在 VPID 域中结合 PCID 为 linear mapping 建立相应的 cache 信息。
(2)启用 EPT 机制时,处理器在 VPID 与 EP4TA 联合的域中结合 PCID 为 combined mapping 建立相应的 cache 信息。

举例说明他们的层级关系:

VMM 为三个虚拟机分别设置的 VPID 值为:0001H,0002H 及 0003H,如图6-13 所示。

79.png

  • VM1(没有启用 EPT),维护由 linear mapping 产生的 cache 信息。
    • VPID 为 0001H值。
    • PCID 为 001H 与002H值。
  • VM2,维护由 guest-physical mapping 与 combined mapping 产生的 cache 信息。
  • VM3,维护由 guest-physical mapping 与 combined mapping 产生的 cache 信息。

总结如下:

  1. linear mapping 产生的 cache 具有 VPID 与 PCID 域。
  2. guest-physical mapping 产生的 cache 只有 EP4TA 域。
  3. combined mapping 产生的 cache 具有 VPID, PCID 及 EP4TA 域。

cache 域刷新:VMX 指今集里提供了两条基于 VPID 与 EP4TA 域的 cache 刷新指令。

  1. INVVPID 指令,刷新 VPID 域下与线性地址映射相关的 cache 信息。包括:
    • 由 linear mapping 产生的 cache 信息。
    • 由 combined mapping 产生的 cache 信息。
  2. INVEPT 指令,刷新 EP4TA 域下与 GPA 映射相关的 cache 信息。包括:
    • 由 guest-physical mapping 产生的 cache 信息。
    • 由 combined mapping 产生的 cache 信息。

5 Cache 刷新管理

5.1 刷新 Cache 的场景

5.2 刷新 Cache 的指令