You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ma...@apache.org on 2021/04/16 03:41:53 UTC

[incubator-nuttx] 02/02: arch: Allocate the space from the beginning in up_stack_frame

This is an automated email from the ASF dual-hosted git repository.

masayuki pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 2335b69120a3e36f1aa0cecc19c95208806cae54
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Mon Apr 12 23:44:08 2021 +0800

    arch: Allocate the space from the beginning in up_stack_frame
    
    arch: Allocate the space from the beginning in up_stack_frame
    
    and modify the affected portion:
    1.Correct the stack dump and check
    2.Allocate tls_info_s by up_stack_frame too
    3.Move the stack fork allocation from arch to sched
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 Documentation/reference/os/arch.rst                |  29 +-
 arch/arm/src/arm/arm_assert.c                      |  10 +-
 arch/arm/src/arm/arm_initialstate.c                |   5 +-
 arch/arm/src/arm/vfork.S                           |   6 +-
 arch/arm/src/armv6-m/arm_assert.c                  |  14 +-
 arch/arm/src/armv6-m/arm_initialstate.c            |   5 +-
 arch/arm/src/armv6-m/vfork.S                       |   6 +-
 arch/arm/src/armv7-a/arm_assert.c                  |   8 +-
 arch/arm/src/armv7-a/arm_cpuidlestack.c            |  10 +-
 arch/arm/src/armv7-a/arm_initialstate.c            |   5 +-
 arch/arm/src/armv7-a/vfork.S                       |   6 +-
 arch/arm/src/armv7-m/arm_assert.c                  |  16 +-
 arch/arm/src/armv7-m/arm_initialstate.c            |   5 +-
 arch/arm/src/armv7-m/gnu/vfork.S                   |   6 +-
 arch/arm/src/armv7-m/iar/vfork.S                   |   6 +-
 arch/arm/src/armv7-r/arm_assert.c                  |   8 +-
 arch/arm/src/armv7-r/arm_initialstate.c            |   5 +-
 arch/arm/src/armv7-r/vfork.S                       |   6 +-
 arch/arm/src/armv8-m/arm_assert.c                  |  16 +-
 arch/arm/src/armv8-m/arm_initialstate.c            |   5 +-
 arch/arm/src/armv8-m/vfork.S                       |   6 +-
 arch/arm/src/common/arm_checkstack.c               |   6 +-
 arch/arm/src/common/arm_createstack.c              |  48 +---
 arch/arm/src/common/arm_stackframe.c               |  20 +-
 arch/arm/src/common/arm_usestack.c                 |  42 +--
 arch/arm/src/common/arm_vfork.c                    |  62 ++---
 arch/arm/src/cxd56xx/cxd56_cpuidlestack.c          |   4 +-
 arch/arm/src/cxd56xx/cxd56_cpustart.c              |   3 +-
 arch/arm/src/lc823450/lc823450_cpuidlestack.c      |   4 +-
 arch/arm/src/lc823450/lc823450_cpustart.c          |   3 +-
 arch/arm/src/rp2040/rp2040_cpuidlestack.c          |   4 +-
 arch/arm/src/rp2040/rp2040_cpustart.c              |   3 +-
 arch/arm/src/sam34/sam4cm_cpuidlestack.c           |   4 +-
 arch/arm/src/sam34/sam4cm_cpustart.c               |   3 +-
 arch/avr/src/avr/up_checkstack.c                   |   4 +-
 arch/avr/src/avr/up_createstack.c                  |  34 +--
 arch/avr/src/avr/up_dumpstate.c                    |  16 +-
 arch/avr/src/avr/up_initialstate.c                 |  11 +-
 arch/avr/src/avr/up_stackframe.c                   |  21 +-
 arch/avr/src/avr/up_usestack.c                     |  14 +-
 arch/avr/src/avr32/up_createstack.c                |  30 +--
 arch/avr/src/avr32/up_dumpstate.c                  |  16 +-
 arch/avr/src/avr32/up_initialstate.c               |   5 +-
 arch/avr/src/avr32/up_stackframe.c                 |  20 +-
 arch/avr/src/avr32/up_usestack.c                   |  16 +-
 arch/hc/src/common/up_createstack.c                |  30 +--
 arch/hc/src/common/up_stackframe.c                 |  21 +-
 arch/hc/src/common/up_usestack.c                   |  18 +-
 arch/hc/src/m9s12/m9s12_assert.c                   |  10 +-
 arch/hc/src/m9s12/m9s12_initialstate.c             |   9 +-
 arch/mips/src/common/mips_createstack.c            |  30 +--
 arch/mips/src/common/mips_stackframe.c             |  20 +-
 arch/mips/src/common/mips_usestack.c               |  16 +-
 arch/mips/src/mips32/mips_dumpstate.c              |  10 +-
 arch/mips/src/mips32/mips_initialstate.c           |   5 +-
 arch/mips/src/mips32/mips_vfork.c                  |  72 ++---
 arch/mips/src/mips32/vfork.S                       |   6 +-
 arch/misoc/src/lm32/lm32_createstack.c             |  30 +--
 arch/misoc/src/lm32/lm32_dumpstate.c               |  10 +-
 arch/misoc/src/lm32/lm32_initialstate.c            |   5 +-
 arch/misoc/src/lm32/lm32_stackframe.c              |  20 +-
 arch/misoc/src/lm32/lm32_usestack.c                |  16 +-
 arch/misoc/src/minerva/minerva_createstack.c       |  30 +--
 arch/misoc/src/minerva/minerva_dumpstate.c         |  10 +-
 arch/misoc/src/minerva/minerva_initialstate.c      |   7 +-
 arch/misoc/src/minerva/minerva_stackframe.c        |  18 +-
 arch/misoc/src/minerva/minerva_usestack.c          |  16 +-
 arch/or1k/src/common/up_assert.c                   |  16 +-
 arch/or1k/src/common/up_checkstack.c               |  34 +--
 arch/or1k/src/common/up_createstack.c              |  39 +--
 arch/or1k/src/common/up_initialstate.c             |   5 +-
 arch/or1k/src/common/up_stackframe.c               |  20 +-
 arch/or1k/src/common/up_usestack.c                 |  16 +-
 arch/renesas/src/common/up_createstack.c           |  30 +--
 arch/renesas/src/common/up_stackframe.c            |  18 +-
 arch/renesas/src/common/up_usestack.c              |  16 +-
 arch/renesas/src/m16c/m16c_dumpstate.c             |  10 +-
 arch/renesas/src/m16c/m16c_initialstate.c          |   9 +-
 arch/renesas/src/rx65n/rx65n_dumpstate.c           |  10 +-
 arch/renesas/src/rx65n/rx65n_initialstate.c        |   5 +-
 arch/renesas/src/sh1/sh1_dumpstate.c               |  10 +-
 arch/renesas/src/sh1/sh1_initialstate.c            |   5 +-
 arch/risc-v/src/common/riscv_checkstack.c          |  30 +--
 arch/risc-v/src/common/riscv_createstack.c         |  35 +--
 arch/risc-v/src/common/riscv_stackframe.c          |  20 +-
 arch/risc-v/src/common/riscv_usestack.c            |  18 +-
 arch/risc-v/src/k210/k210_cpuidlestack.c           |   4 +-
 arch/risc-v/src/rv32im/riscv_assert.c              |  10 +-
 arch/risc-v/src/rv32im/riscv_initialstate.c        |   5 +-
 arch/risc-v/src/rv32im/riscv_vfork.c               |  72 ++---
 arch/risc-v/src/rv64gc/riscv_assert.c              |   8 +-
 arch/risc-v/src/rv64gc/riscv_initialstate.c        |   5 +-
 arch/sim/src/sim/up_checkstack.c                   |  27 +-
 arch/sim/src/sim/up_cpuidlestack.c                 |   6 +-
 arch/sim/src/sim/up_createstack.c                  |  39 +--
 arch/sim/src/sim/up_initialstate.c                 |   5 +-
 arch/sim/src/sim/up_releasestack.c                 |   2 +-
 arch/sim/src/sim/up_stackframe.c                   |  18 +-
 arch/sim/src/sim/up_usestack.c                     |  23 +-
 arch/sim/src/sim/up_vfork.c                        |  69 ++---
 arch/sim/src/sim/up_vfork32.S                      |   6 +-
 arch/sim/src/sim/up_vfork64.S                      |   6 +-
 arch/sim/src/sim/up_vfork_arm.S                    |   6 +-
 arch/x86/src/common/up_assert.c                    |  10 +-
 arch/x86/src/i486/up_createstack.c                 |  30 +--
 arch/x86/src/i486/up_initialstate.c                |   5 +-
 arch/x86/src/i486/up_stackframe.c                  |  20 +-
 arch/x86/src/i486/up_usestack.c                    |  16 +-
 arch/x86_64/src/common/up_assert.c                 |  11 +-
 arch/x86_64/src/intel64/up_createstack.c           |  30 +--
 arch/x86_64/src/intel64/up_initialstate.c          |  16 +-
 arch/x86_64/src/intel64/up_stackframe.c            |  20 +-
 arch/x86_64/src/intel64/up_usestack.c              |  16 +-
 arch/xtensa/src/common/xtensa_checkstack.c         |  10 +-
 arch/xtensa/src/common/xtensa_createstack.c        |  30 +--
 arch/xtensa/src/common/xtensa_dumpstate.c          |  10 +-
 arch/xtensa/src/common/xtensa_initialstate.c       |  10 +-
 arch/xtensa/src/common/xtensa_stackframe.c         |  20 +-
 arch/xtensa/src/common/xtensa_usestack.c           |  20 +-
 arch/xtensa/src/esp32/esp32_cpuidlestack.c         |  10 +-
 arch/xtensa/src/esp32/esp32_cpustart.c             |   2 +-
 arch/z16/src/common/z16_createstack.c              |  30 +--
 arch/z16/src/common/z16_initialstate.c             |   3 +-
 arch/z16/src/common/z16_stackdump.c                |  12 +-
 arch/z16/src/common/z16_stackframe.c               |  20 +-
 arch/z16/src/common/z16_usestack.c                 |  18 +-
 arch/z80/src/common/z80_createstack.c              |  30 +--
 arch/z80/src/common/z80_stackdump.c                |  12 +-
 arch/z80/src/common/z80_stackframe.c               |  18 +-
 arch/z80/src/common/z80_usestack.c                 |  16 +-
 arch/z80/src/ez80/ez80_initialstate.c              |   7 +-
 arch/z80/src/z180/z180_initialstate.c              |   6 +-
 arch/z80/src/z8/z8_initialstate.c                  |   3 +-
 arch/z80/src/z80/z80_initialstate.c                |   6 +-
 boards/arm/cxd56xx/common/src/cxd56_crashdump.c    |   3 +-
 boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c  |   5 +-
 boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c   |   5 +-
 .../renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c   |   5 +-
 .../renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c   |   5 +-
 fs/procfs/fs_procfsproc.c                          |   2 +-
 include/nuttx/arch.h                               |  33 ++-
 include/nuttx/lib/libvars.h                        |  76 ------
 include/nuttx/sched.h                              |  25 +-
 include/nuttx/tls.h                                |  48 +++-
 libs/libc/pthread/pthread_get_stackaddr_np.c       |   2 +-
 libs/libc/tls/Make.defs                            |   2 +
 .../libc/tls/task_getinfo.c                        |  44 ++-
 libs/libc/tls/tls.h                                |  34 ---
 libs/libc/unistd/lib_getoptvars.c                  |  13 +-
 sched/group/Make.defs                              |   4 -
 sched/group/group.h                                |   6 -
 sched/pthread/pthread_create.c                     |  18 +-
 sched/sched/sched_get_stackinfo.c                  |  15 +-
 sched/task/task_init.c                             |  31 +--
 sched/task/task_vfork.c                            | 299 ++++++---------------
 155 files changed, 1074 insertions(+), 1710 deletions(-)

diff --git a/Documentation/reference/os/arch.rst b/Documentation/reference/os/arch.rst
index 3b94233..eccfbae 100644
--- a/Documentation/reference/os/arch.rst
+++ b/Documentation/reference/os/arch.rst
@@ -57,8 +57,8 @@ APIs Exported by Architecture-Specific Logic to NuttX
   -  ``adj_stack_size``: Stack size after adjustment for hardware,
      processor, etc. This value is retained only for debug purposes.
   -  ``stack_alloc_ptr``: Pointer to allocated stack
-  -  ``adj_stack_ptr``: Adjusted ``stack_alloc_ptr`` for HW. The
-     initial value of the stack pointer.
+  -  ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data
+     and Arguments has been removed from the stack allocation.
 
   :param tcb: The TCB of new task.
   :param stack_size: The requested stack size. At least this much
@@ -93,8 +93,8 @@ APIs Exported by Architecture-Specific Logic to NuttX
   -  ``adj_stack_size``: Stack size after adjustment for hardware,
      processor, etc. This value is retained only for debug purposes.
   -  ``stack_alloc_ptr``: Pointer to allocated stack
-  -  ``adj_stack_ptr``: Adjusted ``stack_alloc_ptr`` for HW. The
-     initial value of the stack pointer.
+  -  ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data
+     and Arguments has been removed from the stack allocation.
 
   :param tcb: The TCB of new task.
   :param stack_size: The allocated stack size.
@@ -120,9 +120,24 @@ APIs Exported by Architecture-Specific Logic to NuttX
 
   -  ``adj_stack_size``: Stack size after removal of the stack frame
      from the stack.
-  -  ``adj_stack_ptr``: Adjusted initial stack pointer after the
-     frame has been removed from the stack. This will still be the
-     initial value of the stack pointer when the task is started.
+  -  ``stack_base_ptr``: Adjusted stack base pointer after the TLS Data
+     and Arguments has been removed from the stack allocation.
+
+  Here is the diagram after some allocation(tls, arg):
+
+                   +-------------+ <-stack_alloc_ptr(lowest)
+                   |  TLS Data   |
+                   +-------------+
+                   |  Arguments  |
+  stack_base_ptr-> +-------------+\
+                   |  Available  | +
+                   |    Stack    | |
+                |  |             | |
+                |  |             | +->adj_stack_size
+                v  |             | |
+                   |             | |
+                   |             | +
+                   +-------------+/
 
   :param tcb: The TCB of new task.
   :param frame_size: The size of the stack frame to allocate.
diff --git a/arch/arm/src/arm/arm_assert.c b/arch/arm/src/arm/arm_assert.c
index 8988035..bc1345d 100644
--- a/arch/arm/src/arm/arm_assert.c
+++ b/arch/arm/src/arm/arm_assert.c
@@ -171,7 +171,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -240,14 +240,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
 #ifdef CONFIG_ARCH_USBDUMP
diff --git a/arch/arm/src/arm/arm_initialstate.c b/arch/arm/src/arm/arm_initialstate.c
index d247838..d15d0b6 100644
--- a/arch/arm/src/arm/arm_initialstate.c
+++ b/arch/arm/src/arm/arm_initialstate.c
@@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb)
 
   /* Save the initial stack pointer */
 
