git: 0fc8a7967228 - main - linux: Unmap the VDSO page when unloading
Mark Johnston
markj at FreeBSD.org
Tue Feb 16 14:40:11 UTC 2021
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=0fc8a796722846d0d676548aa0f5cc660199db73
commit 0fc8a796722846d0d676548aa0f5cc660199db73
Author: Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-02-16 14:30:21 +0000
Commit: Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-02-16 14:40:02 +0000
linux: Unmap the VDSO page when unloading
linux_shared_page_init() creates an object and grabs and maps a single
page to back the VDSO. When destroying the VDSO object, we failed to
destroy the mapping and free KVA. Fix this.
Reviewed by: kib
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D28696
---
sys/amd64/linux/linux_sysvec.c | 3 ++-
sys/amd64/linux32/linux32_sysvec.c | 3 ++-
sys/arm64/linux/linux_sysvec.c | 3 ++-
sys/compat/linux/linux_vdso.c | 6 +++++-
sys/compat/linux/linux_vdso.h | 2 +-
5 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
index dbfc650a916e..abc750c63682 100644
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -818,7 +818,8 @@ static void
linux_vdso_deinstall(void *param)
{
- __elfN(linux_shared_page_fini)(linux_shared_page_obj);
+ __elfN(linux_shared_page_fini)(linux_shared_page_obj,
+ linux_shared_page_mapping);
}
SYSUNINIT(elf_linux_vdso_uninit, SI_SUB_EXEC, SI_ORDER_FIRST,
linux_vdso_deinstall, NULL);
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index d06a1fb17d9b..bb86baefaec4 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -961,7 +961,8 @@ static void
linux_vdso_deinstall(void *param)
{
- __elfN(linux_shared_page_fini)(linux_shared_page_obj);
+ __elfN(linux_shared_page_fini)(linux_shared_page_obj,
+ linux_shared_page_mapping);
}
SYSUNINIT(elf_linux_vdso_uninit, SI_SUB_EXEC, SI_ORDER_FIRST,
linux_vdso_deinstall, NULL);
diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c
index 366fe7c2dc44..1d628ffe6ecb 100644
--- a/sys/arm64/linux/linux_sysvec.c
+++ b/sys/arm64/linux/linux_sysvec.c
@@ -461,7 +461,8 @@ linux_vdso_deinstall(const void *param)
{
LIN_SDT_PROBE0(sysvec, linux_vdso_deinstall, todo);
- __elfN(linux_shared_page_fini)(linux_shared_page_obj);
+ __elfN(linux_shared_page_fini)(linux_shared_page_obj,
+ linux_shared_page_mapping);
}
SYSUNINIT(elf_linux_vdso_uninit, SI_SUB_EXEC, SI_ORDER_FIRST,
linux_vdso_deinstall, NULL);
diff --git a/sys/compat/linux/linux_vdso.c b/sys/compat/linux/linux_vdso.c
index 096f2e424850..a05c0b01ff40 100644
--- a/sys/compat/linux/linux_vdso.c
+++ b/sys/compat/linux/linux_vdso.c
@@ -93,9 +93,13 @@ __elfN(linux_shared_page_init)(char **mapping)
}
void
-__elfN(linux_shared_page_fini)(vm_object_t obj)
+__elfN(linux_shared_page_fini)(vm_object_t obj, void *mapping)
{
+ vm_offset_t va;
+ va = (vm_offset_t)mapping;
+ pmap_qremove(va, 1);
+ kva_free(va, PAGE_SIZE);
vm_object_deallocate(obj);
}
diff --git a/sys/compat/linux/linux_vdso.h b/sys/compat/linux/linux_vdso.h
index 542efef9cb82..073c51696387 100644
--- a/sys/compat/linux/linux_vdso.h
+++ b/sys/compat/linux/linux_vdso.h
@@ -39,7 +39,7 @@ struct linux_vdso_sym {
};
vm_object_t __elfN(linux_shared_page_init)(char **);
-void __elfN(linux_shared_page_fini)(vm_object_t);
+void __elfN(linux_shared_page_fini)(vm_object_t, void *);
void __elfN(linux_vdso_fixup)(struct sysentvec *);
void __elfN(linux_vdso_reloc)(struct sysentvec *);
void __elfN(linux_vdso_sym_init)(struct linux_vdso_sym *);
More information about the dev-commits-src-all
mailing list