diff --git a/Documentation/reference/os/addrenv.rst b/Documentation/reference/os/addrenv.rst
index 6cb2865607..cd23a3d091 100644
--- a/Documentation/reference/os/addrenv.rst
+++ b/Documentation/reference/os/addrenv.rst
@@ -34,7 +34,6 @@ The CPU-specific logic must provide two categories in interfaces:
    - :c:func:`up_addrenv_vdata()`: Returns the virtual base address of the ``.bss``/``.data`` address environment.
    - :c:func:`up_addrenv_heapsize()`: Return the initial heap size.
    - :c:func:`up_addrenv_select()`: Instantiate an address environment.
-   - :c:func:`up_addrenv_restore()`: Restore an address environment.
    - :c:func:`up_addrenv_clone()`: Copy an address environment from one location to another.
 
 #. **Tasking Support**. Other interfaces must be provided to
@@ -162,7 +161,7 @@ The CPU-specific logic must provide two categories in interfaces:
   :return: The initial heap size allocated is returned on success;
     a negated errno value on failure.
 
-.. c:function:: int up_addrenv_select(arch_addrenv_t *addrenv, save_addrenv_t *oldenv)
+.. c:function:: int up_addrenv_select(arch_addrenv_t *addrenv)
 
   After an address environment has been established for a task
   (via up_addrenv_create()), this function may be called to instantiate
@@ -172,24 +171,6 @@ The CPU-specific logic must provide two categories in interfaces:
 
   :param addrenv: The representation of the task address environment
     previously returned by ``up_addrenv_create()``.
-  :param oldenv: The address environment that was in place before
-    ``up_addrenv_select()`` was called. This may be used with
-    ``up_addrenv_restore()`` to restore the original address
-    environment that was in place before ``up_addrenv_select()``
-    was called. Note that this may be a task agnostic,
-    platform-specific representation that may or may not be
-    different from ``arch_addrenv_t``.
-
-  :return: Zero (OK) on success; a negated errno value on failure.
-
-.. c:function:: int up_addrenv_restore(save_addrenv_t oldenv)
-
-  After an address environment has been temporarily instantiated
-  by up_addrenv_select, this function may be called to restore
-  the original address environment.
-
-  :param oldenv: The platform-specific representation of the address
-    environment previously returned by ``up_addrenv_select()``.
 
   :return: Zero (OK) on success; a negated errno value on failure.
 
diff --git a/arch/arm/include/arch.h b/arch/arm/include/arch.h
index 84f80d2303..e2631b3cf8 100644
--- a/arch/arm/include/arch.h
+++ b/arch/arm/include/arch.h
@@ -152,29 +152,6 @@ struct arch_addrenv_s
 };
 
 typedef struct arch_addrenv_s arch_addrenv_t;
-
-/* This type is used when the OS needs to temporarily instantiate a
- * different address environment.  Used in the implementation of
- *
- *   int up_addrenv_select(arch_addrenv_t addrenv, save_addrenv_t *oldenv);
- *   int up_addrenv_restore(save_addrenv_t oldenv);
- *
- * In this case, the saved valued in the L1 page table are returned
- */
-
-struct save_addrenv_s
-{
-  uint32_t text[ARCH_TEXT_NSECTS];
-  uint32_t data[ARCH_DATA_NSECTS];
-#ifdef CONFIG_BUILD_KERNEL
-  uint32_t heap[ARCH_HEAP_NSECTS];
-#ifdef CONFIG_ARCH_VMA_MAPPING
-  uint32_t shm[ARCH_SHM_NSECTS];
-#endif
-#endif
-};
-
-typedef struct save_addrenv_s save_addrenv_t;
 #endif
 
 /****************************************************************************
diff --git a/arch/arm/src/armv7-a/arm_addrenv.c b/arch/arm/src/armv7-a/arm_addrenv.c
index 1edadbad50..a44c2c1de9 100644
--- a/arch/arm/src/armv7-a/arm_addrenv.c
+++ b/arch/arm/src/armv7-a/arm_addrenv.c
@@ -34,7 +34,6 @@
  *                         address environment
  *   up_addrenv_heapsize - Returns the size of the initial heap allocation.
  *   up_addrenv_select   - Instantiate an address environment
- *   up_addrenv_restore  - Restore an address environment
  *   up_addrenv_clone    - Copy an address environment from one location to
  *                         another.
  *
@@ -489,39 +488,25 @@ ssize_t up_addrenv_heapsize(const arch_addrenv_t *addrenv)
  * Input Parameters:
  *   addrenv - The representation of the task address environment previously
  *     returned by up_addrenv_create.
- *   oldenv
- *     The address environment that was in place before up_addrenv_select().
- *     This may be used with up_addrenv_restore() to restore the original
- *     address environment that was in place before up_addrenv_select() was
- *     called.  Note that this may be a task agnostic, platform-specific
- *     representation that may or may not be different from arch_addrenv_t.
  *
  * Returned Value:
  *   Zero (OK) on success; a negated errno value on failure.
  *
  ****************************************************************************/
 
