Module Name: src
Committed By: ryo
Date: Fri Oct 12 00:57:17 UTC 2018
Modified Files:
src/sys/arch/aarch64/aarch64: pmap.c
src/sys/arch/aarch64/include: pmap.h
Log Message:
rewrite pmap_pte_lookup() to share similar code.
To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/sys/arch/aarch64/aarch64/pmap.c
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/aarch64/include/pmap.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/aarch64/aarch64/pmap.c
diff -u src/sys/arch/aarch64/aarch64/pmap.c:1.26 src/sys/arch/aarch64/aarch64/pmap.c:1.27
--- src/sys/arch/aarch64/aarch64/pmap.c:1.26 Thu Oct 4 23:53:13 2018
+++ src/sys/arch/aarch64/aarch64/pmap.c Fri Oct 12 00:57:17 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.26 2018/10/04 23:53:13 ryo Exp $ */
+/* $NetBSD: pmap.c,v 1.27 2018/10/12 00:57:17 ryo Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.26 2018/10/04 23:53:13 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.27 2018/10/12 00:57:17 ryo Exp $");
#include "opt_arm_debug.h"
#include "opt_ddb.h"
@@ -186,7 +186,8 @@ struct pv_entry {
pt_entry_t *pv_ptep; /* for fast pte lookup */
};
-static pt_entry_t *_pmap_pte_lookup(struct pmap *, vaddr_t);
+static pt_entry_t *_pmap_pte_lookup_l3(struct pmap *, vaddr_t);
+static pt_entry_t *_pmap_pte_lookup_bs(struct pmap *, vaddr_t, vsize_t *);
static pt_entry_t _pmap_pte_adjust_prot(pt_entry_t, vm_prot_t, vm_prot_t, bool);
static pt_entry_t _pmap_pte_adjust_cacheflags(pt_entry_t, u_int);
static void _pmap_remove(struct pmap *, vaddr_t, bool);
@@ -618,91 +619,16 @@ pmap_extract(struct pmap *pm, vaddr_t va
{
static pt_entry_t *ptep;
paddr_t pa;
- bool found;
+ vsize_t blocksize = 0;
-#if 0
- PM_ADDR_CHECK(pm, va);
-#else
- if (((pm == pmap_kernel()) &&
- !(VM_MIN_KERNEL_ADDRESS <= va && va < VM_MAX_KERNEL_ADDRESS) &&
- !(AARCH64_KSEG_START <= va && va < AARCH64_KSEG_END)) ||
- ((pm != pmap_kernel()) &&
- !(VM_MIN_ADDRESS <= va && va <= VM_MAX_ADDRESS)))
+ ptep = _pmap_pte_lookup_bs(pm, va, &blocksize);
+ if (ptep == NULL)
return false;
-#endif
-
- extern char __kernel_text[];
- extern char _end[];
- if ((vaddr_t)__kernel_text <= va && va < (vaddr_t)_end) {
- pa = KERN_VTOPHYS(va);
- found = true;
- } else if (AARCH64_KSEG_START <= va && va < AARCH64_KSEG_END) {
- pa = AARCH64_KVA_TO_PA(va);
- found = true;
- } else {
- pt_entry_t pte;
-
- ptep = _pmap_pte_lookup(pm, va);
- if (ptep == NULL) {
- pd_entry_t pde, *l1, *l2, *l3;
-
- /*
- * traverse L0 -> L1 -> L2 -> L3 table
- * with considering block
- */
- pde = pm->pm_l0table[l0pde_index(va)];
- if (!l0pde_valid(pde)) {
- found = false;
- goto done;
- }
-
- l1 = (void *)AARCH64_PA_TO_KVA(l0pde_pa(pde));
- pde = l1[l1pde_index(va)];
- if (!l1pde_valid(pde)) {
- found = false;
- goto done;
- }
- if (l1pde_is_block(pde)) {
- pa = l1pde_pa(pde) + (va & L1_OFFSET);
- found = true;
- goto done;
- }
-
- KASSERT(l1pde_is_table(pde));
-
- l2 = (void *)AARCH64_PA_TO_KVA(l1pde_pa(pde));
- pde = l2[l2pde_index(va)];
- if (!l2pde_valid(pde)) {
- found = false;
- goto done;
- }
- if (l2pde_is_block(pde)) {
- pa = l2pde_pa(pde) + (va & L2_OFFSET);
- found = true;
- goto done;
- }
-
- KASSERT(l2pde_is_table(pde));
- l3 = (void *)AARCH64_PA_TO_KVA(l2pde_pa(pde));
- pte = l3[l3pte_index(va)];
-
- } else {
- pte = *ptep;
- }
- if (!l3pte_valid(pte) || !l3pte_is_page(pte)) {
- found = false;
- goto done;
- }
-
- KASSERT(l3pte_is_page(pte));
- pa = l3pte_pa(pte) + (va & L3_OFFSET);
- found = true;
- }
- done:
- if (found && (pap != NULL))
+ pa = lxpde_pa(*ptep) + (va & (blocksize - 1));
+ if (pap != NULL)
*pap = pa;
- return found;
+ return true;
}
paddr_t
@@ -731,49 +657,84 @@ vtophys(vaddr_t va)
}
static pt_entry_t *
-_pmap_pte_lookup(struct pmap *pm, vaddr_t va)
+_pmap_pte_lookup_bs(struct pmap *pm, vaddr_t va, vsize_t *bs)
{
- if (AARCH64_KSEG_START <= va && va < AARCH64_KSEG_END) {
- panic("page entry is mapped in KSEG");
- } else {
- pd_entry_t *l0, *l1, *l2, *l3;
- pd_entry_t pde;
- pt_entry_t *ptep;
- unsigned int idx;
+ pt_entry_t *ptep;
+ pd_entry_t *l0, *l1, *l2, *l3;
+ pd_entry_t pde;
+ vsize_t blocksize;
+ unsigned int idx;
- /*
- * traverse L0 -> L1 -> L2 -> L3 table
- */
- l0 = pm->pm_l0table;
+ if (((pm == pmap_kernel()) && ((va & TTBR_SEL_VA) == 0)) ||
+ ((pm != pmap_kernel()) && ((va & TTBR_SEL_VA) != 0))) {
+ blocksize = 0;
+ ptep = NULL;
+ goto done;
+ }
- idx = l0pde_index(va);
- pde = l0[idx];
- if (!l0pde_valid(pde))
- return NULL;
-
- l1 = (void *)AARCH64_PA_TO_KVA(l0pde_pa(pde));
- idx = l1pde_index(va);
- pde = l1[idx];
- if (!l1pde_valid(pde))
- return NULL;
-
- if (l1pde_is_block(pde))
- return NULL;
-
- l2 = (void *)AARCH64_PA_TO_KVA(l1pde_pa(pde));
- idx = l2pde_index(va);
- pde = l2[idx];
- if (!l2pde_valid(pde))
- return NULL;
- if (l2pde_is_block(pde))
- return NULL;
-
- l3 = (void *)AARCH64_PA_TO_KVA(l2pde_pa(pde));
- idx = l3pte_index(va);
- ptep = &l3[idx]; /* as PTE */
+ /*
+ * traverse L0 -> L1 -> L2 -> L3
+ */
+ blocksize = L0_SIZE;
+ l0 = pm->pm_l0table;
+ idx = l0pde_index(va);
+ pde = l0[idx];
+ if (!l0pde_valid(pde)) {
+ ptep = NULL;
+ goto done;
+ }
- return ptep;
+ blocksize = L1_SIZE;
+ l1 = (pd_entry_t *)AARCH64_PA_TO_KVA(l0pde_pa(pde));
+ idx = l1pde_index(va);
+ pde = l1[idx];
+ if (!l1pde_valid(pde)) {
+ ptep = NULL;
+ goto done;
}
+ if (l1pde_is_block(pde)) {
+ ptep = &l1[idx];
+ goto done;
+ }
+
+ blocksize = L2_SIZE;
+ l2 = (pd_entry_t *)AARCH64_PA_TO_KVA(l1pde_pa(pde));
+ idx = l2pde_index(va);
+ pde = l2[idx];
+ if (!l2pde_valid(pde)) {
+ ptep = NULL;
+ goto done;
+ }
+ if (l2pde_is_block(pde)) {
+ ptep = &l2[idx];
+ goto done;
+ }
+
+ blocksize = L3_SIZE;
+ l3 = (pd_entry_t *)AARCH64_PA_TO_KVA(l2pde_pa(pde));
+ idx = l3pte_index(va);
+ pde = l3[idx];
+ if (!l3pte_valid(pde)) {
+ ptep = NULL;
+ goto done;
+ }
+ ptep = &l3[idx];
+
+ done:
+ if (bs != NULL)
+ *bs = blocksize;
+ return ptep;
+}
+
+static pt_entry_t *
+_pmap_pte_lookup_l3(struct pmap *pm, vaddr_t va)
+{
+ pt_entry_t *ptep;
+ vsize_t blocksize = 0;
+
+ ptep = _pmap_pte_lookup_bs(pm, va, &blocksize);
+ if ((ptep != NULL) && (blocksize == L3_SIZE))
+ return ptep;
return NULL;
}
@@ -1126,7 +1087,7 @@ pmap_protect(struct pmap *pm, vaddr_t sv
uint32_t mdattr;
bool executable;
- ptep = _pmap_pte_lookup(pm, va);
+ ptep = _pmap_pte_lookup_l3(pm, va);
if (ptep == NULL) {
PMAP_COUNT(protect_none);
continue;
@@ -1561,7 +1522,7 @@ _pmap_remove(struct pmap *pm, vaddr_t va
pm_lock(pm);
- ptep = _pmap_pte_lookup(pm, va);
+ ptep = _pmap_pte_lookup_l3(pm, va);
if (ptep != NULL) {
pte = *ptep;
if (!l3pte_valid(pte))
@@ -1665,7 +1626,7 @@ pmap_unwire(struct pmap *pm, vaddr_t va)
PM_ADDR_CHECK(pm, va);
pm_lock(pm);
- ptep = _pmap_pte_lookup(pm, va);
+ ptep = _pmap_pte_lookup_l3(pm, va);
if (ptep != NULL) {
pte = *ptep;
if (!l3pte_valid(pte) ||
@@ -1718,7 +1679,7 @@ pmap_fault_fixup(struct pmap *pm, vaddr_
pm_lock(pm);
- ptep = _pmap_pte_lookup(pm, va);
+ ptep = _pmap_pte_lookup_l3(pm, va);
if (ptep == NULL) {
UVMHIST_LOG(pmaphist, "pte_lookup failure: va=%016lx",
va, 0, 0, 0);
@@ -1942,45 +1903,9 @@ pmap_is_referenced(struct vm_page *pg)
pt_entry_t *
kvtopte(vaddr_t va)
{
- pd_entry_t *l0, *l1, *l2, *l3;
- pd_entry_t pde;
- pt_entry_t *ptep;
- unsigned int idx;
-
KASSERT(VM_MIN_KERNEL_ADDRESS <= va && va < VM_MAX_KERNEL_ADDRESS);
- /*
- * traverse L0 -> L1 -> L2 block (or -> L3 table)
- */
- l0 = pmap_kernel()->pm_l0table;
-
- idx = l0pde_index(va);
- pde = l0[idx];
- if (!l0pde_valid(pde))
- return NULL;
-
- l1 = (void *)AARCH64_PA_TO_KVA(l0pde_pa(pde));
- idx = l1pde_index(va);
- pde = l1[idx];
- if (!l1pde_valid(pde))
- return NULL;
-
- if (l1pde_is_block(pde))
- return NULL;
-
- l2 = (void *)AARCH64_PA_TO_KVA(l1pde_pa(pde));
- idx = l2pde_index(va);
- pde = l2[idx];
- if (!l2pde_valid(pde))
- return NULL;
- if (l2pde_is_block(pde))
- return &l2[idx]; /* kernel text/data use L2 blocks */
-
- l3 = (void *)AARCH64_PA_TO_KVA(l2pde_pa(pde));
- idx = l3pte_index(va);
- ptep = &l3[idx]; /* or may use L3 page? */
-
- return ptep;
+ return _pmap_pte_lookup_bs(pmap_kernel(), va, NULL);
}
/* change attribute of kernel segment */
Index: src/sys/arch/aarch64/include/pmap.h
diff -u src/sys/arch/aarch64/include/pmap.h:1.12 src/sys/arch/aarch64/include/pmap.h:1.13
--- src/sys/arch/aarch64/include/pmap.h:1.12 Thu Oct 4 23:53:14 2018
+++ src/sys/arch/aarch64/include/pmap.h Fri Oct 12 00:57:17 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.12 2018/10/04 23:53:14 ryo Exp $ */
+/* $NetBSD: pmap.h,v 1.13 2018/10/12 00:57:17 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -93,24 +93,25 @@ struct vm_page_md {
#define LX_BLKPAG_ATTR_DEVICE_MEM __SHIFTIN(3, LX_BLKPAG_ATTR_INDX)
#define LX_BLKPAG_ATTR_MASK LX_BLKPAG_ATTR_INDX
-#define l0pde_pa(pde) ((paddr_t)((pde) & LX_TBL_PA))
+#define lxpde_pa(pde) ((paddr_t)((pde) & LX_TBL_PA))
+#define l0pde_pa(pde) lxpde_pa(pde)
#define l0pde_index(v) (((vaddr_t)(v) & L0_ADDR_BITS) >> L0_SHIFT)
#define l0pde_valid(pde) (((pde) & LX_VALID) == LX_VALID)
/* l0pte always contains table entries */
-#define l1pde_pa(pde) ((paddr_t)((pde) & LX_TBL_PA))
+#define l1pde_pa(pde) lxpde_pa(pde)
#define l1pde_index(v) (((vaddr_t)(v) & L1_ADDR_BITS) >> L1_SHIFT)
#define l1pde_valid(pde) (((pde) & LX_VALID) == LX_VALID)
#define l1pde_is_block(pde) (((pde) & LX_TYPE) == LX_TYPE_BLK)
#define l1pde_is_table(pde) (((pde) & LX_TYPE) == LX_TYPE_TBL)
-#define l2pde_pa(pde) ((paddr_t)((pde) & LX_TBL_PA))
+#define l2pde_pa(pde) lxpde_pa(pde)
#define l2pde_index(v) (((vaddr_t)(v) & L2_ADDR_BITS) >> L2_SHIFT)
#define l2pde_valid(pde) (((pde) & LX_VALID) == LX_VALID)
#define l2pde_is_block(pde) (((pde) & LX_TYPE) == LX_TYPE_BLK)
#define l2pde_is_table(pde) (((pde) & LX_TYPE) == LX_TYPE_TBL)
-#define l3pte_pa(pde) ((paddr_t)((pde) & LX_TBL_PA))
+#define l3pte_pa(pde) lxpde_pa(pde)
#define l3pte_executable(pde,user) \
(((pde) & ((user) ? LX_BLKPAG_UXN : LX_BLKPAG_PXN)) == 0)
#define l3pte_readable(pde) ((pde) & LX_BLKPAG_AF)