Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/pmap.c
Show First 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | |||||
#define PMAP_INLINE __attribute__((__gnu_inline__)) inline | #define PMAP_INLINE __attribute__((__gnu_inline__)) inline | ||||
#else | #else | ||||
#define PMAP_INLINE extern inline | #define PMAP_INLINE extern inline | ||||
#endif | #endif | ||||
#else | #else | ||||
#define PMAP_INLINE | #define PMAP_INLINE | ||||
#endif | #endif | ||||
/* | |||||
* These are configured by the mair_el1 register. This is set up in locore.S | |||||
*/ | |||||
#define DEVICE_MEMORY 0 | |||||
#define UNCACHED_MEMORY 1 | |||||
#define CACHED_MEMORY 2 | |||||
#ifdef PV_STATS | #ifdef PV_STATS | ||||
#define PV_STAT(x) do { x ; } while (0) | #define PV_STAT(x) do { x ; } while (0) | ||||
#else | #else | ||||
#define PV_STAT(x) do { } while (0) | #define PV_STAT(x) do { } while (0) | ||||
#endif | #endif | ||||
#define pmap_l2_pindex(v) ((v) >> L2_SHIFT) | #define pmap_l2_pindex(v) ((v) >> L2_SHIFT) | ||||
#define pa_to_pvh(pa) (&pv_table[pmap_l2_pindex(pa)]) | #define pa_to_pvh(pa) (&pv_table[pmap_l2_pindex(pa)]) | ||||
▲ Show 20 Lines • Show All 514 Lines • ▼ Show 20 Lines | if ((pa & L1_OFFSET) != 0) { | ||||
*/ | */ | ||||
if ((pa & L1_OFFSET) == 0) | if ((pa & L1_OFFSET) == 0) | ||||
break; | break; | ||||
l2_slot = pmap_l2_index(va); | l2_slot = pmap_l2_index(va); | ||||
KASSERT(l2_slot != 0, ("...")); | KASSERT(l2_slot != 0, ("...")); | ||||
pmap_store(&l2[l2_slot], | pmap_store(&l2[l2_slot], | ||||
(pa & ~L2_OFFSET) | ATTR_DEFAULT | ATTR_XN | | (pa & ~L2_OFFSET) | ATTR_DEFAULT | ATTR_XN | | ||||
ATTR_IDX(CACHED_MEMORY) | L2_BLOCK); | ATTR_IDX(VM_MEMATTR_WRITE_BACK) | L2_BLOCK); | ||||
} | } | ||||
KASSERT(va == (pa - dmap_phys_base + DMAP_MIN_ADDRESS), | KASSERT(va == (pa - dmap_phys_base + DMAP_MIN_ADDRESS), | ||||
("...")); | ("...")); | ||||
} | } | ||||
for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1] && | for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1] && | ||||
(physmap[i + 1] - pa) >= L1_SIZE; | (physmap[i + 1] - pa) >= L1_SIZE; | ||||
pa += L1_SIZE, va += L1_SIZE) { | pa += L1_SIZE, va += L1_SIZE) { | ||||
l1_slot = ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT); | l1_slot = ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT); | ||||
pmap_store(&pagetable_dmap[l1_slot], | pmap_store(&pagetable_dmap[l1_slot], | ||||
(pa & ~L1_OFFSET) | ATTR_DEFAULT | ATTR_XN | | (pa & ~L1_OFFSET) | ATTR_DEFAULT | ATTR_XN | | ||||
ATTR_IDX(CACHED_MEMORY) | L1_BLOCK); | ATTR_IDX(VM_MEMATTR_WRITE_BACK) | L1_BLOCK); | ||||
} | } | ||||
/* Create L2 mappings at the end of the region */ | /* Create L2 mappings at the end of the region */ | ||||
if (pa < physmap[i + 1]) { | if (pa < physmap[i + 1]) { | ||||
l1_slot = ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT); | l1_slot = ((va - DMAP_MIN_ADDRESS) >> L1_SHIFT); | ||||
if (l1_slot != prev_l1_slot) { | if (l1_slot != prev_l1_slot) { | ||||
prev_l1_slot = l1_slot; | prev_l1_slot = l1_slot; | ||||
l2 = (pt_entry_t *)freemempos; | l2 = (pt_entry_t *)freemempos; | ||||
l2_pa = pmap_early_vtophys(kern_l1, | l2_pa = pmap_early_vtophys(kern_l1, | ||||
(vm_offset_t)l2); | (vm_offset_t)l2); | ||||
freemempos += PAGE_SIZE; | freemempos += PAGE_SIZE; | ||||
pmap_store(&pagetable_dmap[l1_slot], | pmap_store(&pagetable_dmap[l1_slot], | ||||
(l2_pa & ~Ln_TABLE_MASK) | L1_TABLE); | (l2_pa & ~Ln_TABLE_MASK) | L1_TABLE); | ||||
memset(l2, 0, PAGE_SIZE); | memset(l2, 0, PAGE_SIZE); | ||||
} | } | ||||
KASSERT(l2 != NULL, | KASSERT(l2 != NULL, | ||||
("pmap_bootstrap_dmap: NULL l2 map")); | ("pmap_bootstrap_dmap: NULL l2 map")); | ||||
for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1]; | for (; va < DMAP_MAX_ADDRESS && pa < physmap[i + 1]; | ||||
pa += L2_SIZE, va += L2_SIZE) { | pa += L2_SIZE, va += L2_SIZE) { | ||||
l2_slot = pmap_l2_index(va); | l2_slot = pmap_l2_index(va); | ||||
pmap_store(&l2[l2_slot], | pmap_store(&l2[l2_slot], | ||||
(pa & ~L2_OFFSET) | ATTR_DEFAULT | ATTR_XN | | (pa & ~L2_OFFSET) | ATTR_DEFAULT | ATTR_XN | | ||||
ATTR_IDX(CACHED_MEMORY) | L2_BLOCK); | ATTR_IDX(VM_MEMATTR_WRITE_BACK) | L2_BLOCK); | ||||
} | } | ||||
} | } | ||||
if (pa > dmap_phys_max) { | if (pa > dmap_phys_max) { | ||||
dmap_phys_max = pa; | dmap_phys_max = pa; | ||||
dmap_max_addr = va; | dmap_max_addr = va; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 498 Lines • ▼ Show 20 Lines | pmap_kenter(vm_offset_t sva, vm_size_t size, vm_paddr_t pa, int mode) | ||||
KASSERT((pa & L3_OFFSET) == 0, | KASSERT((pa & L3_OFFSET) == 0, | ||||
("pmap_kenter: Invalid physical address")); | ("pmap_kenter: Invalid physical address")); | ||||
KASSERT((sva & L3_OFFSET) == 0, | KASSERT((sva & L3_OFFSET) == 0, | ||||
("pmap_kenter: Invalid virtual address")); | ("pmap_kenter: Invalid virtual address")); | ||||
KASSERT((size & PAGE_MASK) == 0, | KASSERT((size & PAGE_MASK) == 0, | ||||
("pmap_kenter: Mapping is not page-sized")); | ("pmap_kenter: Mapping is not page-sized")); | ||||
attr = ATTR_DEFAULT | ATTR_IDX(mode) | L3_PAGE; | attr = ATTR_DEFAULT | ATTR_IDX(mode) | L3_PAGE; | ||||
if (mode == DEVICE_MEMORY) | if (mode == VM_MEMATTR_DEVICE) | ||||
attr |= ATTR_XN; | attr |= ATTR_XN; | ||||
else | else | ||||
attr |= ATTR_UXN; | attr |= ATTR_UXN; | ||||
va = sva; | va = sva; | ||||
while (size != 0) { | while (size != 0) { | ||||
pde = pmap_pde(kernel_pmap, va, &lvl); | pde = pmap_pde(kernel_pmap, va, &lvl); | ||||
KASSERT(pde != NULL, | KASSERT(pde != NULL, | ||||
Show All 9 Lines | pmap_kenter(vm_offset_t sva, vm_size_t size, vm_paddr_t pa, int mode) | ||||
} | } | ||||
pmap_invalidate_range(kernel_pmap, sva, va); | pmap_invalidate_range(kernel_pmap, sva, va); | ||||
} | } | ||||
void | void | ||||
pmap_kenter_device(vm_offset_t sva, vm_size_t size, vm_paddr_t pa) | pmap_kenter_device(vm_offset_t sva, vm_size_t size, vm_paddr_t pa) | ||||
{ | { | ||||
pmap_kenter(sva, size, pa, DEVICE_MEMORY); | pmap_kenter(sva, size, pa, VM_MEMATTR_DEVICE); | ||||
} | } | ||||
/* | /* | ||||
* Remove a page from the kernel pagetables. | * Remove a page from the kernel pagetables. | ||||
*/ | */ | ||||
PMAP_INLINE void | PMAP_INLINE void | ||||
pmap_kremove(vm_offset_t va) | pmap_kremove(vm_offset_t va) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | for (i = 0; i < count; i++) { | ||||
KASSERT(pde != NULL, | KASSERT(pde != NULL, | ||||
("pmap_qenter: Invalid page entry, va: 0x%lx", va)); | ("pmap_qenter: Invalid page entry, va: 0x%lx", va)); | ||||
KASSERT(lvl == 2, | KASSERT(lvl == 2, | ||||
("pmap_qenter: Invalid level %d", lvl)); | ("pmap_qenter: Invalid level %d", lvl)); | ||||
m = ma[i]; | m = ma[i]; | ||||
pa = VM_PAGE_TO_PHYS(m) | ATTR_DEFAULT | ATTR_AP(ATTR_AP_RW) | | pa = VM_PAGE_TO_PHYS(m) | ATTR_DEFAULT | ATTR_AP(ATTR_AP_RW) | | ||||
ATTR_UXN | ATTR_IDX(m->md.pv_memattr) | L3_PAGE; | ATTR_UXN | ATTR_IDX(m->md.pv_memattr) | L3_PAGE; | ||||
if (m->md.pv_memattr == DEVICE_MEMORY) | if (m->md.pv_memattr == VM_MEMATTR_DEVICE) | ||||
pa |= ATTR_XN; | pa |= ATTR_XN; | ||||
pte = pmap_l2_to_l3(pde, va); | pte = pmap_l2_to_l3(pde, va); | ||||
pmap_load_store(pte, pa); | pmap_load_store(pte, pa); | ||||
va += L3_SIZE; | va += L3_SIZE; | ||||
} | } | ||||
pmap_invalidate_range(kernel_pmap, sva, va); | pmap_invalidate_range(kernel_pmap, sva, va); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,897 Lines • ▼ Show 20 Lines | pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, | ||||
va = trunc_page(va); | va = trunc_page(va); | ||||
if ((m->oflags & VPO_UNMANAGED) == 0) | if ((m->oflags & VPO_UNMANAGED) == 0) | ||||
VM_PAGE_OBJECT_BUSY_ASSERT(m); | VM_PAGE_OBJECT_BUSY_ASSERT(m); | ||||
pa = VM_PAGE_TO_PHYS(m); | pa = VM_PAGE_TO_PHYS(m); | ||||
new_l3 = (pt_entry_t)(pa | ATTR_DEFAULT | ATTR_IDX(m->md.pv_memattr) | | new_l3 = (pt_entry_t)(pa | ATTR_DEFAULT | ATTR_IDX(m->md.pv_memattr) | | ||||
L3_PAGE); | L3_PAGE); | ||||
if ((prot & VM_PROT_WRITE) == 0) | if ((prot & VM_PROT_WRITE) == 0) | ||||
new_l3 |= ATTR_AP(ATTR_AP_RO); | new_l3 |= ATTR_AP(ATTR_AP_RO); | ||||
if ((prot & VM_PROT_EXECUTE) == 0 || m->md.pv_memattr == DEVICE_MEMORY) | if ((prot & VM_PROT_EXECUTE) == 0 || | ||||
m->md.pv_memattr == VM_MEMATTR_DEVICE) | |||||
new_l3 |= ATTR_XN; | new_l3 |= ATTR_XN; | ||||
if ((flags & PMAP_ENTER_WIRED) != 0) | if ((flags & PMAP_ENTER_WIRED) != 0) | ||||
new_l3 |= ATTR_SW_WIRED; | new_l3 |= ATTR_SW_WIRED; | ||||
if (va < VM_MAXUSER_ADDRESS) | if (va < VM_MAXUSER_ADDRESS) | ||||
new_l3 |= ATTR_AP(ATTR_AP_USER) | ATTR_PXN; | new_l3 |= ATTR_AP(ATTR_AP_USER) | ATTR_PXN; | ||||
else | else | ||||
new_l3 |= ATTR_UXN; | new_l3 |= ATTR_UXN; | ||||
if (pmap != kernel_pmap) | if (pmap != kernel_pmap) | ||||
▲ Show 20 Lines • Show All 251 Lines • ▼ Show 20 Lines | pmap_enter_2mpage(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, | ||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED); | PMAP_LOCK_ASSERT(pmap, MA_OWNED); | ||||
new_l2 = (pd_entry_t)(VM_PAGE_TO_PHYS(m) | ATTR_DEFAULT | | new_l2 = (pd_entry_t)(VM_PAGE_TO_PHYS(m) | ATTR_DEFAULT | | ||||
ATTR_IDX(m->md.pv_memattr) | ATTR_AP(ATTR_AP_RO) | L2_BLOCK); | ATTR_IDX(m->md.pv_memattr) | ATTR_AP(ATTR_AP_RO) | L2_BLOCK); | ||||
if ((m->oflags & VPO_UNMANAGED) == 0) { | if ((m->oflags & VPO_UNMANAGED) == 0) { | ||||
new_l2 |= ATTR_SW_MANAGED; | new_l2 |= ATTR_SW_MANAGED; | ||||
new_l2 &= ~ATTR_AF; | new_l2 &= ~ATTR_AF; | ||||
} | } | ||||
if ((prot & VM_PROT_EXECUTE) == 0 || m->md.pv_memattr == DEVICE_MEMORY) | if ((prot & VM_PROT_EXECUTE) == 0 || | ||||
m->md.pv_memattr == VM_MEMATTR_DEVICE) | |||||
new_l2 |= ATTR_XN; | new_l2 |= ATTR_XN; | ||||
if (va < VM_MAXUSER_ADDRESS) | if (va < VM_MAXUSER_ADDRESS) | ||||
new_l2 |= ATTR_AP(ATTR_AP_USER) | ATTR_PXN; | new_l2 |= ATTR_AP(ATTR_AP_USER) | ATTR_PXN; | ||||
else | else | ||||
new_l2 |= ATTR_UXN; | new_l2 |= ATTR_UXN; | ||||
if (pmap != kernel_pmap) | if (pmap != kernel_pmap) | ||||
new_l2 |= ATTR_nG; | new_l2 |= ATTR_nG; | ||||
return (pmap_enter_l2(pmap, va, new_l2, PMAP_ENTER_NOSLEEP | | return (pmap_enter_l2(pmap, va, new_l2, PMAP_ENTER_NOSLEEP | | ||||
▲ Show 20 Lines • Show All 285 Lines • ▼ Show 20 Lines | pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, | ||||
/* | /* | ||||
* Increment counters | * Increment counters | ||||
*/ | */ | ||||
pmap_resident_count_inc(pmap, 1); | pmap_resident_count_inc(pmap, 1); | ||||
pa = VM_PAGE_TO_PHYS(m); | pa = VM_PAGE_TO_PHYS(m); | ||||
l3_val = pa | ATTR_DEFAULT | ATTR_IDX(m->md.pv_memattr) | | l3_val = pa | ATTR_DEFAULT | ATTR_IDX(m->md.pv_memattr) | | ||||
ATTR_AP(ATTR_AP_RO) | L3_PAGE; | ATTR_AP(ATTR_AP_RO) | L3_PAGE; | ||||
if ((prot & VM_PROT_EXECUTE) == 0 || m->md.pv_memattr == DEVICE_MEMORY) | if ((prot & VM_PROT_EXECUTE) == 0 || | ||||
m->md.pv_memattr == VM_MEMATTR_DEVICE) | |||||
l3_val |= ATTR_XN; | l3_val |= ATTR_XN; | ||||
if (va < VM_MAXUSER_ADDRESS) | if (va < VM_MAXUSER_ADDRESS) | ||||
l3_val |= ATTR_AP(ATTR_AP_USER) | ATTR_PXN; | l3_val |= ATTR_AP(ATTR_AP_USER) | ATTR_PXN; | ||||
else | else | ||||
l3_val |= ATTR_UXN; | l3_val |= ATTR_UXN; | ||||
if (pmap != kernel_pmap) | if (pmap != kernel_pmap) | ||||
l3_val |= ATTR_nG; | l3_val |= ATTR_nG; | ||||
▲ Show 20 Lines • Show All 1,364 Lines • ▼ Show 20 Lines | for (i = 0; i < l2_blocks; i++) { | ||||
va)); | va)); | ||||
KASSERT(lvl == 1, | KASSERT(lvl == 1, | ||||
("pmap_mapbios: Invalid level %d", lvl)); | ("pmap_mapbios: Invalid level %d", lvl)); | ||||
/* Insert L2_BLOCK */ | /* Insert L2_BLOCK */ | ||||
l2 = pmap_l1_to_l2(pde, va); | l2 = pmap_l1_to_l2(pde, va); | ||||
pmap_load_store(l2, | pmap_load_store(l2, | ||||
pa | ATTR_DEFAULT | ATTR_XN | | pa | ATTR_DEFAULT | ATTR_XN | | ||||
ATTR_IDX(CACHED_MEMORY) | L2_BLOCK); | ATTR_IDX(VM_MEMATTR_WRITE_BACK) | L2_BLOCK); | ||||
va += L2_SIZE; | va += L2_SIZE; | ||||
pa += L2_SIZE; | pa += L2_SIZE; | ||||
} | } | ||||
pmap_invalidate_all(kernel_pmap); | pmap_invalidate_all(kernel_pmap); | ||||
va = preinit_map_va + (start_idx * L2_SIZE); | va = preinit_map_va + (start_idx * L2_SIZE); | ||||
} else { | } else { | ||||
/* kva_alloc may be used to map the pages */ | /* kva_alloc may be used to map the pages */ | ||||
offset = pa & PAGE_MASK; | offset = pa & PAGE_MASK; | ||||
size = round_page(offset + size); | size = round_page(offset + size); | ||||
va = kva_alloc(size); | va = kva_alloc(size); | ||||
if (va == 0) | if (va == 0) | ||||
panic("%s: Couldn't allocate KVA", __func__); | panic("%s: Couldn't allocate KVA", __func__); | ||||
pde = pmap_pde(kernel_pmap, va, &lvl); | pde = pmap_pde(kernel_pmap, va, &lvl); | ||||
KASSERT(lvl == 2, ("pmap_mapbios: Invalid level %d", lvl)); | KASSERT(lvl == 2, ("pmap_mapbios: Invalid level %d", lvl)); | ||||
/* L3 table is linked */ | /* L3 table is linked */ | ||||
va = trunc_page(va); | va = trunc_page(va); | ||||
pa = trunc_page(pa); | pa = trunc_page(pa); | ||||
pmap_kenter(va, size, pa, CACHED_MEMORY); | pmap_kenter(va, size, pa, VM_MEMATTR_WRITE_BACK); | ||||
} | } | ||||
return ((void *)(va + offset)); | return ((void *)(va + offset)); | ||||
} | } | ||||
void | void | ||||
pmap_unmapbios(vm_offset_t va, vm_size_t size) | pmap_unmapbios(vm_offset_t va, vm_size_t size) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 169 Lines • ▼ Show 20 Lines | if ((pmap_load(pte) & ATTR_IDX_MASK) == ATTR_IDX(mode)) { | ||||
if (newpte == NULL) | if (newpte == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
pte = pmap_l2_to_l3(pte, tmpva); | pte = pmap_l2_to_l3(pte, tmpva); | ||||
case 3: | case 3: | ||||
/* Update the entry */ | /* Update the entry */ | ||||
l3 = pmap_load(pte); | l3 = pmap_load(pte); | ||||
l3 &= ~ATTR_IDX_MASK; | l3 &= ~ATTR_IDX_MASK; | ||||
l3 |= ATTR_IDX(mode); | l3 |= ATTR_IDX(mode); | ||||
if (mode == DEVICE_MEMORY) | if (mode == VM_MEMATTR_DEVICE) | ||||
l3 |= ATTR_XN; | l3 |= ATTR_XN; | ||||
pmap_update_entry(kernel_pmap, pte, l3, tmpva, | pmap_update_entry(kernel_pmap, pte, l3, tmpva, | ||||
PAGE_SIZE); | PAGE_SIZE); | ||||
/* | /* | ||||
* If moving to a non-cacheable entry flush | * If moving to a non-cacheable entry flush | ||||
* the cache. | * the cache. | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | for (i = 0; i < Ln_ENTRIES; i++) { | ||||
phys += L2_SIZE; | phys += L2_SIZE; | ||||
} | } | ||||
KASSERT(l2[0] == ((oldl1 & ~ATTR_DESCR_MASK) | L2_BLOCK), | KASSERT(l2[0] == ((oldl1 & ~ATTR_DESCR_MASK) | L2_BLOCK), | ||||
("Invalid l2 page (%lx != %lx)", l2[0], | ("Invalid l2 page (%lx != %lx)", l2[0], | ||||
(oldl1 & ~ATTR_DESCR_MASK) | L2_BLOCK)); | (oldl1 & ~ATTR_DESCR_MASK) | L2_BLOCK)); | ||||
if (tmpl1 != 0) { | if (tmpl1 != 0) { | ||||
pmap_kenter(tmpl1, PAGE_SIZE, | pmap_kenter(tmpl1, PAGE_SIZE, | ||||
DMAP_TO_PHYS((vm_offset_t)l1) & ~L3_OFFSET, CACHED_MEMORY); | DMAP_TO_PHYS((vm_offset_t)l1) & ~L3_OFFSET, | ||||
VM_MEMATTR_WRITE_BACK); | |||||
l1 = (pt_entry_t *)(tmpl1 + ((vm_offset_t)l1 & PAGE_MASK)); | l1 = (pt_entry_t *)(tmpl1 + ((vm_offset_t)l1 & PAGE_MASK)); | ||||
} | } | ||||
pmap_update_entry(pmap, l1, l2phys | L1_TABLE, va, PAGE_SIZE); | pmap_update_entry(pmap, l1, l2phys | L1_TABLE, va, PAGE_SIZE); | ||||
if (tmpl1 != 0) { | if (tmpl1 != 0) { | ||||
pmap_kremove(tmpl1); | pmap_kremove(tmpl1); | ||||
kva_free(tmpl1, PAGE_SIZE); | kva_free(tmpl1, PAGE_SIZE); | ||||
▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | pmap_demote_l2_locked(pmap_t pmap, pt_entry_t *l2, vm_offset_t va, | ||||
if (ml3->valid == 0 || (l3[0] & ATTR_MASK) != (newl3 & ATTR_MASK)) | if (ml3->valid == 0 || (l3[0] & ATTR_MASK) != (newl3 & ATTR_MASK)) | ||||
pmap_fill_l3(l3, newl3); | pmap_fill_l3(l3, newl3); | ||||
/* | /* | ||||
* Map the temporary page so we don't lose access to the l2 table. | * Map the temporary page so we don't lose access to the l2 table. | ||||
*/ | */ | ||||
if (tmpl2 != 0) { | if (tmpl2 != 0) { | ||||
pmap_kenter(tmpl2, PAGE_SIZE, | pmap_kenter(tmpl2, PAGE_SIZE, | ||||
DMAP_TO_PHYS((vm_offset_t)l2) & ~L3_OFFSET, CACHED_MEMORY); | DMAP_TO_PHYS((vm_offset_t)l2) & ~L3_OFFSET, | ||||
VM_MEMATTR_WRITE_BACK); | |||||
l2 = (pt_entry_t *)(tmpl2 + ((vm_offset_t)l2 & PAGE_MASK)); | l2 = (pt_entry_t *)(tmpl2 + ((vm_offset_t)l2 & PAGE_MASK)); | ||||
} | } | ||||
/* | /* | ||||
* The spare PV entries must be reserved prior to demoting the | * The spare PV entries must be reserved prior to demoting the | ||||
* mapping, that is, prior to changing the PDE. Otherwise, the state | * mapping, that is, prior to changing the PDE. Otherwise, the state | ||||
* of the L2 and the PV lists will be inconsistent, which can result | * of the L2 and the PV lists will be inconsistent, which can result | ||||
* in reclaim_pv_chunk() attempting to remove a PV entry from the | * in reclaim_pv_chunk() attempting to remove a PV entry from the | ||||
▲ Show 20 Lines • Show All 487 Lines • Show Last 20 Lines |