-  xcp->regs[REG_SP]      = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP]      = (uint32_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/arm/src/arm/vfork.S b/arch/arm/src/arm/vfork.S
index 6de4f5f..4abdf51 100644
--- a/arch/arm/src/arm/vfork.S
+++ b/arch/arm/src/arm/vfork.S
@@ -57,16 +57,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *      This consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv6-m/arm_assert.c b/arch/arm/src/armv6-m/arm_assert.c
index 8c617a8..8db89a6 100644
--- a/arch/arm/src/armv6-m/arm_assert.c
+++ b/arch/arm/src/armv6-m/arm_assert.c
@@ -209,7 +209,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -266,14 +266,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp < ustackbase && sp >= ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
       up_stackdump(sp, ustackbase);
     }
   else
     {
       _alert("ERROR: Stack pointer is not within the allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
 #else
@@ -288,14 +288,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 #endif
 
diff --git a/arch/arm/src/armv6-m/arm_initialstate.c b/arch/arm/src/armv6-m/arm_initialstate.c
index c38a4fb..5df0fa0 100644
--- a/arch/arm/src/armv6-m/arm_initialstate.c
+++ b/arch/arm/src/armv6-m/arm_initialstate.c
@@ -64,7 +64,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -74,7 +74,8 @@ void up_initial_state(struct tcb_s *tcb)
 
   /* Save the initial stack pointer */
 
-  xcp->regs[REG_SP]      = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP]      = (uint32_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
 
   /* Save the task entry point (stripping off the thumb bit) */
 
diff --git a/arch/arm/src/armv6-m/vfork.S b/arch/arm/src/armv6-m/vfork.S
index 90e2b1f..624134d 100644
--- a/arch/arm/src/armv6-m/vfork.S
+++ b/arch/arm/src/armv6-m/vfork.S
@@ -57,16 +57,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *      This consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv7-a/arm_assert.c b/arch/arm/src/armv7-a/arm_assert.c
index b74c224..273e691 100644
--- a/arch/arm/src/armv7-a/arm_assert.c
+++ b/arch/arm/src/armv7-a/arm_assert.c
@@ -212,7 +212,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   _alert("Current sp: %08x\n", sp);
@@ -291,10 +291,10 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase - ustacksize && sp < ustackbase)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
       _alert("User Stack\n", sp);
-      up_stackdump(sp, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
 
 #ifdef CONFIG_ARCH_KERNEL_STACK
@@ -312,7 +312,7 @@ static void up_dumpstate(void)
   else
     {
       _alert("ERROR: Stack pointer is not within the allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(ustackbase, ustackbase + ustacksize);
 #ifdef CONFIG_ARCH_KERNEL_STACK
       up_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE);
 #endif
diff --git a/arch/arm/src/armv7-a/arm_cpuidlestack.c b/arch/arm/src/armv7-a/arm_cpuidlestack.c
index 0dd2885..2e9a118 100644
--- a/arch/arm/src/armv7-a/arm_cpuidlestack.c
+++ b/arch/arm/src/armv7-a/arm_cpuidlestack.c
@@ -94,8 +94,8 @@ static FAR const uint32_t *g_cpu_stackalloc[CONFIG_SMP_NCPUS] =
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - cpu:         CPU index that indicates which CPU the IDLE task is
@@ -111,7 +111,6 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size)
 {
 #if CONFIG_SMP_NCPUS > 1
   uintptr_t stack_alloc;
-  uintptr_t top_of_stack;
 
   DEBUGASSERT(cpu > 0 && cpu < CONFIG_SMP_NCPUS && tcb != NULL &&
               stack_size <= SMP_STACK_SIZE);
@@ -120,11 +119,10 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size)
 
   stack_alloc          = (uintptr_t)g_cpu_stackalloc[cpu];
   DEBUGASSERT(stack_alloc != 0 && STACK_ISALIGNED(stack_alloc));
-  top_of_stack         = stack_alloc + SMP_STACK_SIZE;
 
   tcb->adj_stack_size  = SMP_STACK_SIZE;
-  tcb->stack_alloc_ptr = (FAR uint32_t *)stack_alloc;
-  tcb->adj_stack_ptr   = (FAR uint32_t *)top_of_stack;
+  tcb->stack_alloc_ptr = (FAR void *)stack_alloc;
+  tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
 #endif
 
   return OK;
diff --git a/arch/arm/src/armv7-a/arm_initialstate.c b/arch/arm/src/armv7-a/arm_initialstate.c
index 5ce1d28..521649b 100644
--- a/arch/arm/src/armv7-a/arm_initialstate.c
+++ b/arch/arm/src/armv7-a/arm_initialstate.c
@@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb)
 
   /* Save the initial stack pointer */
 
-  xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+                                tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/arm/src/armv7-a/vfork.S b/arch/arm/src/armv7-a/vfork.S
index 1fed24d..9524c07 100644
--- a/arch/arm/src/armv7-a/vfork.S
+++ b/arch/arm/src/armv7-a/vfork.S
@@ -57,16 +57,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *      This consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv7-m/arm_assert.c b/arch/arm/src/armv7-m/arm_assert.c
index 01cfe7a..f2b7659 100644
--- a/arch/arm/src/armv7-m/arm_assert.c
+++ b/arch/arm/src/armv7-m/arm_assert.c
@@ -217,7 +217,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 7
@@ -278,14 +278,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp < ustackbase && sp >= ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      up_stackdump(sp, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
       _alert("ERROR: Stack pointer is not within the allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
 #else
@@ -303,14 +303,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within the allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within the allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
 #endif
diff --git a/arch/arm/src/armv7-m/arm_initialstate.c b/arch/arm/src/armv7-m/arm_initialstate.c
index 6420de8..90872ad 100644
--- a/arch/arm/src/armv7-m/arm_initialstate.c
+++ b/arch/arm/src/armv7-m/arm_initialstate.c
@@ -65,7 +65,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb)
 
   /* Save the initial stack pointer */
 
-  xcp->regs[REG_SP]      = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP]      = (uint32_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
 
 #ifdef CONFIG_ARMV7M_STACKCHECK
   /* Set the stack limit value */
diff --git a/arch/arm/src/armv7-m/gnu/vfork.S b/arch/arm/src/armv7-m/gnu/vfork.S
index b6b6188..b5b6dd2 100644
--- a/arch/arm/src/armv7-m/gnu/vfork.S
+++ b/arch/arm/src/armv7-m/gnu/vfork.S
@@ -59,16 +59,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *      This consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv7-m/iar/vfork.S b/arch/arm/src/armv7-m/iar/vfork.S
index 91810cb..305e747 100644
--- a/arch/arm/src/armv7-m/iar/vfork.S
+++ b/arch/arm/src/armv7-m/iar/vfork.S
@@ -60,16 +60,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *      This consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv7-r/arm_assert.c b/arch/arm/src/armv7-r/arm_assert.c
index 70cb80f..17ed679 100644
--- a/arch/arm/src/armv7-r/arm_assert.c
+++ b/arch/arm/src/armv7-r/arm_assert.c
@@ -209,7 +209,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   _alert("Current sp: %08x\n", sp);
@@ -284,10 +284,10 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase - ustacksize && sp < ustackbase)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
       _alert("User Stack\n", sp);
-      up_stackdump(sp, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
 
 #ifdef CONFIG_ARCH_KERNEL_STACK
@@ -305,7 +305,7 @@ static void up_dumpstate(void)
   else
     {
       _alert("ERROR: Stack pointer is not within the allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(ustackbase, ustackbase + ustacksize);
 #ifdef CONFIG_ARCH_KERNEL_STACK
       up_stackdump(kstackbase, kstackbase + CONFIG_ARCH_KERNEL_STACKSIZE);
 #endif
diff --git a/arch/arm/src/armv7-r/arm_initialstate.c b/arch/arm/src/armv7-r/arm_initialstate.c
index 79be124..3656bb6 100644
--- a/arch/arm/src/armv7-r/arm_initialstate.c
+++ b/arch/arm/src/armv7-r/arm_initialstate.c
@@ -62,7 +62,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -72,7 +72,8 @@ void up_initial_state(struct tcb_s *tcb)
 
   /* Save the initial stack pointer */
 
-  xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+                                tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/arm/src/armv7-r/vfork.S b/arch/arm/src/armv7-r/vfork.S
index 3d6d56c..670fdb3 100644
--- a/arch/arm/src/armv7-r/vfork.S
+++ b/arch/arm/src/armv7-r/vfork.S
@@ -57,16 +57,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *      This consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/armv8-m/arm_assert.c b/arch/arm/src/armv8-m/arm_assert.c
index 71b78f8..ebdf521 100644
--- a/arch/arm/src/armv8-m/arm_assert.c
+++ b/arch/arm/src/armv8-m/arm_assert.c
@@ -217,7 +217,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 7
@@ -278,14 +278,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp < ustackbase && sp >= ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      up_stackdump(sp, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
       _alert("ERROR: Stack pointer is not within the allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
 #else
@@ -303,14 +303,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within the allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within the allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
 #endif
diff --git a/arch/arm/src/armv8-m/arm_initialstate.c b/arch/arm/src/armv8-m/arm_initialstate.c
index a34c853..b2bbf88 100644
--- a/arch/arm/src/armv8-m/arm_initialstate.c
+++ b/arch/arm/src/armv8-m/arm_initialstate.c
@@ -65,7 +65,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb)
 
   /* Save the initial stack pointer */
 
-  xcp->regs[REG_SP]      = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP]      = (uint32_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
 
 #ifdef CONFIG_ARMV8M_STACKCHECK
   /* Set the stack limit value */
diff --git a/arch/arm/src/armv8-m/vfork.S b/arch/arm/src/armv8-m/vfork.S
index 9d04830..7f68b3b 100644
--- a/arch/arm/src/armv8-m/vfork.S
+++ b/arch/arm/src/armv8-m/vfork.S
@@ -59,16 +59,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *      This consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/arm/src/common/arm_checkstack.c b/arch/arm/src/common/arm_checkstack.c
index 7d8524d..5f9f414 100644
--- a/arch/arm/src/common/arm_checkstack.c
+++ b/arch/arm/src/common/arm_checkstack.c
@@ -31,7 +31,6 @@
 #include <debug.h>
 
 #include <nuttx/arch.h>
-#include <nuttx/tls.h>
 #include <nuttx/board.h>
 
 #include "sched/sched.h"
@@ -207,13 +206,12 @@ void arm_stack_color(FAR void *stackbase, size_t nbytes)
 
 size_t up_check_tcbstack(FAR struct tcb_s *tcb)
 {
-  return do_stackcheck((FAR void *)((uintptr_t)tcb->adj_stack_ptr -
-      tcb->adj_stack_size), tcb->adj_stack_size);
+  return do_stackcheck(tcb->stack_base_ptr, tcb->adj_stack_size);
 }
 
 ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
 {
-  return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb);
+  return tcb->adj_stack_size - up_check_tcbstack(tcb);
 }
 
 size_t up_check_stack(void)
diff --git a/arch/arm/src/common/arm_createstack.c b/arch/arm/src/common/arm_createstack.c
index dda4b1f..b14ba88 100644
--- a/arch/arm/src/common/arm_createstack.c
+++ b/arch/arm/src/common/arm_createstack.c
@@ -58,12 +58,6 @@
 #define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
 #define STACK_ALIGN_UP(a)   (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
 
-/* 32bit alignment macros */
-
-#define INT32_ALIGN_MASK    (3)
-#define INT32_ALIGN_DOWN(a) ((a) & ~INT32_ALIGN_MASK)
-#define INT32_ALIGN_UP(a)   (((a) + INT32_ALIGN_MASK) & ~INT32_ALIGN_MASK)
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -80,8 +74,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -108,28 +102,20 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  size_t alloc_size;
-  size_t tls_size;
-
-  /* Add the size of the TLS information structure and align. */
-
-  tls_size   = INT32_ALIGN_UP(sizeof(struct tls_info_s));
-  alloc_size = STACK_ALIGN_UP(stack_size + tls_size);
+  stack_size = STACK_ALIGN_UP(stack_size);
 
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
    */
 
-  DEBUGASSERT(alloc_size <= TLS_MAXSTACK);
-  if (alloc_size > TLS_MAXSTACK)
+  DEBUGASSERT(stack_size <= TLS_MAXSTACK);
+  if (stack_size > TLS_MAXSTACK)
     {
-      alloc_size = TLS_MAXSTACK;
+      stack_size = TLS_MAXSTACK;
     }
 #endif
 
-  stack_size = alloc_size - tls_size;
-
   /* Is there already a stack allocated of a different size? */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
@@ -154,16 +140,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, alloc_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, alloc_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -173,7 +157,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
           tcb->stack_alloc_ptr =
-              (uint32_t *)kmm_memalign(CONFIG_STACK_ALIGNMENT, alloc_size);
+              kmm_memalign(CONFIG_STACK_ALIGNMENT, stack_size);
         }
       else
 #endif
@@ -181,7 +165,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
           /* Use the user-space allocator if this is a task or pthread */
 
           tcb->stack_alloc_ptr =
-              (uint32_t *)kumm_memalign(CONFIG_STACK_ALIGNMENT, alloc_size);
+              kumm_memalign(CONFIG_STACK_ALIGNMENT, stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -206,19 +190,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * Items on the stack are referenced as positive word offsets from sp.
        */
 
-      /* Since both stack_alloc_ptr and alloc_size are in
+      /* Since both stack_alloc_ptr and stack_size are in
        * CONFIG_STACK_ALIGNMENT, and the stack ptr is decremented before
        * the first write, we can directly save our variables to struct
        * tcb_s.
        */
 
       tcb->adj_stack_size = stack_size;
-      tcb->adj_stack_ptr  = (FAR void *)((uintptr_t)tcb->stack_alloc_ptr +
-          alloc_size);
-
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, tls_size);
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
 
 #ifdef CONFIG_STACK_COLORATION
       /* If stack debug is enabled, then fill the stack with a
@@ -226,8 +205,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * water marks.
        */
 
-      arm_stack_color((FAR void *)((uintptr_t)tcb->adj_stack_ptr -
-          tcb->adj_stack_size), tcb->adj_stack_size);
+      arm_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 #endif /* CONFIG_STACK_COLORATION */
 
       board_autoled_on(LED_STACKCREATED);
diff --git a/arch/arm/src/common/arm_stackframe.c b/arch/arm/src/common/arm_stackframe.c
index 5fa6c36..bf9bb92 100644
--- a/arch/arm/src/common/arm_stackframe.c
+++ b/arch/arm/src/common/arm_stackframe.c
@@ -79,9 +79,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -96,6 +95,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -107,16 +108,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr    = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size  -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Reset the initial stack pointer */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/arm/src/common/arm_usestack.c b/arch/arm/src/common/arm_usestack.c
index e8f5269..dcef734 100644
--- a/arch/arm/src/common/arm_usestack.c
+++ b/arch/arm/src/common/arm_usestack.c
@@ -53,12 +53,6 @@
 #define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
 #define STACK_ALIGN_UP(a)   (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
 
-/* 32bit alignment macros */
-
-#define INT32_ALIGN_MASK    (3)
-#define INT32_ALIGN_DOWN(a) ((a) & ~INT32_ALIGN_MASK)
-#define INT32_ALIGN_UP(a)   (((a) + INT32_ALIGN_MASK) & ~INT32_ALIGN_MASK)
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -77,8 +71,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -93,16 +87,12 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t tls_size;
-
 #ifdef CONFIG_TLS_ALIGNED
   /* Make certain that the user provided stack is properly aligned */
 
   DEBUGASSERT(((uintptr_t)stack & TLS_STACK_MASK) == 0);
 #endif
 
-  tls_size = INT32_ALIGN_UP(sizeof(struct tls_info_s));
-
   /* Is there already a stack allocated? */
 
   if (tcb->stack_alloc_ptr)
@@ -127,28 +117,9 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   /* Save the new stack allocation */
 
   tcb->stack_alloc_ptr = stack;
-
-  /* Align stack top */
-
-  tcb->adj_stack_ptr =
-      (FAR void *)STACK_ALIGN_DOWN((uintptr_t)stack + stack_size);
-
-  /* Offset by tls_size */
-
-  stack = (FAR void *)((uintptr_t)stack + tls_size);
-
-  /* Is there enough room for at least TLS ? */
-
-  if ((uintptr_t)stack > (uintptr_t)tcb->adj_stack_ptr)
-    {
-      return -ENOMEM;
-    }
-
-  tcb->adj_stack_size = (uintptr_t)tcb->adj_stack_ptr - (uintptr_t)stack;
-
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, tls_size);
+  tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
+  tcb->adj_stack_size  =
+      STACK_ALIGN_DOWN((uintptr_t)stack + stack_size) - (uintptr_t)stack;
 
 #ifdef CONFIG_STACK_COLORATION
   /* If stack debug is enabled, then fill the stack with a
@@ -156,8 +127,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * water marks.
    */
 
-  arm_stack_color((FAR void *)((uintptr_t)tcb->adj_stack_ptr -
-                  tcb->adj_stack_size), tcb->adj_stack_size);
+  arm_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 #endif /* CONFIG_STACK_COLORATION */
 
   return OK;
diff --git a/arch/arm/src/common/arm_vfork.c b/arch/arm/src/common/arm_vfork.c
index 35bd20a..feb4302 100644
--- a/arch/arm/src/common/arm_vfork.c
+++ b/arch/arm/src/common/arm_vfork.c
@@ -67,16 +67,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *      This consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
@@ -100,13 +100,11 @@ pid_t up_vfork(const struct vfork_s *context)
 {
   struct tcb_s *parent = this_task();
   struct task_tcb_s *child;
-  size_t stacksize;
   uint32_t newsp;
   uint32_t newfp;
+  uint32_t newtop;
+  uint32_t stacktop;
   uint32_t stackutil;
-  size_t argsize;
-  void *argv;
-  int ret;
 
   sinfo("vfork context [%p]:\n", context);
   sinfo("  r4:%08" PRIx32 " r5:%08" PRIx32
@@ -119,7 +117,7 @@ pid_t up_vfork(const struct vfork_s *context)
 
   /* Allocate and initialize a TCB for the child task. */
 
-  child = nxtask_setup_vfork((start_t)(context->lr & ~1), &argsize);
+  child = nxtask_setup_vfork((start_t)(context->lr & ~1));
   if (!child)
     {
       serr("ERROR: nxtask_setup_vfork failed\n");
@@ -128,37 +126,18 @@ pid_t up_vfork(const struct vfork_s *context)
 
   sinfo("TCBs: Parent=%p Child=%p\n", parent, child);
 
-  /* Get the size of the parent task's stack. */
-
-  stacksize = parent->adj_stack_size;
-
-  /* Allocate the stack for the TCB */
-
-  ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize,
-                        parent->flags & TCB_FLAG_TTYPE_MASK);
-  if (ret != OK)
-    {
-      serr("ERROR: up_create_stack failed: %d\n", ret);
-      nxtask_abort_vfork(child, -ret);
-      return (pid_t)ERROR;
-    }
-
-  /* Allocate the memory and copy argument from parent task */
-
-  argv = up_stack_frame((FAR struct tcb_s *)child, argsize);
-  memcpy(argv, parent->adj_stack_ptr, argsize);
-
   /* How much of the parent's stack was utilized?  The ARM uses
    * a push-down stack so that the current stack pointer should
    * be lower than the initial, adjusted stack pointer.  The
    * stack usage should be the difference between those two.
    */
 
-  DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp);
-  stackutil = (uint32_t)parent->adj_stack_ptr - context->sp;
+  stacktop = (uint32_t)parent->stack_base_ptr +
+                       parent->adj_stack_size;
+  DEBUGASSERT(stacktop > context->sp);
+  stackutil = stacktop - context->sp;
 
-  sinfo("Parent: stacksize:%zu stackutil:%" PRId32 "\n",
-        stacksize, stackutil);
+  sinfo("Parent: stackutil:%" PRIu32 "\n", stackutil);
 
   /* Make some feeble effort to preserve the stack contents.  This is
    * feeble because the stack surely contains invalid pointers and other
@@ -167,26 +146,27 @@ pid_t up_vfork(const struct vfork_s *context)
    * effort is overkill.
    */
 
-  newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil;
+  newtop = (uint32_t)child->cmn.stack_base_ptr +
+                     child->cmn.adj_stack_size;
+  newsp = newtop - stackutil;
   memcpy((void *)newsp, (const void *)context->sp, stackutil);
 
   /* Was there a frame pointer in place before? */
 
-  if (context->fp <= (uint32_t)parent->adj_stack_ptr &&
-      context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize)
+  if (context->fp >= context->sp && context->fp < stacktop)
     {
-      uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp;
-      newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil;
+      uint32_t frameutil = stacktop - context->fp;
+      newfp = newtop - frameutil;
     }
   else
     {
       newfp = context->fp;
     }
 
-  sinfo("Parent: stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
-        parent->adj_stack_ptr, context->sp, context->fp);
-  sinfo("Child:  stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
-        child->cmn.adj_stack_ptr, newsp, newfp);
+  sinfo("Old stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
+        stacktop, context->sp, context->fp);
+  sinfo("New stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
+        newtop, newsp, newfp);
 
   /* Update the stack pointer, frame pointer, and volatile registers.  When
    * the child TCB was initialized, all of the values were set to zero.
diff --git a/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c b/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c
index 4f3f49f..0bf1f6a 100644
--- a/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c
+++ b/arch/arm/src/cxd56xx/cxd56_cpuidlestack.c
@@ -67,8 +67,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - cpu:         CPU index that indicates which CPU the IDLE task is
diff --git a/arch/arm/src/cxd56xx/cxd56_cpustart.c b/arch/arm/src/cxd56xx/cxd56_cpustart.c
index a948d9a..266a7ed 100644
--- a/arch/arm/src/cxd56xx/cxd56_cpustart.c
+++ b/arch/arm/src/cxd56xx/cxd56_cpustart.c
@@ -179,7 +179,8 @@ int up_cpu_start(int cpu)
 
   /* Copy initial stack and reset vector for APP_DSP */
 
-  putreg32((uint32_t)tcb->adj_stack_ptr, VECTOR_ISTACK);
+  putreg32((uint32_t)tcb->stack_base_ptr +
+           tcb->adj_stack_size, VECTOR_ISTACK);
   putreg32((uint32_t)appdsp_boot, VECTOR_RESETV);
 
   spin_lock(&g_appdsp_boot);
diff --git a/arch/arm/src/lc823450/lc823450_cpuidlestack.c b/arch/arm/src/lc823450/lc823450_cpuidlestack.c
index bcf4830..a163c9d 100644
--- a/arch/arm/src/lc823450/lc823450_cpuidlestack.c
+++ b/arch/arm/src/lc823450/lc823450_cpuidlestack.c
@@ -63,8 +63,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - cpu:         CPU index that indicates which CPU the IDLE task is
diff --git a/arch/arm/src/lc823450/lc823450_cpustart.c b/arch/arm/src/lc823450/lc823450_cpustart.c
index 16fcd2b..043ceae 100644
--- a/arch/arm/src/lc823450/lc823450_cpustart.c
+++ b/arch/arm/src/lc823450/lc823450_cpustart.c
@@ -167,7 +167,8 @@ int up_cpu_start(int cpu)
   putreg32(0x1, REMAP); /* remap enable */
   backup[0] = getreg32(CPU1_VECTOR_ISTACK);
   backup[1] = getreg32(CPU1_VECTOR_RESETV);
-  putreg32((uint32_t)tcb->adj_stack_ptr, CPU1_VECTOR_ISTACK);
+  putreg32((uint32_t)tcb->stack_base_ptr +
+           tcb->adj_stack_size, CPU1_VECTOR_ISTACK);
   putreg32((uint32_t)cpu1_boot, CPU1_VECTOR_RESETV);
 
   spin_lock(&g_cpu_wait[0]);
diff --git a/arch/arm/src/rp2040/rp2040_cpuidlestack.c b/arch/arm/src/rp2040/rp2040_cpuidlestack.c
index e675a2f..eacab6a 100644
--- a/arch/arm/src/rp2040/rp2040_cpuidlestack.c
+++ b/arch/arm/src/rp2040/rp2040_cpuidlestack.c
@@ -67,8 +67,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - cpu:         CPU index that indicates which CPU the IDLE task is
diff --git a/arch/arm/src/rp2040/rp2040_cpustart.c b/arch/arm/src/rp2040/rp2040_cpustart.c
index 05e1fdd..08c16c2 100644
--- a/arch/arm/src/rp2040/rp2040_cpustart.c
+++ b/arch/arm/src/rp2040/rp2040_cpustart.c
@@ -222,7 +222,8 @@ int up_cpu_start(int cpu)
   core1_boot_msg[0] = 0;
   core1_boot_msg[1] = 1;
   core1_boot_msg[2] = getreg32(ARMV6M_SYSCON_VECTAB);
-  core1_boot_msg[3] = (uint32_t)tcb->adj_stack_ptr;
+  core1_boot_msg[3] = (uint32_t)tcb->stack_base_ptr +
+                                tcb->adj_stack_size;
   core1_boot_msg[4] = (uint32_t)core1_boot;
 
   do
diff --git a/arch/arm/src/sam34/sam4cm_cpuidlestack.c b/arch/arm/src/sam34/sam4cm_cpuidlestack.c
index 815dd40..98a1b4a 100644
--- a/arch/arm/src/sam34/sam4cm_cpuidlestack.c
+++ b/arch/arm/src/sam34/sam4cm_cpuidlestack.c
@@ -97,8 +97,8 @@ void up_idle(void)
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - cpu:         CPU index that indicates which CPU the IDLE task is
diff --git a/arch/arm/src/sam34/sam4cm_cpustart.c b/arch/arm/src/sam34/sam4cm_cpustart.c
index 5df6802..a653dfc 100644
--- a/arch/arm/src/sam34/sam4cm_cpustart.c
+++ b/arch/arm/src/sam34/sam4cm_cpustart.c
@@ -204,7 +204,8 @@ int up_cpu_start(int cpu)
 
   /* Copy initial vectors for CPU1 */
 
-  putreg32((uint32_t)tcb->adj_stack_ptr, CPU1_VECTOR_ISTACK);
+  putreg32((uint32_t)tcb->stack_base_ptr +
+           tcb->adj_stack_size, CPU1_VECTOR_ISTACK);
   putreg32((uint32_t)cpu1_boot, CPU1_VECTOR_RESETV);
 
   spin_lock(&g_cpu1_boot);
diff --git a/arch/avr/src/avr/up_checkstack.c b/arch/avr/src/avr/up_checkstack.c
index 5175782..5003c8a 100644
--- a/arch/avr/src/avr/up_checkstack.c
+++ b/arch/avr/src/avr/up_checkstack.c
@@ -146,12 +146,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
 
 size_t up_check_tcbstack(FAR struct tcb_s *tcb)
 {
-  return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size);
+  return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size);
 }
 
 ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
 {
-  return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb);
+  return tcb->adj_stack_size - up_check_tcbstack(tcb);
 }
 
 size_t up_check_stack(void)
