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