-int up_addrenv_select(const arch_addrenv_t *addrenv,
-                      save_addrenv_t *oldenv)
+int up_addrenv_select(const arch_addrenv_t *addrenv)
 {
   uintptr_t vaddr;
   uintptr_t paddr;
   int i;
 
-  binfo("addrenv=%p oldenv=%p\n", addrenv, oldenv);
+  binfo("addrenv=%p\n", addrenv);
   DEBUGASSERT(addrenv);
 
   for (vaddr = CONFIG_ARCH_TEXT_VBASE, i = 0;
        i < ARCH_TEXT_NSECTS;
        vaddr += SECTION_SIZE, i++)
     {
-      /* Save the old L1 page table entry */
-
-      if (oldenv)
-        {
-          oldenv->text[i] = mmu_l1_getentry(vaddr);
-        }
-
       /* Set (or clear) the new page table entry */
 
       paddr = (uintptr_t)addrenv->text[i];
@@ -541,13 +526,6 @@ int up_addrenv_select(const arch_addrenv_t *addrenv,
        i < ARCH_DATA_NSECTS;
        vaddr += SECTION_SIZE, i++)
     {
-      /* Save the old L1 page table entry */
-
-      if (oldenv)
-        {
-          oldenv->data[i] = mmu_l1_getentry(vaddr);
-        }
-
       /* Set (or clear) the new page table entry */
 
       paddr = (uintptr_t)addrenv->data[i];
@@ -568,13 +546,6 @@ int up_addrenv_select(const arch_addrenv_t *addrenv,
        i < ARCH_HEAP_NSECTS;
        vaddr += SECTION_SIZE, i++)
     {
-      /* Save the old L1 page table entry */
-
-      if (oldenv)
-        {
-          oldenv->heap[i] = mmu_l1_getentry(vaddr);
-        }
-
       /* Set (or clear) the new page table entry */
 
       paddr = (uintptr_t)addrenv->heap[i];
@@ -595,13 +566,6 @@ int up_addrenv_select(const arch_addrenv_t *addrenv,
        i < ARCH_SHM_NSECTS;
        vaddr += SECTION_SIZE, i++)
     {
-      /* Save the old L1 page table entry */
-
-      if (oldenv)
-        {
-          oldenv->shm[i] = mmu_l1_getentry(vaddr);
-        }
-
       /* Set (or clear) the new page table entry */
 
       paddr = (uintptr_t)addrenv->shm[i];
@@ -621,75 +585,6 @@ int up_addrenv_select(const arch_addrenv_t *addrenv,
   return OK;
 }
 
-/****************************************************************************
- * Name: up_addrenv_restore
- *
- * Description:
- *   After an address environment has been temporarily instantiated by
- *   up_addrenv_select(), this function may be called to restore the
- *   original address environment.
- *
- * Input Parameters:
- *   oldenv - The platform-specific representation of the address environment
- *     previously returned by up_addrenv_select.
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int up_addrenv_restore(const save_addrenv_t *oldenv)
-{
-  uintptr_t vaddr;
-  int i;
-
-  binfo("oldenv=%p\n", oldenv);
-  DEBUGASSERT(oldenv);
-
-  for (vaddr = CONFIG_ARCH_TEXT_VBASE, i = 0;
-       i < ARCH_TEXT_NSECTS;
-       vaddr += SECTION_SIZE, i++)
-    {
-      /* Restore the L1 page table entry */
-
-      mmu_l1_restore(vaddr, oldenv->text[i]);
-    }
-
-  for (vaddr = CONFIG_ARCH_DATA_VBASE, i = 0;
-       i < ARCH_DATA_NSECTS;
-       vaddr += SECTION_SIZE, i++)
-    {
-      /* Restore the L1 page table entry */
-
-      mmu_l1_restore(vaddr, oldenv->data[i]);
-    }
-
-#ifdef CONFIG_BUILD_KERNEL
-  for (vaddr = CONFIG_ARCH_HEAP_VBASE, i = 0;
-       i < ARCH_HEAP_NSECTS;
-       vaddr += SECTION_SIZE, i++)
-    {
-      /* Restore the L1 page table entry */
-
-      mmu_l1_restore(vaddr, oldenv->heap[i]);
-    }
-
-#ifdef CONFIG_ARCH_VMA_MAPPING
-  for (vaddr = CONFIG_ARCH_SHM_VBASE, i = 0;
-       i < ARCH_SHM_NSECTS;
-       vaddr += SECTION_SIZE, i++)
-    {
-      /* Restore the L1 page table entry */
-
-      mmu_l1_restore(vaddr, oldenv->shm[i]);
-    }
-
-#endif
-#endif
-
-  return OK;
-}
-
 /****************************************************************************
  * Name: up_addrenv_coherent
  *
diff --git a/arch/arm/src/armv7-a/arm_addrenv_kstack.c b/arch/arm/src/armv7-a/arm_addrenv_kstack.c
index a1b08db484..86ea406908 100644
--- a/arch/arm/src/armv7-a/arm_addrenv_kstack.c
+++ b/arch/arm/src/armv7-a/arm_addrenv_kstack.c
@@ -34,7 +34,6 @@
  *                         address environment
  *   up_addrenv_heapsize - Returns the size of the initial heap allocation.
  *   up_addrenv_select   - Instantiate an address environment
- *   up_addrenv_restore  - Restore an address environment
  *   up_addrenv_clone    - Copy an address environment from one location to
  *                         another.
  *
diff --git a/arch/arm/src/armv7-a/arm_addrenv_ustack.c b/arch/arm/src/armv7-a/arm_addrenv_ustack.c
index 79db3e9ae4..0d1ed8aeca 100644
--- a/arch/arm/src/armv7-a/arm_addrenv_ustack.c
+++ b/arch/arm/src/armv7-a/arm_addrenv_ustack.c
@@ -34,7 +34,6 @@
  *                         address environment
  *   up_addrenv_heapsize - Returns the size of the initial heap allocation.
  *   up_addrenv_select   - Instantiate an address environment
- *   up_addrenv_restore  - Restore an address environment
  *   up_addrenv_clone    - Copy an address environment from one location to
  *                         another.
  *
diff --git a/arch/arm/src/armv7-a/arm_pgalloc.c b/arch/arm/src/armv7-a/arm_pgalloc.c
index 8e7af3b4be..761e25b3ba 100644
--- a/arch/arm/src/armv7-a/arm_pgalloc.c
+++ b/arch/arm/src/armv7-a/arm_pgalloc.c
@@ -136,7 +136,7 @@ static int get_pgtable(arch_addrenv_t *addrenv, uintptr_t vaddr)
 
           /* And instantiate the modified environment */
 
-          up_addrenv_select(addrenv, NULL);
+          up_addrenv_select(addrenv);
         }
     }
 
diff --git a/arch/arm/src/common/arm_checkstack.c b/arch/arm/src/common/arm_checkstack.c
index 7cc2a3973b..80d1c323ab 100644
--- a/arch/arm/src/common/arm_checkstack.c
+++ b/arch/arm/src/common/arm_checkstack.c
@@ -30,6 +30,7 @@
 #include <assert.h>
 #include <debug.h>
 
+#include <nuttx/addrenv.h>
 #include <nuttx/arch.h>
 #include <nuttx/board.h>
 
@@ -202,12 +203,11 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
   size_t size;
 
 #ifdef CONFIG_ARCH_ADDRENV
-  save_addrenv_t oldenv;
   bool saved = false;
 
-  if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
+  if (tcb->addrenv_own != NULL)
     {
-      up_addrenv_select(&tcb->addrenv_own->addrenv, &oldenv);
+      addrenv_select(tcb->addrenv_own);
       saved = true;
     }
 #endif
@@ -217,7 +217,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
 #ifdef CONFIG_ARCH_ADDRENV
   if (saved)
     {
-      up_addrenv_restore(&oldenv);
+      addrenv_restore();
     }
 #endif
 
diff --git a/arch/arm64/include/arch.h b/arch/arm64/include/arch.h
index ded0f3a37c..9782ca9b73 100644
--- a/arch/arm64/include/arch.h
+++ b/arch/arm64/include/arch.h
@@ -90,29 +90,6 @@ struct arch_addrenv_s
 };
 
 typedef struct arch_addrenv_s arch_addrenv_t;