diff --git a/arch/avr/src/avr/up_createstack.c b/arch/avr/src/avr/up_createstack.c
index a6c606c..8ac95e7 100644
--- a/arch/avr/src/avr/up_createstack.c
+++ b/arch/avr/src/avr/up_createstack.c
@@ -64,8 +64,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -86,10 +86,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -129,16 +125,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -147,14 +141,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -172,8 +166,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
-
       /* Yes.. If stack debug is enabled, then fill the stack with a
        * recognizable value that we can use later to test for high
        * water marks.
@@ -183,23 +175,11 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
       memset(tcb->stack_alloc_ptr, STACK_COLOR, stack_size);
 #endif
 
-      /* The AVR uses a push-down stack:  the stack grows toward lower
-       * addresses in memory.  The stack pointer register, points to the
-       * lowest, valid work address (the "top" of the stack).  Items on the
-       * stack are referenced as positive word offsets from sp.
-       */
-
-      top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
-
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (FAR void *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = stack_size;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
 #if defined(ARCH_HAVE_LEDS)
       board_autoled_on(LED_STACKCREATED);
 #endif
diff --git a/arch/avr/src/avr/up_dumpstate.c b/arch/avr/src/avr/up_dumpstate.c
index b84a95f..dcf0030 100644
--- a/arch/avr/src/avr/up_dumpstate.c
+++ b/arch/avr/src/avr/up_dumpstate.c
@@ -139,7 +139,7 @@ void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint16_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint16_t)rtcb->stack_base_ptr;
   ustacksize = (uint16_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -196,14 +196,14 @@ void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp < ustackbase && sp >= ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      up_stackdump(sp, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
       _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 #else
   _alert("sp:         %04x\n", sp);
@@ -217,14 +217,14 @@ void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 #endif
 }
diff --git a/arch/avr/src/avr/up_initialstate.c b/arch/avr/src/avr/up_initialstate.c
index fb8a2a8..5135dc7 100644
--- a/arch/avr/src/avr/up_initialstate.c
+++ b/arch/avr/src/avr/up_initialstate.c
@@ -55,6 +55,7 @@
 void up_initial_state(struct tcb_s *tcb)
 {
   struct xcptcontext *xcp = &tcb->xcp;
+  uintptr_t sp;
 
   /* Initialize the idle thread stack */
 
@@ -62,7 +63,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -72,10 +73,12 @@ void up_initial_state(struct tcb_s *tcb)
 
   memset(xcp, 0, sizeof(struct xcptcontext));
 
-  /* Set the initial stack pointer to the "base" of the allocated stack */
+  /* Set the initial stack pointer to the top of the allocated stack */
 
-  xcp->regs[REG_SPH]   = (uint8_t)((uint16_t)tcb->adj_stack_ptr >> 8);
-  xcp->regs[REG_SPL]   = (uint8_t)((uint16_t)tcb->adj_stack_ptr & 0xff);
+  sp                   = (uintptr_t)tcb->stack_base_ptr +
+                                    tcb->adj_stack_size;
+  xcp->regs[REG_SPH]   = (uint8_t)(sp >> 8);
+  xcp->regs[REG_SPL]   = (uint8_t)(sp & 0xff);
 
   /* Save the task entry point */
 
diff --git a/arch/avr/src/avr/up_stackframe.c b/arch/avr/src/avr/up_stackframe.c
index 860350e..687f105 100644
--- a/arch/avr/src/avr/up_stackframe.c
+++ b/arch/avr/src/avr/up_stackframe.c
@@ -77,9 +77,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -94,6 +93,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -105,17 +106,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr     = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size   -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Set the initial stack pointer to the "base" of the allocated stack */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_SPH] = (uint8_t)((uint16_t)tcb->adj_stack_ptr >> 8);
-  tcb->xcp.regs[REG_SPL] = (uint8_t)((uint16_t)tcb->adj_stack_ptr & 0xff);
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/avr/src/avr/up_usestack.c b/arch/avr/src/avr/up_usestack.c
index bdde37c..8e796e9 100644
--- a/arch/avr/src/avr/up_usestack.c
+++ b/arch/avr/src/avr/up_usestack.c
@@ -54,8 +54,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -70,8 +70,6 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
-
 #ifdef CONFIG_TLS_ALIGNED
   /* Make certain that the user provided stack is properly aligned */
 
@@ -105,16 +103,10 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * positive word offsets from sp.
    */
 
-  top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
-
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (FAR void *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = stack_size;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/avr/src/avr32/up_createstack.c b/arch/avr/src/avr32/up_createstack.c
index 6ef611e..daa48d6 100644
--- a/arch/avr/src/avr32/up_createstack.c
+++ b/arch/avr/src/avr32/up_createstack.c
@@ -64,8 +64,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -91,10 +91,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -134,16 +130,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -152,14 +146,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -177,7 +171,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* Yes.. If stack debug is enabled, then fill the stack with a
@@ -195,24 +189,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * the stack are referenced as positive word offsets from sp.
        */
 
-      top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
       /* The AVR32 stack must be aligned at word (4 byte) boundaries. If
        * necessary top_of_stack must be rounded down to the next boundary
        */
 
       top_of_stack &= ~3;
-      size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (FAR void *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/avr/src/avr32/up_dumpstate.c b/arch/avr/src/avr32/up_dumpstate.c
index 98f2960..04b800a 100644
--- a/arch/avr/src/avr32/up_dumpstate.c
+++ b/arch/avr/src/avr32/up_dumpstate.c
@@ -109,7 +109,7 @@ void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -166,14 +166,14 @@ void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp < ustackbase && sp >= ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      up_stackdump(sp, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
       _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 #else
   _alert("sp:         %08x\n", sp);
@@ -187,14 +187,14 @@ void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 #endif
 }
diff --git a/arch/avr/src/avr32/up_initialstate.c b/arch/avr/src/avr32/up_initialstate.c
index ee33df6..eea5c8c 100644
--- a/arch/avr/src/avr32/up_initialstate.c
+++ b/arch/avr/src/avr32/up_initialstate.c
@@ -60,7 +60,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -85,7 +85,8 @@ void up_initial_state(struct tcb_s *tcb)
 
   /* Set the initial stack pointer to the top of the allocated stack */
 
-  xcp->regs[REG_SP]      = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP]      = (uint32_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/avr/src/avr32/up_stackframe.c b/arch/avr/src/avr32/up_stackframe.c
index 67ea2cd..b01ea52 100644
--- a/arch/avr/src/avr32/up_stackframe.c
+++ b/arch/avr/src/avr32/up_stackframe.c
@@ -79,9 +79,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -96,6 +95,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -107,16 +108,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr    = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size  -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Reset the initial stack pointer */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/avr/src/avr32/up_usestack.c b/arch/avr/src/avr32/up_usestack.c
index ef3b1d4..c253226 100644
--- a/arch/avr/src/avr32/up_usestack.c
+++ b/arch/avr/src/avr32/up_usestack.c
@@ -53,8 +53,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -69,7 +69,7 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -106,7 +106,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * referenced as positive word offsets from sp.
    */
 
-  top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The AVR32 stack must be aligned at word (4 byte)
    * boundaries. If necessary top_of_stack must be rounded
@@ -114,16 +114,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    */
 
   top_of_stack &= ~3;
-  size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (FAR void *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/hc/src/common/up_createstack.c b/arch/hc/src/common/up_createstack.c
index d0f89b9..3fe163f 100644
--- a/arch/hc/src/common/up_createstack.c
+++ b/arch/hc/src/common/up_createstack.c
@@ -61,8 +61,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -88,10 +88,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -131,16 +127,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -149,14 +143,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -174,7 +168,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* Yes.. If stack debug is enabled, then fill the stack with a
@@ -193,7 +187,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * stack address.
        */
 
-      top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
       /* The CPU12 stack should be aligned at half-word (2 byte)
        * boundaries. If necessary top_of_stack must be rounded
@@ -201,17 +195,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       top_of_stack &= ~1;
-      size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->alloc_stack_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/hc/src/common/up_stackframe.c b/arch/hc/src/common/up_stackframe.c
index d8fd239..b57de5c 100644
--- a/arch/hc/src/common/up_stackframe.c
+++ b/arch/hc/src/common/up_stackframe.c
@@ -79,9 +79,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -96,6 +95,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -107,17 +108,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr    = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size  -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Reset the initial stack pointer */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_SPH] = (uint16_t)tcb->adj_stack_ptr >> 8;
-  tcb->xcp.regs[REG_SPL] = (uint16_t)tcb->adj_stack_ptr & 0xff;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/hc/src/common/up_usestack.c b/arch/hc/src/common/up_usestack.c
index 87523e9..d7173b8 100644
--- a/arch/hc/src/common/up_usestack.c
+++ b/arch/hc/src/common/up_usestack.c
@@ -52,8 +52,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -66,9 +66,9 @@
  *
  ****************************************************************************/
 
-int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
+int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -105,7 +105,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * stack address.
    */
 
-  top_of_stack = (size_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The CPU12 stack should be aligned at half-word (2 byte)
    * boundaries. If necessary top_of_stack must be rounded
@@ -113,16 +113,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    */
 
   top_of_stack &= ~1;
-  size_of_stack = top_of_stack - (size_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/hc/src/m9s12/m9s12_assert.c b/arch/hc/src/m9s12/m9s12_assert.c
index 8e778f6..c14faa8 100644
--- a/arch/hc/src/m9s12/m9s12_assert.c
+++ b/arch/hc/src/m9s12/m9s12_assert.c
@@ -184,7 +184,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint16_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint16_t)rtcb->stack_base_ptr;
   ustacksize = (uint16_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -238,14 +238,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
 #ifdef CONFIG_ARCH_USBDUMP
diff --git a/arch/hc/src/m9s12/m9s12_initialstate.c b/arch/hc/src/m9s12/m9s12_initialstate.c
index 25f8313..7cb6d69 100644
--- a/arch/hc/src/m9s12/m9s12_initialstate.c
+++ b/arch/hc/src/m9s12/m9s12_initialstate.c
@@ -52,6 +52,7 @@
 void up_initial_state(struct tcb_s *tcb)
 {
   struct xcptcontext *xcp = &tcb->xcp;
+  uintptr_t sp;
 
   /* Initialize the idle thread stack */
 
@@ -59,7 +60,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -69,8 +70,10 @@ void up_initial_state(struct tcb_s *tcb)
 
   /* Save the initial stack pointer */
 
-  xcp->regs[REG_SPH]      = (uint16_t)tcb->adj_stack_ptr >> 8;
-  xcp->regs[REG_SPL]      = (uint16_t)tcb->adj_stack_ptr & 0xff;
+  sp                      = (uintptr_t)tcb->stack_base_ptr +
+                                       tcb->adj_stack_size;
+  xcp->regs[REG_SPH]      = sp >> 8;
+  xcp->regs[REG_SPL]      = sp & 0xff;
 
   /* Save the task entry point */
 
diff --git a/arch/mips/src/common/mips_createstack.c b/arch/mips/src/common/mips_createstack.c
index f3c9ea5..b906a0d 100644
--- a/arch/mips/src/common/mips_createstack.c
+++ b/arch/mips/src/common/mips_createstack.c
@@ -82,8 +82,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -109,10 +109,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -151,16 +147,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -169,14 +163,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -194,7 +188,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* Yes.. If stack debug is enabled, then fill the stack with a
@@ -212,7 +206,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * the stack are referenced as positive word offsets from sp.
        */
 
-      top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
       /* The MIPS stack must be aligned at word (4 byte) boundaries; for
        * floating point use, the stack must be aligned to 8-byte addresses.
@@ -228,17 +222,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * The size need not be aligned.
        */
 
-      size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/mips/src/common/mips_stackframe.c b/arch/mips/src/common/mips_stackframe.c
index df6287a..3fdfcc4 100644
--- a/arch/mips/src/common/mips_stackframe.c
+++ b/arch/mips/src/common/mips_stackframe.c
@@ -82,9 +82,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -99,6 +98,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -110,16 +111,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr    = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size  -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Reset the initial stack pointer */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/mips/src/common/mips_usestack.c b/arch/mips/src/common/mips_usestack.c
index 531e7c5..e6e4e60 100644
--- a/arch/mips/src/common/mips_usestack.c
+++ b/arch/mips/src/common/mips_usestack.c
@@ -73,8 +73,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -89,7 +89,7 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -125,7 +125,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * as positive word offsets from sp.
    */
 
-  top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The MIPS stack must be aligned at word (4 byte) or double word (8 byte)
    * boundaries. If necessary top_of_stack must be rounded down to the
@@ -140,16 +140,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * The size need not be aligned.
    */
 
-  size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/mips/src/mips32/mips_dumpstate.c b/arch/mips/src/mips32/mips_dumpstate.c
index 0268698..b850e85 100644
--- a/arch/mips/src/mips32/mips_dumpstate.c
+++ b/arch/mips/src/mips32/mips_dumpstate.c
@@ -139,7 +139,7 @@ void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -193,14 +193,14 @@ void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 }
 
diff --git a/arch/mips/src/mips32/mips_initialstate.c b/arch/mips/src/mips32/mips_initialstate.c
index 65fc6c2..0a3d0c2 100644
--- a/arch/mips/src/mips32/mips_initialstate.c
+++ b/arch/mips/src/mips32/mips_initialstate.c
@@ -64,7 +64,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -78,7 +78,8 @@ void up_initial_state(struct tcb_s *tcb)
    * only the start function would do that and we have control over that one.
    */
 
-  xcp->regs[REG_SP]      = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP]      = (uint32_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/mips/src/mips32/mips_vfork.c b/arch/mips/src/mips32/mips_vfork.c
index 536b78d..65aa693 100644
--- a/arch/mips/src/mips32/mips_vfork.c
+++ b/arch/mips/src/mips32/mips_vfork.c
@@ -69,16 +69,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *      this consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
@@ -102,15 +102,13 @@ pid_t up_vfork(const struct vfork_s *context)
 {
   struct tcb_s *parent = this_task();
   struct task_tcb_s *child;
-  size_t stacksize;
   uint32_t newsp;
 #ifdef CONFIG_MIPS32_FRAMEPOINTER
   uint32_t newfp;
 #endif
+  uint32_t newtop;
+  uint32_t stacktop;
   uint32_t stackutil;
-  size_t argsize;
-  void *argv;
-  int ret;
 
   sinfo("s0:%08" PRIx32 " s1:%08" PRIx32 " s2:%08" PRIx32
         " s3:%08" PRIx32 " s4:%08" PRIx32 "\n",
@@ -141,7 +139,7 @@ pid_t up_vfork(const struct vfork_s *context)
 
   /* Allocate and initialize a TCB for the child task. */
 
-  child = nxtask_setup_vfork((start_t)context->ra, &argsize);
+  child = nxtask_setup_vfork((start_t)context->ra);
   if (!child)
     {
       sinfo("nxtask_setup_vfork failed\n");
@@ -150,39 +148,18 @@ pid_t up_vfork(const struct vfork_s *context)
 
   sinfo("Parent=%p Child=%p\n", parent, child);
 
-  /* Get the size of the parent task's stack.  Due to alignment operations,
-   * the adjusted stack size may be smaller than the stack size originally
-   * requested.
-   */
-
-  stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1;
-
-  /* Allocate the stack for the TCB */
-
-  ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize,
-                        parent->flags & TCB_FLAG_TTYPE_MASK);
-  if (ret != OK)
-    {
-      serr("ERROR: up_create_stack failed: %d\n", ret);
-      nxtask_abort_vfork(child, -ret);
-      return (pid_t)ERROR;
-    }
-
-  /* Allocate the memory and copy argument from parent task */
-
-  argv = up_stack_frame((FAR struct tcb_s *)child, argsize);
-  memcpy(argv, parent->adj_stack_ptr, argsize);
-
   /* How much of the parent's stack was utilized?  The MIPS uses
    * a push-down stack so that the current stack pointer should
    * be lower than the initial, adjusted stack pointer.  The
    * stack usage should be the difference between those two.
    */
 
-  DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp);
-  stackutil = (uint32_t)parent->adj_stack_ptr - context->sp;
+  stacktop = (uint32_t)parent->stack_base_ptr +
+                       parent->adj_stack_size;
+  DEBUGASSERT(stacktop > context->sp);
+  stackutil = stacktop - context->sp;
 
-  sinfo("stacksize:%zd stackutil:%" PRId32 "\n", stacksize, stackutil);
+  sinfo("Parent: stackutil:%" PRIu32 "\n", stackutil);
 
   /* Make some feeble effort to perserve the stack contents.  This is
    * feeble because the stack surely contains invalid pointers and other
@@ -191,32 +168,33 @@ pid_t up_vfork(const struct vfork_s *context)
    * effort is overkill.
    */
 
-  newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil;
+  newtop = (uintptr_t)child->cmn.stack_base_ptr +
+                      child->cmn.adj_stack_size;
+  newsp = newtop - stackutil;
   memcpy((void *)newsp, (const void *)context->sp, stackutil);
 
   /* Was there a frame pointer in place before? */
 
 #ifdef CONFIG_MIPS32_FRAMEPOINTER
-  if (context->fp <= (uint32_t)parent->adj_stack_ptr &&
-      context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize)
+  if (context->fp >= context->sp && context->fp < stacktop)
     {
-      uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp;
-      newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil;
+      uint32_t frameutil = stacktop - context->fp;
+      newfp = newtop - frameutil;
     }
   else
     {
       newfp = context->fp;
     }
 
-  sinfo("Old stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
-        parent->adj_stack_ptr, context->sp, context->fp);
-  sinfo("New stack base:%p SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
-        child->cmn.adj_stack_ptr, newsp, newfp);
+  sinfo("Old stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
+        stacktop, context->sp, context->fp);
+  sinfo("New stack top:%08" PRIx32 " SP:%08" PRIx32 " FP:%08" PRIx32 "\n",
+        newtop, newsp, newfp);
 #else
-  sinfo("Old stack base:%p SP:%08" PRIx32 "\n",
-        parent->adj_stack_ptr, context->sp);
-  sinfo("New stack base:%p SP:%08" PRIx32 "\n",
-        child->cmn.adj_stack_ptr, newsp);
+  sinfo("Old stack top:%08" PRIx32 " SP:%08" PRIx32 "\n",
+        stacktop, context->sp);
+  sinfo("New stack top:%08" PRIx32 " SP:%08" PRIx32 "\n",
+        newtop, newsp);
 #endif
 
   /* Update the stack pointer, frame pointer, global pointer and saved
diff --git a/arch/mips/src/mips32/vfork.S b/arch/mips/src/mips32/vfork.S
index aa7f96c..4dfa94a 100644
--- a/arch/mips/src/mips32/vfork.S
+++ b/arch/mips/src/mips32/vfork.S
@@ -56,16 +56,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.  This
  *      consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/misoc/src/lm32/lm32_createstack.c b/arch/misoc/src/lm32/lm32_createstack.c
index 8e354ab..e00f5ab 100644
--- a/arch/misoc/src/lm32/lm32_createstack.c
+++ b/arch/misoc/src/lm32/lm32_createstack.c
@@ -97,8 +97,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -124,10 +124,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -166,16 +162,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -184,14 +178,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -209,7 +203,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* Yes.. If stack debug is enabled, then fill the stack with a
@@ -227,7 +221,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * the stack are referenced as positive word offsets from sp.
        */
 
-      top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
       /* The LM32 stack must be aligned at word (4 byte) boundaries; for
        * floating point use, the stack must be aligned to 8-byte addresses.
@@ -236,17 +230,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
-      size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (FAR uint32_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/misoc/src/lm32/lm32_dumpstate.c b/arch/misoc/src/lm32/lm32_dumpstate.c
index fa44403..6dded3d 100644
--- a/arch/misoc/src/lm32/lm32_dumpstate.c
+++ b/arch/misoc/src/lm32/lm32_dumpstate.c
@@ -141,7 +141,7 @@ void lm32_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -195,14 +195,14 @@ void lm32_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 }
 
diff --git a/arch/misoc/src/lm32/lm32_initialstate.c b/arch/misoc/src/lm32/lm32_initialstate.c
index 45024e6..525cd7a 100644
--- a/arch/misoc/src/lm32/lm32_initialstate.c
+++ b/arch/misoc/src/lm32/lm32_initialstate.c
@@ -77,7 +77,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -91,7 +91,8 @@ void up_initial_state(struct tcb_s *tcb)
    * only the start function would do that and we have control over that one
    */
 
-  xcp->regs[REG_SP]      = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP]      = (uint32_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/misoc/src/lm32/lm32_stackframe.c b/arch/misoc/src/lm32/lm32_stackframe.c
index c436f5a..624c6fe 100644
--- a/arch/misoc/src/lm32/lm32_stackframe.c
+++ b/arch/misoc/src/lm32/lm32_stackframe.c
@@ -90,9 +90,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -107,6 +106,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -118,16 +119,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr    = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size  -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Reset the initial stack pointer */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/misoc/src/lm32/lm32_usestack.c b/arch/misoc/src/lm32/lm32_usestack.c
index 13aa6af..c55a100 100644
--- a/arch/misoc/src/lm32/lm32_usestack.c
+++ b/arch/misoc/src/lm32/lm32_usestack.c
@@ -51,8 +51,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -67,7 +67,7 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -103,23 +103,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * positive word offsets from sp.
    */
 
-  top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The i486 stack must be aligned at word (4 byte) boundaries. If necessary
    * top_of_stack must be rounded down to the next boundary
    */
 
   top_of_stack &= ~3;
-  size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/misoc/src/minerva/minerva_createstack.c b/arch/misoc/src/minerva/minerva_createstack.c
index a46539a..186e564 100644
--- a/arch/misoc/src/minerva/minerva_createstack.c
+++ b/arch/misoc/src/minerva/minerva_createstack.c
@@ -89,8 +89,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -116,10 +116,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -159,16 +155,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -177,14 +171,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -202,7 +196,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* Yes.. If stack debug is enabled, then fill the stack with a
@@ -220,7 +214,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * the stack are referenced as positive word offsets from sp.
        */
 
-      top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
       /* The MINERVA stack must be aligned at word (4 byte) boundaries; for
        * floating point use, the stack must be aligned to 8-byte addresses.
@@ -229,17 +223,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
-      size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr = (FAR uint32_t *) top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/misoc/src/minerva/minerva_dumpstate.c b/arch/misoc/src/minerva/minerva_dumpstate.c
index c3de5f9..4e5331c 100644
--- a/arch/misoc/src/minerva/minerva_dumpstate.c
+++ b/arch/misoc/src/minerva/minerva_dumpstate.c
@@ -148,7 +148,7 @@ void minerva_dumpstate(void)
    * == NULL)
    */
 
-  ustackbase = (uint32_t) rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t) rtcb->stack_base_ptr;
   ustacksize = (uint32_t) rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -200,14 +200,14 @@ void minerva_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 }
 
diff --git a/arch/misoc/src/minerva/minerva_initialstate.c b/arch/misoc/src/minerva/minerva_initialstate.c
index 7bcd29b..21953eb 100644
--- a/arch/misoc/src/minerva/minerva_initialstate.c
+++ b/arch/misoc/src/minerva/minerva_initialstate.c
@@ -81,7 +81,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -95,11 +95,12 @@ void up_initial_state(struct tcb_s *tcb)
    * only the start function would do that and we have control over that one.
    */
 
-  xcp->regs[REG_SP] = (uint32_t) tcb->adj_stack_ptr;
+  xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+                                tcb->adj_stack_size;
 
   /* Save the task entry point */
 
-  xcp->regs[REG_CSR_MEPC] = (uint32_t) tcb->start;
+  xcp->regs[REG_CSR_MEPC] = (uint32_t)tcb->start;
 
   xcp->regs[REG_CSR_MSTATUS] = CSR_MSTATUS_MPIE;
 
diff --git a/arch/misoc/src/minerva/minerva_stackframe.c b/arch/misoc/src/minerva/minerva_stackframe.c
index ba8b5cb..3dc536e 100644
--- a/arch/misoc/src/minerva/minerva_stackframe.c
+++ b/arch/misoc/src/minerva/minerva_stackframe.c
@@ -90,9 +90,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -107,6 +106,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -118,16 +119,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
+
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr   = (uint8_t *)tcb->adj_stack_ptr - frame_size;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
   tcb->adj_stack_size -= frame_size;
 
-  /* Reset the initial stack pointer */
-
-  tcb->xcp.regs[REG_SP] = (uint32_t) tcb->adj_stack_ptr;
-
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/misoc/src/minerva/minerva_usestack.c b/arch/misoc/src/minerva/minerva_usestack.c
index fbb2de1..3d1c6d7 100644
--- a/arch/misoc/src/minerva/minerva_usestack.c
+++ b/arch/misoc/src/minerva/minerva_usestack.c
@@ -51,8 +51,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -67,7 +67,7 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -103,23 +103,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * positive word offsets from sp.
    */
 
-  top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The i486 stack must be aligned at word (4 byte) boundaries. If necessary
    * top_of_stack must be rounded down to the next boundary
    */
 
   top_of_stack &= ~3;
-  size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/or1k/src/common/up_assert.c b/arch/or1k/src/common/up_assert.c
index 6df9c2c..fe9ff7a 100644
--- a/arch/or1k/src/common/up_assert.c
+++ b/arch/or1k/src/common/up_assert.c
@@ -209,7 +209,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -266,14 +266,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp < ustackbase && sp >= ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      up_stackdump(sp, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
       _alert("ERROR: Stack pointer is not within the allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
 #else
@@ -288,14 +288,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 #endif
 
diff --git a/arch/or1k/src/common/up_checkstack.c b/arch/or1k/src/common/up_checkstack.c
index c9fb7ec..2562ae5 100644
--- a/arch/or1k/src/common/up_checkstack.c
+++ b/arch/or1k/src/common/up_checkstack.c
@@ -31,7 +31,6 @@
 #include <debug.h>
 
 #include <nuttx/arch.h>
-#include <nuttx/tls.h>
 #include <nuttx/board.h>
 
 #include "sched/sched.h"
@@ -43,14 +42,12 @@
  * Private Function Prototypes
  ****************************************************************************/
 
-static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack);
+static size_t do_stackcheck(uintptr_t alloc, size_t size);
 
 /****************************************************************************
- * Private Functions
+ * Private Function
  ****************************************************************************/
 
-static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack);
-
 /****************************************************************************
  * Name: do_stackcheck
  *
@@ -68,7 +65,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack);
  *
  ****************************************************************************/
 
-static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack)
+static size_t do_stackcheck(uintptr_t alloc, size_t size)
 {
   FAR uintptr_t start;
   FAR uintptr_t end;
@@ -82,21 +79,8 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack)
 
   /* Get aligned addresses of the top and bottom of the stack */
 
-  if (!int_stack)
-    {
-      /* Skip over the TLS data structure at the bottom of the stack */
-
-#ifdef CONFIG_TLS_ALIGNED
-      DEBUGASSERT((alloc & TLS_STACK_MASK) == 0);
-#endif
-      start = alloc + sizeof(struct tls_info_s);
-    }
-  else
-    {
-      start = alloc & ~3;
-    }
-
-  end   = (alloc + size + 3) & ~3;
+  start = (alloc + 3) & ~3;
+  end   = (alloc + size) & ~3;
 
   /* Get the adjusted size based on the top and bottom of the stack */
 
@@ -133,13 +117,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack)
 
 size_t up_check_tcbstack(FAR struct tcb_s *tcb)
 {
-  return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size,
-                       false);
+  return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size);
 }
 
 ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
 {
-  return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb);
+  return tcb->adj_stack_size - up_check_tcbstack(tcb);
 }
 
 size_t up_check_stack(void)
