Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Reverte my previous changes kern_exec.c r1.512. It ...



details:   https://anonhg.NetBSD.org/src/rev/fd78c7145603
branches:  trunk
changeset: 1026450:fd78c7145603
user:      ryo <ryo%NetBSD.org@localhost>
date:      Thu Nov 25 10:31:50 2021 +0000

description:
Reverte my previous changes kern_exec.c r1.512. It panics.

This changes was insufficient because es_emul is referenced by multiple execsw.

diffstat:

 sys/kern/kern_exec.c |  119 +++++++++++++++-----------------------------------
 1 files changed, 36 insertions(+), 83 deletions(-)

diffs (202 lines):

diff -r d341280fde8f -r fd78c7145603 sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c      Thu Nov 25 09:40:45 2021 +0000
+++ b/sys/kern/kern_exec.c      Thu Nov 25 10:31:50 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exec.c,v 1.512 2021/11/25 02:37:38 ryo Exp $      */
+/*     $NetBSD: kern_exec.c,v 1.513 2021/11/25 10:31:50 ryo Exp $      */
 
 /*-
  * Copyright (c) 2008, 2019, 2020 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.512 2021/11/25 02:37:38 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.513 2021/11/25 10:31:50 ryo Exp $");
 
 #include "opt_exec.h"
 #include "opt_execfmt.h"
@@ -139,8 +139,6 @@
     char * const *, execve_fetch_element_t, char **);
 static int copyinargstrs(struct execve_data * restrict, char * const *,
     execve_fetch_element_t, char **, size_t *, void (*)(const void *, size_t));
-static int exec_sigcode_alloc(const struct emul *);
-static void exec_sigcode_free(const struct emul *);
 static int exec_sigcode_map(struct proc *, const struct emul *);
 
 #if defined(DEBUG) && !defined(DEBUG_EXEC)
@@ -252,6 +250,8 @@
  */
 krwlock_t exec_lock __cacheline_aligned;
 
+static kmutex_t sigobject_lock __cacheline_aligned;
+
 /*
  * Data used between a loadvm and execve part of an "exec" operation
  */
