近段时间在Vmware中使用 VT EPT技术时
发生性能爆降甚至鼠标不能动的现象
检查 VM exit 事件,无任何问题
设置 Vmware 核心数 16 发现比 核心数 4 还卡
设置核心数 1 发现 稳定运行 无卡顿
觉得可能是 EPT 多次寻址问题
HyperPlatform 项目将在每个CPU设置不同的EPT目录
我将代码改为以下
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
EptData
*
g_EptData
=
0
;
/
/
Builds EPT, allocates pre
-
allocated entires, initializes
and
returns EptData
_Use_decl_annotations_ EptData
*
EptInitialization() {
PAGED_CODE()
if
(g_EptData !
=
0
)
/
/
增加
return
g_EptData;
/
/
增加
static const auto kEptPageWalkLevel
=
4ul
;
/
/
Allocate ept_data
const auto ept_data
=
static_cast<EptData
*
>(ExAllocatePoolWithTag(
NonPagedPool, sizeof(EptData), kHyperPlatformCommonPoolTag));
if
(!ept_data) {
return
nullptr;
}
RtlZeroMemory(ept_data, sizeof(EptData));
/
/
/
/
Allocate EptPointer
/
/
const auto ept_poiner
=
reinterpret_cast<EptPointer
*
>(ExAllocatePoolWithTag(
/
/
NonPagedPool, PAGE_SIZE, kHyperPlatformCommonPoolTag));
/
/
if
(!ept_poiner) {
/
/
ExFreePoolWithTag(ept_data, kHyperPlatformCommonPoolTag);
/
/
return
nullptr;
/
/
}
/
/
RtlZeroMemory(ept_poiner, PAGE_SIZE);
/
/
Allocate EPT_PML4
and
initialize EptPointer
const auto ept_pml4
=
static_cast<EptCommonEntry
*
>(
ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, kHyperPlatformCommonPoolTag));
if
(!ept_pml4) {
ExFreePoolWithTag(ept_data, kHyperPlatformCommonPoolTag);
return
nullptr;
}
RtlZeroMemory(ept_pml4, PAGE_SIZE);
ept_data
-
>ept_pointer.
all
=
0
;
ept_data
-
>ept_pointer.fields.memory_type
=
static_cast<ULONG64>(EptpGetMemoryType(UtilPaFromVa(ept_pml4)));
ept_data
-
>ept_pointer.fields.page_walk_length
=
kEptPageWalkLevel
-
1
;
ept_data
-
>ept_pointer.fields.pml4_address
=
UtilPfnFromPa(UtilPaFromVa(ept_pml4));
/
/
Initialize
all
EPT entries
for
all
physical memory pages
const auto pm_ranges
=
UtilGetPhysicalMemoryRanges();
for
(auto run_index
=
0ul
; run_index < pm_ranges
-
>number_of_runs;
+
+
run_index) {
const auto run
=
&pm_ranges
-
>run[run_index];
const auto base_addr
=
run
-
>base_page
*
PAGE_SIZE;
for
(auto page_index
=
0ull
; page_index < run
-
>page_count;
+
+
page_index) {
const auto indexed_addr
=
base_addr
+
page_index
*
PAGE_SIZE;
const auto ept_pt_entry
=
EptpConstructTables(ept_pml4,
4
, indexed_addr, nullptr);
if
(!ept_pt_entry) {
EptpDestructTables(ept_pml4,
4
);
ExFreePoolWithTag(ept_data, kHyperPlatformCommonPoolTag);
return
nullptr;
}
}
}
/
/
Initialize an EPT entry
for
APIC_BASE. It
is
required to allocated it now
/
/
for
some reasons,
or
else
, system hangs.
const Ia32ApicBaseMsr apic_msr
=
{ UtilReadMsr64(Msr::kIa32ApicBase) };
if
(!EptpConstructTables(ept_pml4,
4
, apic_msr.fields.apic_base
*
PAGE_SIZE,
nullptr)) {
EptpDestructTables(ept_pml4,
4
);
ExFreePoolWithTag(ept_data, kHyperPlatformCommonPoolTag);
return
nullptr;
}
/
/
Allocate preallocated_entries
const auto preallocated_entries_size
=
sizeof(EptCommonEntry
*
)
*
kEptpNumberOfPreallocatedEntries;
const auto preallocated_entries
=
static_cast<EptCommonEntry
*
*
>(
ExAllocatePoolWithTag(NonPagedPool, preallocated_entries_size,
kHyperPlatformCommonPoolTag));
if
(!preallocated_entries) {
EptpDestructTables(ept_pml4,
4
);
ExFreePoolWithTag(ept_data, kHyperPlatformCommonPoolTag);
return
nullptr;
}
RtlZeroMemory(preallocated_entries, preallocated_entries_size);
/
/
And fill preallocated_entries with newly created entries
for
(auto i
=
0ul
; i < kEptpNumberOfPreallocatedEntries;
+
+
i) {
const auto ept_entry
=
EptpAllocateEptEntry(nullptr);
if
(!ept_entry) {
EptpFreeUnusedPreAllocatedEntries(preallocated_entries,
0
);
EptpDestructTables(ept_pml4,
4
);
ExFreePoolWithTag(ept_data, kHyperPlatformCommonPoolTag);
return
nullptr;
}
preallocated_entries[i]
=
ept_entry;
}
/
/
Initialization completed
ept_data
-
>ept_pml4
=
ept_pml4;
ept_data
-
>preallocated_entries
=
preallocated_entries;
ept_data
-
>preallocated_entries_count
=
0
;
g_EptData
=
ept_data;
/
/
增加
return
ept_data;
}
测试发现性能正常 操作流畅 无卡顿 CPU占用降低
so 问题解决
原理是设置CPU核心为同一页表
Vmware 可能某种原因无法识别我们是为那个CPU设置的页表
但是他可以根据 设置的物理地址判断是否为同一个页表结构