@@ -156,8 +139,7 @@ ssize_t up_check_stack_remain(void)
 size_t up_check_intstack(void)
 {
   return do_stackcheck((uintptr_t)&g_intstackalloc,
-                       (CONFIG_ARCH_INTERRUPTSTACK & ~3),
-                       true);
+                       (CONFIG_ARCH_INTERRUPTSTACK & ~3));
 }
 
 size_t up_check_intstack_remain(void)
diff --git a/arch/or1k/src/common/up_createstack.c b/arch/or1k/src/common/up_createstack.c
index 2202947..9a440ce 100644
--- a/arch/or1k/src/common/up_createstack.c
+++ b/arch/or1k/src/common/up_createstack.c
@@ -74,8 +74,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -102,10 +102,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -145,16 +141,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -163,14 +157,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -188,36 +182,25 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-#if defined(CONFIG_STACK_COLORATION)
-      uintptr_t stack_base;
-#endif
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
-      top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
       top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
-      size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
 #ifdef CONFIG_STACK_COLORATION
       /* If stack debug is enabled, then fill the stack with a
        * recognizable value that we can use later to test for high
        * water marks.
        */
 
-      stack_base = (uintptr_t)tcb->stack_alloc_ptr +
-                   sizeof(struct tls_info_s);
-      stack_size = tcb->adj_stack_size -
-                   sizeof(struct tls_info_s);
-      up_stack_color((FAR void *)stack_base, stack_size);
+      up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 
 #endif /* CONFIG_STACK_COLORATION */
 
diff --git a/arch/or1k/src/common/up_initialstate.c b/arch/or1k/src/common/up_initialstate.c
index a884c78..28c9827 100644
--- a/arch/or1k/src/common/up_initialstate.c
+++ b/arch/or1k/src/common/up_initialstate.c
@@ -79,7 +79,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -87,7 +87,8 @@ void up_initial_state(struct tcb_s *tcb)
 
   memset(xcp, 0, sizeof(struct xcptcontext));
 
-  xcp->regs[REG_R1]      = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_R1]      = (uint32_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
   xcp->regs[REG_PC]      = (uint32_t)tcb->start;
 
   mfspr(SPR_SYS_SR, sr);
diff --git a/arch/or1k/src/common/up_stackframe.c b/arch/or1k/src/common/up_stackframe.c
index 98903ec..c6e8485 100644
--- a/arch/or1k/src/common/up_stackframe.c
+++ b/arch/or1k/src/common/up_stackframe.c
@@ -71,9 +71,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -88,6 +87,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -99,16 +100,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr    = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size  -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Reset the initial stack pointer */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_R1] = (uint32_t)tcb->adj_stack_ptr;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/or1k/src/common/up_usestack.c b/arch/or1k/src/common/up_usestack.c
index 1ccdaf2..9866c4c 100644
--- a/arch/or1k/src/common/up_usestack.c
+++ b/arch/or1k/src/common/up_usestack.c
@@ -51,8 +51,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -67,7 +67,7 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -103,23 +103,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * positive word offsets from sp.
    */
 
-  top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The i486 stack must be aligned at word (4 byte) boundaries. If necessary
    * top_of_stack must be rounded down to the next boundary
    */
 
   top_of_stack &= ~3;
-  size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/renesas/src/common/up_createstack.c b/arch/renesas/src/common/up_createstack.c
index dbdfb3d..c504371 100644
--- a/arch/renesas/src/common/up_createstack.c
+++ b/arch/renesas/src/common/up_createstack.c
@@ -61,8 +61,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -88,10 +88,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -131,16 +127,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -149,14 +143,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -174,7 +168,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* Yes.. If stack debug is enabled, then fill the stack with a
@@ -193,7 +187,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * referenced as positive word offsets from sp.
        */
 
-      top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
       /* The SH stack must be aligned at word (4 byte)
        * boundaries. If necessary top_of_stack must be rounded
@@ -201,17 +195,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       top_of_stack &= ~3;
-      size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/renesas/src/common/up_stackframe.c b/arch/renesas/src/common/up_stackframe.c
index 7ad96a7..ebc7ead 100644
--- a/arch/renesas/src/common/up_stackframe.c
+++ b/arch/renesas/src/common/up_stackframe.c
@@ -78,9 +78,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -95,6 +94,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -106,16 +107,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
+
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr   = (uint8_t *)tcb->adj_stack_ptr - frame_size;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
   tcb->adj_stack_size -= frame_size;
 
-  /* Reset the initial state */
-
-  up_initial_state(tcb);
-
   /* And return a pointer to allocated memory */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/renesas/src/common/up_usestack.c b/arch/renesas/src/common/up_usestack.c
index bd7a120..b447b3e 100644
--- a/arch/renesas/src/common/up_usestack.c
+++ b/arch/renesas/src/common/up_usestack.c
@@ -53,8 +53,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -69,7 +69,7 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -105,23 +105,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * stack are referenced as positive word offsets from sp.
    */
 
-  top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The SH stack must be aligned at word (4 byte) boundaries. If necessary
    * top_of_stack must be rounded down to the next boundary
    */
 
   top_of_stack &= ~3;
-  size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr = (FAR void *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/renesas/src/m16c/m16c_dumpstate.c b/arch/renesas/src/m16c/m16c_dumpstate.c
index 52dbcf1..a5c8ff5 100644
--- a/arch/renesas/src/m16c/m16c_dumpstate.c
+++ b/arch/renesas/src/m16c/m16c_dumpstate.c
@@ -136,7 +136,7 @@ void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint16_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint16_t)rtcb->stack_base_ptr;
   ustacksize = (uint16_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory.
@@ -197,14 +197,14 @@ void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      m16c_stackdump(ustackbase - ustacksize, ustackbase);
+      m16c_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      m16c_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      m16c_stackdump(ustackbase, ustackbase + ustacksize);
     }
 }
 
diff --git a/arch/renesas/src/m16c/m16c_initialstate.c b/arch/renesas/src/m16c/m16c_initialstate.c
index 9a5f9e5..5c88e0f 100644
--- a/arch/renesas/src/m16c/m16c_initialstate.c
+++ b/arch/renesas/src/m16c/m16c_initialstate.c
@@ -54,6 +54,7 @@ void up_initial_state(FAR struct tcb_s *tcb)
 {
   FAR struct xcptcontext *xcp  = &tcb->xcp;
   FAR uint8_t            *regs = xcp->regs;
+  uintptr_t               sp;
 
   /* Initialize the idle thread stack */
 
@@ -61,7 +62,7 @@ void up_initial_state(FAR struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -90,7 +91,9 @@ void up_initial_state(FAR struct tcb_s *tcb)
 
   /* Offset 18-20: User stack pointer */
 
+  sp      = (uintptr_t)tcb->stack_base_ptr +
+                       tcb->adj_stack_size;
   regs    = &xcp->regs[REG_SP];
-  *regs++ = (uint32_t)tcb->adj_stack_ptr >> 8;  /* Bits 8-15 of SP */
-  *regs   = (uint32_t)tcb->adj_stack_ptr;       /* Bits 0-7 of SP */
+  *regs++ = sp >> 8; /* Bits 8-15 of SP */
+  *regs   = sp;      /* Bits 0-7 of SP */
 }
diff --git a/arch/renesas/src/rx65n/rx65n_dumpstate.c b/arch/renesas/src/rx65n/rx65n_dumpstate.c
index 0fa573b..ebf9905 100644
--- a/arch/renesas/src/rx65n/rx65n_dumpstate.c
+++ b/arch/renesas/src/rx65n/rx65n_dumpstate.c
@@ -143,7 +143,7 @@ void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint16_t)rtcb->adj_stack_size;
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
@@ -194,14 +194,14 @@ void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      rx65n_stackdump(ustackbase - ustacksize, ustackbase);
+      rx65n_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      rx65n_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      rx65n_stackdump(ustackbase, ustackbase + ustacksize);
     }
 }
 
diff --git a/arch/renesas/src/rx65n/rx65n_initialstate.c b/arch/renesas/src/rx65n/rx65n_initialstate.c
index e371367..c6808b1 100644
--- a/arch/renesas/src/rx65n/rx65n_initialstate.c
+++ b/arch/renesas/src/rx65n/rx65n_initialstate.c
@@ -67,7 +67,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -75,7 +75,8 @@ void up_initial_state(struct tcb_s *tcb)
 
   memset(xcp, 0, sizeof(struct xcptcontext));
 
-  xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+                                tcb->adj_stack_size;
   xcp->regs[REG_PC] = (uint32_t)tcb->start;
 
   /* Enable or disable interrupts, based on user configuration */
diff --git a/arch/renesas/src/sh1/sh1_dumpstate.c b/arch/renesas/src/sh1/sh1_dumpstate.c
index 5988d25..215100f 100644
--- a/arch/renesas/src/sh1/sh1_dumpstate.c
+++ b/arch/renesas/src/sh1/sh1_dumpstate.c
@@ -123,7 +123,7 @@ void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -177,14 +177,14 @@ void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      sh1_stackdump(ustackbase - ustacksize, ustackbase);
+      sh1_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      sh1_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      sh1_stackdump(ustackbase, ustackbase + ustacksize);
     }
 }
 
diff --git a/arch/renesas/src/sh1/sh1_initialstate.c b/arch/renesas/src/sh1/sh1_initialstate.c
index e097f6d..d52e09a 100644
--- a/arch/renesas/src/sh1/sh1_initialstate.c
+++ b/arch/renesas/src/sh1/sh1_initialstate.c
@@ -79,7 +79,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -89,7 +89,8 @@ void up_initial_state(struct tcb_s *tcb)
 
   /* Set the initial stack pointer to the "top" of the allocated stack */
 
-  xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP] = (uint32_t)tcb->stack_base_ptr +
+                                tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/risc-v/src/common/riscv_checkstack.c b/arch/risc-v/src/common/riscv_checkstack.c
index eec04ae..ca35375 100644
--- a/arch/risc-v/src/common/riscv_checkstack.c
+++ b/arch/risc-v/src/common/riscv_checkstack.c
@@ -31,7 +31,6 @@
 #include <debug.h>
 
 #include <nuttx/arch.h>
-#include <nuttx/tls.h>
 #include <nuttx/board.h>
 
 #include "sched/sched.h"
@@ -43,7 +42,7 @@
  * Private Function Prototypes
  ****************************************************************************/
 
-static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack);
+static size_t do_stackcheck(uintptr_t alloc, size_t size);
 
 /****************************************************************************
  * Name: do_stackcheck
@@ -62,7 +61,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack);
  *
  ****************************************************************************/
 
-static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack)
+static size_t do_stackcheck(uintptr_t alloc, size_t size)
 {
   FAR uintptr_t start;
   FAR uintptr_t end;
@@ -76,21 +75,8 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack)
 
   /* Get aligned addresses of the top and bottom of the stack */
 
-  if (!int_stack)
-    {
-      /* Skip over the TLS data structure at the bottom of the stack */
-
-#ifdef CONFIG_TLS_ALIGNED
-      DEBUGASSERT((alloc & TLS_STACK_MASK) == 0);
-#endif
-      start = alloc + sizeof(struct tls_info_s);
-    }
-  else
-    {
-      start = alloc & ~3;
-    }
-
-  end   = (alloc + size + 3) & ~3;
+  start = (alloc + 3) & ~3;
+  end   = (alloc + size) & ~3;
 
   /* Get the adjusted size based on the top and bottom of the stack */
 
@@ -172,13 +158,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack)
 
 size_t up_check_tcbstack(FAR struct tcb_s *tcb)
 {
-  return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size,
-                       false);
+  return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size);
 }
 
 ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
 {
-  return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb);
+  return tcb->adj_stack_size - up_check_tcbstack(tcb);
 }
 
 size_t up_check_stack(void)
@@ -195,8 +180,7 @@ ssize_t up_check_stack_remain(void)
 size_t up_check_intstack(void)
 {
   return do_stackcheck((uintptr_t)&g_intstackalloc,
-                       (CONFIG_ARCH_INTERRUPTSTACK & ~3),
-                       true);
+                       (CONFIG_ARCH_INTERRUPTSTACK & ~3));
 }
 
 size_t up_check_intstack_remain(void)
diff --git a/arch/risc-v/src/common/riscv_createstack.c b/arch/risc-v/src/common/riscv_createstack.c
index 4754520..2086b85 100644
--- a/arch/risc-v/src/common/riscv_createstack.c
+++ b/arch/risc-v/src/common/riscv_createstack.c
@@ -83,8 +83,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -110,10 +110,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -153,16 +149,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -171,14 +165,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -196,10 +190,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-#if defined(CONFIG_STACK_COLORATION)
-      uintptr_t stack_base;
-#endif
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* RISCV uses a push-down stack:  the stack grows toward lower
@@ -221,24 +212,16 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (FAR uint32_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
 #ifdef CONFIG_STACK_COLORATION
       /* If stack debug is enabled, then fill the stack with a
        * recognizable value that we can use later to test for high
        * water marks.
        */
 
-      stack_base = (uintptr_t)tcb->stack_alloc_ptr +
-                   sizeof(struct tls_info_s);
-      stack_size = tcb->adj_stack_size -
-                   sizeof(struct tls_info_s);
-      riscv_stack_color((FAR void *)stack_base, stack_size);
+      riscv_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 
 #endif /* CONFIG_STACK_COLORATION */
 
diff --git a/arch/risc-v/src/common/riscv_stackframe.c b/arch/risc-v/src/common/riscv_stackframe.c
index 193adcb..5b4b7f3 100644
--- a/arch/risc-v/src/common/riscv_stackframe.c
+++ b/arch/risc-v/src/common/riscv_stackframe.c
@@ -83,9 +83,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -100,6 +99,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -111,16 +112,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr    = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size  -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Reset the initial stack pointer */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_SP] = (uintptr_t)tcb->adj_stack_ptr;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/risc-v/src/common/riscv_usestack.c b/arch/risc-v/src/common/riscv_usestack.c
index 7cdb9fb..d6debd5 100644
--- a/arch/risc-v/src/common/riscv_usestack.c
+++ b/arch/risc-v/src/common/riscv_usestack.c
@@ -74,8 +74,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -88,9 +88,9 @@
  *
  ****************************************************************************/
 
-int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
+int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -130,22 +130,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uintptr_t *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
 #if defined(CONFIG_STACK_COLORATION)
   /* If stack debug is enabled, then fill the stack with a
    * recognizable value that we can use later to test for high
    * water marks.
    */
 
-  riscv_stack_color((FAR void *)((uintptr_t)tcb->stack_alloc_ptr +
-                 sizeof(struct tls_info_s)),
-                 size_of_stack - sizeof(struct tls_info_s));
+  riscv_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 #endif
 
   return OK;
diff --git a/arch/risc-v/src/k210/k210_cpuidlestack.c b/arch/risc-v/src/k210/k210_cpuidlestack.c
index 9872182..1c59e18 100644
--- a/arch/risc-v/src/k210/k210_cpuidlestack.c
+++ b/arch/risc-v/src/k210/k210_cpuidlestack.c
@@ -67,8 +67,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - cpu:         CPU index that indicates which CPU the IDLE task is
diff --git a/arch/risc-v/src/rv32im/riscv_assert.c b/arch/risc-v/src/rv32im/riscv_assert.c
index 5b55b6d..a541082 100644
--- a/arch/risc-v/src/rv32im/riscv_assert.c
+++ b/arch/risc-v/src/rv32im/riscv_assert.c
@@ -184,7 +184,7 @@ static void riscv_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -238,14 +238,14 @@ static void riscv_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      riscv_stackdump(ustackbase - ustacksize, ustackbase);
+      riscv_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      riscv_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      riscv_stackdump(ustackbase, ustackbase + ustacksize);
     }
 }
 
diff --git a/arch/risc-v/src/rv32im/riscv_initialstate.c b/arch/risc-v/src/rv32im/riscv_initialstate.c
index 6338b30..4106125 100644
--- a/arch/risc-v/src/rv32im/riscv_initialstate.c
+++ b/arch/risc-v/src/rv32im/riscv_initialstate.c
@@ -63,7 +63,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -77,7 +77,8 @@ void up_initial_state(struct tcb_s *tcb)
    * only the start function would do that and we have control over that one
    */
 
