git: 3e322ded35f7 - stable/13 - Unmap shared page manually before doing vm_map_remove() on exit or exec
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 04 Nov 2021 01:08:01 UTC
The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=3e322ded35f72e0851ab9cfe0c0d37f479c1347e commit 3e322ded35f72e0851ab9cfe0c0d37f479c1347e Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-10-20 20:32:59 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-11-04 00:56:39 +0000 Unmap shared page manually before doing vm_map_remove() on exit or exec (cherry picked from commit 1c69690319c5bb7deae6ce1add6ea25bb40b3b91) --- sys/kern/kern_exec.c | 25 +++++++++++++++++++++++++ sys/kern/kern_exit.c | 1 + sys/sys/sysent.h | 1 + 3 files changed, 27 insertions(+) diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index eb2d7d9986e2..4a405637be4a 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1047,6 +1047,30 @@ exec_onexec_old(struct thread *td) umtx_exec(td->td_proc); } +/* + * This is an optimization which removes the unmanaged shared page + * mapping. In combination with pmap_remove_pages(), which cleans all + * managed mappings in the process' vmspace pmap, no work will be left + * for pmap_remove(min, max). + */ +void +exec_free_abi_mappings(struct proc *p) +{ + struct vmspace *vmspace; + struct sysentvec *sv; + + vmspace = p->p_vmspace; + if (refcount_load(&vmspace->vm_refcnt) != 1) + return; + + sv = p->p_sysent; + if (sv->sv_shared_page_obj == NULL) + return; + + pmap_remove(vmspace_pmap(vmspace), sv->sv_shared_page_base, + sv->sv_shared_page_base + sv->sv_shared_page_len); +} + /* * Destroy old address space, and allocate a new stack. * The new stack is only sgrowsiz large because it is grown @@ -1091,6 +1115,7 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv) vm_map_min(map) == sv_minuser && vm_map_max(map) == sv->sv_maxuser && cpu_exec_vmspace_reuse(p, map)) { + exec_free_abi_mappings(p); shmexit(vmspace); pmap_remove_pages(vmspace_pmap(vmspace)); vm_map_remove(map, vm_map_min(map), vm_map_max(map)); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index bfd25366b49c..47ead49bb202 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -416,6 +416,7 @@ exit1(struct thread *td, int rval, int signo) mtx_unlock(&ppeers_lock); } + exec_free_abi_mappings(p); vmspace_exit(td); (void)acct_process(td); diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index a6b4b9fe9378..3e87bc7c3744 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -318,6 +318,7 @@ void exec_sysvec_init_secondary(struct sysentvec *sv, struct sysentvec *sv2); void exec_inittk(void); void exit_onexit(struct proc *p); +void exec_free_abi_mappings(struct proc *p); void exec_onexec_old(struct thread *td); #define INIT_SYSENTVEC(name, sv) \