Page MenuHomeFreeBSD

D26066.id78889.diff
No OneTemporary

D26066.id78889.diff

Index: sys/arm64/arm64/pmap.c
===================================================================
--- sys/arm64/arm64/pmap.c
+++ sys/arm64/arm64/pmap.c
@@ -975,6 +975,8 @@
kernel_pmap->pm_l0_paddr = l0pt - kern_delta;
kernel_pmap->pm_cookie = COOKIE_FROM(-1, INT_MIN);
kernel_pmap->pm_stage = PM_STAGE1;
+ kernel_pmap->pm_levels = 4;
+ kernel_pmap->pm_ttbr = kernel_pmap->pm_l0_paddr;
kernel_pmap->pm_asid_set = &asids;
/* Assume the address we were loaded to is a valid physical address */
@@ -1719,33 +1721,37 @@
pmap->pm_root.rt_root = 0;
pmap->pm_cookie = COOKIE_FROM(ASID_RESERVED_FOR_PID_0, INT_MIN);
pmap->pm_stage = PM_STAGE1;
+ pmap->pm_levels = 4;
+ pmap->pm_ttbr = pmap->pm_l0_paddr;
pmap->pm_asid_set = &asids;
PCPU_SET(curpmap, pmap);
}
int
-pmap_pinit_stage(pmap_t pmap, enum pmap_stage stage)
+pmap_pinit_stage(pmap_t pmap, enum pmap_stage stage, int levels)
{
- vm_page_t l0pt;
+ vm_page_t m;
/*
* allocate the l0 page
*/
- while ((l0pt = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL |
+ while ((m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL |
VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO)) == NULL)
vm_wait(NULL);
- pmap->pm_l0_paddr = VM_PAGE_TO_PHYS(l0pt);
+ pmap->pm_l0_paddr = VM_PAGE_TO_PHYS(m);
pmap->pm_l0 = (pd_entry_t *)PHYS_TO_DMAP(pmap->pm_l0_paddr);
- if ((l0pt->flags & PG_ZERO) == 0)
+ if ((m->flags & PG_ZERO) == 0)
pagezero(pmap->pm_l0);
pmap->pm_root.rt_root = 0;
bzero(&pmap->pm_stats, sizeof(pmap->pm_stats));
pmap->pm_cookie = COOKIE_FROM(-1, INT_MAX);
+ MPASS(levels == 3 || levels == 4);
+ pmap->pm_levels = levels;
pmap->pm_stage = stage;
switch (stage) {
case PM_STAGE1:
@@ -1762,6 +1768,18 @@
/* XXX Temporarily disable deferred ASID allocation. */
pmap_alloc_asid(pmap);
+ /*
+ * Allocate the level 1 entry to use as the root. This will increase
+ * the refcount on the level 1 page so it won't be removed until
+ * pmap_release() is called.
+ */
+ if (pmap->pm_levels == 3) {
+ PMAP_LOCK(pmap);
+ m = _pmap_alloc_l3(pmap, NUL2E + NUL1E, NULL);
+ PMAP_UNLOCK(pmap);
+ }
+ pmap->pm_ttbr = VM_PAGE_TO_PHYS(m);
+
return (1);
}
@@ -1769,7 +1787,7 @@
pmap_pinit(pmap_t pmap)
{
- return (pmap_pinit_stage(pmap, PM_STAGE1));
+ return (pmap_pinit_stage(pmap, PM_STAGE1, 4));
}
/*
@@ -2022,10 +2040,29 @@
void
pmap_release(pmap_t pmap)
{
+ boolean_t rv;
+ struct spglist free;
struct asid_set *set;
vm_page_t m;
int asid;
+ if (pmap->pm_levels != 4) {
+ PMAP_ASSERT_STAGE2(pmap);
+ KASSERT(pmap->pm_stats.resident_count == 1,
+ ("pmap_release: pmap resident count %ld != 0",
+ pmap->pm_stats.resident_count));
+ KASSERT((pmap->pm_l0[0] & ATTR_DESCR_VALID) == ATTR_DESCR_VALID,
+ ("pmap_release: Invalid l0 entry: %lx", pmap->pm_l0[0]));
+
+ SLIST_INIT(&free);
+ m = PHYS_TO_VM_PAGE(pmap->pm_ttbr);
+ PMAP_LOCK(pmap);
+ rv = pmap_unwire_l3(pmap, 0, m, &free);
+ PMAP_UNLOCK(pmap);
+ MPASS(rv == TRUE);
+ vm_page_free_pages_toq(&free, true);
+ }
+
KASSERT(pmap->pm_stats.resident_count == 0,
("pmap_release: pmap resident count %ld != 0",
pmap->pm_stats.resident_count));
@@ -6344,7 +6381,7 @@
{
return (ASID_TO_OPERAND(COOKIE_TO_ASID(pmap->pm_cookie)) |
- pmap->pm_l0_paddr);
+ pmap->pm_ttbr);
}
static bool
Index: sys/arm64/include/pmap.h
===================================================================
--- sys/arm64/include/pmap.h
+++ sys/arm64/include/pmap.h
@@ -85,6 +85,7 @@
struct pmap {
struct mtx pm_mtx;
struct pmap_statistics pm_stats; /* pmap statistics */
+ uint64_t pm_ttbr;
vm_paddr_t pm_l0_paddr;
pd_entry_t *pm_l0;
TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */
@@ -92,6 +93,7 @@
long pm_cookie; /* encodes the pmap's ASID */
struct asid_set *pm_asid_set; /* The ASID/VMID set to use */
enum pmap_stage pm_stage;
+ int pm_levels;
};
typedef struct pmap *pmap_t;
@@ -170,7 +172,7 @@
void pmap_kremove_device(vm_offset_t, vm_size_t);
void *pmap_mapdev_attr(vm_offset_t pa, vm_size_t size, vm_memattr_t ma);
bool pmap_page_is_mapped(vm_page_t m);
-int pmap_pinit_stage(pmap_t, enum pmap_stage);
+int pmap_pinit_stage(pmap_t, enum pmap_stage, int);
bool pmap_ps_enabled(pmap_t pmap);
uint64_t pmap_to_ttbr0(pmap_t pmap);

File Metadata

Mime Type
text/plain
Expires
Thu, Aug 27, 7:45 AM (18 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37364704
Default Alt Text
D26066.id78889.diff (4 KB)

Event Timeline