-  xcp->regs[REG_SP]      = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP]      = (uint32_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/risc-v/src/rv32im/riscv_vfork.c b/arch/risc-v/src/rv32im/riscv_vfork.c
index 3ed4b8d..bb390fa 100644
--- a/arch/risc-v/src/rv32im/riscv_vfork.c
+++ b/arch/risc-v/src/rv32im/riscv_vfork.c
@@ -68,16 +68,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *     This consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
@@ -105,15 +105,13 @@ pid_t up_vfork(const struct vfork_s *context)
 {
   struct tcb_s *parent = this_task();
   struct task_tcb_s *child;
-  size_t stacksize;
   uint32_t newsp;
 #ifdef CONFIG_RISCV_FRAMEPOINTER
   uint32_t newfp;
 #endif
+  uint32_t newtop;
+  uint32_t stacktop;
   uint32_t stackutil;
-  size_t argsize;
-  void *argv;
-  int ret;
 
   sinfo("s0:%08x s1:%08x s2:%08x s3:%08x s4:%08x\n",
         context->s0, context->s1, context->s2, context->s3, context->s4);
@@ -141,7 +139,7 @@ pid_t up_vfork(const struct vfork_s *context)
 
   /* Allocate and initialize a TCB for the child task. */
 
-  child = nxtask_setup_vfork((start_t)context->ra, &argsize);
+  child = nxtask_setup_vfork((start_t)context->ra);
   if (!child)
     {
       sinfo("nxtask_setup_vfork failed\n");
@@ -150,39 +148,18 @@ pid_t up_vfork(const struct vfork_s *context)
 
   sinfo("Parent=%p Child=%p\n", parent, child);
 
-  /* Get the size of the parent task's stack.  Due to alignment operations,
-   * the adjusted stack size may be smaller than the stack size originally
-   * requested.
-   */
-
-  stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1;
-
-  /* Allocate the stack for the TCB */
-
-  ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize,
-                        parent->flags & TCB_FLAG_TTYPE_MASK);
-  if (ret != OK)
-    {
-      serr("ERROR: up_create_stack failed: %d\n", ret);
-      nxtask_abort_vfork(child, -ret);
-      return (pid_t)ERROR;
-    }
-
-  /* Allocate the memory and copy argument from parent task */
-
-  argv = up_stack_frame((FAR struct tcb_s *)child, argsize);
-  memcpy(argv, parent->adj_stack_ptr, argsize);
-
   /* How much of the parent's stack was utilized?  The RISC-V uses
    * a push-down stack so that the current stack pointer should
    * be lower than the initial, adjusted stack pointer.  The
    * stack usage should be the difference between those two.
    */
 
-  DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp);
-  stackutil = (uint32_t)parent->adj_stack_ptr - context->sp;
+  stacktop = (uint32_t)parent->stack_base_ptr +
+                       parent->adj_stack_size;
+  DEBUGASSERT(stacktop > context->sp);
+  stackutil = stacktop - context->sp;
 
-  sinfo("stacksize:%d stackutil:%d\n", stacksize, stackutil);
+  sinfo("Parent: stackutil:%" PRIu32 "\n", stackutil);
 
   /* Make some feeble effort to preserve the stack contents.  This is
    * feeble because the stack surely contains invalid pointers and other
@@ -191,32 +168,33 @@ pid_t up_vfork(const struct vfork_s *context)
    * effort is overkill.
    */
 
-  newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil;
+  newtop = (uint32_t)child->cmn.stack_base_ptr +
+                     child->cmn.adj_stack_size;
+  newsp = newtop - stackutil;
   memcpy((void *)newsp, (const void *)context->sp, stackutil);
 
   /* Was there a frame pointer in place before? */
 
 #ifdef CONFIG_RISCV_FRAMEPOINTER
-  if (context->fp <= (uint32_t)parent->adj_stack_ptr &&
-      context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize)
+  if (context->fp >= context->sp && context->fp < stacktop)
     {
-      uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp;
-      newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil;
+      uint32_t frameutil = stacktop - context->fp;
+      newfp = newtop - frameutil;
     }
   else
     {
       newfp = context->fp;
     }
 
-  sinfo("Old stack base:%08x SP:%08x FP:%08x\n",
-        parent->adj_stack_ptr, context->sp, context->fp);
-  sinfo("New stack base:%08x SP:%08x FP:%08x\n",
-        child->cmn.adj_stack_ptr, newsp, newfp);
+  sinfo("Old stack top:%08x SP:%08x FP:%08x\n",
+        stacktop, context->sp, context->fp);
+  sinfo("New stack top:%08x SP:%08x FP:%08x\n",
+        newtop, newsp, newfp);
 #else
-  sinfo("Old stack base:%08x SP:%08x\n",
-        parent->adj_stack_ptr, context->sp);
-  sinfo("New stack base:%08x SP:%08x\n",
-        child->cmn.adj_stack_ptr, newsp);
+  sinfo("Old stack top:%08x SP:%08x\n",
+        stacktop, context->sp);
+  sinfo("New stack top:%08x SP:%08x\n",
+        newtop, newsp);
 #endif
 
   /* Update the stack pointer, frame pointer, global pointer and saved
diff --git a/arch/risc-v/src/rv64gc/riscv_assert.c b/arch/risc-v/src/rv64gc/riscv_assert.c
index 1ba121b..d7a9b80 100644
--- a/arch/risc-v/src/rv64gc/riscv_assert.c
+++ b/arch/risc-v/src/rv64gc/riscv_assert.c
@@ -195,7 +195,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uintptr_t)rtcb->adj_stack_ptr;
+  ustackbase = (uintptr_t)rtcb->stack_base_ptr;
   ustacksize = (uintptr_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -247,14 +247,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
       _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
 }
 
diff --git a/arch/risc-v/src/rv64gc/riscv_initialstate.c b/arch/risc-v/src/rv64gc/riscv_initialstate.c
index afd13f6..d20b187 100644
--- a/arch/risc-v/src/rv64gc/riscv_initialstate.c
+++ b/arch/risc-v/src/rv64gc/riscv_initialstate.c
@@ -63,7 +63,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -77,7 +77,8 @@ void up_initial_state(struct tcb_s *tcb)
    * only the start function would do that and we have control over that one
    */
 
-  xcp->regs[REG_SP]      = (uintptr_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP]      = (uintptr_t)tcb->stack_base_ptr +
+                                      tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/sim/src/sim/up_checkstack.c b/arch/sim/src/sim/up_checkstack.c
index 8d276e9..1cd6165 100644
--- a/arch/sim/src/sim/up_checkstack.c
+++ b/arch/sim/src/sim/up_checkstack.c
@@ -46,7 +46,6 @@
 #include <debug.h>
 
 #include <nuttx/arch.h>
-#include <nuttx/tls.h>
 #include <nuttx/board.h>
 
 #include "sched/sched.h"
@@ -56,7 +55,7 @@
  * Private Function Prototypes
  ****************************************************************************/
 
-static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack);
+static size_t do_stackcheck(uintptr_t alloc, size_t size);
 
 /****************************************************************************
  * Name: do_stackcheck
@@ -75,7 +74,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack);
  *
  ****************************************************************************/
 
-static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack)
+static size_t do_stackcheck(uintptr_t alloc, size_t size)
 {
   FAR uintptr_t start;
   FAR uintptr_t end;
@@ -89,21 +88,8 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack)
 
   /* Get aligned addresses of the top and bottom of the stack */
 
-  if (!int_stack)
-    {
-      /* Skip over the TLS data structure at the bottom of the stack */
-
-#ifdef CONFIG_TLS_ALIGNED
-      DEBUGASSERT((alloc & TLS_STACK_MASK) == 0);
-#endif
-      start = alloc + sizeof(struct tls_info_s);
-    }
-  else
-    {
-      start = alloc & ~3;
-    }
-
-  end   = (alloc + size + 3) & ~3;
+  start = (alloc + 3) & ~3;
+  end   = (alloc + size) & ~3;
 
   /* Get the adjusted size based on the top and bottom of the stack */
 
@@ -185,13 +171,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size, bool int_stack)
 
 size_t up_check_tcbstack(FAR struct tcb_s *tcb)
 {
-  return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size,
-                       false);
+  return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size);
 }
 
 ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
 {
-  return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb);
+  return tcb->adj_stack_size - up_check_tcbstack(tcb);
 }
 
 size_t up_check_stack(void)
diff --git a/arch/sim/src/sim/up_cpuidlestack.c b/arch/sim/src/sim/up_cpuidlestack.c
index e878f2c..ce9e7c1 100644
--- a/arch/sim/src/sim/up_cpuidlestack.c
+++ b/arch/sim/src/sim/up_cpuidlestack.c
@@ -63,8 +63,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - cpu:         CPU index that indicates which CPU the IDLE task is
@@ -82,6 +82,6 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size)
 
   tcb->adj_stack_size  = 0;
   tcb->stack_alloc_ptr = NULL;
-  tcb->adj_stack_ptr   = NULL;
+  tcb->stack_base_ptr   = NULL;
   return OK;
 }
diff --git a/arch/sim/src/sim/up_createstack.c b/arch/sim/src/sim/up_createstack.c
index 20b6d2a..dcfd0d2 100644
--- a/arch/sim/src/sim/up_createstack.c
+++ b/arch/sim/src/sim/up_createstack.c
@@ -66,8 +66,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -91,10 +91,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
   FAR uint8_t *stack_alloc_ptr;
   int ret = ERROR;
 
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -109,43 +105,25 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   /* Move up to next even word boundary if necessary */
 
-  size_t adj_stack_size  = STACK_ALIGN_UP(stack_size);
+  size_t adj_stack_size = STACK_ALIGN_UP(stack_size);
 
   /* Allocate the memory for the stack */
 
 #ifdef CONFIG_TLS_ALIGNED
-  stack_alloc_ptr = (FAR uint8_t *)kumm_memalign(TLS_STACK_ALIGN,
-                                                 adj_stack_size);
+  stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, adj_stack_size);
 #else
-  stack_alloc_ptr = (FAR uint8_t *)kumm_malloc(adj_stack_size);
+  stack_alloc_ptr = kumm_malloc(adj_stack_size);
 #endif
 
   /* Was the allocation successful? */
 
   if (stack_alloc_ptr)
     {
-#if defined(CONFIG_STACK_COLORATION)
-      uintptr_t stack_base;
-#endif
-
-      /* This is the address of the last aligned word in the allocation.
-       * NOTE that stack_alloc_ptr + adj_stack_size may lie one byte
-       * outside of the stack.  This is okay for an initial state; the
-       * first pushed values will be within the stack allocation.
-       */
-
-      uintptr_t adj_stack_addr =
-        STACK_ALIGN_DOWN((uintptr_t)stack_alloc_ptr + adj_stack_size);
-
       /* Save the values in the TCB */
 
       tcb->adj_stack_size  = adj_stack_size;
       tcb->stack_alloc_ptr = stack_alloc_ptr;
-      tcb->adj_stack_ptr   = (FAR void *)adj_stack_addr;
-
-      /* Initialize the TLS data structure */
-
-      memset(stack_alloc_ptr, 0, sizeof(struct tls_info_s));
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
 
 #ifdef CONFIG_STACK_COLORATION
       /* If stack debug is enabled, then fill the stack with a
@@ -153,10 +131,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * water marks.
        */
 
-      stack_base = (uintptr_t)tcb->stack_alloc_ptr +
-                   sizeof(struct tls_info_s);
-      stack_size = tcb->adj_stack_size - sizeof(struct tls_info_s);
-      up_stack_color((FAR void *)stack_base, stack_size);
+      up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 
 #endif /* CONFIG_STACK_COLORATION */
 
diff --git a/arch/sim/src/sim/up_initialstate.c b/arch/sim/src/sim/up_initialstate.c
index 0a4a94c..bca7c25 100644
--- a/arch/sim/src/sim/up_initialstate.c
+++ b/arch/sim/src/sim/up_initialstate.c
@@ -55,11 +55,12 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(sim_getsp() -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)sim_getsp();
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
   memset(&tcb->xcp, 0, sizeof(struct xcptcontext));
-  tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr - sizeof(xcpt_reg_t);
+  tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
   tcb->xcp.regs[JB_PC] = (xcpt_reg_t)tcb->start;
 }
diff --git a/arch/sim/src/sim/up_releasestack.c b/arch/sim/src/sim/up_releasestack.c
index a9e33c2..179b699 100644
--- a/arch/sim/src/sim/up_releasestack.c
+++ b/arch/sim/src/sim/up_releasestack.c
@@ -74,5 +74,5 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 
   dtcb->stack_alloc_ptr = NULL;
   dtcb->adj_stack_size  = 0;
-  dtcb->adj_stack_ptr   = NULL;
+  dtcb->stack_base_ptr   = NULL;
 }
diff --git a/arch/sim/src/sim/up_stackframe.c b/arch/sim/src/sim/up_stackframe.c
index 8c50d03..5aae8bf 100644
--- a/arch/sim/src/sim/up_stackframe.c
+++ b/arch/sim/src/sim/up_stackframe.c
@@ -69,9 +69,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -86,6 +85,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -97,16 +98,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
+
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr   = (uint8_t *)tcb->adj_stack_ptr - frame_size;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
   tcb->adj_stack_size -= frame_size;
 
-  /* Reset the initial state */
-
-  tcb->xcp.regs[JB_SP] = (xcpt_reg_t)tcb->adj_stack_ptr - sizeof(xcpt_reg_t);
-
   /* And return a pointer to the allocated memory */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/sim/src/sim/up_usestack.c b/arch/sim/src/sim/up_usestack.c
index d8ca91a..41952a0 100644
--- a/arch/sim/src/sim/up_usestack.c
+++ b/arch/sim/src/sim/up_usestack.c
@@ -67,8 +67,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -83,7 +83,6 @@
 
 int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
 {
-  uintptr_t adj_stack_addr;
   size_t adj_stack_size;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -97,23 +96,11 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
 
   adj_stack_size = STACK_ALIGN_DOWN(stack_size);
 
-  /* This is the address of the last word in the allocation.
-   * NOTE that stack_alloc_ptr + adj_stack_size may lie one byte
-   * outside of the stack.  This is okay for an initial state; the
-   * first pushed values will be within the stack allocation.
-   */
-
-  adj_stack_addr = STACK_ALIGN_DOWN((uintptr_t)stack + adj_stack_size);
-
   /* Save the values in the TCB */
 
   tcb->adj_stack_size  = adj_stack_size;
   tcb->stack_alloc_ptr = stack;
-  tcb->adj_stack_ptr   = (FAR void *)adj_stack_addr;
-
-  /* Initialize the TLS data structure */
-
-  memset(stack, 0, sizeof(struct tls_info_s));
+  tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
 
 #if defined(CONFIG_STACK_COLORATION)
   /* If stack debug is enabled, then fill the stack with a
@@ -121,9 +108,7 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
    * water marks.
    */
 
-  up_stack_color((FAR void *)((uintptr_t)tcb->stack_alloc_ptr +
-                 sizeof(struct tls_info_s)),
-                 adj_stack_size - sizeof(struct tls_info_s));
+  up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 #endif
 
   return OK;
diff --git a/arch/sim/src/sim/up_vfork.c b/arch/sim/src/sim/up_vfork.c
index 116bad2..daa4d7c 100644
--- a/arch/sim/src/sim/up_vfork.c
+++ b/arch/sim/src/sim/up_vfork.c
@@ -56,16 +56,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.
  *      This consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
@@ -86,13 +86,11 @@ pid_t up_vfork(const xcpt_reg_t *context)
 {
   struct tcb_s *parent = this_task();
   struct task_tcb_s *child;
-  size_t stacksize;
   xcpt_reg_t newsp;
   xcpt_reg_t newfp;
+  xcpt_reg_t newtop;
+  xcpt_reg_t stacktop;
   xcpt_reg_t stackutil;
-  size_t argsize;
-  void *argv;
-  int ret;
 
   sinfo("vfork context [%p]:\n", context);
   sinfo("  frame pointer:%08" PRIxPTR " sp:%08" PRIxPTR " pc:%08" PRIxPTR ""
@@ -100,7 +98,7 @@ pid_t up_vfork(const xcpt_reg_t *context)
 
   /* Allocate and initialize a TCB for the child task. */
 
-  child = nxtask_setup_vfork((start_t)(context[JB_PC]), &argsize);
+  child = nxtask_setup_vfork((start_t)context[JB_PC]);
   if (!child)
     {
       serr("ERROR: nxtask_setup_vfork failed\n");
@@ -109,38 +107,18 @@ pid_t up_vfork(const xcpt_reg_t *context)
 
   sinfo("TCBs: Parent=%p Child=%p\n", parent, child);
 
-  /* Get the size of the parent task's stack. */
-
-  stacksize = parent->adj_stack_size;
-
-  /* Allocate the stack for the TCB */
-
-  ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize,
-                        parent->flags & TCB_FLAG_TTYPE_MASK);
-  if (ret != OK)
-    {
-      serr("ERROR: up_create_stack failed: %d\n", ret);
-      nxtask_abort_vfork(child, -ret);
-      return (pid_t)ERROR;
-    }
-
-  /* Allocate the memory and copy argument from parent task */
-
-  argv = up_stack_frame((FAR struct tcb_s *)child, argsize);
-
-  memcpy(argv, parent->adj_stack_ptr, argsize);
-
   /* How much of the parent's stack was utilized?  The ARM uses
    * a push-down stack so that the current stack pointer should
    * be lower than the initial, adjusted stack pointer.  The
    * stack usage should be the difference between those two.
    */
 
-  DEBUGASSERT((xcpt_reg_t)parent->adj_stack_ptr > context[JB_SP]);
-  stackutil = (xcpt_reg_t)parent->adj_stack_ptr - context[JB_SP];
+  stacktop = (xcpt_reg_t)parent->stack_base_ptr +
+                         parent->adj_stack_size;
+  DEBUGASSERT(stacktop > context[JB_SP]);
+  stackutil = stacktop - context[JB_SP];
 
-  sinfo("Parent: stacksize:%zu stackutil:%" PRIdPTR "\n",
-        stacksize, stackutil);
+  sinfo("Parent: stackutil:%" PRIuPTR "\n", stackutil);
 
   /* Make some feeble effort to preserve the stack contents.  This is
    * feeble because the stack surely contains invalid pointers and other
@@ -149,28 +127,27 @@ pid_t up_vfork(const xcpt_reg_t *context)
    * effort is overkill.
    */
 
-  newsp = (xcpt_reg_t)child->cmn.adj_stack_ptr - stackutil;
+  newtop = (xcpt_reg_t)child->cmn.stack_base_ptr +
+                       child->cmn.adj_stack_size;
+  newsp = newtop - stackutil;
   memcpy((void *)newsp, (const void *)context[JB_SP], stackutil);
 
   /* Was there a frame pointer in place before? */
 
-  if (context[JB_FP] <= (xcpt_reg_t)parent->adj_stack_ptr &&
-      context[JB_FP] >= (xcpt_reg_t)parent->adj_stack_ptr -
-                              stacksize)
+  if (context[JB_FP] >= context[JB_SP] && context[JB_FP] < stacktop)
     {
-      xcpt_reg_t frameutil = (xcpt_reg_t)parent->adj_stack_ptr -
-                                context[JB_FP];
-      newfp = (xcpt_reg_t)child->cmn.adj_stack_ptr - frameutil;
+      xcpt_reg_t frameutil = stacktop - context[JB_FP];
+      newfp = newtop - frameutil;
     }
   else
     {
       newfp = context[JB_FP];
     }
 
-  sinfo("Parent: stack base:%p SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n",
-        parent->adj_stack_ptr, context[JB_SP], context[JB_FP]);
-  sinfo("Child:  stack base:%p SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n",
-        child->cmn.adj_stack_ptr, newsp, newfp);
+  sinfo("Old stack top:%08" PRIxPTR " SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n",
+        stacktop, context[JB_SP], context[JB_FP]);
+  sinfo("New stack top:%08" PRIxPTR " SP:%08" PRIxPTR " FP:%08" PRIxPTR "\n",
+        newtop, newsp, newfp);
 
   /* Update the stack pointer, frame pointer, and volatile registers.  When
    * the child TCB was initialized, all of the values were set to zero.
@@ -179,8 +156,8 @@ pid_t up_vfork(const xcpt_reg_t *context)
    * child thread.
    */
 
-  memcpy(child->cmn.xcp.regs, context, sizeof(xcpt_reg_t) *
-         XCPTCONTEXT_REGS);
+  memcpy(child->cmn.xcp.regs, context,
+         sizeof(xcpt_reg_t) * XCPTCONTEXT_REGS);
   child->cmn.xcp.regs[JB_FP] = newfp; /* Frame pointer */
   child->cmn.xcp.regs[JB_SP] = newsp; /* Stack pointer */
 
diff --git a/arch/sim/src/sim/up_vfork32.S b/arch/sim/src/sim/up_vfork32.S
index 8dad26b..223a023 100644
--- a/arch/sim/src/sim/up_vfork32.S
+++ b/arch/sim/src/sim/up_vfork32.S
@@ -63,16 +63,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.  This
  *      consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/sim/src/sim/up_vfork64.S b/arch/sim/src/sim/up_vfork64.S
index fa76ac1..48da703 100644
--- a/arch/sim/src/sim/up_vfork64.S
+++ b/arch/sim/src/sim/up_vfork64.S
@@ -63,16 +63,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.  This
  *      consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/sim/src/sim/up_vfork_arm.S b/arch/sim/src/sim/up_vfork_arm.S
index b75870c..a60faff 100644
--- a/arch/sim/src/sim/up_vfork_arm.S
+++ b/arch/sim/src/sim/up_vfork_arm.S
@@ -55,16 +55,16 @@
  *
  *   1) User code calls vfork().  vfork() collects context information and
  *      transfers control up up_vfork().
- *   2) up_vfork()and calls nxtask_setup_vfork().
+ *   2) up_vfork() and calls nxtask_setup_vfork().
  *   3) nxtask_setup_vfork() allocates and configures the child task's TCB.  This
  *      consists of:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
diff --git a/arch/x86/src/common/up_assert.c b/arch/x86/src/common/up_assert.c
index 2f090d1..b7abe09 100644
--- a/arch/x86/src/common/up_assert.c
+++ b/arch/x86/src/common/up_assert.c
@@ -145,7 +145,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -199,14 +199,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      up_stackdump(ustackbase - ustacksize, ustackbase);
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
 #ifdef CONFIG_ARCH_USBDUMP
diff --git a/arch/x86/src/i486/up_createstack.c b/arch/x86/src/i486/up_createstack.c
index 31b2372..ed4a22b 100644
--- a/arch/x86/src/i486/up_createstack.c
+++ b/arch/x86/src/i486/up_createstack.c
@@ -63,8 +63,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -90,10 +90,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -133,16 +129,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -151,14 +145,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -176,7 +170,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* Yes.. If stack debug is enabled, then fill the stack with a
@@ -194,24 +188,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * the stack are referenced as positive word offsets from sp.
        */
 
-      top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
       /* The i486 stack must be aligned at word (4 byte) boundaries. If
        * necessary top_of_stack must be rounded down to the next boundary
        */
 
       top_of_stack &= ~3;
-      size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/x86/src/i486/up_initialstate.c b/arch/x86/src/i486/up_initialstate.c
index 254bf9f..fe40db4 100644
--- a/arch/x86/src/i486/up_initialstate.c
+++ b/arch/x86/src/i486/up_initialstate.c
@@ -60,7 +60,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -73,7 +73,8 @@ void up_initial_state(struct tcb_s *tcb)
    * that depends on if a priority change is required or not.
    */
 
-  xcp->regs[REG_SP]      = (uint32_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_SP]      = (uint32_t)tcb->stack_base_ptr +
+                                     tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/x86/src/i486/up_stackframe.c b/arch/x86/src/i486/up_stackframe.c
index e1b1d36..ebd5b00 100644
--- a/arch/x86/src/i486/up_stackframe.c
+++ b/arch/x86/src/i486/up_stackframe.c
@@ -80,9 +80,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -97,6 +96,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -108,16 +109,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr    = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size  -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Reset the initial stack pointer */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/x86/src/i486/up_usestack.c b/arch/x86/src/i486/up_usestack.c
index 1e73f62..ac40aeb 100644
--- a/arch/x86/src/i486/up_usestack.c
+++ b/arch/x86/src/i486/up_usestack.c
@@ -53,8 +53,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -69,7 +69,7 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -105,23 +105,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * positive word offsets from sp.
    */
 