-
-/* This type is used when the OS needs to temporarily instantiate a
- * different address environment.  Used in the implementation of
- *
- *   int up_addrenv_select(arch_addrenv_t addrenv, save_addrenv_t *oldenv);
- *   int up_addrenv_restore(save_addrenv_t oldenv);
- *
- * In this case, the saved value in the L1 page table are returned
- */
-
-struct save_addrenv_s
-{
-  uint32_t text[ARCH_TEXT_NSECTS];
-  uint32_t data[ARCH_DATA_NSECTS];
-#ifdef CONFIG_BUILD_KERNEL
-  uint32_t heap[ARCH_HEAP_NSECTS];
-#ifdef CONFIG_ARCH_VMA_MAPPING
-  uint32_t shm[ARCH_SHM_NSECTS];
-#endif
-#endif
-};
-
-typedef struct save_addrenv_s save_addrenv_t;
 #endif
 
 /****************************************************************************
diff --git a/arch/or1k/include/arch.h b/arch/or1k/include/arch.h
index 7d47e0685e..38f4ddcb59 100644
--- a/arch/or1k/include/arch.h
+++ b/arch/or1k/include/arch.h
@@ -102,31 +102,6 @@ struct arch_addrenv_s
   size_t heapsize;
 #endif
 };
-
-typedef struct arch_addrenv_s arch_addrenv_t;
-
-/* This type is used when the OS needs to temporarily instantiate a
- * different address environment.  Used in the implementation of
- *
- *   int up_addrenv_select(arch_addrenv_t addrenv, save_addrenv_t *oldenv);
- *   int up_addrenv_restore(save_addrenv_t oldenv);
- *
- * In this case, the saved valued in the L1 page table are returned
- */
-
-struct save_addrenv_s
-{
-  uint32_t text[ARCH_TEXT_NSECTS];
-  uint32_t data[ARCH_DATA_NSECTS];
-#ifdef CONFIG_BUILD_KERNEL
-  uint32_t heap[ARCH_HEAP_NSECTS];
-#ifdef CONFIG_ARCH_VMA_MAPPING
-  uint32_t shm[ARCH_SHM_NSECTS];
-#endif
-#endif
-};
-
-typedef struct save_addrenv_s save_addrenv_t;
 #endif
 
 /****************************************************************************
diff --git a/arch/risc-v/include/arch.h b/arch/risc-v/include/arch.h
index 10c7dfdc3c..3be03ccb73 100644
--- a/arch/risc-v/include/arch.h
+++ b/arch/risc-v/include/arch.h
@@ -101,12 +101,6 @@ struct arch_addrenv_s
 };
 
 typedef struct arch_addrenv_s arch_addrenv_t;
-
-/* If an address environment needs to be saved, saving the satp register
- * will suffice. The register width is architecture dependent
- */
-
-typedef uintptr_t save_addrenv_t;
 #endif /* __ASSEMBLY__ */
 #endif /* CONFIG_ARCH_ADDRENV */
 
diff --git a/arch/risc-v/src/common/riscv_addrenv.c b/arch/risc-v/src/common/riscv_addrenv.c
index 786f3c5713..e5074cfa5f 100644
--- a/arch/risc-v/src/common/riscv_addrenv.c
+++ b/arch/risc-v/src/common/riscv_addrenv.c
@@ -34,7 +34,6 @@
  *                         address environment
  *   up_addrenv_heapsize - Returns the size of the initial heap allocation.
  *   up_addrenv_select   - Instantiate an address environment
- *   up_addrenv_restore  - Restore an address environment
  *   up_addrenv_clone    - Copy an address environment from one location to
  *                        another.
  *
@@ -713,58 +712,19 @@ ssize_t up_addrenv_heapsize(const arch_addrenv_t *addrenv)
  * Input Parameters:
  *   addrenv - The representation of the task address environment previously
  *     returned by up_addrenv_create.
- *   oldenv
- *     The address environment that was in place before up_addrenv_select().
- *     This may be used with up_addrenv_restore() to restore the original
- *     address environment that was in place before up_addrenv_select() was
- *     called.  Note that this may be a task agnostic, hardware
- *     representation that is different from arch_addrenv_t.
  *
  * Returned Value:
  *   Zero (OK) on success; a negated errno value on failure.
  *
  ****************************************************************************/
 
-int up_addrenv_select(const arch_addrenv_t *addrenv,
-                      save_addrenv_t *oldenv)
+int up_addrenv_select(const arch_addrenv_t *addrenv)
 {
   DEBUGASSERT(addrenv && addrenv->satp);
-  if (oldenv)
-    {
-      /* Save the old environment */
-
-      uintptr_t satp_reg = mmu_read_satp();
-      *oldenv = (save_addrenv_t)satp_reg;
-    }
-
   mmu_write_satp(addrenv->satp);
   return OK;
 }
 
-/****************************************************************************
- * Name: up_addrenv_restore
- *
- * Description:
- *   After an address environment has been temporarily instantiated by
- *   up_addrenv_select, this function may be called to restore the
- *   original address environment.
- *
- * Input Parameters:
- *   oldenv - The hardware representation of the address environment
- *     previously returned by up_addrenv_select.
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int up_addrenv_restore(const save_addrenv_t *oldenv)
-{
-  DEBUGASSERT(oldenv);
-  mmu_write_satp((uintptr_t)*oldenv);
-  return OK;
-}
-
 /****************************************************************************
  * Name: up_addrenv_coherent
  *
diff --git a/arch/risc-v/src/common/riscv_checkstack.c b/arch/risc-v/src/common/riscv_checkstack.c
index f662528ab2..ab704c73e8 100644
--- a/arch/risc-v/src/common/riscv_checkstack.c
+++ b/arch/risc-v/src/common/riscv_checkstack.c
@@ -30,6 +30,7 @@
 #include <assert.h>
 #include <debug.h>
 
+#include <nuttx/addrenv.h>
 #include <nuttx/arch.h>
 
 #include "sched/sched.h"
@@ -158,12 +159,11 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
   size_t size;
 
 #ifdef CONFIG_ARCH_ADDRENV
-  save_addrenv_t oldenv;
   bool saved = false;
 
-  if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
+  if (tcb->addrenv_own != NULL)
     {
-      up_addrenv_select(&tcb->addrenv_own->addrenv, &oldenv);
+      addrenv_select(tcb->addrenv_own);
       saved = true;
     }
 #endif
@@ -174,7 +174,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
 #ifdef CONFIG_ARCH_ADDRENV
   if (saved)
     {
-      up_addrenv_restore(&oldenv);
+      addrenv_restore();
     }
 #endif
 
diff --git a/arch/z80/include/z180/arch.h b/arch/z80/include/z180/arch.h
index b9440be607..26c3f40fa1 100644
--- a/arch/z80/include/z180/arch.h
+++ b/arch/z80/include/z180/arch.h
@@ -50,7 +50,6 @@
  */
 
 #ifdef CONFIG_ARCH_ADDRENV
