Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/amd64/pmap.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | |||||
* and to when physical maps must be made correct. | * and to when physical maps must be made correct. | ||||
*/ | */ | ||||
#include "opt_ddb.h" | #include "opt_ddb.h" | ||||
#include "opt_pmap.h" | #include "opt_pmap.h" | ||||
#include "opt_vm.h" | #include "opt_vm.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/asan.h> | |||||
#include <sys/bitstring.h> | #include <sys/bitstring.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/counter.h> | #include <sys/counter.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/ktr.h> | #include <sys/ktr.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
Show All 26 Lines | |||||
#include <vm/vm_pageout.h> | #include <vm/vm_pageout.h> | ||||
#include <vm/vm_pager.h> | #include <vm/vm_pager.h> | ||||
#include <vm/vm_phys.h> | #include <vm/vm_phys.h> | ||||
#include <vm/vm_radix.h> | #include <vm/vm_radix.h> | ||||
#include <vm/vm_reserv.h> | #include <vm/vm_reserv.h> | ||||
#include <vm/vm_dumpset.h> | #include <vm/vm_dumpset.h> | ||||
#include <vm/uma.h> | #include <vm/uma.h> | ||||
#include <machine/asan.h> | |||||
#include <machine/intr_machdep.h> | #include <machine/intr_machdep.h> | ||||
#include <x86/apicvar.h> | #include <x86/apicvar.h> | ||||
#include <x86/ifunc.h> | #include <x86/ifunc.h> | ||||
#include <machine/cpu.h> | #include <machine/cpu.h> | ||||
#include <machine/cputypes.h> | #include <machine/cputypes.h> | ||||
#include <machine/intr_machdep.h> | #include <machine/intr_machdep.h> | ||||
#include <machine/md_var.h> | #include <machine/md_var.h> | ||||
#include <machine/pcb.h> | #include <machine/pcb.h> | ||||
▲ Show 20 Lines • Show All 255 Lines • ▼ Show 20 Lines | |||||
static u_int64_t KPTphys; /* phys addr of kernel level 1 */ | static u_int64_t KPTphys; /* phys addr of kernel level 1 */ | ||||
static u_int64_t KPDphys; /* phys addr of kernel level 2 */ | static u_int64_t KPDphys; /* phys addr of kernel level 2 */ | ||||
static u_int64_t KPDPphys; /* phys addr of kernel level 3 */ | static u_int64_t KPDPphys; /* phys addr of kernel level 3 */ | ||||
u_int64_t KPML4phys; /* phys addr of kernel level 4 */ | u_int64_t KPML4phys; /* phys addr of kernel level 4 */ | ||||
u_int64_t KPML5phys; /* phys addr of kernel level 5, | u_int64_t KPML5phys; /* phys addr of kernel level 5, | ||||
if supported */ | if supported */ | ||||
#ifdef KASAN | |||||
static uint64_t KASANPDPphys; | |||||
#endif | |||||
static pml4_entry_t *kernel_pml4; | static pml4_entry_t *kernel_pml4; | ||||
static u_int64_t DMPDphys; /* phys addr of direct mapped level 2 */ | static u_int64_t DMPDphys; /* phys addr of direct mapped level 2 */ | ||||
static u_int64_t DMPDPphys; /* phys addr of direct mapped level 3 */ | static u_int64_t DMPDPphys; /* phys addr of direct mapped level 3 */ | ||||
static int ndmpdpphys; /* number of DMPDPphys pages */ | static int ndmpdpphys; /* number of DMPDPphys pages */ | ||||
static vm_paddr_t KERNend; /* phys addr of end of bootstrap data */ | static vm_paddr_t KERNend; /* phys addr of end of bootstrap data */ | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 1,185 Lines • ▼ Show 20 Lines | bootaddr_rwx(vm_paddr_t pa) | ||||
if (pa < round_2mpage(etext - KERNBASE)) | if (pa < round_2mpage(etext - KERNBASE)) | ||||
return (0); | return (0); | ||||
return (pg_nx); | return (pg_nx); | ||||
} | } | ||||
static void | static void | ||||
create_pagetables(vm_paddr_t *firstaddr) | create_pagetables(vm_paddr_t *firstaddr) | ||||
{ | { | ||||
int i, j, ndm1g, nkpdpe, nkdmpde; | |||||
pd_entry_t *pd_p; | pd_entry_t *pd_p; | ||||
pdp_entry_t *pdp_p; | pdp_entry_t *pdp_p; | ||||
pml4_entry_t *p4_p; | pml4_entry_t *p4_p; | ||||
uint64_t DMPDkernphys; | uint64_t DMPDkernphys; | ||||
#ifdef KASAN | |||||
pt_entry_t *pt_p; | |||||
uint64_t KASANPDphys, KASANPTphys, KASANphys; | |||||
vm_offset_t kasankernbase; | |||||
int kasankpdpi, kasankpdi, nkasanpte; | |||||
#endif | |||||
int i, j, ndm1g, nkpdpe, nkdmpde; | |||||
/* Allocate page table pages for the direct map */ | /* Allocate page table pages for the direct map */ | ||||
ndmpdp = howmany(ptoa(Maxmem), NBPDP); | ndmpdp = howmany(ptoa(Maxmem), NBPDP); | ||||
if (ndmpdp < 4) /* Minimum 4GB of dirmap */ | if (ndmpdp < 4) /* Minimum 4GB of dirmap */ | ||||
ndmpdp = 4; | ndmpdp = 4; | ||||
ndmpdpphys = howmany(ndmpdp, NPDPEPG); | ndmpdpphys = howmany(ndmpdp, NPDPEPG); | ||||
if (ndmpdpphys > NDMPML4E) { | if (ndmpdpphys > NDMPML4E) { | ||||
/* | /* | ||||
Show All 23 Lines | #endif | ||||
} | } | ||||
if (ndm1g < ndmpdp) | if (ndm1g < ndmpdp) | ||||
DMPDphys = allocpages(firstaddr, ndmpdp - ndm1g); | DMPDphys = allocpages(firstaddr, ndmpdp - ndm1g); | ||||
dmaplimit = (vm_paddr_t)ndmpdp << PDPSHIFT; | dmaplimit = (vm_paddr_t)ndmpdp << PDPSHIFT; | ||||
/* Allocate pages */ | /* Allocate pages */ | ||||
KPML4phys = allocpages(firstaddr, 1); | KPML4phys = allocpages(firstaddr, 1); | ||||
KPDPphys = allocpages(firstaddr, NKPML4E); | KPDPphys = allocpages(firstaddr, NKPML4E); | ||||
#ifdef KASAN | |||||
KASANPDPphys = allocpages(firstaddr, NKASANPML4E); | |||||
KASANPDphys = allocpages(firstaddr, 1); | |||||
#endif | |||||
/* | /* | ||||
* Allocate the initial number of kernel page table pages required to | * Allocate the initial number of kernel page table pages required to | ||||
* bootstrap. We defer this until after all memory-size dependent | * bootstrap. We defer this until after all memory-size dependent | ||||
* allocations are done (e.g. direct map), so that we don't have to | * allocations are done (e.g. direct map), so that we don't have to | ||||
* build in too much slop in our estimate. | * build in too much slop in our estimate. | ||||
* | * | ||||
* Note that when NKPML4E > 1, we have an empty page underneath | * Note that when NKPML4E > 1, we have an empty page underneath | ||||
* all but the KPML4I'th one, so we need NKPML4E-1 extra (zeroed) | * all but the KPML4I'th one, so we need NKPML4E-1 extra (zeroed) | ||||
* pages. (pmap_enter requires a PD page to exist for each KPML4E.) | * pages. (pmap_enter requires a PD page to exist for each KPML4E.) | ||||
*/ | */ | ||||
nkpt_init(*firstaddr); | nkpt_init(*firstaddr); | ||||
nkpdpe = NKPDPE(nkpt); | nkpdpe = NKPDPE(nkpt); | ||||
KPTphys = allocpages(firstaddr, nkpt); | KPTphys = allocpages(firstaddr, nkpt); | ||||
KPDphys = allocpages(firstaddr, nkpdpe); | KPDphys = allocpages(firstaddr, nkpdpe); | ||||
#ifdef KASAN | |||||
nkasanpte = howmany(nkpt, KASAN_SHADOW_SCALE); | |||||
KASANPTphys = allocpages(firstaddr, nkasanpte); | |||||
KASANphys = allocpages(firstaddr, nkasanpte * NPTEPG); | |||||
#endif | |||||
/* | /* | ||||
* Connect the zero-filled PT pages to their PD entries. This | * Connect the zero-filled PT pages to their PD entries. This | ||||
* implicitly maps the PT pages at their correct locations within | * implicitly maps the PT pages at their correct locations within | ||||
* the PTmap. | * the PTmap. | ||||
*/ | */ | ||||
pd_p = (pd_entry_t *)KPDphys; | pd_p = (pd_entry_t *)KPDphys; | ||||
for (i = 0; i < nkpt; i++) | for (i = 0; i < nkpt; i++) | ||||
pd_p[i] = (KPTphys + ptoa(i)) | X86_PG_RW | X86_PG_V; | pd_p[i] = (KPTphys + ptoa(i)) | X86_PG_RW | X86_PG_V; | ||||
Show All 16 Lines | #endif | ||||
if (*firstaddr < round_2mpage(KERNend)) | if (*firstaddr < round_2mpage(KERNend)) | ||||
*firstaddr = round_2mpage(KERNend); | *firstaddr = round_2mpage(KERNend); | ||||
/* And connect up the PD to the PDP (leaving room for L4 pages) */ | /* And connect up the PD to the PDP (leaving room for L4 pages) */ | ||||
pdp_p = (pdp_entry_t *)(KPDPphys + ptoa(KPML4I - KPML4BASE)); | pdp_p = (pdp_entry_t *)(KPDPphys + ptoa(KPML4I - KPML4BASE)); | ||||
for (i = 0; i < nkpdpe; i++) | for (i = 0; i < nkpdpe; i++) | ||||
pdp_p[i + KPDPI] = (KPDphys + ptoa(i)) | X86_PG_RW | X86_PG_V; | pdp_p[i + KPDPI] = (KPDphys + ptoa(i)) | X86_PG_RW | X86_PG_V; | ||||
#ifdef KASAN | |||||
kasankernbase = kasan_md_addr_to_shad(KERNBASE); | |||||
kasankpdpi = pmap_pdpe_index(kasankernbase); | |||||
kasankpdi = pmap_pde_index(kasankernbase); | |||||
pdp_p = (pdp_entry_t *)KASANPDPphys; | |||||
pdp_p[kasankpdpi] = (KASANPDphys | X86_PG_RW | X86_PG_V | pg_nx); | |||||
pd_p = (pd_entry_t *)KASANPDphys; | |||||
for (i = 0; i < nkasanpte; i++) | |||||
pd_p[i + kasankpdi] = (KASANPTphys + ptoa(i)) | X86_PG_RW | | |||||
X86_PG_V | pg_nx; | |||||
pt_p = (pt_entry_t *)KASANPTphys; | |||||
for (i = 0; i < nkasanpte * NPTEPG; i++) | |||||
pt_p[i] = (KASANphys + ptoa(i)) | X86_PG_RW | X86_PG_V | | |||||
X86_PG_M | X86_PG_A | pg_nx; | |||||
#endif | |||||
/* | /* | ||||
* Now, set up the direct map region using 2MB and/or 1GB pages. If | * Now, set up the direct map region using 2MB and/or 1GB pages. If | ||||
* the end of physical memory is not aligned to a 1GB page boundary, | * the end of physical memory is not aligned to a 1GB page boundary, | ||||
* then the residual physical memory is mapped with 2MB pages. Later, | * then the residual physical memory is mapped with 2MB pages. Later, | ||||
* if pmap_mapdev{_attr}() uses the direct map for non-write-back | * if pmap_mapdev{_attr}() uses the direct map for non-write-back | ||||
* memory, pmap_change_attr() will demote any 2MB or 1GB page mappings | * memory, pmap_change_attr() will demote any 2MB or 1GB page mappings | ||||
* that are partially used. | * that are partially used. | ||||
*/ | */ | ||||
Show All 32 Lines | for (i = 0; i < nkdmpde; i++) | ||||
X86_PG_V | pg_nx; | X86_PG_V | pg_nx; | ||||
} | } | ||||
/* And recursively map PML4 to itself in order to get PTmap */ | /* And recursively map PML4 to itself in order to get PTmap */ | ||||
p4_p = (pml4_entry_t *)KPML4phys; | p4_p = (pml4_entry_t *)KPML4phys; | ||||
p4_p[PML4PML4I] = KPML4phys; | p4_p[PML4PML4I] = KPML4phys; | ||||
p4_p[PML4PML4I] |= X86_PG_RW | X86_PG_V | pg_nx; | p4_p[PML4PML4I] |= X86_PG_RW | X86_PG_V | pg_nx; | ||||
/* Connect the Direct Map slot(s) up to the PML4. */ | #ifdef KASAN | ||||
/* Connect the KASAN shadow map slots up to the PML4. */ | |||||
for (i = 0; i < NKASANPML4E; i++) { | |||||
p4_p[KASANPML4I + i] = KASANPDPphys + ptoa(i); | |||||
p4_p[KASANPML4I + i] |= X86_PG_RW | X86_PG_V | pg_nx; | |||||
} | |||||
#endif | |||||
/* Connect the Direct Map slots up to the PML4. */ | |||||
for (i = 0; i < ndmpdpphys; i++) { | for (i = 0; i < ndmpdpphys; i++) { | ||||
p4_p[DMPML4I + i] = DMPDPphys + ptoa(i); | p4_p[DMPML4I + i] = DMPDPphys + ptoa(i); | ||||
p4_p[DMPML4I + i] |= X86_PG_RW | X86_PG_V | pg_nx; | p4_p[DMPML4I + i] |= X86_PG_RW | X86_PG_V | pg_nx; | ||||
} | } | ||||
/* Connect the KVA slots up to the PML4 */ | /* Connect the KVA slots up to the PML4 */ | ||||
for (i = 0; i < NKPML4E; i++) { | for (i = 0; i < NKPML4E; i++) { | ||||
p4_p[KPML4BASE + i] = KPDPphys + ptoa(i); | p4_p[KPML4BASE + i] = KPDPphys + ptoa(i); | ||||
▲ Show 20 Lines • Show All 2,347 Lines • ▼ Show 20 Lines | pmap_pinit_pml4(vm_page_t pml4pg) | ||||
pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pml4pg)); | pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pml4pg)); | ||||
/* Wire in kernel global address entries. */ | /* Wire in kernel global address entries. */ | ||||
for (i = 0; i < NKPML4E; i++) { | for (i = 0; i < NKPML4E; i++) { | ||||
pm_pml4[KPML4BASE + i] = (KPDPphys + ptoa(i)) | X86_PG_RW | | pm_pml4[KPML4BASE + i] = (KPDPphys + ptoa(i)) | X86_PG_RW | | ||||
X86_PG_V; | X86_PG_V; | ||||
} | } | ||||
#ifdef KASAN | |||||
for (i = 0; i < NKASANPML4E; i++) { | |||||
pm_pml4[KASANPML4I + i] = (KASANPDPphys + ptoa(i)) | X86_PG_RW | | |||||
X86_PG_V | pg_nx; | |||||
} | |||||
#endif | |||||
for (i = 0; i < ndmpdpphys; i++) { | for (i = 0; i < ndmpdpphys; i++) { | ||||
pm_pml4[DMPML4I + i] = (DMPDPphys + ptoa(i)) | X86_PG_RW | | pm_pml4[DMPML4I + i] = (DMPDPphys + ptoa(i)) | X86_PG_RW | | ||||
X86_PG_V; | X86_PG_V; | ||||
} | } | ||||
/* install self-referential address mapping entry(s) */ | /* install self-referential address mapping entry(s) */ | ||||
pm_pml4[PML4PML4I] = VM_PAGE_TO_PHYS(pml4pg) | X86_PG_V | X86_PG_RW | | pm_pml4[PML4PML4I] = VM_PAGE_TO_PHYS(pml4pg) | X86_PG_V | X86_PG_RW | | ||||
X86_PG_A | X86_PG_M; | X86_PG_A | X86_PG_M; | ||||
▲ Show 20 Lines • Show All 566 Lines • ▼ Show 20 Lines | pmap_release(pmap_t pmap) | ||||
m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pmap->pm_pmltop)); | m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pmap->pm_pmltop)); | ||||
if (pmap_is_la57(pmap)) { | if (pmap_is_la57(pmap)) { | ||||
pmap->pm_pmltop[pmap_pml5e_index(UPT_MAX_ADDRESS)] = 0; | pmap->pm_pmltop[pmap_pml5e_index(UPT_MAX_ADDRESS)] = 0; | ||||
pmap->pm_pmltop[PML5PML5I] = 0; | pmap->pm_pmltop[PML5PML5I] = 0; | ||||
} else { | } else { | ||||
for (i = 0; i < NKPML4E; i++) /* KVA */ | for (i = 0; i < NKPML4E; i++) /* KVA */ | ||||
pmap->pm_pmltop[KPML4BASE + i] = 0; | pmap->pm_pmltop[KPML4BASE + i] = 0; | ||||
#ifdef KASAN | |||||
for (i = 0; i < NKASANPML4E; i++) /* KASAN shadow map */ | |||||
pmap->pm_pmltop[KASANPML4I + i] = 0; | |||||
#endif | |||||
for (i = 0; i < ndmpdpphys; i++)/* Direct Map */ | for (i = 0; i < ndmpdpphys; i++)/* Direct Map */ | ||||
pmap->pm_pmltop[DMPML4I + i] = 0; | pmap->pm_pmltop[DMPML4I + i] = 0; | ||||
pmap->pm_pmltop[PML4PML4I] = 0; /* Recursive Mapping */ | pmap->pm_pmltop[PML4PML4I] = 0; /* Recursive Mapping */ | ||||
for (i = 0; i < lm_ents; i++) /* Large Map */ | for (i = 0; i < lm_ents; i++) /* Large Map */ | ||||
pmap->pm_pmltop[LMSPML4I + i] = 0; | pmap->pm_pmltop[LMSPML4I + i] = 0; | ||||
} | } | ||||
pmap_free_pt_page(NULL, m, true); | pmap_free_pt_page(NULL, m, true); | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | pmap_growkernel(vm_offset_t addr) | ||||
* "KERNBASE". | * "KERNBASE". | ||||
*/ | */ | ||||
if (KERNBASE < addr && addr <= KERNBASE + nkpt * NBPDR) | if (KERNBASE < addr && addr <= KERNBASE + nkpt * NBPDR) | ||||
return; | return; | ||||
addr = roundup2(addr, NBPDR); | addr = roundup2(addr, NBPDR); | ||||
if (addr - 1 >= vm_map_max(kernel_map)) | if (addr - 1 >= vm_map_max(kernel_map)) | ||||
addr = vm_map_max(kernel_map); | addr = vm_map_max(kernel_map); | ||||
if (kernel_vm_end < addr) | |||||
kasan_shadow_map((void *)kernel_vm_end, addr - kernel_vm_end); | |||||
markj: This function is implemented in D29416. | |||||
while (kernel_vm_end < addr) { | while (kernel_vm_end < addr) { | ||||
pdpe = pmap_pdpe(kernel_pmap, kernel_vm_end); | pdpe = pmap_pdpe(kernel_pmap, kernel_vm_end); | ||||
if ((*pdpe & X86_PG_V) == 0) { | if ((*pdpe & X86_PG_V) == 0) { | ||||
/* We need a new PDP entry */ | /* We need a new PDP entry */ | ||||
nkpg = pmap_alloc_pt_page(kernel_pmap, | nkpg = pmap_alloc_pt_page(kernel_pmap, | ||||
kernel_vm_end >> PDPSHIFT, VM_ALLOC_WIRED | | kernel_vm_end >> PDPSHIFT, VM_ALLOC_WIRED | | ||||
VM_ALLOC_INTERRUPT | VM_ALLOC_ZERO); | VM_ALLOC_INTERRUPT | VM_ALLOC_ZERO); | ||||
if (nkpg == NULL) | if (nkpg == NULL) | ||||
▲ Show 20 Lines • Show All 6,344 Lines • ▼ Show 20 Lines | for (;;) { | ||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
if (error != ENOMEM) | if (error != ENOMEM) | ||||
break; | break; | ||||
vm_wait(NULL); | vm_wait(NULL); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef KASAN | |||||
static vm_page_t | |||||
pmap_kasan_enter_alloc_4k(void) | |||||
{ | |||||
vm_page_t m; | |||||
m = vm_page_alloc(NULL, 0, VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | | |||||
VM_ALLOC_WIRED | VM_ALLOC_ZERO); | |||||
if (m == NULL) | |||||
panic("%s: no memory to grow shadow map", __func__); | |||||
if ((m->flags & PG_ZERO) == 0) | |||||
pmap_zero_page(m); | |||||
return (m); | |||||
} | |||||
static vm_page_t | |||||
pmap_kasan_enter_alloc_2m(void) | |||||
{ | |||||
vm_page_t m; | |||||
m = vm_page_alloc_contig(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | | |||||
VM_ALLOC_WIRED, NPTEPG, 0, ~0ul, NBPDR, 0, VM_MEMATTR_DEFAULT); | |||||
if (m != NULL) | |||||
memset((void *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)), 0, NBPDR); | |||||
return (m); | |||||
} | |||||
/* | /* | ||||
* Grow the shadow map by at least one 4KB page at the specified address. Use | |||||
* 2MB pages when possible. | |||||
*/ | |||||
void | |||||
pmap_kasan_enter(vm_offset_t va) | |||||
{ | |||||
pdp_entry_t *pdpe; | |||||
pd_entry_t *pde; | |||||
pt_entry_t *pte; | |||||
vm_page_t m; | |||||
mtx_assert(&kernel_map->system_mtx, MA_OWNED); | |||||
pdpe = pmap_pdpe(kernel_pmap, va); | |||||
if ((*pdpe & X86_PG_V) == 0) { | |||||
m = pmap_kasan_enter_alloc_4k(); | |||||
*pdpe = (pdp_entry_t)(VM_PAGE_TO_PHYS(m) | X86_PG_RW | | |||||
X86_PG_V | pg_nx); | |||||
} | |||||
pde = pmap_pdpe_to_pde(pdpe, va); | |||||
if ((*pde & X86_PG_V) == 0) { | |||||
m = pmap_kasan_enter_alloc_2m(); | |||||
if (m != NULL) { | |||||
*pde = (pd_entry_t)(VM_PAGE_TO_PHYS(m) | X86_PG_RW | | |||||
X86_PG_PS | X86_PG_V | pg_nx); | |||||
} else { | |||||
m = pmap_kasan_enter_alloc_4k(); | |||||
*pde = (pd_entry_t)(VM_PAGE_TO_PHYS(m) | X86_PG_RW | | |||||
X86_PG_V | pg_nx); | |||||
} | |||||
} | |||||
if ((*pde & X86_PG_PS) != 0) | |||||
return; | |||||
pte = pmap_pde_to_pte(pde, va); | |||||
if ((*pte & X86_PG_V) != 0) | |||||
return; | |||||
KASSERT((*pte & X86_PG_V) == 0, | |||||
("%s: shadow address %#lx is already mapped", __func__, va)); | |||||
m = pmap_kasan_enter_alloc_4k(); | |||||
*pte = (pt_entry_t)(VM_PAGE_TO_PHYS(m) | X86_PG_RW | X86_PG_V | | |||||
X86_PG_M | X86_PG_A | pg_nx); | |||||
} | |||||
#endif | |||||
/* | |||||
* Track a range of the kernel's virtual address space that is contiguous | * Track a range of the kernel's virtual address space that is contiguous | ||||
* in various mapping attributes. | * in various mapping attributes. | ||||
*/ | */ | ||||
struct pmap_kernel_map_range { | struct pmap_kernel_map_range { | ||||
vm_offset_t sva; | vm_offset_t sva; | ||||
pt_entry_t attrs; | pt_entry_t attrs; | ||||
int ptes; | int ptes; | ||||
int pdes; | int pdes; | ||||
▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | sysctl_kmaps(SYSCTL_HANDLER_ARGS) | ||||
for (sva = 0, i = pmap_pml4e_index(sva); i < NPML4EPG; i++) { | for (sva = 0, i = pmap_pml4e_index(sva); i < NPML4EPG; i++) { | ||||
switch (i) { | switch (i) { | ||||
case PML4PML4I: | case PML4PML4I: | ||||
sbuf_printf(sb, "\nRecursive map:\n"); | sbuf_printf(sb, "\nRecursive map:\n"); | ||||
break; | break; | ||||
case DMPML4I: | case DMPML4I: | ||||
sbuf_printf(sb, "\nDirect map:\n"); | sbuf_printf(sb, "\nDirect map:\n"); | ||||
break; | break; | ||||
#ifdef KASAN | |||||
case KASANPML4I: | |||||
sbuf_printf(sb, "\nKASAN shadow map:\n"); | |||||
break; | |||||
#endif | |||||
case KPML4BASE: | case KPML4BASE: | ||||
sbuf_printf(sb, "\nKernel map:\n"); | sbuf_printf(sb, "\nKernel map:\n"); | ||||
break; | break; | ||||
case LMSPML4I: | case LMSPML4I: | ||||
sbuf_printf(sb, "\nLarge map:\n"); | sbuf_printf(sb, "\nLarge map:\n"); | ||||
break; | break; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 256 Lines • Show Last 20 Lines |
This function is implemented in D29416.