-  top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The i486 stack must be aligned at word (4 byte) boundaries. If necessary
    * top_of_stack must be rounded down to the next boundary
    */
 
   top_of_stack &= ~3;
-  size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/x86_64/src/common/up_assert.c b/arch/x86_64/src/common/up_assert.c
index e4a88fb..88f5a72 100644
--- a/arch/x86_64/src/common/up_assert.c
+++ b/arch/x86_64/src/common/up_assert.c
@@ -123,7 +123,7 @@ static void up_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint64_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint64_t)rtcb->stack_base_ptr;
   ustacksize = (uint64_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -172,15 +172,14 @@ static void up_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-#endif
+      up_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      up_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      up_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
   /* Then dump the registers (if available) */
diff --git a/arch/x86_64/src/intel64/up_createstack.c b/arch/x86_64/src/intel64/up_createstack.c
index e56e739..958e072 100644
--- a/arch/x86_64/src/intel64/up_createstack.c
+++ b/arch/x86_64/src/intel64/up_createstack.c
@@ -63,8 +63,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -90,10 +90,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -133,16 +129,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -151,14 +145,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -176,7 +170,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* Yes.. If stack debug is enabled, then fill the stack with a
@@ -194,7 +188,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * the stack are referenced as positive quad-words offsets from sp.
        */
 
-      top_of_stack = (uint64_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
       /* The intel64 stack must be aligned at word (16 byte) boundaries. If
        * necessary top_of_stack must be rounded down to the next boundary.
@@ -203,17 +197,13 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       top_of_stack &= ~0x0f;
-      size_of_stack = top_of_stack - (uint64_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (uint64_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/x86_64/src/intel64/up_initialstate.c b/arch/x86_64/src/intel64/up_initialstate.c
index a4fff01..a517c04 100644
--- a/arch/x86_64/src/intel64/up_initialstate.c
+++ b/arch/x86_64/src/intel64/up_initialstate.c
@@ -51,12 +51,9 @@
  *
  ****************************************************************************/
 
-extern uintptr_t tux_mm_new_pd1(void);
-
 void up_initial_state(struct tcb_s *tcb)
 {
   struct xcptcontext *xcp = &tcb->xcp;
-  struct tcb_s *rtcb;
 
   /* Initialize the idle thread stack */
 
@@ -64,7 +61,7 @@ void up_initial_state(struct tcb_s *tcb)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
                                       CONFIG_IDLETHREAD_STACKSIZE);
-      tcb->adj_stack_ptr   = (void *)g_idle_topstack;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -80,17 +77,14 @@ void up_initial_state(struct tcb_s *tcb)
 
   xcp->regs[3]      = (uint64_t)0x0000000000001f80;
 
-  /* set page table to share space with current process */
-
-  rtcb = this_task();
-  UNUSED(rtcb);
-
   /* Save the initial stack pointer... the value of the stackpointer before
    * the "interrupt occurs."
    */
 
-  xcp->regs[REG_RSP]      = (uint64_t)tcb->adj_stack_ptr;
-  xcp->regs[REG_RBP]      = (uint64_t)tcb->adj_stack_ptr;
+  xcp->regs[REG_RSP]      = (uint64_t)tcb->stack_base_ptr +
+                                      tcb->adj_stack_size;
+  xcp->regs[REG_RBP]      = (uint64_t)tcb->stack_base_ptr +
+                                      tcb->adj_stack_size;
 
   /* Save the task entry point */
 
diff --git a/arch/x86_64/src/intel64/up_stackframe.c b/arch/x86_64/src/intel64/up_stackframe.c
index b8256de..2fc0b97 100644
--- a/arch/x86_64/src/intel64/up_stackframe.c
+++ b/arch/x86_64/src/intel64/up_stackframe.c
@@ -80,9 +80,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -97,6 +96,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -108,16 +109,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr    = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size  -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, tcb->adj_stack_size);
 
-  /* Reset the initial stack pointer */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_RSP] = (uint64_t)tcb->adj_stack_ptr;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/x86_64/src/intel64/up_usestack.c b/arch/x86_64/src/intel64/up_usestack.c
index 26ee3b7..6a1bbed 100644
--- a/arch/x86_64/src/intel64/up_usestack.c
+++ b/arch/x86_64/src/intel64/up_usestack.c
@@ -53,8 +53,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -69,7 +69,7 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -105,7 +105,7 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * referenced as positive word offsets from sp.
    */
 
-  top_of_stack = (uint64_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The intel64 stack must be aligned at word (16 byte) boundaries. If
    * necessary top_of_stack must be rounded down to the next boundary.
@@ -114,16 +114,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    */
 
   top_of_stack &= ~0x0f;
-  size_of_stack = top_of_stack - (uint64_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint64_t *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/xtensa/src/common/xtensa_checkstack.c b/arch/xtensa/src/common/xtensa_checkstack.c
index b27d9b1..2e2a434 100644
--- a/arch/xtensa/src/common/xtensa_checkstack.c
+++ b/arch/xtensa/src/common/xtensa_checkstack.c
@@ -31,7 +31,6 @@
 #include <debug.h>
 
 #include <nuttx/arch.h>
-#include <nuttx/tls.h>
 #include <nuttx/board.h>
 
 #include "xtensa.h"
@@ -87,10 +86,7 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
    * Skip over the TLS data structure at the bottom of the stack
    */
 
-#ifdef CONFIG_TLS_ALIGNED
-  DEBUGASSERT((alloc & TLS_STACK_MASK) == 0);
-#endif
-  start = STACK_ALIGN_UP(alloc + sizeof(struct tls_info_s));
+  start = STACK_ALIGN_UP(alloc);
   end   = STACK_ALIGN_DOWN(alloc + size);
 
   /* Get the adjusted size based on the top and bottom of the stack */
@@ -173,12 +169,12 @@ static size_t do_stackcheck(uintptr_t alloc, size_t size)
 
 size_t up_check_tcbstack(FAR struct tcb_s *tcb)
 {
-  return do_stackcheck((uintptr_t)tcb->stack_alloc_ptr, tcb->adj_stack_size);
+  return do_stackcheck((uintptr_t)tcb->stack_base_ptr, tcb->adj_stack_size);
 }
 
 ssize_t up_check_tcbstack_remain(FAR struct tcb_s *tcb)
 {
-  return (ssize_t)tcb->adj_stack_size - (ssize_t)up_check_tcbstack(tcb);
+  return tcb->adj_stack_size - up_check_tcbstack(tcb);
 }
 
 size_t up_check_stack(void)
diff --git a/arch/xtensa/src/common/xtensa_createstack.c b/arch/xtensa/src/common/xtensa_createstack.c
index 9a42dfb..b3a6556 100644
--- a/arch/xtensa/src/common/xtensa_createstack.c
+++ b/arch/xtensa/src/common/xtensa_createstack.c
@@ -71,8 +71,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -103,10 +103,6 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
   uintptr_t cpstart;
 #endif
 
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -156,16 +152,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)UMM_MEMALIGN(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = UMM_MEMALIGN(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -174,14 +168,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)UMM_MALLOC(stack_size);
+          tcb->stack_alloc_ptr = UMM_MALLOC(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -243,26 +237,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
       top_of_stack  = STACK_ALIGN_DOWN(top_of_stack);
-      size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (FAR uint32_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
 #ifdef CONFIG_STACK_COLORATION
       /* If stack debug is enabled, then fill the stack with a
        * recognizable value that we can use later to test for high
        * water marks.
        */
 
-      up_stack_color((FAR void *)tcb->stack_alloc_ptr +
-                     sizeof(struct tls_info_s),
-                     tcb->adj_stack_size - sizeof(struct tls_info_s));
+      up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 #endif
 
       board_autoled_on(LED_STACKCREATED);
diff --git a/arch/xtensa/src/common/xtensa_dumpstate.c b/arch/xtensa/src/common/xtensa_dumpstate.c
index bd05c45..34e70e0 100644
--- a/arch/xtensa/src/common/xtensa_dumpstate.c
+++ b/arch/xtensa/src/common/xtensa_dumpstate.c
@@ -291,7 +291,7 @@ void xtensa_dumpstate(void)
 
   /* Get the limits on the user stack memory */
 
-  ustackbase = (uint32_t)rtcb->adj_stack_ptr;
+  ustackbase = (uint32_t)rtcb->stack_base_ptr;
   ustacksize = (uint32_t)rtcb->adj_stack_size;
 
   /* Get the limits on the interrupt stack memory */
@@ -362,14 +362,14 @@ void xtensa_dumpstate(void)
    * stack memory.
    */
 
-  if (sp >= ustackbase || sp < ustackbase - ustacksize)
+  if (sp >= ustackbase && sp < ustackbase + ustacksize)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      xtensa_stackdump(ustackbase - ustacksize, ustackbase);
+      xtensa_stackdump(sp, ustackbase + ustacksize);
     }
   else
     {
-      xtensa_stackdump(sp, ustackbase);
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      xtensa_stackdump(ustackbase, ustackbase + ustacksize);
     }
 
   /* Dump the state of all tasks (if available) */
diff --git a/arch/xtensa/src/common/xtensa_initialstate.c b/arch/xtensa/src/common/xtensa_initialstate.c
index 1dc939e..772ad0e 100644
--- a/arch/xtensa/src/common/xtensa_initialstate.c
+++ b/arch/xtensa/src/common/xtensa_initialstate.c
@@ -63,8 +63,7 @@ void up_initial_state(struct tcb_s *tcb)
   if (tcb->pid == 0)
     {
       tcb->stack_alloc_ptr = g_idlestack;
-      tcb->adj_stack_ptr   = (char *)g_idlestack +
-                             CONFIG_IDLETHREAD_STACKSIZE;
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -74,9 +73,10 @@ void up_initial_state(struct tcb_s *tcb)
 
   /* Set initial values of registers */
 
-  xcp->regs[REG_PC]   = (uint32_t)tcb->start;         /* Task entrypoint                */
-  xcp->regs[REG_A0]   = 0;                            /* To terminate GDB backtrace     */
-  xcp->regs[REG_A1]   = (uint32_t)tcb->adj_stack_ptr; /* Physical top of stack frame    */
+  xcp->regs[REG_PC]   = (uint32_t)tcb->start;           /* Task entrypoint                */
+  xcp->regs[REG_A0]   = 0;                              /* To terminate GDB backtrace     */
+  xcp->regs[REG_A1]   = (uint32_t)tcb->stack_base_ptr + /* Physical top of stack frame    */
+                                  tcb->adj_stack_size;
 
   /* Set initial PS to int level 0, EXCM disabled ('rfe' will enable), user
    * mode.
diff --git a/arch/xtensa/src/common/xtensa_stackframe.c b/arch/xtensa/src/common/xtensa_stackframe.c
index e7589ec..7707168 100644
--- a/arch/xtensa/src/common/xtensa_stackframe.c
+++ b/arch/xtensa/src/common/xtensa_stackframe.c
@@ -68,9 +68,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -85,6 +84,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -96,16 +97,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr    = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size  -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Reset the initial stack pointer (A1) */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_A1] = (uint32_t)tcb->adj_stack_ptr;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return the pointer to the allocated region */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/xtensa/src/common/xtensa_usestack.c b/arch/xtensa/src/common/xtensa_usestack.c
index e3b6677..647b2bb 100644
--- a/arch/xtensa/src/common/xtensa_usestack.c
+++ b/arch/xtensa/src/common/xtensa_usestack.c
@@ -67,8 +67,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -83,7 +83,7 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -111,33 +111,27 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * as positive word offsets from sp.
    */
 
-  top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The XTENSA stack must be aligned at 16 bytes boundaries. If necessary
    * top_of_stack must be rounded down to the next boundary.
    */
 
   top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
-  size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
 #if defined(CONFIG_STACK_COLORATION)
   /* If stack debug is enabled, then fill the stack with a
    * recognizable value that we can use later to test for high
    * water marks.
    */
 
-  up_stack_color((FAR void *)((uintptr_t)tcb->stack_alloc_ptr +
-                 sizeof(struct tls_info_s)),
-                 size_of_stack - sizeof(struct tls_info_s));
+  up_stack_color(tcb->stack_base_ptr, tcb->adj_stack_size);
 #endif
 
   return OK;
diff --git a/arch/xtensa/src/esp32/esp32_cpuidlestack.c b/arch/xtensa/src/esp32/esp32_cpuidlestack.c
index 3aad0cf..a12d774 100644
--- a/arch/xtensa/src/esp32/esp32_cpuidlestack.c
+++ b/arch/xtensa/src/esp32/esp32_cpuidlestack.c
@@ -73,8 +73,8 @@ uint32_t g_cpu1_idlestack[CPU1_IDLETHREAD_STACKWORDS]
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - cpu:         CPU index that indicates which CPU the IDLE task is
@@ -88,8 +88,6 @@ uint32_t g_cpu1_idlestack[CPU1_IDLETHREAD_STACKWORDS]
 
 int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size)
 {
-  uintptr_t topofstack;
-
   /* XTENSA uses a push-down stack:  the stack grows toward lower* addresses
    * in memory.  The stack pointer register points to the lowest, valid
    * working address (the "top" of the stack).  Items on the stack are
@@ -100,9 +98,7 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size)
 
   tcb->stack_alloc_ptr = g_cpu1_idlestack;
   tcb->adj_stack_size  = CPU1_IDLETHREAD_STACKSIZE;
-  topofstack           = (uintptr_t)g_cpu1_idlestack +
-                         CPU1_IDLETHREAD_STACKSIZE;
-  tcb->adj_stack_ptr   = (uint32_t *)topofstack;
+  tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
 
 #if XCHAL_CP_NUM > 0
   /* REVISIT: Does it make since to have co-processors enabled on the IDLE
diff --git a/arch/xtensa/src/esp32/esp32_cpustart.c b/arch/xtensa/src/esp32/esp32_cpustart.c
index 8fa169d..742f078 100644
--- a/arch/xtensa/src/esp32/esp32_cpustart.c
+++ b/arch/xtensa/src/esp32/esp32_cpustart.c
@@ -158,7 +158,7 @@ void xtensa_appcpu_start(void)
    * is to switch to a well-known IDLE thread stack.
    */
 
-  sp = (uint32_t)tcb->adj_stack_ptr;
+  sp = (uint32_t)tcb->stack_base_ptr + tcb->adj_stack_size;
   __asm__ __volatile__("mov sp, %0\n" : : "r"(sp));
 
   sinfo("CPU%d Started\n", up_cpu_index());
diff --git a/arch/z16/src/common/z16_createstack.c b/arch/z16/src/common/z16_createstack.c
index 8630069..5c3004d 100644
--- a/arch/z16/src/common/z16_createstack.c
+++ b/arch/z16/src/common/z16_createstack.c
@@ -62,8 +62,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -84,10 +84,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -127,16 +123,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -145,14 +139,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -170,7 +164,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* Yes.. If stack debug is enabled, then fill the stack with a
@@ -188,24 +182,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * the stack are referenced as positive word offsets from sp.
        */
 
-      top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
       /* Align the stack to word (4 byte) boundaries.  This is probably
        * a greater alignment than is required.
        */
 
       top_of_stack &= ~3;
-      size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (uint32_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/z16/src/common/z16_initialstate.c b/arch/z16/src/common/z16_initialstate.c
index bff0656..216823c 100644
--- a/arch/z16/src/common/z16_initialstate.c
+++ b/arch/z16/src/common/z16_initialstate.c
@@ -59,6 +59,7 @@ void up_initial_state(struct tcb_s *tcb)
 #ifndef CONFIG_SUPPRESS_INTERRUPTS
   tcb->xcp.regs[REG_FLAGS] = (uint16_t)Z16F_CNTRL_FLAGS_IRQE; /* IRQE flag will enable interrupts */
 #endif
-  reg32[REG_SP / 2]        = (uint32_t)tcb->adj_stack_ptr;
+  reg32[REG_SP / 2]        = (uint32_t)tcb->stack_base_ptr +
+                                       tcb->adj_stack_size;
   reg32[REG_PC / 2]        = (uint32_t)tcb->start;
 }
diff --git a/arch/z16/src/common/z16_stackdump.c b/arch/z16/src/common/z16_stackdump.c
index 73648d0..705aa67 100644
--- a/arch/z16/src/common/z16_stackdump.c
+++ b/arch/z16/src/common/z16_stackdump.c
@@ -50,7 +50,7 @@ static void z16_stackdump(void)
 {
   struct tcb_s *rtcb = this_task();
   chipreg_t sp = z16_getsp();
-  chipreg_t stack_base = (chipreg_t)rtcb->adj_stack_ptr;
+  chipreg_t stack_base = (chipreg_t)rtcb->stack_base_ptr;
   chipreg_t stack_size = (chipreg_t)rtcb->adj_stack_size;
   chipreg_t stack;
 
@@ -58,18 +58,18 @@ static void z16_stackdump(void)
   _alert("stack_size: %08x\n", stack_size);
   _alert("sp:         %08x\n", sp);
 
-  if (sp >= stack_base || sp < stack_base - stack_size)
+  if (sp >= stack_base && sp < stack_base + stack_size)
     {
-      _err("ERROR: Stack pointer is not within allocated stack\n");
-      stack = stack_base - stack_size;
+      stack = sp;
     }
   else
     {
-      stack = sp;
+      _err("ERROR: Stack pointer is not within allocated stack\n");
+      stack = stack_base;
     }
 
   for (stack = stack & ~0x0f;
-       stack < stack_base;
+       stack < stack_base + stack_size;
        stack += 8 * sizeof(chipreg_t))
     {
       chipreg_t *ptr = (chipreg_t *)stack;
diff --git a/arch/z16/src/common/z16_stackframe.c b/arch/z16/src/common/z16_stackframe.c
index a421704..6b1e09d 100644
--- a/arch/z16/src/common/z16_stackframe.c
+++ b/arch/z16/src/common/z16_stackframe.c
@@ -71,9 +71,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -88,6 +87,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -99,16 +100,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
-  /* Save the adjusted stack values in the struct tcb_s */
-
-  tcb->adj_stack_ptr      = (uint8_t *)tcb->adj_stack_ptr - frame_size;
-  tcb->adj_stack_size    -= frame_size;
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
 
-  /* Reset the initial stack pointer */
+  /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->xcp.regs[REG_SP / 2] = (uint32_t)tcb->adj_stack_ptr;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
+  tcb->adj_stack_size -= frame_size;
 
   /* And return a pointer to the allocated memory */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/z16/src/common/z16_usestack.c b/arch/z16/src/common/z16_usestack.c
index bfdc548..a5a374c 100644
--- a/arch/z16/src/common/z16_usestack.c
+++ b/arch/z16/src/common/z16_usestack.c
@@ -53,8 +53,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -67,9 +67,9 @@
  *
  ****************************************************************************/
 
-int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
+int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -105,23 +105,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * the stack are referenced as positive word offsets from sp.
    */
 
-  top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* Align the stack to word (4 byte) boundaries.  This is probably
    * a greater alignment than is required.
    */
 
   top_of_stack &= ~3;
-  size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_size = top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/z80/src/common/z80_createstack.c b/arch/z80/src/common/z80_createstack.c
index 3585f3c..4826af9 100644
--- a/arch/z80/src/common/z80_createstack.c
+++ b/arch/z80/src/common/z80_createstack.c
@@ -61,8 +61,8 @@
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -88,10 +88,6 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Add the size of the TLS information structure */
-
-  stack_size += sizeof(struct tls_info_s);
-
 #ifdef CONFIG_TLS_ALIGNED
   /* The allocated stack size must not exceed the maximum possible for the
    * TLS feature.
@@ -131,16 +127,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kmm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kmm_memalign(TLS_STACK_ALIGN, stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr =
-            (uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
+          tcb->stack_alloc_ptr = kumm_memalign(TLS_STACK_ALIGN, stack_size);
         }
 
 #else /* CONFIG_TLS_ALIGNED */
@@ -149,14 +143,14 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
       if (ttype == TCB_FLAG_TTYPE_KERNEL)
         {
-          tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kmm_malloc(stack_size);
         }
       else
 #endif
         {
           /* Use the user-space allocator if this is a task or pthread */
 
-          tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
+          tcb->stack_alloc_ptr = kumm_malloc(stack_size);
         }
 #endif /* CONFIG_TLS_ALIGNED */
 
@@ -174,7 +168,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   if (tcb->stack_alloc_ptr)
     {
-      size_t top_of_stack;
+      uintptr_t top_of_stack;
       size_t size_of_stack;
 
       /* Yes.. If stack debug is enabled, then fill the stack with a
@@ -193,24 +187,20 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * referenced as positive word offsets from sp.
        */
 
-      top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+      top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
       /* The Z80 stack does not need to be aligned.  Here is is aligned at
        * word (4 byte) boundary.
        */
 
       top_of_stack &= ~3;
-      size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+      size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
       /* Save the adjusted stack values in the struct tcb_s */
 
-      tcb->adj_stack_ptr  = (FAR uint32_t *)top_of_stack;
+      tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
       tcb->adj_stack_size = size_of_stack;
 
-      /* Initialize the TLS data structure */
-
-      memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
       board_autoled_on(LED_STACKCREATED);
       return OK;
     }
diff --git a/arch/z80/src/common/z80_stackdump.c b/arch/z80/src/common/z80_stackdump.c
index 189c5a9..093696e 100644
--- a/arch/z80/src/common/z80_stackdump.c
+++ b/arch/z80/src/common/z80_stackdump.c
@@ -45,7 +45,7 @@ void up_stackdump(void)
 {
   FAR struct tcb_s *rtcb = this_task();
   uintptr_t sp = z80_getsp();
-  uintptr_t stack_base = (uintptr_t)rtcb->adj_stack_ptr;
+  uintptr_t stack_base = (uintptr_t)rtcb->stack_base_ptr;
   uintptr_t stack_size = (uintptr_t)rtcb->adj_stack_size;
   uintptr_t stack;
 
@@ -53,17 +53,17 @@ void up_stackdump(void)
   _alert("stack_size: %06x\n", stack_size);
   _alert("sp:         %06x\n", sp);
 
-  if (sp >= stack_base || sp < stack_base - stack_size)
+  if (sp >= stack_base && sp < stack_base + stack_size)
     {
-      _alert("ERROR: Stack pointer is not within allocated stack\n");
-      stack = stack_base - stack_size;
+      stack = sp;
     }
   else
     {
-      stack = sp;
+      _alert("ERROR: Stack pointer is not within allocated stack\n");
+      stack = stack_base;
     }
 
-  for (stack = stack & ~0x0f; stack < stack_base; stack += 16)
+  for (stack = stack & ~0x0f; stack < stack_base + stack_size; stack += 16)
     {
       FAR uint8_t *ptr = (FAR uint8_t *)stack;
 
diff --git a/arch/z80/src/common/z80_stackframe.c b/arch/z80/src/common/z80_stackframe.c
index 2120bb9..3756200 100644
--- a/arch/z80/src/common/z80_stackframe.c
+++ b/arch/z80/src/common/z80_stackframe.c
@@ -70,9 +70,8 @@
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -87,6 +86,8 @@
 
 FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
 {
+  FAR void *ret;
+
   /* Align the frame_size */
 
   frame_size = STACK_ALIGN_UP(frame_size);
@@ -98,16 +99,15 @@ FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
       return NULL;
     }
 
+  ret = tcb->stack_base_ptr;
+  memset(ret, 0, frame_size);
+
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_ptr   = (uint8_t *)tcb->adj_stack_ptr - frame_size;
+  tcb->stack_base_ptr   = (FAR uint8_t *)tcb->stack_base_ptr + frame_size;
   tcb->adj_stack_size -= frame_size;
 
-  /* Reset the initial stack pointer */
-
-  tcb->xcp.regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
-
   /* And return a pointer to the allocated memory */
 
-  return tcb->adj_stack_ptr;
+  return ret;
 }
diff --git a/arch/z80/src/common/z80_usestack.c b/arch/z80/src/common/z80_usestack.c
index 260d884..40b212b 100644
--- a/arch/z80/src/common/z80_usestack.c
+++ b/arch/z80/src/common/z80_usestack.c
@@ -52,8 +52,8 @@
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -68,7 +68,7 @@
 
 int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 {
-  size_t top_of_stack;
+  uintptr_t top_of_stack;
   size_t size_of_stack;
 
 #ifdef CONFIG_TLS_ALIGNED
@@ -104,23 +104,19 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
    * the stack are* referenced as positive word offsets from sp.
    */
 
-  top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size;
+  top_of_stack = (uintptr_t)tcb->stack_alloc_ptr + stack_size;
 
   /* The Z80 stack does not need to be aligned.  Here is is aligned at
    * word (4 byte) boundary.
    */
 
   top_of_stack &= ~3;
-  size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr;
+  size_of_stack = top_of_stack - (uintptr_t)tcb->stack_alloc_ptr;
 
   /* Save the adjusted stack values in the struct tcb_s */
 
-  tcb->adj_stack_size = top_of_stack;
+  tcb->stack_base_ptr  = tcb->stack_alloc_ptr;
   tcb->adj_stack_size = size_of_stack;
 
-  /* Initialize the TLS data structure */
-
-  memset(tcb->stack_alloc_ptr, 0, sizeof(struct tls_info_s));
-
   return OK;
 }
diff --git a/arch/z80/src/ez80/ez80_initialstate.c b/arch/z80/src/ez80/ez80_initialstate.c
index d6d0573..cd97727 100644
--- a/arch/z80/src/ez80/ez80_initialstate.c
+++ b/arch/z80/src/ez80/ez80_initialstate.c
@@ -52,7 +52,7 @@
 
 void up_initial_state(FAR struct tcb_s *tcb)
 {
-  struct xcptcontext *xcp = &tcb->xcp;
+  FAR struct xcptcontext *xcp = &tcb->xcp;
 
   /* Initialize the initial exception register context structure */
 
@@ -61,9 +61,10 @@ void up_initial_state(FAR struct tcb_s *tcb)
 #ifndef CONFIG_SUPPRESS_INTERRUPTS
   /* Parity/Overflow flag will enable interrupts */
 
-  ((FAR uint8_t *)xcp->regs)[XCPT_IF_OFFSET]  = EZ80_PV_FLAG;
+  ((FAR uint8_t *)xcp->regs)[XCPT_IF_OFFSET] = EZ80_PV_FLAG;
 #endif
 
-  xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
+  xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr +
+                                  tcb->adj_stack_size;
   xcp->regs[XCPT_PC] = (chipreg_t)tcb->start;
 }
diff --git a/arch/z80/src/z180/z180_initialstate.c b/arch/z80/src/z180/z180_initialstate.c
index 43f4c52..f05ce92 100644
--- a/arch/z80/src/z180/z180_initialstate.c
+++ b/arch/z80/src/z180/z180_initialstate.c
@@ -58,8 +58,7 @@ void up_initial_state(struct tcb_s *tcb)
   if (tcb->pid == 0)
     {
       tcb->stack_alloc_ptr = (void *)CONFIG_STACK_BASE;
-      tcb->adj_stack_ptr   = (void *)(CONFIG_STACK_BASE +
-                                      CONFIG_IDLETHREAD_STACKSIZE);
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -69,6 +68,7 @@ void up_initial_state(struct tcb_s *tcb)
 #ifndef CONFIG_SUPPRESS_INTERRUPTS
   xcp->regs[XCPT_I]  = Z180_PV_FLAG; /* Parity flag will enable interrupts */
 #endif
-  xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
+  xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr +
+                                  tcb->adj_stack_size;
   xcp->regs[XCPT_PC] = (chipreg_t)tcb->start;
 }
diff --git a/arch/z80/src/z8/z8_initialstate.c b/arch/z80/src/z8/z8_initialstate.c
index d62c4b9..187e162 100644
--- a/arch/z80/src/z8/z8_initialstate.c
+++ b/arch/z80/src/z8/z8_initialstate.c
@@ -74,6 +74,7 @@ void up_initial_state(FAR struct tcb_s *tcb)
   xcp->regs[XCPT_IRQCTL]  = 0x0080; /* IRQE bit will enable interrupts */
 #endif
   xcp->regs[XCPT_RPFLAGS] = 0xe000; /* RP=%e0 */
-  xcp->regs[XCPT_SP]      = (chipreg_t)tcb->adj_stack_ptr;
+  xcp->regs[XCPT_SP]      = (chipreg_t)tcb->stack_base_ptr +
+                                       tcb->adj_stack_size;
   xcp->regs[XCPT_PC]      = (chipreg_t)tcb->start;
 }
diff --git a/arch/z80/src/z80/z80_initialstate.c b/arch/z80/src/z80/z80_initialstate.c
index 05c2df3..9b24a65 100644
--- a/arch/z80/src/z80/z80_initialstate.c
+++ b/arch/z80/src/z80/z80_initialstate.c
@@ -58,8 +58,7 @@ void up_initial_state(struct tcb_s *tcb)
   if (tcb->pid == 0)
     {
       tcb->stack_alloc_ptr = (void *)CONFIG_STACK_BASE;
-      tcb->adj_stack_ptr   = (void *)(CONFIG_STACK_BASE +
-                                      CONFIG_IDLETHREAD_STACKSIZE);
+      tcb->stack_base_ptr   = tcb->stack_alloc_ptr;
       tcb->adj_stack_size  = CONFIG_IDLETHREAD_STACKSIZE;
     }
 
@@ -69,6 +68,7 @@ void up_initial_state(struct tcb_s *tcb)
 #ifndef CONFIG_SUPPRESS_INTERRUPTS
   xcp->regs[XCPT_I]  = Z80_PV_FLAG; /* Parity flag will enable interrupts */
 #endif
-  xcp->regs[XCPT_SP] = (chipreg_t)tcb->adj_stack_ptr;
+  xcp->regs[XCPT_SP] = (chipreg_t)tcb->stack_base_ptr +
+                                  tcb->adj_stack_size;
   xcp->regs[XCPT_PC] = (chipreg_t)tcb->start;
 }
diff --git a/boards/arm/cxd56xx/common/src/cxd56_crashdump.c b/boards/arm/cxd56xx/common/src/cxd56_crashdump.c
index 83117c3..8ccf65f 100644
--- a/boards/arm/cxd56xx/common/src/cxd56_crashdump.c
+++ b/boards/arm/cxd56xx/common/src/cxd56_crashdump.c
@@ -181,7 +181,8 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
       pdump->info.stacks.user.sp = currentsp;
     }
 
-  pdump->info.stacks.user.top = (uint32_t)rtcb->adj_stack_ptr;
+  pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr +
+                                          rtcb->adj_stack_size;
   pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size;
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
diff --git a/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c b/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c
index df58f75..fb14e79 100644
--- a/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c
+++ b/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c
@@ -449,8 +449,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
       pdump->info.stacks.user.sp = currentsp;
     }
 
-  pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr;
-  pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size;
+  pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr +
+                                          rtcb->adj_stack_size;
+  pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size;
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
   /* Get the limits on the interrupt stack memory */
diff --git a/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c b/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c
index 87e2f1a..b3a1600 100644
--- a/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c
+++ b/boards/arm/stm32f7/nucleo-144/src/stm32_bbsram.c
@@ -449,8 +449,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
       pdump->info.stacks.user.sp = currentsp;
     }
 
-  pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr;
-  pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size;
+  pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr +
+                                          rtcb->adj_stack_size;
+  pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size;
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
   /* Get the limits on the interrupt stack memory */
diff --git a/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c b/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c
index 0118242..31153f7 100644
--- a/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c
+++ b/boards/renesas/rx65n/rx65n-grrose/src/rx65n_sbram.c
@@ -403,8 +403,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
       pdump->info.stacks.user.sp = currentsp;
     }
 