-typedef uint8_t save_addrenv_t;
 
 /* At the task-level, the z180 address environment is represented as struct
  * z180_cbr_s which is defined in irq.h.
diff --git a/arch/z80/src/z180/z180_mmu.c b/arch/z80/src/z180/z180_mmu.c
index ccc016405c..d5e6c9495c 100644
--- a/arch/z80/src/z180/z180_mmu.c
+++ b/arch/z80/src/z180/z180_mmu.c
@@ -174,7 +174,6 @@ int z80_mmu_initialize(void)
  *                         address environment
  *   up_addrenv_heapsize - Returns the size of the initial heap allocation.
  *   up_addrenv_select   - Instantiate an address environment
- *   up_addrenv_restore  - Restore an address environment
  *   up_addrenv_clone    - Copy an address environment from one location to
  *                        another.
  *
@@ -443,30 +442,20 @@ ssize_t up_addrenv_heapsize(FAR const arch_addrenv_t *addrenv)
  * Input Parameters:
  *   addrenv - The representation of the task address environment previously
  *     returned by up_addrenv_create.
- *   oldenv
- *     The address environment that was in place before up_addrenv_select().
- *     This may be used with up_addrenv_restore() to restore the original
- *     address environment that was in place before up_addrenv_select() was
- *     called.  Note that this may be a task agnostic, hardware
- *     representation that is different from arch_addrenv_t.
  *
  * Returned Value:
  *   Zero (OK) on success; a negated errno value on failure.
  *
  ****************************************************************************/
 
