Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137520032
D42288.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D42288.diff
View Options
diff --git a/sys/riscv/include/pte.h b/sys/riscv/include/pte.h
--- a/sys/riscv/include/pte.h
+++ b/sys/riscv/include/pte.h
@@ -80,7 +80,7 @@
#define PTE_RWX (PTE_R | PTE_W | PTE_X)
#define PTE_RX (PTE_R | PTE_X)
#define PTE_KERN (PTE_V | PTE_R | PTE_W | PTE_A | PTE_D)
-#define PTE_PROMOTE (PTE_V | PTE_RWX | PTE_D | PTE_A | PTE_G | PTE_U | \
+#define PTE_PROMOTE (PTE_V | PTE_RWX | PTE_D | PTE_G | PTE_U | \
PTE_SW_MANAGED | PTE_SW_WIRED)
/* Bits 63 - 54 are reserved for future use. */
diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c
--- a/sys/riscv/riscv/pmap.c
+++ b/sys/riscv/riscv/pmap.c
@@ -1194,14 +1194,26 @@
* for mapping a distinct range of virtual addresses. The pmap's collection is
* ordered by this virtual address range.
*
- * If "promoted" is false, then the page table page "ml3" must be zero filled.
+ * If "promoted" is false, then the page table page "mpte" must be zero filled;
+ * "mpte"'s valid field will be set to 0.
+ *
+ * If "promoted" is true and "all_l3e_PTE_A_set" is false, then "mpte" must
+ * contain valid mappings with identical attributes except for PTE_A;
+ * "mpte"'s valid field will be set to 1.
+ *
+ * If "promoted" and "all_l3e_PTE_A_set" are both true, then "mpte" must contain
+ * valid mappings with identical attributes including PTE_A; "mpte"'s valid
+ * field will be set to VM_PAGE_BITS_ALL.
*/
static __inline int
-pmap_insert_pt_page(pmap_t pmap, vm_page_t ml3, bool promoted)
+pmap_insert_pt_page(pmap_t pmap, vm_page_t ml3, bool promoted,
+ bool all_l3e_PTE_A_set)
{
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
- ml3->valid = promoted ? VM_PAGE_BITS_ALL : 0;
+ KASSERT(promoted || !all_l3e_PTE_A_set,
+ ("a zero-filled PTP can't have PTE_A set in every PTE"));
+ ml3->valid = promoted ? (all_l3e_PTE_A_set ? VM_PAGE_BITS_ALL : 1) : 0;
return (vm_radix_insert(&pmap->pm_root, ml3));
}
@@ -2169,7 +2181,7 @@
* If this page table page was unmapped by a promotion, then it
* contains valid mappings. Zero it to invalidate those mappings.
*/
- if (ml3->valid != 0)
+ if (vm_page_any_valid(ml3))
pagezero((void *)PHYS_TO_DMAP(ml3pa));
/*
@@ -2230,7 +2242,7 @@
} else {
ml3 = pmap_remove_pt_page(pmap, sva);
if (ml3 != NULL) {
- KASSERT(ml3->valid == VM_PAGE_BITS_ALL,
+ KASSERT(vm_page_any_valid(ml3),
("pmap_remove_l2: l3 page not promoted"));
pmap_resident_count_dec(pmap, 1);
KASSERT(ml3->ref_count == Ln_ENTRIES,
@@ -2703,7 +2715,7 @@
* If the page table page is not leftover from an earlier promotion,
* initialize it.
*/
- if (mpte->valid == 0) {
+ if (!vm_page_all_valid(mpte)) {
for (i = 0; i < Ln_ENTRIES; i++)
pmap_store(firstl3 + i, newl3 + (i << PTE_PPN0_S));
}
@@ -2712,8 +2724,7 @@
"addresses"));
/*
- * If the mapping has changed attributes, update the page table
- * entries.
+ * If the mapping has changed attributes, update the PTEs.
*/
if ((pmap_load(firstl3) & PTE_PROMOTE) != (newl3 & PTE_PROMOTE))
for (i = 0; i < Ln_ENTRIES; i++)
@@ -2752,7 +2763,7 @@
pmap_promote_l2(pmap_t pmap, pd_entry_t *l2, vm_offset_t va, vm_page_t ml3,
struct rwlock **lockp)
{
- pt_entry_t *firstl3, firstl3e, *l3, l3e;
+ pt_entry_t all_l3e_PTE_A, *firstl3, firstl3e, *l3, l3e;
vm_paddr_t pa;
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
@@ -2760,6 +2771,11 @@
KASSERT((pmap_load(l2) & PTE_RWX) == 0,
("pmap_promote_l2: invalid l2 entry %p", l2));
+ /*
+ * Examine the first L3E in the specified PTP. Abort if this L3E is
+ * ineligible for promotion or does not map the first 4KB physical page
+ * within a 2MB page.
+ */
firstl3 = (pt_entry_t *)PHYS_TO_DMAP(PTE_TO_PHYS(pmap_load(l2)));
firstl3e = pmap_load(firstl3);
pa = PTE_TO_PHYS(firstl3e);
@@ -2787,8 +2803,14 @@
}
}
- pa += PAGE_SIZE;
- for (l3 = firstl3 + 1; l3 < firstl3 + Ln_ENTRIES; l3++) {
+ /*
+ * Examine each of the other PTEs in the specified PTP. Abort if this
+ * PTE maps an unexpected 4KB physical page or does not have identical
+ * characteristics to the first PTE.
+ */
+ all_l3e_PTE_A = firstl3e & PTE_A;
+ pa += L2_SIZE - PAGE_SIZE;
+ for (l3 = firstl3 + Ln_ENTRIES - 1; l3 > firstl3; l3--) {
l3e = pmap_load(l3);
if (PTE_TO_PHYS(l3e) != pa) {
CTR2(KTR_PMAP,
@@ -2810,14 +2832,28 @@
atomic_add_long(&pmap_l2_p_failures, 1);
return;
}
- pa += PAGE_SIZE;
+ all_l3e_PTE_A &= l3e;
+ pa -= PAGE_SIZE;
}
+ /*
+ * Unless all PTEs have PTE_A set, clear it from the superpage
+ * mapping, so that promotions triggered by speculative mappings,
+ * such as pmap_enter_quick(), don't automatically mark the
+ * underlying pages as referenced.
+ */
+ firstl3e &= ~PTE_A | all_l3e_PTE_A;
+
+ /*
+ * Save the page table page in its current state until the L2
+ * mapping the superpage is demoted by pmap_demote_l2() or
+ * destroyed by pmap_remove_l3().
+ */
if (ml3 == NULL)
ml3 = PHYS_TO_VM_PAGE(PTE_TO_PHYS(pmap_load(l2)));
KASSERT(ml3->pindex == pmap_l2_pindex(va),
("pmap_promote_l2: page table page's pindex is wrong"));
- if (pmap_insert_pt_page(pmap, ml3, true)) {
+ if (pmap_insert_pt_page(pmap, ml3, true, all_l3e_PTE_A != 0)) {
CTR2(KTR_PMAP, "pmap_promote_l2: failure for va %#lx pmap %p",
va, pmap);
atomic_add_long(&pmap_l2_p_failures, 1);
@@ -3229,7 +3265,7 @@
* leave the kernel page table page zero filled.
*/
mt = PHYS_TO_VM_PAGE(PTE_TO_PHYS(pmap_load(l2)));
- if (pmap_insert_pt_page(pmap, mt, false))
+ if (pmap_insert_pt_page(pmap, mt, false, false))
panic("pmap_enter_l2: trie insert failed");
} else
KASSERT(pmap_load(l2) == 0,
@@ -3847,7 +3883,7 @@
}
mpte = pmap_remove_pt_page(pmap, pv->pv_va);
if (mpte != NULL) {
- KASSERT(mpte->valid == VM_PAGE_BITS_ALL,
+ KASSERT(vm_page_any_valid(mpte),
("pmap_remove_pages: pte page not promoted"));
pmap_resident_count_dec(pmap, 1);
KASSERT(mpte->ref_count == Ln_ENTRIES,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 25, 3:24 AM (8 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26000149
Default Alt Text
D42288.diff (5 KB)
Attached To
Mode
D42288: riscv: Port improvements from arm64/amd64 pmaps, part 1
Attached
Detach File
Event Timeline
Log In to Comment