Fix index calculation for the page table pages for efirt 1:1 map.

Stop issuing pre-assigned number to enumerate all page table pages,
the assignment is incorrect.  Instead automatically calculate the next
unused index. This index in fact does not serve any purpose except to
be unique to satisfy vm_page_grab() interface, we do not look up the
page by the index later.

Reported and tested by:	emaste
Reviewed by:	andrew
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
PR:	223906
Differential revision:	https://reviews.freebsd.org/D13273
This commit is contained in:
Konstantin Belousov 2017-11-28 09:34:43 +00:00
parent 2bfca5775b
commit dde5602786
2 changed files with 16 additions and 14 deletions

View File

@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
static pml4_entry_t *efi_pml4;
static vm_object_t obj_1t1_pt;
static vm_page_t efi_pml4_page;
static vm_pindex_t efi_1t1_idx;
void
efi_destroy_1t1_map(void)
@ -85,10 +86,10 @@ efi_destroy_1t1_map(void)
}
static vm_page_t
efi_1t1_page(vm_pindex_t idx)
efi_1t1_page(void)
{
return (vm_page_grab(obj_1t1_pt, idx, VM_ALLOC_NOBUSY |
return (vm_page_grab(obj_1t1_pt, efi_1t1_idx++, VM_ALLOC_NOBUSY |
VM_ALLOC_WIRED | VM_ALLOC_ZERO));
}
@ -106,7 +107,7 @@ efi_1t1_pte(vm_offset_t va)
pml4_idx = pmap_pml4e_index(va);
pml4e = &efi_pml4[pml4_idx];
if (*pml4e == 0) {
m = efi_1t1_page(1 + pml4_idx);
m = efi_1t1_page();
mphys = VM_PAGE_TO_PHYS(m);
*pml4e = mphys | X86_PG_RW | X86_PG_V;
} else {
@ -117,7 +118,7 @@ efi_1t1_pte(vm_offset_t va)
pdp_idx = pmap_pdpe_index(va);
pdpe += pdp_idx;
if (*pdpe == 0) {
m = efi_1t1_page(1 + NPML4EPG + (pml4_idx + 1) * (pdp_idx + 1));
m = efi_1t1_page();
mphys = VM_PAGE_TO_PHYS(m);
*pdpe = mphys | X86_PG_RW | X86_PG_V;
} else {
@ -128,8 +129,7 @@ efi_1t1_pte(vm_offset_t va)
pd_idx = pmap_pde_index(va);
pde += pd_idx;
if (*pde == 0) {
m = efi_1t1_page(1 + NPML4EPG + NPML4EPG * NPDPEPG +
(pml4_idx + 1) * (pdp_idx + 1) * (pd_idx + 1));
m = efi_1t1_page();
mphys = VM_PAGE_TO_PHYS(m);
*pde = mphys | X86_PG_RW | X86_PG_V;
} else {
@ -155,8 +155,9 @@ efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz)
obj_1t1_pt = vm_pager_allocate(OBJT_PHYS, NULL, ptoa(1 +
NPML4EPG + NPML4EPG * NPDPEPG + NPML4EPG * NPDPEPG * NPDEPG),
VM_PROT_ALL, 0, NULL);
efi_1t1_idx = 0;
VM_OBJECT_WLOCK(obj_1t1_pt);
efi_pml4_page = efi_1t1_page(0);
efi_pml4_page = efi_1t1_page();
VM_OBJECT_WUNLOCK(obj_1t1_pt);
efi_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(efi_pml4_page));
pmap_pinit_pml4(efi_pml4_page);

View File

@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
static vm_object_t obj_1t1_pt;
static vm_page_t efi_l0_page;
static pd_entry_t *efi_l0;
static vm_pindex_t efi_1t1_idx;
void
efi_destroy_1t1_map(void)
@ -86,10 +87,10 @@ efi_destroy_1t1_map(void)
}
static vm_page_t
efi_1t1_page(vm_pindex_t idx)
efi_1t1_page(void)
{
return (vm_page_grab(obj_1t1_pt, idx, VM_ALLOC_NOBUSY |
return (vm_page_grab(obj_1t1_pt, efi_1t1_idx++, VM_ALLOC_NOBUSY |
VM_ALLOC_WIRED | VM_ALLOC_ZERO));
}
@ -105,7 +106,7 @@ efi_1t1_l3(vm_offset_t va)
l0_idx = pmap_l0_index(va);
l0 = &efi_l0[l0_idx];
if (*l0 == 0) {
m = efi_1t1_page(1 + l0_idx);
m = efi_1t1_page();
mphys = VM_PAGE_TO_PHYS(m);
*l0 = mphys | L0_TABLE;
} else {
@ -116,7 +117,7 @@ efi_1t1_l3(vm_offset_t va)
l1_idx = pmap_l1_index(va);
l1 += l1_idx;
if (*l1 == 0) {
m = efi_1t1_page(1 + L0_ENTRIES + (l0_idx + 1) * (l1_idx + 1));
m = efi_1t1_page();
mphys = VM_PAGE_TO_PHYS(m);
*l1 = mphys | L1_TABLE;
} else {
@ -127,8 +128,7 @@ efi_1t1_l3(vm_offset_t va)
l2_idx = pmap_l2_index(va);
l2 += l2_idx;
if (*l2 == 0) {
m = efi_1t1_page(1 + L0_ENTRIES + L0_ENTRIES * Ln_ENTRIES +
(l0_idx + 1) * (l1_idx + 1) * (l2_idx + 1));
m = efi_1t1_page();
mphys = VM_PAGE_TO_PHYS(m);
*l2 = mphys | L2_TABLE;
} else {
@ -160,7 +160,8 @@ efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz)
L0_ENTRIES * Ln_ENTRIES * Ln_ENTRIES * Ln_ENTRIES,
VM_PROT_ALL, 0, NULL);
VM_OBJECT_WLOCK(obj_1t1_pt);
efi_l0_page = efi_1t1_page(0);
efi_1t1_idx = 0;
efi_l0_page = efi_1t1_page();
VM_OBJECT_WUNLOCK(obj_1t1_pt);
efi_l0 = (pd_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(efi_l0_page));
bzero(efi_l0, L0_ENTRIES * sizeof(*efi_l0));