Skip to content

Commit 127c73c

Browse files
lifeixacrnsi
authored andcommitted
hv: mmu: add strict check for adding page table mapping
The current implement only do "only add a page table mapping for a region when it's not mapped" check when this page table entry is a PTE entry. However, it need to do this check for PDPTE entry and PDE entry too. Tracked-On: #3475 Signed-off-by: Li, Fei1 <fei1.li@intel.com>
1 parent c691c5b commit 127c73c

File tree

1 file changed

+37
-29
lines changed

1 file changed

+37
-29
lines changed

hypervisor/arch/x86/pagetable.c

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ static void add_pte(const uint64_t *pde, uint64_t paddr_start, uint64_t vaddr_st
249249
uint64_t *pte = pt_page + index;
250250

251251
if (mem_ops->pgentry_present(*pte) != 0UL) {
252-
ASSERT(false, "invalid op, pte present");
252+
pr_fatal("%s, pte 0x%llx is already present!\n", __func__, vaddr);
253253
} else {
254254
set_pgentry(pte, paddr | prot, mem_ops);
255255
paddr += PTE_SIZE;
@@ -280,23 +280,27 @@ static void add_pde(const uint64_t *pdpte, uint64_t paddr_start, uint64_t vaddr_
280280
uint64_t *pde = pd_page + index;
281281
uint64_t vaddr_next = (vaddr & PDE_MASK) + PDE_SIZE;
282282

283-
if (mem_ops->pgentry_present(*pde) == 0UL) {
284-
if (mem_aligned_check(paddr, PDE_SIZE) &&
285-
mem_aligned_check(vaddr, PDE_SIZE) &&
286-
(vaddr_next <= vaddr_end)) {
287-
set_pgentry(pde, paddr | (prot | PAGE_PSE), mem_ops);
288-
if (vaddr_next < vaddr_end) {
289-
paddr += (vaddr_next - vaddr);
290-
vaddr = vaddr_next;
291-
continue;
283+
if (pde_large(*pde) != 0UL) {
284+
pr_fatal("%s, pde 0x%llx is already present!\n", __func__, vaddr);
285+
} else {
286+
if (mem_ops->pgentry_present(*pde) == 0UL) {
287+
if (mem_aligned_check(paddr, PDE_SIZE) &&
288+
mem_aligned_check(vaddr, PDE_SIZE) &&
289+
(vaddr_next <= vaddr_end)) {
290+
set_pgentry(pde, paddr | (prot | PAGE_PSE), mem_ops);
291+
if (vaddr_next < vaddr_end) {
292+
paddr += (vaddr_next - vaddr);
293+
vaddr = vaddr_next;
294+
continue;
295+
}
296+
break; /* done */
297+
} else {
298+
void *pt_page = mem_ops->get_pt_page(mem_ops->info, vaddr);
299+
construct_pgentry(pde, pt_page, mem_ops->get_default_access_right(), mem_ops);
292300
}
293-
break; /* done */
294-
} else {
295-
void *pt_page = mem_ops->get_pt_page(mem_ops->info, vaddr);
296-
construct_pgentry(pde, pt_page, mem_ops->get_default_access_right(), mem_ops);
297301
}
302+
add_pte(pde, paddr, vaddr, vaddr_end, prot, mem_ops);
298303
}
299-
add_pte(pde, paddr, vaddr, vaddr_end, prot, mem_ops);
300304
if (vaddr_next >= vaddr_end) {
301305
break; /* done */
302306
}
@@ -322,23 +326,27 @@ static void add_pdpte(const uint64_t *pml4e, uint64_t paddr_start, uint64_t vadd
322326
uint64_t *pdpte = pdpt_page + index;
323327
uint64_t vaddr_next = (vaddr & PDPTE_MASK) + PDPTE_SIZE;
324328

325-
if (mem_ops->pgentry_present(*pdpte) == 0UL) {
326-
if (mem_aligned_check(paddr, PDPTE_SIZE) &&
327-
mem_aligned_check(vaddr, PDPTE_SIZE) &&
328-
(vaddr_next <= vaddr_end)) {
329-
set_pgentry(pdpte, paddr | (prot | PAGE_PSE), mem_ops);
330-
if (vaddr_next < vaddr_end) {
331-
paddr += (vaddr_next - vaddr);
332-
vaddr = vaddr_next;
333-
continue;
329+
if (pdpte_large(*pdpte) != 0UL) {
330+
pr_fatal("%s, pdpte 0x%llx is already present!\n", __func__, vaddr);
331+
} else {
332+
if (mem_ops->pgentry_present(*pdpte) == 0UL) {
333+
if (mem_aligned_check(paddr, PDPTE_SIZE) &&
334+
mem_aligned_check(vaddr, PDPTE_SIZE) &&
335+
(vaddr_next <= vaddr_end)) {
336+
set_pgentry(pdpte, paddr | (prot | PAGE_PSE), mem_ops);
337+
if (vaddr_next < vaddr_end) {
338+
paddr += (vaddr_next - vaddr);
339+
vaddr = vaddr_next;
340+
continue;
341+
}
342+
break; /* done */
343+
} else {
344+
void *pd_page = mem_ops->get_pd_page(mem_ops->info, vaddr);
345+
construct_pgentry(pdpte, pd_page, mem_ops->get_default_access_right(), mem_ops);
334346
}
335-
break; /* done */
336-
} else {
337-
void *pd_page = mem_ops->get_pd_page(mem_ops->info, vaddr);
338-
construct_pgentry(pdpte, pd_page, mem_ops->get_default_access_right(), mem_ops);
339347
}
348+
add_pde(pdpte, paddr, vaddr, vaddr_end, prot, mem_ops);
340349
}
341-
add_pde(pdpte, paddr, vaddr, vaddr_end, prot, mem_ops);
342350
if (vaddr_next >= vaddr_end) {
343351
break; /* done */
344352
}

0 commit comments

Comments
 (0)