Skip to content

Commit 236bb10

Browse files
lifeixlijinxia
authored andcommitted
hv: mmu: refine delete page table mapping
Merge mmu_modify with mmu_del to mmu_modify_or_del(..., type). While type is MR_MODIFY, the actual action is doing mmu_modify; while type is MR_DEL, the actual action is doing mmu_del. Signed-off-by: Li, Fei1 <fei1.li@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent 34c6862 commit 236bb10

File tree

6 files changed

+77
-50
lines changed

6 files changed

+77
-50
lines changed

hypervisor/arch/x86/ept.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,9 @@ int register_mmio_emulation_handler(struct vm *vm,
250250
* need to unmap it.
251251
*/
252252
if (is_vm0(vm)) {
253-
ept_mr_del(vm, start, start, end - start);
253+
ept_mr_del(vm,
254+
(uint64_t *)vm->arch_vm.nworld_eptp,
255+
start, end - start);
254256
}
255257

256258
/* Return success */
@@ -529,8 +531,8 @@ int ept_mr_modify(struct vm *vm, uint64_t *pml4_page,
529531
uint16_t i;
530532
int ret;
531533

532-
ret = mmu_modify(pml4_page, gpa, size,
533-
prot_set, prot_clr, PTT_EPT);
534+
ret = mmu_modify_or_del(pml4_page, gpa, size,
535+
prot_set, prot_clr, PTT_EPT, MR_MODIFY);
534536

535537
foreach_vcpu(i, vm, vcpu) {
536538
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
@@ -539,28 +541,31 @@ int ept_mr_modify(struct vm *vm, uint64_t *pml4_page,
539541
return ret;
540542
}
541543

542-
int ept_mr_del(struct vm *vm, uint64_t hpa_arg,
543-
uint64_t gpa_arg, uint64_t size)
544+
int ept_mr_del(struct vm *vm, uint64_t *pml4_page,
545+
uint64_t gpa, uint64_t size)
544546
{
545-
struct map_params map_params;
546-
uint16_t i;
547547
struct vcpu *vcpu;
548-
uint64_t hpa = hpa_arg;
549-
uint64_t gpa = gpa_arg;
548+
uint16_t i;
549+
int ret;
550+
uint64_t hpa = gpa2hpa(vm, gpa);
550551

551-
/* Setup memory map parameters */
552-
map_params.page_table_type = PTT_EPT;
553-
map_params.pml4_base = vm->arch_vm.nworld_eptp;
554-
map_params.pml4_inverted = vm->arch_vm.m2p;
552+
ret = mmu_modify_or_del(pml4_page, gpa, size,
553+
0UL, 0UL, PTT_EPT, MR_DEL);
554+
if (ret < 0) {
555+
return ret;
556+
}
555557

556-
unmap_mem(&map_params, (void *)hpa, (void *)gpa, size, 0U);
558+
if (hpa != 0UL) {
559+
ret = mmu_modify_or_del((uint64_t *)vm->arch_vm.m2p,
560+
hpa, size, 0UL, 0UL, PTT_EPT, MR_DEL);
561+
}
557562

558563
foreach_vcpu(i, vm, vcpu) {
559564
vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH);
560565
}
561566

562-
dev_dbg(ACRN_DBG_EPT, "%s, hpa 0x%llx gpa 0x%llx size 0x%llx\n",
563-
__func__, hpa, gpa, size);
567+
dev_dbg(ACRN_DBG_EPT, "%s, gpa 0x%llx size 0x%llx\n",
568+
__func__, gpa, size);
564569

565570
return 0;
566571
}

hypervisor/arch/x86/guest/guest.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,8 @@ int prepare_vm0_memmap_and_e820(struct vm *vm)
639639
* will cause EPT violation if sos accesses hv memory
640640
*/
641641
hv_hpa = get_hv_image_base();
642-
ept_mr_del(vm, hv_hpa, hv_hpa, CONFIG_RAM_SIZE);
642+
ept_mr_del(vm, (uint64_t *)vm->arch_vm.nworld_eptp,
643+
hv_hpa, CONFIG_RAM_SIZE);
643644
return 0;
644645
}
645646

hypervisor/arch/x86/mmu.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -593,19 +593,20 @@ void init_paging(void)
593593
for (i = 0U; i < e820_entries; i++) {
594594
entry = &e820[i];
595595
if (entry->type == E820_TYPE_RAM) {
596-
mmu_modify((uint64_t *)mmu_pml4_addr,
596+
mmu_modify_or_del((uint64_t *)mmu_pml4_addr,
597597
entry->baseaddr, entry->length,
598598
PAGE_CACHE_WB, PAGE_CACHE_MASK,
599-
PTT_HOST);
599+
PTT_HOST, MR_MODIFY);
600600
}
601601
}
602602

603603
/* set the paging-structure entries' U/S flag
604604
* to supervisor-mode for hypervisor owned memroy.
605605
*/
606606
hv_hpa = get_hv_image_base();
607-
mmu_modify((uint64_t *)mmu_pml4_addr, hv_hpa, CONFIG_RAM_SIZE,
608-
PAGE_CACHE_WB, PAGE_CACHE_MASK | PAGE_USER, PTT_HOST);
607+
mmu_modify_or_del((uint64_t *)mmu_pml4_addr, hv_hpa, CONFIG_RAM_SIZE,
608+
PAGE_CACHE_WB, PAGE_CACHE_MASK | PAGE_USER,
609+
PTT_HOST, MR_MODIFY);
609610

610611
/* Enable paging */
611612
enable_paging(HVA2HPA(mmu_pml4_addr));

hypervisor/arch/x86/pagetable.c

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,30 @@ static int split_large_page(uint64_t *pte,
5656
return 0;
5757
}
5858

59-
static inline void __modify_pte(uint64_t *pte,
60-
uint64_t prot_set, uint64_t prot_clr)
59+
static inline void __modify_or_del_pte(uint64_t *pte,
60+
uint64_t prot_set, uint64_t prot_clr, uint32_t type)
6161
{
62-
uint64_t new_pte = *pte;
63-
new_pte &= ~prot_clr;
64-
new_pte |= prot_set;
65-
set_pte(pte, new_pte);
62+
if (type == MR_MODIFY) {
63+
uint64_t new_pte = *pte;
64+
new_pte &= ~prot_clr;
65+
new_pte |= prot_set;
66+
set_pte(pte, new_pte);
67+
} else {
68+
set_pte(pte, 0);
69+
}
6670
}
6771

6872
/*
6973
* In PT level,
74+
* type: MR_MODIFY
7075
* modify [vaddr_start, vaddr_end) memory type or page access right.
76+
* type: MR_DEL
77+
* delete [vaddr_start, vaddr_end) MT PT mapping
7178
*/
72-
static int modify_pte(uint64_t *pde,
79+
static int modify_or_del_pte(uint64_t *pde,
7380
uint64_t vaddr_start, uint64_t vaddr_end,
7481
uint64_t prot_set, uint64_t prot_clr,
75-
enum _page_table_type ptt)
82+
enum _page_table_type ptt, uint32_t type)
7683
{
7784
uint64_t *pt_page = pde_page_vaddr(*pde);
7885
uint64_t vaddr = vaddr_start;
@@ -88,7 +95,7 @@ static int modify_pte(uint64_t *pde,
8895
return -EFAULT;
8996
}
9097

91-
__modify_pte(pte, prot_set, prot_clr);
98+
__modify_or_del_pte(pte, prot_set, prot_clr, type);
9299
vaddr += PTE_SIZE;
93100
if (vaddr >= vaddr_end) {
94101
break;
@@ -100,12 +107,15 @@ static int modify_pte(uint64_t *pde,
100107

101108
/*
102109
* In PD level,
110+
* type: MR_MODIFY
103111
* modify [vaddr_start, vaddr_end) memory type or page access right.
112+
* type: MR_DEL
113+
* delete [vaddr_start, vaddr_end) MT PT mapping
104114
*/
105-
static int modify_pde(uint64_t *pdpte,
115+
static int modify_or_del_pde(uint64_t *pdpte,
106116
uint64_t vaddr_start, uint64_t vaddr_end,
107117
uint64_t prot_set, uint64_t prot_clr,
108-
enum _page_table_type ptt)
118+
enum _page_table_type ptt, uint32_t type)
109119
{
110120
int ret = 0;
111121
uint64_t *pd_page = pdpte_page_vaddr(*pdpte);
@@ -130,16 +140,17 @@ static int modify_pde(uint64_t *pdpte,
130140
return ret;
131141
}
132142
} else {
133-
__modify_pte(pde, prot_set, prot_clr);
143+
__modify_or_del_pte(pde,
144+
prot_set, prot_clr, type);
134145
if (vaddr_next < vaddr_end) {
135146
vaddr = vaddr_next;
136147
continue;
137148
}
138149
return 0;
139150
}
140151
}
141-
ret = modify_pte(pde, vaddr, vaddr_end,
142-
prot_set, prot_clr, ptt);
152+
ret = modify_or_del_pte(pde, vaddr, vaddr_end,
153+
prot_set, prot_clr, ptt, type);
143154
if (ret != 0 || (vaddr_next >= vaddr_end)) {
144155
return ret;
145156
}
@@ -151,12 +162,15 @@ static int modify_pde(uint64_t *pdpte,
151162

152163
/*
153164
* In PDPT level,
165+
* type: MR_MODIFY
154166
* modify [vaddr_start, vaddr_end) memory type or page access right.
167+
* type: MR_DEL
168+
* delete [vaddr_start, vaddr_end) MT PT mapping
155169
*/
156-
static int modify_pdpte(uint64_t *pml4e,
170+
static int modify_or_del_pdpte(uint64_t *pml4e,
157171
uint64_t vaddr_start, uint64_t vaddr_end,
158172
uint64_t prot_set, uint64_t prot_clr,
159-
enum _page_table_type ptt)
173+
enum _page_table_type ptt, uint32_t type)
160174
{
161175
int ret = 0;
162176
uint64_t *pdpt_page = pml4e_page_vaddr(*pml4e);
@@ -181,16 +195,17 @@ static int modify_pdpte(uint64_t *pml4e,
181195
return ret;
182196
}
183197
} else {
184-
__modify_pte(pdpte, prot_set, prot_clr);
198+
__modify_or_del_pte(pdpte,
199+
prot_set, prot_clr, type);
185200
if (vaddr_next < vaddr_end) {
186201
vaddr = vaddr_next;
187202
continue;
188203
}
189204
return 0;
190205
}
191206
}
192-
ret = modify_pde(pdpte, vaddr, vaddr_end,
193-
prot_set, prot_clr, ptt);
207+
ret = modify_or_del_pde(pdpte, vaddr, vaddr_end,
208+
prot_set, prot_clr, ptt, type);
194209
if (ret != 0 || (vaddr_next >= vaddr_end)) {
195210
return ret;
196211
}
@@ -201,6 +216,7 @@ static int modify_pdpte(uint64_t *pml4e,
201216
}
202217

203218
/*
219+
* type: MR_MODIFY
204220
* modify [vaddr, vaddr + size ) memory type or page access right.
205221
* prot_clr - memory type or page access right want to be clear
206222
* prot_set - memory type or page access right want to be set
@@ -209,19 +225,22 @@ static int modify_pdpte(uint64_t *pml4e,
209225
* to what you want to set, prot_clr to what you want to clear. But if you
210226
* want to modify the MT, you should set the prot_set to what MT you want
211227
* to set, prot_clr to the MT mask.
228+
* type: MR_DEL
229+
* delete [vaddr_base, vaddr_base + size ) memory region page table mapping.
212230
*/
213-
int mmu_modify(uint64_t *pml4_page,
231+
int mmu_modify_or_del(uint64_t *pml4_page,
214232
uint64_t vaddr_base, uint64_t size,
215233
uint64_t prot_set, uint64_t prot_clr,
216-
enum _page_table_type ptt)
234+
enum _page_table_type ptt, uint32_t type)
217235
{
218236
uint64_t vaddr = vaddr_base;
219237
uint64_t vaddr_next, vaddr_end;
220238
uint64_t *pml4e;
221239
int ret;
222240

223241
if (!MEM_ALIGNED_CHECK(vaddr, PAGE_SIZE_4K) ||
224-
!MEM_ALIGNED_CHECK(size, PAGE_SIZE_4K)) {
242+
!MEM_ALIGNED_CHECK(size, PAGE_SIZE_4K) ||
243+
(type != MR_MODIFY && type != MR_DEL)) {
225244
pr_err("%s, invalid parameters!\n", __func__);
226245
return -EINVAL;
227246
}
@@ -236,8 +255,8 @@ int mmu_modify(uint64_t *pml4_page,
236255
pr_err("%s, invalid op, pml4e not present\n", __func__);
237256
return -EFAULT;
238257
}
239-
ret = modify_pdpte(pml4e, vaddr, vaddr_end,
240-
prot_set, prot_clr, ptt);
258+
ret = modify_or_del_pdpte(pml4e, vaddr, vaddr_end,
259+
prot_set, prot_clr, ptt, type);
241260
if (ret != 0) {
242261
return ret;
243262
}

hypervisor/common/hypercall.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,8 @@ static int32_t _set_vm_memory_region(struct vm *vm,
482482
return ept_mr_add(target_vm, hpa,
483483
region->gpa, region->size, prot);
484484
} else {
485-
return ept_mr_del(target_vm, hpa,
485+
return ept_mr_del(target_vm,
486+
(uint64_t *)target_vm->arch_vm.nworld_eptp,
486487
region->gpa, region->size);
487488
}
488489

hypervisor/include/arch/x86/mmu.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,10 @@ int map_mem(struct map_params *map_params, void *paddr, void *vaddr,
326326
uint64_t size, uint32_t flags);
327327
int unmap_mem(struct map_params *map_params, void *paddr, void *vaddr,
328328
uint64_t size, uint32_t flags);
329-
int mmu_modify(uint64_t *pml4_page,
329+
int mmu_modify_or_del(uint64_t *pml4_page,
330330
uint64_t vaddr_base, uint64_t size,
331331
uint64_t prot_set, uint64_t prot_clr,
332-
enum _page_table_type ptt);
332+
enum _page_table_type ptt, uint32_t type);
333333
int check_vmx_mmu_cap(void);
334334
uint16_t allocate_vpid(void);
335335
void flush_vpid_single(uint16_t vpid);
@@ -403,8 +403,8 @@ int ept_mr_add(struct vm *vm, uint64_t hpa_arg,
403403
int ept_mr_modify(struct vm *vm, uint64_t *pml4_page,
404404
uint64_t gpa, uint64_t size,
405405
uint64_t prot_set, uint64_t prot_clr);
406-
int ept_mr_del(struct vm *vm, uint64_t hpa_arg,
407-
uint64_t gpa_arg, uint64_t size);
406+
int ept_mr_del(struct vm *vm, uint64_t *pml4_page,
407+
uint64_t gpa, uint64_t size);
408408

409409
int ept_violation_vmexit_handler(struct vcpu *vcpu);
410410
int ept_misconfig_vmexit_handler(struct vcpu *vcpu);

0 commit comments

Comments
 (0)