-  pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr;
-  pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size;
+  pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr +
+                                          rtcb->adj_stack_size;
+  pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size;
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
   /* Get the limits on the interrupt stack memory */
diff --git a/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c b/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c
index cda6328..04a8ab3 100644
--- a/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c
+++ b/boards/renesas/rx65n/rx65n-rsk2mb/src/rx65n_sbram.c
@@ -401,8 +401,9 @@ void board_crashdump(uintptr_t currentsp, FAR void *tcb,
       pdump->info.stacks.user.sp = currentsp;
     }
 
-  pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr;
-  pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size;
+  pdump->info.stacks.user.top = (uint32_t)rtcb->stack_base_ptr +
+                                          rtcb->adj_stack_size;
+  pdump->info.stacks.user.size = (uint32_t)rtcb->adj_stack_size;
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 3
   /* Get the limits on the interrupt stack memory */
diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c
index a3af61f..8301867 100644
--- a/fs/procfs/fs_procfsproc.c
+++ b/fs/procfs/fs_procfsproc.c
@@ -857,7 +857,7 @@ static ssize_t proc_stack(FAR struct proc_file_s *procfile,
   /* Show the stack base address */
 
   linesize   = snprintf(procfile->line, STATUS_LINELEN, "%-12s0x%p\n",
-                        "StackBase:", tcb->adj_stack_ptr);
+                        "StackBase:", tcb->stack_base_ptr);
   copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
                              &offset);
 
diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h
index 379146e..f9e5bda 100644
--- a/include/nuttx/arch.h
+++ b/include/nuttx/arch.h
@@ -232,8 +232,8 @@ void up_initial_state(FAR struct tcb_s *tcb);
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb: The TCB of new task
@@ -274,8 +274,8 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype);
  *     processor, etc.  This value is retained only for debug
  *     purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The
- *     initial value of the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -308,9 +308,24 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size);
  *
  *   - adj_stack_size: Stack size after removal of the stack frame from
  *     the stack
- *   - adj_stack_ptr: Adjusted initial stack pointer after the frame has
- *     been removed from the stack.  This will still be the initial value
- *     of the stack pointer when the task is started.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
+ *
+ *   Here is the diagram after some allocation(tls, arg):
+ *
+ *                   +-------------+ <-stack_alloc_ptr(lowest)
+ *                   |  TLS Data   |
+ *                   +-------------+
+ *                   |  Arguments  |
+ *  stack_base_ptr-> +-------------+\
+ *                   |  Available  | +
+ *                   |    Stack    | |
+ *                |  |             | |
+ *                |  |             | +->adj_stack_size
+ *                v  |             | |
+ *                   |             | |
+ *                   |             | +
+ *                   +-------------+/
  *
  * Input Parameters:
  *   - tcb:  The TCB of new task
@@ -1847,8 +1862,8 @@ int up_cpu_index(void);
  *   - adj_stack_size: Stack size after adjustment for hardware, processor,
  *     etc.  This value is retained only for debug purposes.
  *   - stack_alloc_ptr: Pointer to allocated stack
- *   - adj_stack_ptr: Adjusted stack_alloc_ptr for HW.  The initial value of
- *     the stack pointer.
+ *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
+ *     Arguments has been removed from the stack allocation.
  *
  * Input Parameters:
  *   - cpu:         CPU index that indicates which CPU the IDLE task is
diff --git a/include/nuttx/lib/libvars.h b/include/nuttx/lib/libvars.h
deleted file mode 100644
index 47612cc..0000000
--- a/include/nuttx/lib/libvars.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
- * include/nuttx/lib/libvars.h
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-#ifndef __INCLUDE_NUTTX_LIB_LIBVARS_H
-#define __INCLUDE_NUTTX_LIB_LIBVARS_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdbool.h>
-
-#include <nuttx/lib/getopt.h>
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-#ifndef CONFIG_BUILD_KERNEL
-/* This structure encapsulates all task-specific variables needed by the C
- * Library.  This structure is retained at the beginning of the main thread
- * of and is accessed via a reference stored in the TLS of all threads in
- * the task group.
- *
- * NOTE: task-specific variables are not needed in the KERNEL build.  In
- * that build mode, all global variables are inherently process-specific.
- */
-
-struct libvars_s
-{
-  struct getopt_s lv_getopt; /* Globals used by getopt() */
-};
-#endif
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C"
-{
-#else
-#define EXTERN extern
-#endif
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* __INCLUDE_NUTTX_LIB_LIBVARS_H */
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index 4e06514..4f7f647 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -38,7 +38,6 @@
 #include <nuttx/clock.h>
 #include <nuttx/irq.h>
 #include <nuttx/wdog.h>
-#include <nuttx/lib/libvars.h>
 #include <nuttx/mm/shm.h>
 #include <nuttx/fs/fs.h>
 #include <nuttx/net/net.h>
@@ -401,8 +400,9 @@ struct stackinfo_s
                                          /* (for debug purposes only)           */
   FAR void *stack_alloc_ptr;             /* Pointer to allocated stack          */
                                          /* Needed to deallocate stack          */
-  FAR void *adj_stack_ptr;               /* Adjusted stack_alloc_ptr for HW     */
-                                         /* The initial stack pointer value     */
+  FAR void *stack_base_ptr;              /* Adjusted initial stack pointer      */
+                                         /* after the frame has been removed    */
+                                         /* from the stack.                     */
 };
 
 /* struct exitinfo_s ************************************************************/
@@ -530,12 +530,6 @@ struct task_group_s
   tls_ndxset_t tg_tlsset;           /* Set of TLS data indexes allocated        */
 #endif
 
-  /* Task-specific Data *********************************************************/
-
-#ifndef CONFIG_BUILD_KERNEL
-  FAR struct libvars_s *tg_libvars; /* C library global variables */
-#endif
-
   /* POSIX Signal Control Fields ************************************************/
 
   sq_queue_t tg_sigactionq;         /* List of actions for signals              */
@@ -662,8 +656,9 @@ struct tcb_s
                                          /* (for debug purposes only)           */
   FAR void *stack_alloc_ptr;             /* Pointer to allocated stack          */
                                          /* Needed to deallocate stack          */
-  FAR void *adj_stack_ptr;               /* Adjusted stack_alloc_ptr for HW     */
-                                         /* The initial stack pointer value     */
+  FAR void *stack_base_ptr;              /* Adjusted initial stack pointer      */
+                                         /* after the frame has been removed    */
+                                         /* from the stack.                     */
 
   /* External Module Support ****************************************************/
 
@@ -1030,10 +1025,10 @@ void nxtask_startup(main_t entrypt, int argc, FAR char *argv[]);
  *    - Allocation of the child task's TCB.
  *    - Initialization of file descriptors and streams
  *    - Configuration of environment variables
+ *    - Allocate and initialize the stack
  *    - Setup the input parameters for the task.
- *    - Initialization of the TCB (including call to up_initial_state()
+ *    - Initialization of the TCB (including call to up_initial_state())
  * 4) vfork() provides any additional operating context. vfork must:
- *    - Allocate and initialize the stack
  *    - Initialize special values in any CPU registers that were not
  *      already configured by up_initial_state()
  * 5) vfork() then calls nxtask_start_vfork()
@@ -1043,7 +1038,7 @@ void nxtask_startup(main_t entrypt, int argc, FAR char *argv[]);
  *
  ********************************************************************************/
 
-FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize);
+FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr);
 pid_t nxtask_start_vfork(FAR struct task_tcb_s *child);
 void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode);
 
@@ -1330,7 +1325,7 @@ int nxsched_set_affinity(pid_t pid, size_t cpusetsize,
  *
  * Input Parameters:
  *   pid       - Identifies the thread to query.  Zero is interpreted as the
- *               the calling thread
+ *               the calling thread, -1 is interpreted as the calling task.
  *   stackinfo - User-provided location to return the stack information.
  *
  * Returned Value:
diff --git a/include/nuttx/tls.h b/include/nuttx/tls.h
index bd729d3..79f0e78 100644
--- a/include/nuttx/tls.h
+++ b/include/nuttx/tls.h
@@ -27,7 +27,7 @@
 
 #include <nuttx/config.h>
 
-#include <sys/types.h>
+#include <nuttx/lib/getopt.h>
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -71,6 +71,26 @@
  *
  * The stack memory is fully accessible to user mode threads.  TLS is not
  * available from interrupt handlers (nor from the IDLE thread).
+ *
+ * The following diagram represent the typic stack layout:
+ *
+ *      Push Down             Push Up
+ *   +-------------+      +-------------+ <- Stack memory allocation
+ *   |  TLS Data   |      |  TLS Data   |
+ *   +-------------+      +-------------+
+ *   | Task Data*  |      | Task Data*  |
+ *   +-------------+      +-------------+
+ *   |  Arguments  |      |  Arguments  |
+ *   +-------------+      +-------------+ |
+ *   |             |      |             | v
+ *   | Available   |      | Available   |
+ *   |   Stack     |      |   Stack     |
+ *   |             |      |             |
+ *   |             |      |             |
+ *   |             | ^    |             |
+ *   +-------------+ |    +-------------+
+ *
+ *  Task data is allocated in the main's thread's stack only
  */
 
 struct tls_info_s
@@ -78,10 +98,17 @@ struct tls_info_s
 #if CONFIG_TLS_NELEM > 0
   uintptr_t tl_elem[CONFIG_TLS_NELEM]; /* TLS elements */
 #endif
-  FAR struct libvars_s *tl_libvars;    /* Task-specific C library data */
   int tl_errno;                        /* Per-thread error number */
 };
 
+struct task_info_s
+{
+  struct tls_info_s ta_tls;    /* Must be first field */
+#ifndef CONFIG_BUILD_KERNEL
+  struct getopt_s   ta_getopt; /* Globals used by getopt() */
+#endif
+};
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -189,4 +216,21 @@ int tls_set_value(int tlsindex, uintptr_t tlsvalue);
 FAR struct tls_info_s *tls_get_info(void);
 #endif
 
+/****************************************************************************
+ * Name: task_get_info
+ *
+ * Description:
+ *   Return a reference to the task_info_s structure.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   A reference to the task-specific task_info_s structure is return on
+ *   success.  NULL would be returned in the event of any failure.
+ *
+ ****************************************************************************/
+
+FAR struct task_info_s *task_get_info(void);
+
 #endif /* __INCLUDE_NUTTX_TLS_H */
diff --git a/libs/libc/pthread/pthread_get_stackaddr_np.c b/libs/libc/pthread/pthread_get_stackaddr_np.c
index e2be546..a8a570b 100644
--- a/libs/libc/pthread/pthread_get_stackaddr_np.c
+++ b/libs/libc/pthread/pthread_get_stackaddr_np.c
@@ -74,5 +74,5 @@ FAR void *pthread_get_stackaddr_np(pthread_t thread)
       return NULL;
     }
 
-  return stackinfo.adj_stack_ptr;
+  return stackinfo.stack_base_ptr;
 }
diff --git a/libs/libc/tls/Make.defs b/libs/libc/tls/Make.defs
index 0e125f8..504d2c6 100644
--- a/libs/libc/tls/Make.defs
+++ b/libs/libc/tls/Make.defs
@@ -18,6 +18,8 @@
 #
 ############################################################################
 
+CSRCS += task_getinfo.c
+
 ifneq ($(CONFIG_TLS_NELEM),0)
 CSRCS += tls_setvalue.c tls_getvalue.c
 endif
diff --git a/sched/group/group_taskdata.c b/libs/libc/tls/task_getinfo.c
similarity index 68%
rename from sched/group/group_taskdata.c
rename to libs/libc/tls/task_getinfo.c
index 392cb3d..8ae77a1 100644
--- a/sched/group/group_taskdata.c
+++ b/libs/libc/tls/task_getinfo.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * sched/group/group_taskdata.c
+ * libs/libc/tls/task_getinfo.c
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -25,51 +25,39 @@
 #include <nuttx/config.h>
 
 #include <sched.h>
-#include <assert.h>
 
 #include <nuttx/tls.h>
 
-#include "group/group.h"
-
-#ifndef CONFIG_BUILD_KERNEL
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: tls_set_taskdata
+ * Name: task_get_info
  *
  * Description:
- *   Set task-specific data pointer in TLS.
+ *   Return a reference to the task_info_s structure.
  *
  * Input Parameters:
- *   tcb - Identifies task to set TLS data
+ *   None
  *
  * Returned Value:
