Page MenuHomeFreeBSD

D36563.diff
No OneTemporary

D36563.diff

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
@@ -3120,13 +3120,12 @@
}
/*
- * Tries to create a read- and/or execute-only 2MB page mapping. Returns true
- * if successful. Returns false if (1) a page table page cannot be allocated
- * without sleeping, (2) a mapping already exists at the specified virtual
- * address, or (3) a PV entry cannot be allocated without reclaiming another
- * PV entry.
+ * Tries to create a read- and/or execute-only 2MB page mapping. Returns
+ * KERN_SUCCESS if the mapping was created. Otherwise, returns an error
+ * value. See pmap_enter_l2() for the possible error values when "no sleep",
+ * "no replace", and "no reclaim" are specified.
*/
-static bool
+static int
pmap_enter_2mpage(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
struct rwlock **lockp)
{
@@ -3144,18 +3143,20 @@
if (va < VM_MAXUSER_ADDRESS)
new_l2 |= PTE_U;
return (pmap_enter_l2(pmap, va, new_l2, PMAP_ENTER_NOSLEEP |
- PMAP_ENTER_NOREPLACE | PMAP_ENTER_NORECLAIM, NULL, lockp) ==
- KERN_SUCCESS);
+ PMAP_ENTER_NOREPLACE | PMAP_ENTER_NORECLAIM, NULL, lockp));
}
/*
* Tries to create the specified 2MB page mapping. Returns KERN_SUCCESS if
- * the mapping was created, and either KERN_FAILURE or KERN_RESOURCE_SHORTAGE
- * otherwise. Returns KERN_FAILURE if PMAP_ENTER_NOREPLACE was specified and
- * a mapping already exists at the specified virtual address. Returns
- * KERN_RESOURCE_SHORTAGE if PMAP_ENTER_NOSLEEP was specified and a page table
- * page allocation failed. Returns KERN_RESOURCE_SHORTAGE if
- * PMAP_ENTER_NORECLAIM was specified and a PV entry allocation failed.
+ * the mapping was created, and one of KERN_FAILURE, KERN_NO_SPACE, or
+ * KERN_RESOURCE_SHORTAGE otherwise. Returns KERN_FAILURE if
+ * PMAP_ENTER_NOREPLACE was specified and a 4KB page mapping already exists
+ * within the 2MB virtual address range starting at the specified virtual
+ * address. Returns KERN_NO_SPACE if PMAP_ENTER_NOREPLACE was specified and a
+ * 2MB page mapping already exists at the specified virtual address. Returns
+ * KERN_RESOURCE_SHORTAGE if either (1) PMAP_ENTER_NOSLEEP was specified and a
+ * page table page allocation failed or (2) PMAP_ENTER_NORECLAIM was specified
+ * and a PV entry allocation failed.
*
* The parameter "m" is only used when creating a managed, writeable mapping.
*/
@@ -3183,11 +3184,19 @@
KASSERT(l2pg->ref_count > 1,
("pmap_enter_l2: l2pg's ref count is too low"));
if ((flags & PMAP_ENTER_NOREPLACE) != 0) {
- l2pg->ref_count--;
- CTR2(KTR_PMAP,
- "pmap_enter_l2: failed to replace existing mapping"
- " for va %#lx in pmap %p", va, pmap);
- return (KERN_FAILURE);
+ if ((oldl2 & PTE_RWX) != 0) {
+ l2pg->ref_count--;
+ CTR2(KTR_PMAP,
+ "pmap_enter_l2: no space for va %#lx"
+ " in pmap %p", va, pmap);
+ return (KERN_NO_SPACE);
+ } else {
+ l2pg->ref_count--;
+ CTR2(KTR_PMAP, "pmap_enter_l2:"
+ " failed to replace existing mapping"
+ " for va %#lx in pmap %p", va, pmap);
+ return (KERN_FAILURE);
+ }
}
SLIST_INIT(&free);
if ((oldl2 & PTE_RWX) != 0)
@@ -3280,6 +3289,7 @@
vm_offset_t va;
vm_page_t m, mpte;
vm_pindex_t diff, psize;
+ int rv;
VM_OBJECT_ASSERT_LOCKED(m_start->object);
@@ -3293,7 +3303,8 @@
va = start + ptoa(diff);
if ((va & L2_OFFSET) == 0 && va + L2_SIZE <= end &&
m->psind == 1 && pmap_ps_enabled(pmap) &&
- pmap_enter_2mpage(pmap, va, m, prot, &lock))
+ ((rv = pmap_enter_2mpage(pmap, va, m, prot, &lock)) ==
+ KERN_SUCCESS || rv == KERN_NO_SPACE))
m = &m[L2_SIZE / PAGE_SIZE - 1];
else
mpte = pmap_enter_quick_locked(pmap, va, m, prot, mpte,

File Metadata

Mime Type
text/plain
Expires
Sat, Jun 20, 2:45 AM (15 m, 28 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34108308
Default Alt Text
D36563.diff (3 KB)

Event Timeline