Changeset View
Changeset View
Standalone View
Standalone View
sys/riscv/riscv/pmap.c
Show First 20 Lines • Show All 222 Lines • ▼ Show 20 Lines | |||||
vm_paddr_t dmap_phys_max; /* The limit of the dmap region */ | vm_paddr_t dmap_phys_max; /* The limit of the dmap region */ | ||||
vm_offset_t dmap_max_addr; /* The virtual address limit of the dmap */ | vm_offset_t dmap_max_addr; /* The virtual address limit of the dmap */ | ||||
/* This code assumes all L1 DMAP entries will be used */ | /* This code assumes all L1 DMAP entries will be used */ | ||||
CTASSERT((DMAP_MIN_ADDRESS & ~L1_OFFSET) == DMAP_MIN_ADDRESS); | CTASSERT((DMAP_MIN_ADDRESS & ~L1_OFFSET) == DMAP_MIN_ADDRESS); | ||||
CTASSERT((DMAP_MAX_ADDRESS & ~L1_OFFSET) == DMAP_MAX_ADDRESS); | CTASSERT((DMAP_MAX_ADDRESS & ~L1_OFFSET) == DMAP_MAX_ADDRESS); | ||||
static struct rwlock_padalign pvh_global_lock; | static struct rwlock_padalign pvh_global_lock; | ||||
static struct mtx_padalign allpmaps_lock; | |||||
/* | /* | ||||
* Data for the pv entry allocation mechanism | * Data for the pv entry allocation mechanism | ||||
*/ | */ | ||||
static TAILQ_HEAD(pch, pv_chunk) pv_chunks = TAILQ_HEAD_INITIALIZER(pv_chunks); | static TAILQ_HEAD(pch, pv_chunk) pv_chunks = TAILQ_HEAD_INITIALIZER(pv_chunks); | ||||
static struct mtx pv_chunks_mutex; | static struct mtx pv_chunks_mutex; | ||||
static struct rwlock pv_list_locks[NPV_LIST_LOCKS]; | static struct rwlock pv_list_locks[NPV_LIST_LOCKS]; | ||||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct pmap *user_pmap; | struct pmap *user_pmap; | ||||
pd_entry_t *l1; | pd_entry_t *l1; | ||||
/* Distribute new kernel L1 entry to all the user pmaps */ | /* Distribute new kernel L1 entry to all the user pmaps */ | ||||
if (pmap != kernel_pmap) | if (pmap != kernel_pmap) | ||||
return; | return; | ||||
mtx_lock(&allpmaps_lock); | |||||
LIST_FOREACH(user_pmap, &allpmaps, pm_list) { | LIST_FOREACH(user_pmap, &allpmaps, pm_list) { | ||||
l1 = &user_pmap->pm_l1[l1index]; | l1 = &user_pmap->pm_l1[l1index]; | ||||
pmap_store(l1, entry); | pmap_store(l1, entry); | ||||
} | } | ||||
mtx_unlock(&allpmaps_lock); | |||||
} | } | ||||
static pt_entry_t * | static pt_entry_t * | ||||
pmap_early_page_idx(vm_offset_t l1pt, vm_offset_t va, u_int *l1_slot, | pmap_early_page_idx(vm_offset_t l1pt, vm_offset_t va, u_int *l1_slot, | ||||
u_int *l2_slot) | u_int *l2_slot) | ||||
{ | { | ||||
pt_entry_t *l2; | pt_entry_t *l2; | ||||
pd_entry_t *l1; | pd_entry_t *l1; | ||||
▲ Show 20 Lines • Show All 236 Lines • ▼ Show 20 Lines | |||||
* system needs to map virtual memory. | * system needs to map virtual memory. | ||||
*/ | */ | ||||
void | void | ||||
pmap_init(void) | pmap_init(void) | ||||
{ | { | ||||
int i; | int i; | ||||
/* | /* | ||||
* Initialize the pv chunk list mutex. | * Initialize the pv chunk and pmap list mutexes. | ||||
*/ | */ | ||||
mtx_init(&pv_chunks_mutex, "pmap pv chunk list", NULL, MTX_DEF); | mtx_init(&pv_chunks_mutex, "pmap pv chunk list", NULL, MTX_DEF); | ||||
mtx_init(&allpmaps_lock, "allpmaps", NULL, MTX_DEF); | |||||
/* | /* | ||||
* Initialize the pool of pv list locks. | * Initialize the pool of pv list locks. | ||||
*/ | */ | ||||
for (i = 0; i < NPV_LIST_LOCKS; i++) | for (i = 0; i < NPV_LIST_LOCKS; i++) | ||||
rw_init(&pv_list_locks[i], "pmap pv list"); | rw_init(&pv_list_locks[i], "pmap pv list"); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 477 Lines • ▼ Show 20 Lines | if ((l1pt->flags & PG_ZERO) == 0) | ||||
pagezero(pmap->pm_l1); | pagezero(pmap->pm_l1); | ||||
bzero(&pmap->pm_stats, sizeof(pmap->pm_stats)); | bzero(&pmap->pm_stats, sizeof(pmap->pm_stats)); | ||||
/* Install kernel pagetables */ | /* Install kernel pagetables */ | ||||
memcpy(pmap->pm_l1, kernel_pmap->pm_l1, PAGE_SIZE); | memcpy(pmap->pm_l1, kernel_pmap->pm_l1, PAGE_SIZE); | ||||
/* Add to the list of all user pmaps */ | /* Add to the list of all user pmaps */ | ||||
mtx_lock(&allpmaps_lock); | |||||
LIST_INSERT_HEAD(&allpmaps, pmap, pm_list); | LIST_INSERT_HEAD(&allpmaps, pmap, pm_list); | ||||
mtx_unlock(&allpmaps_lock); | |||||
return (1); | return (1); | ||||
} | } | ||||
/* | /* | ||||
* This routine is called if the desired page table page does not exist. | * This routine is called if the desired page table page does not exist. | ||||
* | * | ||||
* If page table page allocation fails, this routine may sleep before | * If page table page allocation fails, this routine may sleep before | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | KASSERT(pmap->pm_stats.resident_count == 0, | ||||
("pmap_release: pmap resident count %ld != 0", | ("pmap_release: pmap resident count %ld != 0", | ||||
pmap->pm_stats.resident_count)); | pmap->pm_stats.resident_count)); | ||||
m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pmap->pm_l1)); | m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pmap->pm_l1)); | ||||
vm_page_unwire_noq(m); | vm_page_unwire_noq(m); | ||||
vm_page_free_zero(m); | vm_page_free_zero(m); | ||||
/* Remove pmap from the allpmaps list */ | /* Remove pmap from the allpmaps list */ | ||||
mtx_lock(&allpmaps_lock); | |||||
LIST_REMOVE(pmap, pm_list); | LIST_REMOVE(pmap, pm_list); | ||||
mtx_unlock(&allpmaps_lock); | |||||
/* Remove kernel pagetables */ | /* Remove kernel pagetables */ | ||||
bzero(pmap->pm_l1, PAGE_SIZE); | bzero(pmap->pm_l1, PAGE_SIZE); | ||||
} | } | ||||
#if 0 | #if 0 | ||||
static int | static int | ||||
kvm_size(SYSCTL_HANDLER_ARGS) | kvm_size(SYSCTL_HANDLER_ARGS) | ||||
▲ Show 20 Lines • Show All 2,097 Lines • Show Last 20 Lines |