git: 11793cb60351 - stable/13 - amd64: fix PKRU and swapout interaction
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 21 Apr 2023 00:42:54 UTC
The branch stable/13 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=11793cb6035116242d3480ebff855cc0beea1b0b
commit 11793cb6035116242d3480ebff855cc0beea1b0b
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-04-13 11:37:35 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-04-21 00:32:33 +0000
amd64: fix PKRU and swapout interaction
(cherry picked from commit 1e0e335b0f0dbae8ce49307377b23ef3673bd402)
---
sys/amd64/amd64/pmap.c | 37 ++++++++++++++++++++++++++++---------
sys/amd64/include/pmap.h | 1 +
sys/arm/include/pmap.h | 1 +
sys/arm64/include/pmap.h | 1 +
sys/i386/include/pmap.h | 1 +
sys/mips/include/pmap.h | 1 +
sys/powerpc/include/pmap.h | 1 +
sys/riscv/include/pmap.h | 1 +
sys/vm/vm_map.c | 2 +-
9 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index facbc6d3dd81..3883019daf24 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -6174,14 +6174,8 @@ pmap_remove_ptes(pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
return (anyvalid);
}
-/*
- * Remove the given range of addresses from the specified map.
- *
- * It is assumed that the start and end are properly
- * rounded to the page size.
- */
-void
-pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
+static void
+pmap_remove1(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, bool map_delete)
{
struct rwlock *lock;
vm_page_t mt;
@@ -6213,7 +6207,8 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
pmap_delayed_invl_start();
PMAP_LOCK(pmap);
- pmap_pkru_on_remove(pmap, sva, eva);
+ if (map_delete)
+ pmap_pkru_on_remove(pmap, sva, eva);
/*
* special handling of removing one page. a very
@@ -6335,6 +6330,30 @@ out:
vm_page_free_pages_toq(&free, true);
}
+/*
+ * Remove the given range of addresses from the specified map.
+ *
+ * It is assumed that the start and end are properly
+ * rounded to the page size.
+ */
+void
+pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
+{
+ pmap_remove1(pmap, sva, eva, false);
+}
+
+/*
+ * Remove the given range of addresses as part of a logical unmap
+ * operation. This has the effect of calling pmap_remove(), but
+ * also clears any metadata that should persist for the lifetime
+ * of a logical mapping.
+ */
+void
+pmap_map_delete(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
+{
+ pmap_remove1(pmap, sva, eva, true);
+}
+
/*
* Routine: pmap_remove_all
* Function:
diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h
index 0faee81a67c5..ebdcbc6ce202 100644
--- a/sys/amd64/include/pmap.h
+++ b/sys/amd64/include/pmap.h
@@ -516,6 +516,7 @@ void pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva);
void pmap_get_mapping(pmap_t pmap, vm_offset_t va, uint64_t *ptr, int *num);
boolean_t pmap_map_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t);
void pmap_unmap_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t);
+void pmap_map_delete(pmap_t, vm_offset_t, vm_offset_t);
void pmap_pti_add_kva(vm_offset_t sva, vm_offset_t eva, bool exec);
void pmap_pti_remove_kva(vm_offset_t sva, vm_offset_t eva);
void pmap_pti_pcid_invalidate(uint64_t ucr3, uint64_t kcr3);
diff --git a/sys/arm/include/pmap.h b/sys/arm/include/pmap.h
index d06d44d648d5..8572602be35e 100644
--- a/sys/arm/include/pmap.h
+++ b/sys/arm/include/pmap.h
@@ -45,6 +45,7 @@ extern vm_offset_t virtual_end;
void *pmap_kenter_temporary(vm_paddr_t, int);
#define pmap_page_is_write_mapped(m) (((m)->a.flags & PGA_WRITEABLE) != 0)
void pmap_page_set_memattr(vm_page_t, vm_memattr_t);
+#define pmap_map_delete(pmap, sva, eva) pmap_remove(pmap, sva, eva)
void *pmap_mapdev(vm_paddr_t, vm_size_t);
void pmap_unmapdev(vm_offset_t, vm_size_t);
diff --git a/sys/arm64/include/pmap.h b/sys/arm64/include/pmap.h
index 9140e25e023a..6c3b4211da0c 100644
--- a/sys/arm64/include/pmap.h
+++ b/sys/arm64/include/pmap.h
@@ -179,6 +179,7 @@ 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);
void pmap_disable_promotion(vm_offset_t sva, vm_size_t size);
+#define pmap_map_delete(pmap, sva, eva) pmap_remove(pmap, sva, eva)
void *pmap_mapdev(vm_offset_t, vm_size_t);
void *pmap_mapbios(vm_paddr_t, vm_size_t);
diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h
index 5ac99b92cad3..228c1520f0a0 100644
--- a/sys/i386/include/pmap.h
+++ b/sys/i386/include/pmap.h
@@ -286,6 +286,7 @@ void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva);
void pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva);
void *pmap_trm_alloc(size_t size, int flags);
void pmap_trm_free(void *addr, size_t size);
+#define pmap_map_delete(pmap, sva, eva) pmap_remove(pmap, sva, eva)
void invltlb_glob(void);
diff --git a/sys/mips/include/pmap.h b/sys/mips/include/pmap.h
index fb186011bd85..0cc098fcf4be 100644
--- a/sys/mips/include/pmap.h
+++ b/sys/mips/include/pmap.h
@@ -184,6 +184,7 @@ void pmap_flush_pvcache(vm_page_t m);
int pmap_emulate_modified(pmap_t pmap, vm_offset_t va);
void pmap_page_set_memattr(vm_page_t, vm_memattr_t);
int pmap_change_attr(vm_offset_t, vm_size_t, vm_memattr_t);
+#define pmap_map_delete(pmap, sva, eva) pmap_remove(pmap, sva, eva)
static inline int
pmap_vmspace_copy(pmap_t dst_pmap __unused, pmap_t src_pmap __unused)
diff --git a/sys/powerpc/include/pmap.h b/sys/powerpc/include/pmap.h
index d14398750080..4062417193e5 100644
--- a/sys/powerpc/include/pmap.h
+++ b/sys/powerpc/include/pmap.h
@@ -325,6 +325,7 @@ const char *pmap_mmu_name(void);
bool pmap_ps_enabled(pmap_t pmap);
int pmap_nofault(pmap_t pmap, vm_offset_t va, vm_prot_t flags);
boolean_t pmap_page_is_mapped(vm_page_t m);
+#define pmap_map_delete(pmap, sva, eva) pmap_remove(pmap, sva, eva)
void pmap_page_array_startup(long count);
diff --git a/sys/riscv/include/pmap.h b/sys/riscv/include/pmap.h
index 8834c91362ad..f87e6942af2c 100644
--- a/sys/riscv/include/pmap.h
+++ b/sys/riscv/include/pmap.h
@@ -56,6 +56,7 @@
#define pmap_page_get_memattr(m) ((m)->md.pv_memattr)
#define pmap_page_is_write_mapped(m) (((m)->a.flags & PGA_WRITEABLE) != 0)
void pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma);
+#define pmap_map_delete(pmap, sva, eva) pmap_remove(pmap, sva, eva)
/*
* Pmap stuff
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index fa57cea48dae..ce520de160ef 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -3965,7 +3965,7 @@ vm_map_delete(vm_map_t map, vm_offset_t start, vm_offset_t end)
*/
if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0 ||
entry->object.vm_object != NULL)
- pmap_remove(map->pmap, entry->start, entry->end);
+ pmap_map_delete(map->pmap, entry->start, entry->end);
if (entry->end == map->anon_loc)
map->anon_loc = entry->start;