- *   None
+ *   A reference to the task-specific task_info_s structure is return on
+ *   success.  NULL would be returned in the event of any failure.
  *
  ****************************************************************************/
 
-void tls_set_taskdata(FAR struct tcb_s *tcb)
+FAR struct task_info_s *task_get_info(void)
 {
-  FAR struct tls_info_s *info;
-  FAR struct task_group_s *group;
+  FAR struct task_info_s *info = NULL;
+  struct stackinfo_s stackinfo;
+  int ret;
 
-  DEBUGASSERT(tcb != NULL && tcb->group != NULL);
-  group = tcb->group;
+  ret = nxsched_get_stackinfo(-1, &stackinfo);
+  if (ret >= 0)
+    {
+      info = (FAR struct task_info_s *)stackinfo.stack_alloc_ptr;
+    }
 
-  /* This currently assumes a push-down stack.  The TLS data lies at the
-   * lowest address of the stack allocation.
-   */
-
-  info = (FAR struct tls_info_s *)tcb->stack_alloc_ptr;
-
-  /* Copy the task data point buffer in the group structure into the
-   * thread's TLS data.
-   */
-
-  info->tl_libvars = group->tg_libvars;
+  return info;
 }
-
-#endif /* !CONFIG_BUILD_KERNEL */
\ No newline at end of file
diff --git a/libs/libc/tls/tls.h b/libs/libc/tls/tls.h
deleted file mode 100644
index d935baf..0000000
--- a/libs/libc/tls/tls.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/****************************************************************************
- * libs/libc/tls/tls.h
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-#ifndef __SCHED_TLS_TLS_H
-#define __SCHED_TLS_TLS_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#endif /* __SCHED_TLS_TLS_H */
diff --git a/libs/libc/unistd/lib_getoptvars.c b/libs/libc/unistd/lib_getoptvars.c
index 1e15925..cc0fde2 100644
--- a/libs/libc/unistd/lib_getoptvars.c
+++ b/libs/libc/unistd/lib_getoptvars.c
@@ -24,16 +24,11 @@
 
 #include <nuttx/config.h>
 
-#include <unistd.h>
 #include <assert.h>
 
 #include <nuttx/tls.h>
-#include <nuttx/lib/libvars.h>
-
-#include <arch/tls.h>
 
 #include "unistd.h"
-#include "libc.h"
 
 /****************************************************************************
  * Private Data
@@ -70,13 +65,13 @@ FAR struct getopt_s g_getopt_vars =
 FAR struct getopt_s *getoptvars(void)
 {
 #ifndef CONFIG_BUILD_KERNEL
-  FAR struct tls_info_s *tlsinfo;
+  FAR struct task_info_s *info;
 
   /* Get the structure of getopt() variables using the key. */
 
-  tlsinfo = up_tls_info();
-  DEBUGASSERT(tlsinfo != NULL && tlsinfo->tl_libvars != NULL);
-  return &tlsinfo->tl_libvars->lv_getopt;
+  info = task_get_info();
+  DEBUGASSERT(info != NULL);
+  return &info->ta_getopt;
 #else
   return &g_getopt_vars;
 #endif
diff --git a/sched/group/Make.defs b/sched/group/Make.defs
index 9d2e676..14f1225 100644
--- a/sched/group/Make.defs
+++ b/sched/group/Make.defs
@@ -57,10 +57,6 @@ ifneq ($(CONFIG_TLS_NELEM),0)
 CSRCS += group_tlsalloc.c group_tlsfree.c
 endif
 
-ifndef CONFIG_BUILD_KERNEL
-CSRCS += group_taskdata.c
-endif
-
 # Include group build support
 
 DEPPATH += --dep-path group
diff --git a/sched/group/group.h b/sched/group/group.h
index 94b49bf..3449891 100644
--- a/sched/group/group.h
+++ b/sched/group/group.h
@@ -140,10 +140,4 @@ int  group_setuptaskfiles(FAR struct task_tcb_s *tcb);
 int  group_setupstreams(FAR struct task_tcb_s *tcb);
 #endif
 
-#ifndef CONFIG_BUILD_KERNEL
-/* Task specific data */
-
-void tls_set_taskdata(FAR struct tcb_s *tcb);
-#endif
-
 #endif /* __SCHED_GROUP_GROUP_H */
diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c
index 007c7bf..1c4af3b 100644
--- a/sched/pthread/pthread_create.c
+++ b/sched/pthread/pthread_create.c
@@ -40,6 +40,7 @@
 #include <nuttx/semaphore.h>
 #include <nuttx/kmalloc.h>
 #include <nuttx/pthread.h>
+#include <nuttx/tls.h>
 
 #include "sched/sched.h"
 #include "group/group.h"
@@ -218,6 +219,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
                    pthread_startroutine_t start_routine, pthread_addr_t arg)
 {
   FAR struct pthread_tcb_s *ptcb;
+  FAR struct tls_info_s *info;
   FAR struct join_s *pjoin;
   struct sched_param param;
   int policy;
@@ -291,7 +293,8 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
     {
       /* Allocate the stack for the TCB */
 
-      ret = up_create_stack((FAR struct tcb_s *)ptcb, attr->stacksize,
+      ret = up_create_stack((FAR struct tcb_s *)ptcb,
+                            sizeof(struct tls_info_s) + attr->stacksize,
                             TCB_FLAG_TTYPE_PTHREAD);
     }
 
@@ -301,11 +304,16 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
       goto errout_with_join;
     }
 
-#ifndef CONFIG_BUILD_KERNEL
-  /* Save the allocated task data in TLS */
+  /* Initialize thread local storage */
 
-  tls_set_taskdata(&ptcb->cmn);
-#endif
+  info = up_stack_frame(&ptcb->cmn, sizeof(struct tls_info_s));
+  if (info == NULL)
+    {
+      errcode = ENOMEM;
+      goto errout_with_join;
+    }
+
+  DEBUGASSERT(info == ptcb->cmn.stack_alloc_ptr);
 
   /* Should we use the priority and scheduler specified in the pthread
    * attributes?  Or should we use the current thread's priority and
diff --git a/sched/sched/sched_get_stackinfo.c b/sched/sched/sched_get_stackinfo.c
index 1220964..7d6bda0 100644
--- a/sched/sched/sched_get_stackinfo.c
+++ b/sched/sched/sched_get_stackinfo.c
@@ -42,7 +42,7 @@
  *
  * Input Parameters:
  *   pid       - Identifies the thread to query.  Zero is interpreted as the
- *               the calling thread
+ *               the calling thread, -1 is interpreted as the calling task.
  *   stackinfo - User-provided location to return the stack information.
  *
  * Returned Value:
@@ -69,6 +69,16 @@ int nxsched_get_stackinfo(pid_t pid, FAR struct stackinfo_s *stackinfo)
 
       qtcb = rtcb;
     }
+  else if (pid == -1)
+    {
+      /* We can always query our main thread */
+
+      qtcb = nxsched_get_tcb(rtcb->group->tg_pid);
+      if (qtcb == NULL)
+        {
+          return -ENOENT;
+        }
+    }
   else
     {
       /* Get the task to be queried */
@@ -100,6 +110,7 @@ int nxsched_get_stackinfo(pid_t pid, FAR struct stackinfo_s *stackinfo)
 
   stackinfo->adj_stack_size  = qtcb->adj_stack_size;
   stackinfo->stack_alloc_ptr = qtcb->stack_alloc_ptr;
-  stackinfo->adj_stack_ptr   = qtcb->adj_stack_ptr;
+  stackinfo->stack_base_ptr   = qtcb->stack_base_ptr;
+
   return OK;
 }
diff --git a/sched/task/task_init.c b/sched/task/task_init.c
index bd6a9bc..ba34b93 100644
--- a/sched/task/task_init.c
+++ b/sched/task/task_init.c
@@ -32,7 +32,7 @@
 
 #include <nuttx/arch.h>
 #include <nuttx/sched.h>
-#include <nuttx/lib/libvars.h>
+#include <nuttx/tls.h>
 
 #include "sched/sched.h"
 #include "group/group.h"
@@ -85,9 +85,7 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
                 main_t entry, FAR char * const argv[])
 {
   uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK;
-#ifndef CONFIG_BUILD_KERNEL
-  FAR struct task_group_s *group;
-#endif
+  FAR struct task_info_s *info;
   int ret;
 
 #ifndef CONFIG_DISABLE_PTHREAD
@@ -122,7 +120,9 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
     {
       /* Allocate the stack for the TCB */
 
-      ret = up_create_stack(&tcb->cmn, stack_size, ttype);
+      ret = up_create_stack(&tcb->cmn,
+                            sizeof(struct task_info_s) + stack_size,
+                            ttype);
     }
 
   if (ret < OK)
@@ -130,21 +130,16 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
       goto errout_with_group;
     }
 
-#ifndef CONFIG_BUILD_KERNEL
-  /* Allocate a stack frame to hold task-specific data */
-
-  group = tcb->cmn.group;
-  group->tg_libvars = up_stack_frame(&tcb->cmn, sizeof(struct libvars_s));
-  DEBUGASSERT(group->tg_libvars != NULL);
-
-  /* Initialize the task-specific data */
-
-  memset(group->tg_libvars, 0, sizeof(struct libvars_s));
+  /* Initialize thread local storage */
 
-  /* Save the allocated task data in TLS */
+  info = up_stack_frame(&tcb->cmn, sizeof(struct task_info_s));
+  if (info == NULL)
+    {
+      ret = -ENOMEM;
+      goto errout_with_group;
+    }
 
-  tls_set_taskdata(&tcb->cmn);
-#endif
+  DEBUGASSERT(info == tcb->cmn.stack_alloc_ptr);
 
   /* Initialize the task control block */
 
diff --git a/sched/task/task_vfork.c b/sched/task/task_vfork.c
index 9dd874d..b31b732 100644
--- a/sched/task/task_vfork.c
+++ b/sched/task/task_vfork.c
@@ -34,191 +34,16 @@
 #include <debug.h>
 
 #include <nuttx/sched.h>
+#include <nuttx/tls.h>
 
 #include "sched/sched.h"
 #include "group/group.h"
 #include "task/task.h"
 
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
 /* vfork() requires architecture-specific support as well as waipid(). */
 
 #if defined(CONFIG_ARCH_HAVE_VFORK) && defined(CONFIG_SCHED_WAITPID)
 
-/* This is an artificial limit to detect error conditions where an argv[]
- * list is not properly terminated.
- */
-
-#define MAX_VFORK_ARGS 256
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: nxvfork_setup_name
- *
- * Description:
- *   Copy the task name.
- *
- * Input Parameters:
- *   tcb        - Address of the new task's TCB
- *   name       - Name of the new task
- *
- * Returned Value:
- *  None
- *
- ****************************************************************************/
-
-#if CONFIG_TASK_NAME_SIZE > 0
-static inline void nxvfork_setup_name(FAR struct tcb_s *parent,
-                                      FAR struct task_tcb_s *child)
-{
-  /* Copy the name from the parent into the child TCB */
-
-  strncpy(child->cmn.name, parent->name, CONFIG_TASK_NAME_SIZE);
-}
-#else
-#  define nxvfork_setup_name(p,c)
-#endif /* CONFIG_TASK_NAME_SIZE */
-
-/****************************************************************************
- * Name: nxvfork_setup_stackargs
- *
- * Description:
- *   Clone the task arguments in the same relative positions on the child's
- *   stack.
- *
- * Input Parameters:
- *   parent - Address of the parent task's TCB
- *   child  - Address of the child task's TCB
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno on failure.
- *
- ****************************************************************************/
-
-static inline int nxvfork_setup_stackargs(FAR struct tcb_s *parent,
-                                          FAR struct task_tcb_s *child)
-{
-  /* Is the parent a task? or a pthread?  Only tasks (and kernel threads)
-   * have command line arguments.
-   */
-
-  child->argv = NULL;
-  if ((parent->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD)
-    {
-      FAR struct task_tcb_s *ptcb = (FAR struct task_tcb_s *)parent;
-      uintptr_t offset;
-      int argc;
-
-      /* Get the address correction */
-
-      offset = (uintptr_t)child->cmn.adj_stack_ptr -
-               (uintptr_t)parent->adj_stack_ptr;
-
-      /* Change the child argv[] to point into its stack (instead of its
-       * parent's stack).
-       */
-
-      child->argv = (FAR char **)((uintptr_t)ptcb->argv + offset);
-
-      /* Copy the adjusted address for each argument */
-
-      argc = 0;
-      while (ptcb->argv[argc])
-        {
-          uintptr_t newaddr = (uintptr_t)ptcb->argv[argc] + offset;
-          child->argv[argc] = (FAR char *)newaddr;
-
-          /* Increment the number of args.  Here is a sanity check to
-           * prevent running away with an unterminated argv[] list.
-           * MAX_VFORK_ARGS should be sufficiently large that this never
-           * happens in normal usage.
-           */
-
-          if (++argc > MAX_VFORK_ARGS)
-            {
-              return -E2BIG;
-            }
-        }
-
-      /* Put a terminator entry at the end of the child argv[] array. */
-
-      child->argv[argc] = NULL;
-    }
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: nxvfork_setup_arguments
- *
- * Description:
- *   Clone the argument list from the parent to the child.
- *
- * Input Parameters:
- *   parent - Address of the parent task's TCB
- *   child  - Address of the child task's TCB
- *
- * Returned Value:
- *   Zero (OK) on success; a negated errno on failure.
- *
- ****************************************************************************/
-
-static inline int nxvfork_setup_arguments(FAR struct tcb_s *parent,
-                                          FAR struct task_tcb_s *child)
-{
-  /* Clone the task name */
-
-  nxvfork_setup_name(parent, child);
-
-  /* Adjust and copy the argv[] array. */
-
-  return nxvfork_setup_stackargs(parent, child);
-}
-
-/****************************************************************************
- * Name: nxvfork_sizeof_arguments
- *
- * Description:
- *   Get the parent's argument size.
- *
- * Input Parameters:
- *   parent - Address of the parent task's TCB
- *
- * Return Value:
- *   The parent's argument size.
- *
- ****************************************************************************/
-
-static inline size_t nxvfork_sizeof_arguments(FAR struct tcb_s *parent)
-{
-  if ((parent->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD)
-    {
-      FAR struct task_tcb_s *ptcb = (FAR struct task_tcb_s *)parent;
-      size_t strtablen = 0;
-      int argc = 0;
-
-      while (ptcb->argv[argc])
-        {
-          /* Add the size of this argument (with NUL terminator) */
-
-          strtablen += strlen(ptcb->argv[argc++]) + 1;
-        }
-
-      /* Return the size to hold argv[] array and the strings. */
-
-      return (argc + 1) * sizeof(FAR char *) + strtablen;
-    }
-  else
-    {
-      return 0;
-    }
-}
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -246,10 +71,10 @@ static inline size_t nxvfork_sizeof_arguments(FAR struct tcb_s *parent)
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) up_vfork() provides any additional operating context. up_vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) up_vfork() then calls nxtask_start_vfork()
@@ -266,29 +91,48 @@ static inline size_t nxvfork_sizeof_arguments(FAR struct tcb_s *parent)
  *
  ****************************************************************************/
 
-FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize)
+FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr)
 {
-  FAR struct tcb_s *parent = this_task();
+  FAR struct tcb_s *ptcb = this_task();
+  FAR struct task_tcb_s *parent;
   FAR struct task_tcb_s *child;
+  FAR struct task_info_s *info;
+  FAR const char *name = NULL;
+  size_t stack_size;
   uint8_t ttype;
   int priority;
   int ret;
 
-  DEBUGASSERT(retaddr != NULL && argsize != NULL);
+  DEBUGASSERT(retaddr != NULL);
 
   /* Get the type of the fork'ed task (kernel or user) */
 
-  if ((parent->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
+  if ((ptcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
     {
       /* Fork'ed from a kernel thread */
 
       ttype = TCB_FLAG_TTYPE_KERNEL;
+      parent = (FAR struct task_tcb_s *)ptcb;
     }
   else
     {
       /* Fork'ed from a user task or pthread */
 
       ttype = TCB_FLAG_TTYPE_TASK;
+      if ((ptcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK)
+        {
+          parent = (FAR struct task_tcb_s *)ptcb;
+        }
+      else
+        {
+          parent = (FAR struct task_tcb_s *)
+              nxsched_get_tcb(ptcb->group->tg_pid);
+          if (parent == NULL)
+            {
+              ret = -ENOENT;
+              goto errout;
+            }
+        }
     }
 
   /* Allocate a TCB for the child task. */
@@ -297,13 +141,13 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize)
   if (!child)
     {
       serr("ERROR: Failed to allocate TCB\n");
-      set_errno(ENOMEM);
-      return NULL;
+      ret = -ENOMEM;
+      goto errout;
     }
 
   /* Allocate a new task group with the same privileges as the parent */
 
-  ret = group_allocate(child, parent->flags);
+  ret = group_allocate(child, ttype);
   if (ret < 0)
     {
       goto errout_with_tcb;
@@ -317,33 +161,71 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr, size_t *argsize)
       goto errout_with_tcb;
     }
 
+  /* Allocate the stack for the TCB */
+
+  stack_size = (uintptr_t)ptcb->stack_base_ptr -
+      (uintptr_t)ptcb->stack_alloc_ptr + ptcb->adj_stack_size;
+
+  ret = up_create_stack(&child->cmn, stack_size, ttype);
+  if (ret < OK)
+    {
+      goto errout_with_tcb;
+    }
+
+  /* Setup thread local storage */
+
+  info = up_stack_frame(&child->cmn, sizeof(struct task_info_s));
+  if (info == NULL)
+    {
+      ret = -ENOMEM;
+      goto errout_with_tcb;
+    }
+
+  DEBUGASSERT(info == child->cmn.stack_alloc_ptr);
+  memcpy(info, parent->cmn.stack_alloc_ptr, sizeof(struct task_info_s));
+
   /* Get the priority of the parent task */
 
 #ifdef CONFIG_PRIORITY_INHERITANCE
-  priority = parent->base_priority;   /* "Normal," unboosted priority */
+  priority = ptcb->base_priority;   /* "Normal," unboosted priority */
 #else
-  priority = parent->sched_priority;  /* Current priority */
+  priority = ptcb->sched_priority;  /* Current priority */
 #endif
 
   /* Initialize the task control block.  This calls up_initial_state() */
 
   sinfo("Child priority=%d start=%p\n", priority, retaddr);
-  ret = nxtask_setup_scheduler(child, priority, retaddr, parent->entry.main,
-                          ttype);
+  ret = nxtask_setup_scheduler(child, priority, retaddr,
+                               ptcb->entry.main, ttype);
   if (ret < OK)
     {
       goto errout_with_tcb;
     }
 
-  /* Return the argument size */
+  /* Setup to pass parameters to the new task */
+
+#if CONFIG_TASK_NAME_SIZE > 0
+  name = parent->cmn.name;
+#endif
+
+  nxtask_setup_arguments(child, name, parent->argv);
+
+  /* Now we have enough in place that we can join the group */
 
-  *argsize = nxvfork_sizeof_arguments(parent);
+  ret = group_initialize(child);
+  if (ret < OK)
+    {
+      goto errout_with_list;
+    }
 
   sinfo("parent=%p, returning child=%p\n", parent, child);
   return child;
 
+errout_with_list:
+  dq_rem((FAR dq_entry_t *)child, (FAR dq_queue_t *)&g_inactivetasks);
 errout_with_tcb:
   nxsched_release_tcb((FAR struct tcb_s *)child, ttype);
+errout:
   set_errno(-ret);
   return NULL;
 }
@@ -371,10 +253,10 @@ errout_with_tcb:
  *      - Allocation of the child task's TCB.
  *      - Initialization of file descriptors and streams
  *      - Configuration of environment variables
+ *      - Allocate and initialize the stack
  *      - Setup the input parameters for the task.
- *      - Initialization of the TCB (including call to up_initial_state()
+ *      - Initialization of the TCB (including call to up_initial_state())
  *   4) vfork() provides any additional operating context. vfork must:
- *      - Allocate and initialize the stack
  *      - Initialize special values in any CPU registers that were not
  *        already configured by up_initial_state()
  *   5) vfork() then calls nxtask_start_vfork()
@@ -394,32 +276,13 @@ errout_with_tcb:
 
 pid_t nxtask_start_vfork(FAR struct task_tcb_s *child)
 {
-  FAR struct tcb_s *parent = this_task();
   pid_t pid;
-  int rc;
+  int rc = 0;
   int ret;
 
-  sinfo("Starting Child TCB=%p, parent=%p\n", child, this_task());
+  sinfo("Starting Child TCB=%p\n", child);
   DEBUGASSERT(child);
 
-  /* Duplicate the original argument list in the forked child TCB */
-
-  ret = nxvfork_setup_arguments(parent, child);
-  if (ret < 0)
-    {
-      nxtask_abort_vfork(child, -ret);
-      return ERROR;
-    }
-
-  /* Now we have enough in place that we can join the group */
-
-  ret = group_initialize(child);
-  if (ret < 0)
-    {
-      nxtask_abort_vfork(child, -ret);
-      return ERROR;
-    }
-
   /* Get the assigned pid before we start the task */
 
   pid = (int)child->cmn.pid;
@@ -453,17 +316,11 @@ pid_t nxtask_start_vfork(FAR struct task_tcb_s *child)
    * opportunity to run.
    */
 
-  rc = 0;
-
-#ifdef CONFIG_DEBUG_FEATURES
   ret = waitpid(pid, &rc, 0);
   if (ret < 0)
     {
       serr("ERROR: waitpid failed: %d\n", get_errno());
     }
-#else
-  waitpid(pid, &rc, 0);
-#endif
 
   sched_unlock();
   return pid;
@@ -489,7 +346,7 @@ void nxtask_abort_vfork(FAR struct task_tcb_s *child, int errcode)
   /* Release the TCB */
 
   nxsched_release_tcb((FAR struct tcb_s *)child,
-                   child->cmn.flags & TCB_FLAG_TTYPE_MASK);
+                      child->cmn.flags & TCB_FLAG_TTYPE_MASK);
   set_errno(errcode);
 }