-int up_addrenv_select(FAR const arch_addrenv_t *addrenv,
-                      FAR save_addrenv_t *oldenv)
+int up_addrenv_select(FAR const arch_addrenv_t *addrenv)
 {
   FAR struct z180_cbr_s *cbr = (FAR struct z180_cbr_s *)addrenv;
   irqstate_t flags;
 
-  DEBUGASSERT(cbr && oldenv);
-
-  /* Return the current CBR value from the CBR register */
+  DEBUGASSERT(cbr);
 
   flags = enter_critical_section();
-  *oldenv = (save_addrenv_t)inp(Z180_MMU_CBR);
 
   /* Write the new CBR value into CBR register */
 
@@ -475,29 +464,6 @@ int up_addrenv_select(FAR const arch_addrenv_t *addrenv,
   return OK;
 }
 
-/****************************************************************************
- * Name: up_addrenv_restore
- *
- * Description:
- *   After an address environment has been temporarily instantiated by
- *   up_addrenv_select, this function may be called to restore the
- *   original address environment.
- *
- * Input Parameters:
- *   oldenv - The hardware representation of the address environment
- *     previously returned by up_addrenv_select.
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int up_addrenv_restore(FAR const save_addrenv_t *oldenv)
-{
-  outp(Z180_MMU_CBR, (uint8_t)*oldenv);
-  return OK;
-}
-
 /****************************************************************************
  * Name: up_addrenv_coherent
  *
diff --git a/binfmt/binfmt_execmodule.c b/binfmt/binfmt_execmodule.c
index 3736441a9a..cb38e56d6d 100644
--- a/binfmt/binfmt_execmodule.c
+++ b/binfmt/binfmt_execmodule.c
@@ -31,6 +31,7 @@
 #include <debug.h>
 #include <errno.h>
 
+#include <nuttx/addrenv.h>
 #include <nuttx/arch.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/sched.h>
@@ -110,13 +111,13 @@ static void exec_ctors(FAR void *arg)
  *
  ****************************************************************************/
 
-int exec_module(FAR const struct binary_s *binp,
+int exec_module(FAR struct binary_s *binp,
                 FAR const char *filename, FAR char * const *argv,
                 FAR char * const *envp)
 {
   FAR struct task_tcb_s *tcb;
 #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
-  save_addrenv_t oldenv;
+  FAR struct arch_addrenv_s *addrenv = &binp->addrenv.addrenv;
   FAR void *vheap;
 #endif
   FAR void *stackaddr = NULL;
@@ -164,14 +165,14 @@ int exec_module(FAR const struct binary_s *binp,
 #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
   /* Instantiate the address environment containing the user heap */
 
-  ret = up_addrenv_select(&binp->addrenv, &oldenv);
+  ret = addrenv_select(&binp->addrenv);
   if (ret < 0)
     {
-      berr("ERROR: up_addrenv_select() failed: %d\n", ret);
+      berr("ERROR: addrenv_select() failed: %d\n", ret);
       goto errout_with_envp;
     }
 
-  ret = up_addrenv_vheap(&binp->addrenv, &vheap);
+  ret = up_addrenv_vheap(addrenv, &vheap);
   if (ret < 0)
     {
       berr("ERROR: up_addrenv_vheap() failed: %d\n", ret);
@@ -179,8 +180,8 @@ int exec_module(FAR const struct binary_s *binp,
     }
 
   binfo("Initialize the user heap (heapsize=%zu)\n",
-        up_addrenv_heapsize(&binp->addrenv));
-  umm_initialize(vheap, up_addrenv_heapsize(&binp->addrenv));
+        up_addrenv_heapsize(addrenv));
+  umm_initialize(vheap, up_addrenv_heapsize(addrenv));
 #endif
 
   /* Note that tcb->flags are not modified.  0=normal task */
@@ -272,10 +273,10 @@ int exec_module(FAR const struct binary_s *binp,
 #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
   /* Restore the address environment of the caller */
 
-  ret = up_addrenv_restore(&oldenv);
+  ret = addrenv_restore();
   if (ret < 0)
     {
-      berr("ERROR: up_addrenv_restore() failed: %d\n", ret);
+      berr("ERROR: addrenv_restore() failed: %d\n", ret);
       goto errout_with_tcbinit;
     }
 #endif
@@ -291,7 +292,7 @@ errout_with_tcbinit:
 
 errout_with_addrenv:
 #if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
-  up_addrenv_restore(&oldenv);
+  addrenv_restore();
 errout_with_envp:
 #endif
   binfmt_freeenv(envp);
diff --git a/binfmt/binfmt_unloadmodule.c b/binfmt/binfmt_unloadmodule.c
index 801bb79d20..0c0be333ed 100644
--- a/binfmt/binfmt_unloadmodule.c
+++ b/binfmt/binfmt_unloadmodule.c
@@ -30,6 +30,7 @@
 #include <debug.h>
 #include <errno.h>
 
+#include <nuttx/addrenv.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/binfmt/binfmt.h>
 
@@ -61,7 +62,6 @@ static inline int exec_dtors(FAR struct binary_s *binp)
 {
   binfmt_dtor_t *dtor = binp->dtors;
 #ifdef CONFIG_ARCH_ADDRENV
-  save_addrenv_t oldenv;
   int ret;
 #endif
   int i;
@@ -69,10 +69,10 @@ static inline int exec_dtors(FAR struct binary_s *binp)
   /* Instantiate the address environment containing the destructors */
 
 #ifdef CONFIG_ARCH_ADDRENV
-  ret = up_addrenv_select(&binp->addrenv, &oldenv);
+  ret = addrenv_select(&binp->addrenv);
   if (ret < 0)
     {
-      berr("ERROR: up_addrenv_select() failed: %d\n", ret);
+      berr("ERROR: addrenv_select() failed: %d\n", ret);
       return ret;
     }
 #endif
@@ -90,7 +90,7 @@ static inline int exec_dtors(FAR struct binary_s *binp)
   /* Restore the address environment */
 
 #ifdef CONFIG_ARCH_ADDRENV
-  return up_addrenv_restore(&oldenv);
+  return addrenv_restore();
 #else
   return OK;
 #endif
diff --git a/binfmt/elf.c b/binfmt/elf.c
index 1fc2717ca6..1b20eaef35 100644
--- a/binfmt/elf.c
+++ b/binfmt/elf.c
@@ -271,7 +271,12 @@ static int elf_loadbinary(FAR struct binary_s *binp,
    * needed when the module is executed.
    */
 
-  up_addrenv_clone(&loadinfo.addrenv, &binp->addrenv);
+  up_addrenv_clone(&loadinfo.addrenv.addrenv, &binp->addrenv.addrenv);
+
+  /* Take a reference to the address environment, so it won't get freed */
+
+  addrenv_take(&binp->addrenv);
+
 #else
   binp->alloc[0]  = (FAR void *)loadinfo.textalloc;
   binp->alloc[1]  = (FAR void *)loadinfo.dataalloc;
diff --git a/binfmt/libelf/libelf_addrenv.c b/binfmt/libelf/libelf_addrenv.c
index 3e44d2eab0..e3ff9dede0 100644
--- a/binfmt/libelf/libelf_addrenv.c
+++ b/binfmt/libelf/libelf_addrenv.c
@@ -27,6 +27,7 @@
 #include <errno.h>
 #include <debug.h>
 
+#include <nuttx/addrenv.h>
 #include <nuttx/arch.h>
 #include <nuttx/kmalloc.h>
 
@@ -83,33 +84,38 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
                       size_t datasize, size_t heapsize)
 {
 #ifdef CONFIG_ARCH_ADDRENV
+  FAR struct arch_addrenv_s *addrenv = &loadinfo->addrenv.addrenv;
   FAR void *vtext;
   FAR void *vdata;
   int ret;
 
   /* Create an address environment for the new ELF task */
 
-  ret = up_addrenv_create(textsize, datasize, heapsize, &loadinfo->addrenv);
+  ret = up_addrenv_create(textsize, datasize, heapsize, addrenv);
   if (ret < 0)
     {
       berr("ERROR: up_addrenv_create failed: %d\n", ret);
       return ret;
     }
 
+  /* Take a reference to the address environment, so it won't get freed */
+
+  addrenv_take(&loadinfo->addrenv);
+
   /* Get the virtual address associated with the start of the address
    * environment.  This is the base address that we will need to use to
    * access the ELF image (but only if the address environment has been
    * selected.
    */
 
-  ret = up_addrenv_vtext(&loadinfo->addrenv, &vtext);
+  ret = up_addrenv_vtext(addrenv, &vtext);
   if (ret < 0)
     {
       berr("ERROR: up_addrenv_vtext failed: %d\n", ret);
       return ret;
     }
 
-  ret = up_addrenv_vdata(&loadinfo->addrenv, textsize, &vdata);
+  ret = up_addrenv_vdata(addrenv, textsize, &vdata);
   if (ret < 0)
     {
       berr("ERROR: up_addrenv_vdata failed: %d\n", ret);
@@ -171,16 +177,16 @@ int elf_addrenv_select(FAR struct elf_loadinfo_s *loadinfo)
 
   /* Instantiate the new address environment */
 
-  ret = up_addrenv_select(&loadinfo->addrenv, &loadinfo->oldenv);
+  ret = addrenv_select(&loadinfo->addrenv);
   if (ret < 0)
     {
-      berr("ERROR: up_addrenv_select failed: %d\n", ret);
+      berr("ERROR: addrenv_select failed: %d\n", ret);
       return ret;
     }
 
   /* Allow write access to .text */
 
-  ret = up_addrenv_mprot(&loadinfo->addrenv, loadinfo->textalloc,
+  ret = up_addrenv_mprot(&loadinfo->addrenv.addrenv, loadinfo->textalloc,
                          loadinfo->textsize, ELF_TEXT_WRE);
   if (ret < 0)
     {
@@ -213,7 +219,7 @@ int elf_addrenv_restore(FAR struct elf_loadinfo_s *loadinfo)
 
   /* Remove write access to .text */
 
-  ret = up_addrenv_mprot(&loadinfo->addrenv, loadinfo->textalloc,
+  ret = up_addrenv_mprot(&loadinfo->addrenv.addrenv, loadinfo->textalloc,
                          loadinfo->textsize, ELF_TEXT_WRD);
   if (ret < 0)
     {
@@ -223,10 +229,10 @@ int elf_addrenv_restore(FAR struct elf_loadinfo_s *loadinfo)
 
   /* Restore the old address environment */
 
-  ret = up_addrenv_restore(&loadinfo->oldenv);
+  ret = addrenv_restore();
   if (ret < 0)
     {
-      berr("ERROR: up_addrenv_restore failed: %d\n", ret);
+      berr("ERROR: addrenv_restore failed: %d\n", ret);
       return ret;
     }
 
@@ -259,7 +265,7 @@ void elf_addrenv_free(FAR struct elf_loadinfo_s *loadinfo)
 
   /* Free the address environment */
 
-  ret = up_addrenv_destroy(&loadinfo->addrenv);
+  ret = up_addrenv_destroy(&loadinfo->addrenv.addrenv);
   if (ret < 0)
     {
       berr("ERROR: up_addrenv_destroy failed: %d\n", ret);
diff --git a/binfmt/libelf/libelf_bind.c b/binfmt/libelf/libelf_bind.c
index 355dd41ca4..dc8356e1ae 100644
--- a/binfmt/libelf/libelf_bind.c
+++ b/binfmt/libelf/libelf_bind.c
@@ -643,7 +643,7 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
    */
 
 #if 0 /* REVISIT... has some problems */
-  up_addrenv_coherent(&loadinfo->addrenv);
+  up_addrenv_coherent(&loadinfo->addrenv.addrenv);
 #else
   up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize);
   up_coherent_dcache(loadinfo->dataalloc, loadinfo->datasize);
diff --git a/binfmt/libnxflat/libnxflat.h b/binfmt/libnxflat/libnxflat.h
index c277e31b31..4d14d87b27 100644
--- a/binfmt/libnxflat/libnxflat.h
+++ b/binfmt/libnxflat/libnxflat.h
@@ -76,26 +76,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo,
  ****************************************************************************/
 
 #ifdef CONFIG_ARCH_ADDRENV
-#  define nxflat_addrenv_select(l) up_addrenv_select(&(l)->addrenv, &(l)->oldenv)
-#endif
-
-/****************************************************************************
- * Name: nxflat_addrenv_restore
- *
- * Description:
- *   Restore the address environment before nxflat_addrenv_select() was
- *   called..
- *
- * Input Parameters:
- *   loadinfo - Load state information
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_ARCH_ADDRENV
-#  define nxflat_addrenv_restore(l) up_addrenv_restore(&(l)->oldenv)
+#  define nxflat_addrenv_select(l) addrenv_select(&(l)->addrenv)
 #endif
 
 /****************************************************************************
diff --git a/binfmt/libnxflat/libnxflat_addrenv.c b/binfmt/libnxflat/libnxflat_addrenv.c
index cb120cb300..9c72d88d4d 100644
--- a/binfmt/libnxflat/libnxflat_addrenv.c
+++ b/binfmt/libnxflat/libnxflat_addrenv.c
@@ -30,6 +30,7 @@
 #include <errno.h>
 #include <debug.h>
 
+#include <nuttx/addrenv.h>
 #include <nuttx/arch.h>
 #include <nuttx/kmalloc.h>
 
@@ -70,8 +71,8 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo,
 {
   FAR struct dspace_s *dspace;
 #ifdef CONFIG_ARCH_ADDRENV
+  FAR struct arch_addrenv_s *addrenv = &loadinfo->addrenv.addrenv;
   FAR void *vdata;
-  save_addrenv_t oldenv;
   size_t heapsize;
   int ret;
 #endif
@@ -101,20 +102,24 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo,
 
   /* Create a D-Space address environment for the new NXFLAT task */
 
-  ret = up_addrenv_create(0, envsize, heapsize, &loadinfo->addrenv);
+  ret = up_addrenv_create(0, envsize, heapsize, addrenv);
   if (ret < 0)
     {
       berr("ERROR: up_addrenv_create failed: %d\n", ret);
       goto errout_with_dspace;
     }
 
+  /* Take a reference to the address environment, so it won't get freed */
+
+  addrenv_take(&loadinfo->addrenv);
+
   /* Get the virtual address associated with the start of the address
    * environment.  This is the base address that we will need to use to
    * access the D-Space region (but only if the address environment has been
    * selected.
    */
 
-  ret = up_addrenv_vdata(&loadinfo->addrenv, 0, &vdata);
+  ret = up_addrenv_vdata(addrenv, 0, &vdata);
   if (ret < 0)
     {
       berr("ERROR: up_addrenv_vdata failed: %d\n", ret);
@@ -125,19 +130,19 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo,
    * selected the D-Space address environment to do this.
    */
 
-  ret = up_addrenv_select(loadinfo->addrenv, &oldenv);
+  ret = addrenv_select(&loadinfo->addrenv);
   if (ret < 0)
     {
-      berr("ERROR: up_addrenv_select failed: %d\n", ret);
+      berr("ERROR: addrenv_select failed: %d\n", ret);
       goto errout_with_addrenv;
     }
 
   memset(vdata, 0, envsize);
 
-  ret = up_addrenv_restore(oldenv);
+  ret = addrenv_restore();
   if (ret < 0)
     {
-      berr("ERROR: up_addrenv_restore failed: %d\n", ret);
+      berr("ERROR: addrenv_restore failed: %d\n", ret);
       goto errout_with_addrenv;
     }
 
diff --git a/binfmt/nxflat.c b/binfmt/nxflat.c
index b69914774a..6f08075287 100644
--- a/binfmt/nxflat.c
+++ b/binfmt/nxflat.c
@@ -202,7 +202,7 @@ static int nxflat_loadbinary(FAR struct binary_s *binp,
    * needed when the module is executed.
    */
 
-  up_addrenv_clone(&loadinfo.addrenv, &binp->addrenv);
+  up_addrenv_clone(&loadinfo.addrenv.addrenv, &binp->addrenv.addrenv);
 #endif
 
   nxflat_dumpbuffer("Entry code", (FAR const uint8_t *)binp->entrypt,
diff --git a/include/nuttx/addrenv.h b/include/nuttx/addrenv.h
index 12234d2389..c2416ff548 100644
--- a/include/nuttx/addrenv.h
+++ b/include/nuttx/addrenv.h
@@ -365,7 +365,7 @@ int addrenv_switch(FAR struct tcb_s *tcb);
  ****************************************************************************/
 
 int addrenv_attach(FAR struct tcb_s *tcb,
-                   FAR const struct arch_addrenv_s *addrenv);
+                   FAR const struct addrenv_s *addrenv);
 
 /****************************************************************************
  * Name: addrenv_join
@@ -405,10 +405,11 @@ int addrenv_join(FAR struct tcb_s *ptcb, FAR struct tcb_s *tcb);
 int addrenv_leave(FAR struct tcb_s *tcb);
 
 /****************************************************************************
- * Name: addrenv_take
+ * Name: addrenv_select
  *
  * Description:
- *   Take a reference to an address environment.
+ *   Temporarily select a different address environment for the currently
+ *   running process.
  *
  * Input Parameters:
  *   addrenv - The address environment.
@@ -420,21 +421,54 @@ int addrenv_leave(FAR struct tcb_s *tcb);
  *
  ****************************************************************************/
 
+int addrenv_select(FAR struct addrenv_s *addrenv);
+
+/****************************************************************************
+ * Name: addrenv_restore
+ *
+ * Description:
+ *   Switch back to the procces's own address environment.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   This is a NuttX internal function so it follows the convention that
+ *   0 (OK) is returned on success and a negated errno is returned on
+ *   failure.
+ *
+ ****************************************************************************/
+
+int addrenv_restore(void);
+
+/****************************************************************************
+ * Name: addrenv_take
+ *
+ * Description:
+ *   Take a reference to an address environment.
+ *
+ * Input Parameters:
+ *   addrenv - The address environment.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
 void addrenv_take(FAR struct addrenv_s *addrenv);
 
 /****************************************************************************
  * Name: addrenv_give
  *
  * Description:
- *   Give back a reference to an address environment.
+ *   Give back a reference to an address environment, obtaining the resulting
+ *   reference counter as returned value.
  *
  * Input Parameters:
  *   addrenv - The address environment.
  *
  * Returned Value:
- *   This is a NuttX internal function so it follows the convention that
- *   0 (OK) is returned on success and a negated errno is returned on
- *   failure.
+ *   Remaining reference count.
  *
  ****************************************************************************/
 
@@ -452,9 +486,7 @@ int addrenv_give(FAR struct addrenv_s *addrenv);
  *              no:  The address environment can be dropped at once
  *
  * Returned Value:
- *   This is a NuttX internal function so it follows the convention that
- *   0 (OK) is returned on success and a negated errno is returned on
- *   failure.
+ *   None.
  *
  ****************************************************************************/
 
@@ -478,7 +510,6 @@ void addrenv_drop(FAR struct addrenv_s *addrenv, bool deferred);
  *                         address environment
  *   up_addrenv_heapsize - Returns the size of the initial heap allocation.
  *   up_addrenv_select   - Instantiate an address environment
- *   up_addrenv_restore  - Restore an address environment
  *   up_addrenv_clone    - Copy an address environment from one location to
  *                         another.
  *
diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h
index c0474f86b1..732aae35d7 100644
--- a/include/nuttx/arch.h
+++ b/include/nuttx/arch.h
@@ -789,7 +789,6 @@ bool up_textheap_heapmember(FAR void *p);
  *                         address environment
  *   up_addrenv_heapsize - Returns the size of the initial heap allocation.
  *   up_addrenv_select   - Instantiate an address environment
- *   up_addrenv_restore  - Restore an address environment
  *   up_addrenv_clone    - Copy an address environment from one location to
  *                         another.
  *
@@ -1006,12 +1005,6 @@ ssize_t up_addrenv_heapsize(FAR const arch_addrenv_t *addrenv);
  * Input Parameters:
  *   addrenv - The representation of the task address environment previously
  *     returned by up_addrenv_create.
- *   oldenv
- *     The address environment that was in place before up_addrenv_select().
- *     This may be used with up_addrenv_restore() to restore the original
- *     address environment that was in place before up_addrenv_select() was
- *     called.  Note that this may be a task agnostic, platform-specific
- *     representation that may or may not be different from arch_addrenv_t.
  *
  * Returned Value:
  *   Zero (OK) on success; a negated errno value on failure.
@@ -1019,29 +1012,7 @@ ssize_t up_addrenv_heapsize(FAR const arch_addrenv_t *addrenv);
  ****************************************************************************/
 
 #ifdef CONFIG_ARCH_ADDRENV
-int up_addrenv_select(FAR const arch_addrenv_t *addrenv,
-                      FAR save_addrenv_t *oldenv);
-#endif
-
-/****************************************************************************
- * Name: up_addrenv_restore
- *
- * Description:
- *   After an address environment has been temporarily instantiated by
- *   up_addrenv_select(), this function may be called to restore the
- *   original address environment.
- *
- * Input Parameters:
- *   oldenv - The platform-specific representation of the address environment
- *     previously returned by up_addrenv_select.
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_ARCH_ADDRENV
-int up_addrenv_restore(FAR const save_addrenv_t *oldenv);
+int up_addrenv_select(FAR const arch_addrenv_t *addrenv);
 #endif
 
 /****************************************************************************
diff --git a/include/nuttx/binfmt/binfmt.h b/include/nuttx/binfmt/binfmt.h
index b167b6ec43..80f80c8e62 100644
--- a/include/nuttx/binfmt/binfmt.h
+++ b/include/nuttx/binfmt/binfmt.h
@@ -86,7 +86,7 @@ struct binary_s
    *   used to manage the tasks address space.
    */
 
-  arch_addrenv_t addrenv;              /* Task group address environment */
+  addrenv_t addrenv;                   /* Address environment */
 #endif
 
   size_t mapsize;                      /* Size of the mapped address region (needed for munmap) */
@@ -261,7 +261,7 @@ int unload_module(FAR struct binary_s *bin);
  *
  ****************************************************************************/
 
-int exec_module(FAR const struct binary_s *binp,
+int exec_module(FAR struct binary_s *binp,
                 FAR const char *filename, FAR char * const *argv,
                 FAR char * const *envp);
 
diff --git a/include/nuttx/binfmt/elf.h b/include/nuttx/binfmt/elf.h
index 7c6ec9de1f..8370ec8832 100644
--- a/include/nuttx/binfmt/elf.h
+++ b/include/nuttx/binfmt/elf.h
@@ -119,13 +119,10 @@ struct elf_loadinfo_s
    *
    * addrenv - This is the handle created by up_addrenv_create() that can be
    *   used to manage the tasks address space.
-   * oldenv  - This is a value returned by up_addrenv_select() that must be
-   *   used to restore the current address environment.
    */
 
 #ifdef CONFIG_ARCH_ADDRENV
-  arch_addrenv_t     addrenv;    /* Task group address environment */
-  save_addrenv_t     oldenv;     /* Saved address environment */
+  addrenv_t          addrenv;    /* Address environment */
 #endif
 
   uint16_t           symtabidx;  /* Symbol table section index */
diff --git a/include/nuttx/binfmt/nxflat.h b/include/nuttx/binfmt/nxflat.h
index c40bb63d0c..222fdadc33 100644
--- a/include/nuttx/binfmt/nxflat.h
+++ b/include/nuttx/binfmt/nxflat.h
@@ -84,13 +84,10 @@ struct nxflat_loadinfo_s
    *
    * addrenv - This is the handle created by up_addrenv_create() that can be
    *   used to manage the tasks address space.
-   * oldenv  - This is a value returned by up_addrenv_select() that must be
-   *   used to restore the current address environment.
    */
 
 #ifdef CONFIG_ARCH_ADDRENV
-  arch_addrenv_t addrenv;  /* Task group address environment */
-  save_addrenv_t oldenv;   /* Saved address environment */
+  addrenv_t addrenv;       /* Address environment */
 #endif
 
   /* File descriptors */
diff --git a/sched/addrenv/addrenv.c b/sched/addrenv/addrenv.c
index f352970dca..cfbcca5506 100644
--- a/sched/addrenv/addrenv.c
+++ b/sched/addrenv/addrenv.c
@@ -86,6 +86,35 @@ static void addrenv_destroy(FAR void *arg)
   kmm_free(addrenv);
 }
 
+/****************************************************************************
+ * Name: addrenv_clear_current
+ *
+ * Description:
+ *   Clear the current addrenv from g_addrenv, if it matches the input.
+ *
+ * Input Parameters:
+ *   addrenv - Pointer to the addrenv to free.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void addrenv_clear_current(FAR const addrenv_t *addrenv)
+{
+  int i;
+
+  /* Mark no address environment */
+
+  for (i = 0; i < CONFIG_SMP_NCPUS; i++)
+    {
+      if (addrenv == g_addrenv[i])
+        {
+          g_addrenv[i] = NULL;
+        }
+    }
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -136,7 +165,7 @@ int addrenv_switch(FAR struct tcb_s *tcb)
     }
 
   DEBUGASSERT(tcb);
-  next = tcb->mm_curr;
+  next = tcb->addrenv_curr;
 
   /* Does the group have an address environment? */
 
@@ -179,7 +208,7 @@ int addrenv_switch(FAR struct tcb_s *tcb)
        * instantiated.
        */
 
-      ret = up_addrenv_select(&next->addrenv, NULL);
+      ret = up_addrenv_select(&next->addrenv);
       if (ret < 0)
         {
           berr("ERROR: up_addrenv_select failed: %d\n", ret);
@@ -285,13 +314,13 @@ int addrenv_free(FAR struct tcb_s *tcb)
  ****************************************************************************/
 
 int addrenv_attach(FAR struct tcb_s *tcb,
-                   FAR const struct arch_addrenv_s *addrenv)
+                   FAR const struct addrenv_s *addrenv)
 {
   int ret;
 
   /* Clone the address environment for us */
 
-  ret = up_addrenv_clone(addrenv, &tcb->addrenv_own->addrenv);
+  ret = up_addrenv_clone(&addrenv->addrenv, &tcb->addrenv_own->addrenv);
   if (ret < 0)
     {
       berr("ERROR: up_addrenv_clone failed: %d\n", ret);
@@ -378,6 +407,63 @@ int addrenv_leave(FAR struct tcb_s *tcb)
   return ret;
 }
 
+/****************************************************************************
+ * Name: addrenv_select
+ *
+ * Description:
+ *   Temporarily select a different address environment for the currently
+ *   running process.
+ *
+ * Input Parameters:
+ *   addrenv - The address environment.
+ *
+ * Returned Value:
+ *   This is a NuttX internal function so it follows the convention that
+ *   0 (OK) is returned on success and a negated errno is returned on
+ *   failure.
+ *
+ ****************************************************************************/
+
+int addrenv_select(FAR struct addrenv_s *addrenv)
+{
+  FAR struct tcb_s *tcb = this_task();
+  addrenv_take(addrenv);
+  tcb->addrenv_curr = addrenv;
+  return addrenv_switch(tcb);
+}
+
+/****************************************************************************
+ * Name: addrenv_restore
+ *
+ * Description:
+ *   Switch back to the procces's own address environment.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   This is a NuttX internal function so it follows the convention that
+ *   0 (OK) is returned on success and a negated errno is returned on
+ *   failure.
+ *
+ ****************************************************************************/
+
+int addrenv_restore(void)
+{
+  FAR struct tcb_s *tcb = this_task();
+  addrenv_give(tcb->addrenv_curr);
+
+  if (tcb->addrenv_own == NULL)
+    {
+      /* Kernel thread, clear g_addrenv, as it is not valid any more */
+
+      addrenv_clear_current(tcb->addrenv_curr);
+    }
+
+  tcb->addrenv_curr = tcb->addrenv_own;
+  return addrenv_switch(tcb);
+}
+
 /****************************************************************************
  * Name: addrenv_take
  *
@@ -388,9 +474,7 @@ int addrenv_leave(FAR struct tcb_s *tcb)
  *   addrenv - The address environment.
  *
  * Returned Value:
- *   This is a NuttX internal function so it follows the convention that
- *   0 (OK) is returned on success and a negated errno is returned on
- *   failure.
+ *   None.
  *
  ****************************************************************************/
 
@@ -405,15 +489,14 @@ void addrenv_take(FAR struct addrenv_s *addrenv)
  * Name: addrenv_give
  *
  * Description:
- *   Give back a reference to an address environment.
+ *   Give back a reference to an address environment, obtaining the resulting
+ *   reference counter as returned value.
  *
  * Input Parameters:
  *   addrenv - The address environment.
  *
  * Returned Value:
- *   This is a NuttX internal function so it follows the convention that
- *   0 (OK) is returned on success and a negated errno is returned on
- *   failure.
+ *   Remaining reference count.
  *
  ****************************************************************************/
 
@@ -441,9 +524,7 @@ int addrenv_give(FAR struct addrenv_s *addrenv)
  *              no:  The address environment can be dropped at once
  *
  * Returned Value:
- *   This is a NuttX internal function so it follows the convention that
- *   0 (OK) is returned on success and a negated errno is returned on
- *   failure.
+ *   None.
  *
  ****************************************************************************/
 
diff --git a/sched/misc/assert.c b/sched/misc/assert.c
index b8f4c23148..20ef2f047b 100644
--- a/sched/misc/assert.c
+++ b/sched/misc/assert.c
@@ -24,6 +24,7 @@
 
 #include <nuttx/config.h>
 
+#include <nuttx/addrenv.h>
 #include <nuttx/arch.h>
 #include <nuttx/board.h>
 #include <nuttx/irq.h>
@@ -225,7 +226,6 @@ static void show_stacks(FAR struct tcb_s *rtcb)
 static void get_argv_str(FAR struct tcb_s *tcb, FAR char *args, size_t size)
 {
 #ifdef CONFIG_ARCH_ADDRENV
-  save_addrenv_t oldenv;
   bool saved = false;
 #endif
 
@@ -240,17 +240,9 @@ static void get_argv_str(FAR struct tcb_s *tcb, FAR char *args, size_t size)
     }
 
 #ifdef CONFIG_ARCH_ADDRENV
-  if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
+  if (tcb->addrenv_own != NULL)
     {
-      if (tcb->addrenv_own == NULL)
-        {
-          /* Process should have address environment, but doesn't */
-
-          *args = '\0';
-          return;
-        }
-
-      up_addrenv_select(&tcb->addrenv_own->addrenv, &oldenv);
+      addrenv_select(tcb->addrenv_own);
       saved = true;
     }
 #endif
@@ -277,7 +269,7 @@ static void get_argv_str(FAR struct tcb_s *tcb, FAR char *args, size_t size)
 #ifdef CONFIG_ARCH_ADDRENV
   if (saved)
     {
-      up_addrenv_restore(&oldenv);
+      addrenv_restore();
     }
 #endif
 }