@@ -1815,7 +1815,7 @@
 exec_add(struct execsw *esp, int count)
 {
        struct exec_entry       *it;
-       int                     i, error = 0;
+       int                     i;
 
        if (count == 0) {
                return 0;
@@ -1840,23 +1840,8 @@
        for (i = 0; i < count; i++) {
                it = kmem_alloc(sizeof(*it), KM_SLEEP);
                it->ex_sw = &esp[i];
-               error = exec_sigcode_alloc(it->ex_sw->es_emul);
-               if (error != 0) {
-                       kmem_free(it, sizeof(*it));
-                       break;
-               }
                LIST_INSERT_HEAD(&ex_head, it, ex_list);
        }
-       /* If even one fails, remove them all back. */
-       if (error != 0) {
-               for (i--; i >= 0; i--) {
-                       it = LIST_FIRST(&ex_head);
-                       LIST_REMOVE(it, ex_list);
-                       exec_sigcode_free(it->ex_sw->es_emul);
-                       kmem_free(it, sizeof(*it));
-               }
-               return error;
-       }
 
        /* update execsw[] */
        exec_init(0);
@@ -1901,7 +1886,6 @@
                        next = LIST_NEXT(it, ex_list);
                        if (it->ex_sw == &esp[i]) {
                                LIST_REMOVE(it, ex_list);
-                               exec_sigcode_free(it->ex_sw->es_emul);
                                kmem_free(it, sizeof(*it));
                                break;
                        }
@@ -1935,6 +1919,7 @@
                vaddr_t vmin = 0, vmax;
 
                rw_init(&exec_lock);
+               mutex_init(&sigobject_lock, MUTEX_DEFAULT, IPL_NONE);
                exec_map = uvm_km_suballoc(kernel_map, &vmin, &vmax,
                    maxexec*NCARGS, VM_MAP_PAGEABLE, false, NULL);
                pool_init(&exec_pool, NCARGS, 0, 0, PR_NOALIGN|PR_NOTOUCH,
@@ -2002,24 +1987,21 @@
 }
 
 static int
-exec_sigcode_alloc(const struct emul *e)
+exec_sigcode_map(struct proc *p, const struct emul *e)
 {
        vaddr_t va;
        vsize_t sz;
        int error;
        struct uvm_object *uobj;
 
-       KASSERT(rw_lock_held(&exec_lock));
-
-       if (e == NULL || e->e_sigobject == NULL)
+       sz = (vaddr_t)e->e_esigcode - (vaddr_t)e->e_sigcode;
+
+       if (e->e_sigobject == NULL || sz == 0) {
                return 0;
-
-       sz = (vaddr_t)e->e_esigcode - (vaddr_t)e->e_sigcode;
-       if (sz == 0)
-               return 0;
+       }
 
        /*
-        * Create a sigobject for this emulation.
+        * If we don't have a sigobject for this emulation, create one.
         *
         * sigobject is an anonymous memory object (just like SYSV shared
         * memory) that we keep a permanent reference to and that we map
@@ -2029,61 +2011,32 @@
         * We map it with PROT_READ|PROT_EXEC into the process just
         * the way sys_mmap() would map it.
         */
-       KASSERT(*e->e_sigobject == NULL);
-       uobj = uao_create(sz, 0);
-       (*uobj->pgops->pgo_reference)(uobj);
-       va = vm_map_min(kernel_map);
-       if ((error = uvm_map(kernel_map, &va, round_page(sz),
-           uobj, 0, 0,
-           UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW,
-           UVM_INH_SHARE, UVM_ADV_RANDOM, 0)))) {
-               printf("sigcode kernel mapping failed %d\n", error);
-               (*uobj->pgops->pgo_detach)(uobj);
-               return error;
-       }
-       memcpy((void *)va, e->e_sigcode, sz);
-#ifdef PMAP_NEED_PROCWR
-       pmap_procwr(&proc0, va, sz);
-#endif
-       uvm_unmap(kernel_map, va, va + round_page(sz));
-       *e->e_sigobject = uobj;
-
-       return 0;
-}
-
-static void
-exec_sigcode_free(const struct emul *e)
-{
-       struct uvm_object *uobj;
-
-       KASSERT(rw_lock_held(&exec_lock));
-
-       if (e == NULL || e->e_sigobject == NULL)
-               return;
 
        uobj = *e->e_sigobject;
-       if (uobj == NULL)
-               return;
-
-       (*uobj->pgops->pgo_detach)(uobj);
-       *e->e_sigobject = NULL;
-}
-
-static int
-exec_sigcode_map(struct proc *p, const struct emul *e)
-{
-       vaddr_t va;
-       vsize_t sz;
-       int error;
-       struct uvm_object *uobj;
-
-       sz = (vaddr_t)e->e_esigcode - (vaddr_t)e->e_sigcode;
-       if (e->e_sigobject == NULL || sz == 0)
-               return 0;
-
-       uobj = *e->e_sigobject;
-       if (uobj == NULL)
-               return 0;
+       if (uobj == NULL) {
+               mutex_enter(&sigobject_lock);
+               if ((uobj = *e->e_sigobject) == NULL) {
+                       uobj = uao_create(sz, 0);
+                       (*uobj->pgops->pgo_reference)(uobj);
+                       va = vm_map_min(kernel_map);
+                       if ((error = uvm_map(kernel_map, &va, round_page(sz),
+                           uobj, 0, 0,
+                           UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW,
+                           UVM_INH_SHARE, UVM_ADV_RANDOM, 0)))) {
+                               printf("kernel mapping failed %d\n", error);
+                               (*uobj->pgops->pgo_detach)(uobj);
+                               mutex_exit(&sigobject_lock);
+                               return error;
+                       }
+                       memcpy((void *)va, e->e_sigcode, sz);
+#ifdef PMAP_NEED_PROCWR
+                       pmap_procwr(&proc0, va, sz);
+#endif
+                       uvm_unmap(kernel_map, va, va + round_page(sz));
+                       *e->e_sigobject = uobj;
+               }
+               mutex_exit(&sigobject_lock);
+       }
 
        /* Just a hint to uvm_map where to put it. */
        va = e->e_vm_default_addr(p, (vaddr_t)p->p_vmspace->vm_daddr,



Home | Main Index | Thread Index | Old Index