diff --git a/ChangeLog b/ChangeLog
index b0d3f904e71c12217178e5a57b085b2534e33ffa..bddcb4367bb8646ecec1d4ee5c2ec37b5bcae50e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4402,4 +4402,7 @@
 	  big, initial checkin.  The next step will be to add logic to
 	  allocate stacks for kernel threads from protected kernel memory
 	  and all other task types from unprotected user memory (2013-03-20).
-
+	* arch/*/src/common/up_createstack.c, up_use_stack.c, and
+	  up_release_stack.c:  If creating or releasing the stack for a kernel
+	  thread, use the kernel allocator so that the kernel thread stacks
+	  are protected from user application meddling (2013-03-20).
diff --git a/arch/arm/src/common/up_createstack.c b/arch/arm/src/common/up_createstack.c
index 65eb91159bdc38f1da6f1c2e9ce0334a7bda1bb3..634fb9d61f38a213d85f290ca8ee6aca0b366c85 100644
--- a/arch/arm/src/common/up_createstack.c
+++ b/arch/arm/src/common/up_createstack.c
@@ -146,17 +146,19 @@ static void *memset32(void *s, uint32_t  c, size_t n)
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Is there already a stack allocated of a different size? */
+  /* Is there already a stack allocated of a different size?  Because of
+   * alignment issues, stack_size might erroneously appear to be of a
+   * different size.  Fortunately, this is not a critical operation.
+   */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
     {
-      /* Yes.. free it */
+      /* Yes.. Release the old stack */
 
-      sched_ufree(tcb->stack_alloc_ptr);
-      tcb->stack_alloc_ptr = NULL;
+      up_release_stack(tcb, ttype);
     }
 
-  /* Do we need to allocate a stack? */
+  /* Do we need to allocate a new stack? */
  
   if (!tcb->stack_alloc_ptr)
     {
@@ -164,12 +166,32 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+#if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
+          tcb->stack_alloc_ptr = (uint32_t *)kzalloc(stack_size);
+#else
+          tcb->stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
+#endif
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
 #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
-      tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
 #else
-      tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
 #endif
+        }
+
 #ifdef CONFIG_DEBUG
+      /* Was the allocation successful? */
+
       if (!tcb->stack_alloc_ptr)
         {
           sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size);
@@ -218,7 +240,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
        */
 
 #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK)
-      memset32(tcb->stack_alloc_ptr, 0xDEADBEEF, tcb->adj_stack_size/4);
+      memset32(tcb->stack_alloc_ptr, 0xdeadbeef, tcb->adj_stack_size/4);
 #endif
 
       up_ledon(LED_STACKCREATED);
diff --git a/arch/arm/src/common/up_releasestack.c b/arch/arm/src/common/up_releasestack.c
index 711022f93e45f6720bd2ad80930554966f1183d5..9ab872d3328e497489ac9252cf2267ea3abd4f13 100644
--- a/arch/arm/src/common/up_releasestack.c
+++ b/arch/arm/src/common/up_releasestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  *  arch/arm/src/common/up_releasestack.c
  *
- *   Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,11 +91,31 @@
 
 void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
+  /* Is there a stack allocated? */
+
   if (dtcb->stack_alloc_ptr)
     {
-      sched_ufree(dtcb->stack_alloc_ptr);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          sched_kfree(dtcb->stack_alloc_ptr);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          sched_ufree(dtcb->stack_alloc_ptr);
+        }
+
+      /* Mark the stack freed */
+
       dtcb->stack_alloc_ptr = NULL;
     }
 
+  /* The size of the allocated stack is now zero */
+
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/arm/src/common/up_usestack.c b/arch/arm/src/common/up_usestack.c
index a141006bbdaf18e52d90a800a99178be16f3329a..a45ec99b57b45582b1c5c43161bb8e50ddc113ff 100644
--- a/arch/arm/src/common/up_usestack.c
+++ b/arch/arm/src/common/up_usestack.c
@@ -121,12 +121,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+  /* Is there already a stack allocated? */
+
   if (tcb->stack_alloc_ptr)
     {
-      sched_ufree(tcb->stack_alloc_ptr);
+      /* Yes... Release the old stack allocation */
+
+      up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK);
     }
 
-  /* Save the stack allocation */
+  /* Save the new stack allocation */
 
   tcb->stack_alloc_ptr = stack;
 
diff --git a/arch/avr/src/avr/up_createstack.c b/arch/avr/src/avr/up_createstack.c
index 60f6dceec98466bedcb9a11274d3065925ed5fa9..98423be1f0970cd75c5bedb49b4dc1048838a81f 100644
--- a/arch/avr/src/avr/up_createstack.c
+++ b/arch/avr/src/avr/up_createstack.c
@@ -105,30 +105,52 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Is there already a stack allocated of a different size? */
+  /* Is there already a stack allocated of a different size?  Because of
+   * alignment issues, stack_size might erroneously appear to be of a
+   * different size.  Fortunately, this is not a critical operation.
+   */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
     {
-      /* Yes.. free it */
+      /* Yes.. Release the old stack */
 
-      sched_ufree(tcb->stack_alloc_ptr);
-      tcb->stack_alloc_ptr = NULL;
+      up_release_stack(tcb, ttype);
     }
 
-  /* Do we need to allocate a stack? */
-
+  /* Do we need to allocate a new stack? */
+ 
   if (!tcb->stack_alloc_ptr)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
 #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
-      tcb->stack_alloc_ptr = (FAR void *)kuzalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kzalloc(stack_size);
 #else
-      tcb->stack_alloc_ptr = (FAR void *)kumalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
 #endif
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+#if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
+          tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+#else
+          tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+#endif
+        }
+
 #ifdef CONFIG_DEBUG
+      /* Was the allocation successful? */
+
       if (!tcb->stack_alloc_ptr)
         {
           sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size);
diff --git a/arch/avr/src/avr/up_usestack.c b/arch/avr/src/avr/up_usestack.c
index ebd911fb25da8e3a4fd4f4a76e535bdc452b0d29..629ad6cf021f28823b189ec6490de89730371813 100644
--- a/arch/avr/src/avr/up_usestack.c
+++ b/arch/avr/src/avr/up_usestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * arch/avr/src/avr/up_usestack.c
  *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -98,12 +98,12 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
   if (tcb->stack_alloc_ptr)
     {
-      /* Yes.. free it */
+      /* Yes.. Release the old stack allocation */
 
-      sched_ufree(tcb->stack_alloc_ptr);
+      up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK);
     }
 
-  /* Save the stack allocation */
+  /* Save the new stack allocation */
 
   tcb->stack_alloc_ptr = stack;
 
diff --git a/arch/avr/src/avr32/up_createstack.c b/arch/avr/src/avr32/up_createstack.c
index da7e8788c57c3fb5bca80b72c5268a9a85737d37..76ed2c0f5e0aec3ecdd9a55fcaaf16d68a170dbd 100644
--- a/arch/avr/src/avr32/up_createstack.c
+++ b/arch/avr/src/avr32/up_createstack.c
@@ -104,30 +104,52 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Is there already a stack allocated of a different size? */
+  /* Is there already a stack allocated of a different size?  Because of
+   * alignment issues, stack_size might erroneously appear to be of a
+   * different size.  Fortunately, this is not a critical operation.
+   */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
     {
-      /* Yes.. free it */
+      /* Yes.. Release the old stack */
 
-      sched_ufree(tcb->stack_alloc_ptr);
-      tcb->stack_alloc_ptr = NULL;
+      up_release_stack(tcb, ttype);
     }
 
-  /* Do we need to allocate a stack? */
-
+  /* Do we need to allocate a new stack? */
+ 
   if (!tcb->stack_alloc_ptr)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
 #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
-      tcb->stack_alloc_ptr = (FAR void *)kuzalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kzalloc(stack_size);
 #else
-      tcb->stack_alloc_ptr = (FAR void *)kumalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
 #endif
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+#if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
+          tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+#else
+          tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+#endif
+        }
+
 #ifdef CONFIG_DEBUG
+      /* Was the allocation successful? */
+
       if (!tcb->stack_alloc_ptr)
         {
           sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size);
diff --git a/arch/avr/src/avr32/up_usestack.c b/arch/avr/src/avr32/up_usestack.c
index 86cdc2de402eb294c83b2ca1259cd2673a713904..e71be16e7e17f94dcb975a7be48e11ed1aa5a3bd 100644
--- a/arch/avr/src/avr32/up_usestack.c
+++ b/arch/avr/src/avr32/up_usestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * arch/avr/src/avr32/up_usestack.c
  *
- *   Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -94,12 +94,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+  /* Is there already a stack allocated? */
+
   if (tcb->stack_alloc_ptr)
     {
-      sched_ufree(tcb->stack_alloc_ptr);
+      /* Yes.. Release the old stack allocation */
+
+      up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK);
     }
 
-  /* Save the stack allocation */
+  /* Save the new stack allocation */
 
   tcb->stack_alloc_ptr = stack;
 
diff --git a/arch/avr/src/common/up_releasestack.c b/arch/avr/src/common/up_releasestack.c
index 7d3e6f28c2a6c042397793b2ca7dc7b85ab753e2..ec172bd5e4e4ab8149803ca50779401371afc8e6 100644
--- a/arch/avr/src/common/up_releasestack.c
+++ b/arch/avr/src/common/up_releasestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  *  arch/avr/src/common/up_releasestack.c
  *
- *   Copyright (C) 2010 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,12 +91,32 @@
 
 void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
+  /* Is there a stack allocated? */
+
   if (dtcb->stack_alloc_ptr)
     {
-      sched_ufree(dtcb->stack_alloc_ptr);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          sched_kfree(dtcb->stack_alloc_ptr);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          sched_ufree(dtcb->stack_alloc_ptr);
+        }
+
+      /* Mark the stack freed */
+
       dtcb->stack_alloc_ptr = NULL;
     }
 
+  /* The size of the allocated stack is now zero */
+
   dtcb->adj_stack_size = 0;
 }
 
diff --git a/arch/hc/src/common/up_createstack.c b/arch/hc/src/common/up_createstack.c
index a8b192c4bc2926d67739241a9c4a10536f558966..d7050f5122dbd52a46f2a515e006b37efe2e1d2f 100644
--- a/arch/hc/src/common/up_createstack.c
+++ b/arch/hc/src/common/up_createstack.c
@@ -101,30 +101,52 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Is there already a stack allocated of a different size? */
+  /* Is there already a stack allocated of a different size?  Because of
+   * alignment issues, stack_size might erroneously appear to be of a
+   * different size.  Fortunately, this is not a critical operation.
+   */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
     {
-      /* Yes.. free it */
+      /* Yes.. Release the old stack */
 
-      sched_ufree(tcb->stack_alloc_ptr);
-      tcb->stack_alloc_ptr = NULL;
+      up_release_stack(tcb, ttype);
     }
 
-  /* Do we need to allocate a stack? */
-
+  /* Do we need to allocate a new stack? */
+ 
   if (!tcb->stack_alloc_ptr)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
 #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
-      tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kzalloc(stack_size);
 #else
-      tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
 #endif
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+#if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
+          tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+#else
+          tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+#endif
+        }
+
 #ifdef CONFIG_DEBUG
+      /* Was the allocation successful? */
+
       if (!tcb->stack_alloc_ptr)
         {
           sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size);
diff --git a/arch/hc/src/common/up_releasestack.c b/arch/hc/src/common/up_releasestack.c
index f8c2fa142d15b49b077d96f3ef08eaf251cf4274..800e0ccb5ad52fcae225ece4aaf2029e06736256 100644
--- a/arch/hc/src/common/up_releasestack.c
+++ b/arch/hc/src/common/up_releasestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  *  arch/hc/src/common/up_releasestack.c
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -92,11 +92,31 @@
 
 void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
+  /* Is there a stack allocated? */
+
   if (dtcb->stack_alloc_ptr)
     {
-      sched_ufree(dtcb->stack_alloc_ptr);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          sched_kfree(dtcb->stack_alloc_ptr);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          sched_ufree(dtcb->stack_alloc_ptr);
+        }
+
+      /* Mark the stack freed */
+
       dtcb->stack_alloc_ptr = NULL;
     }
 
+  /* The size of the allocated stack is now zero */
+
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/hc/src/common/up_usestack.c b/arch/hc/src/common/up_usestack.c
index 7f3c8fc6690b73dc86b71381cd42d95614338f89..047ba2e9a56e4743c1c8ecd79f5113760a7ed6b5 100644
--- a/arch/hc/src/common/up_usestack.c
+++ b/arch/hc/src/common/up_usestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * arch/hc/src/common/up_usestack.c
  *
- *   Copyright (C) 2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -93,13 +93,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+  /* Is there already a stack allocated? */
+
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
     {
-      sched_ufree(tcb->stack_alloc_ptr);
-      tcb->stack_alloc_ptr = NULL;
+      /* Yes.. Release the old stack allocation */
+
+      up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK);
     }
 
-  /* Save the stack allocation */
+  /* Save the new stack allocation */
 
   tcb->stack_alloc_ptr = stack;
 
diff --git a/arch/mips/src/common/up_createstack.c b/arch/mips/src/common/up_createstack.c
index b228e80619792033a38fe3aaf60683377459f33a..6109797a34d5fe1cdd6c01e191554011247c0da0 100644
--- a/arch/mips/src/common/up_createstack.c
+++ b/arch/mips/src/common/up_createstack.c
@@ -122,30 +122,52 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Is there already a stack allocated of a different size? */
+  /* Is there already a stack allocated of a different size?  Because of
+   * alignment issues, stack_size might erroneously appear to be of a
+   * different size.  Fortunately, this is not a critical operation.
+   */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
     {
-      /* Yes.. free it */
+      /* Yes.. Release the old stack */
 
-      sched_ufree(tcb->stack_alloc_ptr);
-      tcb->stack_alloc_ptr = NULL;
+      up_release_stack(tcb, ttype);
     }
 
-  /* Do we need to allocate a stack? */
-
+  /* Do we need to allocate a new stack? */
+ 
   if (!tcb->stack_alloc_ptr)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
 #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
-      tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kzalloc(stack_size);
 #else
-      tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
 #endif
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+#if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
+          tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+#else
+          tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+#endif
+        }
+
 #ifdef CONFIG_DEBUG
+      /* Was the allocation successful? */
+
       if (!tcb->stack_alloc_ptr)
         {
           sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size);
diff --git a/arch/mips/src/common/up_releasestack.c b/arch/mips/src/common/up_releasestack.c
index 3ce46bebdcade13e2395cffdcf51661c0a1e8b32..f1cb44c230aa522e74f6ab1eaa1967bebe2c80c2 100644
--- a/arch/mips/src/common/up_releasestack.c
+++ b/arch/mips/src/common/up_releasestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  *  arch/mips/src/common/up_releasestack.c
  *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,11 +91,31 @@
 
 void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
+  /* Is there a stack allocated? */
+
   if (dtcb->stack_alloc_ptr)
     {
-      sched_ufree(dtcb->stack_alloc_ptr);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          sched_kfree(dtcb->stack_alloc_ptr);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          sched_ufree(dtcb->stack_alloc_ptr);
+        }
+
+      /* Mark the stack freed */
+
       dtcb->stack_alloc_ptr = NULL;
     }
 
+  /* The size of the allocated stack is now zero */
+
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/mips/src/common/up_usestack.c b/arch/mips/src/common/up_usestack.c
index fe1d27818ddb925180a6acf6979adfa8ce67c688..b636a51d787dd1209c28e7cd7b853b79caa3f555 100644
--- a/arch/mips/src/common/up_usestack.c
+++ b/arch/mips/src/common/up_usestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * arch/mips/src/common/up_usestack.c
  *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -94,12 +94,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+  /* Is there already a stack allocated? */
+
   if (tcb->stack_alloc_ptr)
     {
-      sched_ufree(tcb->stack_alloc_ptr);
+      /* Yes.. Release the old stack allocation */
+
+      up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK);
     }
 
-  /* Save the stack allocation */
+  /* Save the new stack allocation */
 
   tcb->stack_alloc_ptr = stack;
 
diff --git a/arch/rgmp/src/nuttx.c b/arch/rgmp/src/nuttx.c
index 3dc5310062a35434e00db9beb16ec5db55521a13..79f97fcfca443e2d9e497754543672bc44ced7b8 100644
--- a/arch/rgmp/src/nuttx.c
+++ b/arch/rgmp/src/nuttx.c
@@ -66,11 +66,11 @@ static inline void up_switchcontext(struct tcb_s *ctcb, struct tcb_s *ntcb)
 {
     // do nothing if two tasks are the same
     if (ctcb == ntcb)
-		return;
+        return;
 
     // this function can not be called in interrupt
     if (up_interrupt_context()) {
-		panic("%s: try to switch context in interrupt\n", __func__);
+        panic("%s: try to switch context in interrupt\n", __func__);
     }
 
     // start switch
@@ -81,19 +81,19 @@ static inline void up_switchcontext(struct tcb_s *ctcb, struct tcb_s *ntcb)
 void up_initialize(void)
 {
     extern pidhash_t g_pidhash[];
-	extern void vdev_init(void);
+    extern void vdev_init(void);
     extern void nuttx_arch_init(void);
 
     // intialize the current_task to g_idletcb
     current_task = g_pidhash[PIDHASH(0)].tcb;
 
-	// OS memory alloc system is ready
-	use_os_kmalloc = 1;
+    // OS memory alloc system is ready
+    use_os_kmalloc = 1;
 
     // rgmp vdev init
-	vdev_init();
+    vdev_init();
 
-	nuttx_arch_init();
+    nuttx_arch_init();
 
     // enable interrupt
     local_irq_enable();
@@ -106,13 +106,14 @@ void up_idle(void)
 
 void up_allocate_heap(void **heap_start, size_t *heap_size)
 {
-	void *boot_freemem = boot_alloc(0, sizeof(int));
+    void *boot_freemem = boot_alloc(0, sizeof(int));
     *heap_start = boot_freemem;
     *heap_size = KERNBASE + kmem_size - (uint32_t)boot_freemem;
 }
 
 int up_create_stack(struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+    uint32_t *stack_alloc_ptr;
     int ret = ERROR;
     size_t *adj_stack_ptr;
 
@@ -123,18 +124,27 @@ int up_create_stack(struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
     /* Allocate the memory for the stack */
 
-    uint32_t *stack_alloc_ptr = (uint32_t*)kumalloc(adj_stack_size);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+    /* Use the kernel allocator if this is a kernel thread */
+
+    if (ttype == TCB_FLAG_TTYPE_KERNEL) {
+        stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
+    } else
+#endif
+    {
+        stack_alloc_ptr = (uint32_t*)kumalloc(adj_stack_size);
+    }
     if (stack_alloc_ptr) {
-		/* This is the address of the last word in the allocation */
+        /* This is the address of the last word in the allocation */
 
-		adj_stack_ptr = &stack_alloc_ptr[adj_stack_words - 1];
+        adj_stack_ptr = &stack_alloc_ptr[adj_stack_words - 1];
 
-		/* Save the values in the TCB */
+        /* Save the values in the TCB */
 
-		tcb->adj_stack_size  = adj_stack_size;
-		tcb->stack_alloc_ptr = stack_alloc_ptr;
-		tcb->adj_stack_ptr   = (void *)((unsigned int)adj_stack_ptr & ~7);
-		ret = OK;
+        tcb->adj_stack_size  = adj_stack_size;
+        tcb->stack_alloc_ptr = stack_alloc_ptr;
+        tcb->adj_stack_ptr   = (void *)((unsigned int)adj_stack_ptr & ~7);
+        ret = OK;
     }
     return ret;
 }
@@ -160,13 +170,28 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
 
 void up_release_stack(struct tcb_s *dtcb, uint8_t ttype)
 {
-    if (dtcb->stack_alloc_ptr) {
-		kufree(dtcb->stack_alloc_ptr);
-    }
+  /* Is there a stack allocated? */
+
+  if (dtcb->stack_alloc_ptr) {
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL) {
+          kfree(dtcb->stack_alloc_ptr);
+      } else
+#endif
+      {
+        /* Use the user-space allocator if this is a task or pthread */
 
-    dtcb->stack_alloc_ptr = NULL;
-    dtcb->adj_stack_size  = 0;
-    dtcb->adj_stack_ptr   = NULL;
+        kufree(dtcb->stack_alloc_ptr);
+      }
+  }
+
+  /* Mark the stack freed */
+
+  dtcb->stack_alloc_ptr = NULL;
+  dtcb->adj_stack_size  = 0;
+  dtcb->adj_stack_ptr   = NULL;
 }
 
 /****************************************************************************
@@ -196,43 +221,43 @@ void up_block_task(struct tcb_s *tcb, tstate_t task_state)
 {
     /* Verify that the context switch can be performed */
     if ((tcb->task_state < FIRST_READY_TO_RUN_STATE) ||
-		(tcb->task_state > LAST_READY_TO_RUN_STATE)) {
-		warn("%s: task sched error\n", __func__);
-		return;
+        (tcb->task_state > LAST_READY_TO_RUN_STATE)) {
+        warn("%s: task sched error\n", __func__);
+        return;
     }
     else {
-		struct tcb_s *rtcb = current_task;
-		bool switch_needed;
-
-		/* Remove the tcb task from the ready-to-run list.  If we
-		 * are blocking the task at the head of the task list (the
-		 * most likely case), then a context switch to the next
-		 * ready-to-run task is needed. In this case, it should
-		 * also be true that rtcb == tcb.
-		 */
-		switch_needed = sched_removereadytorun(tcb);
-
-		/* Add the task to the specified blocked task list */
-		sched_addblocked(tcb, (tstate_t)task_state);
-
-		/* Now, perform the context switch if one is needed */
-		if (switch_needed) {
-			struct tcb_s *nexttcb;
-			// this part should not be executed in interrupt context
-			if (up_interrupt_context()) {
-				panic("%s: %d\n", __func__, __LINE__);
-			}
-			// If there are any pending tasks, then add them to the g_readytorun
-			// task list now. It should be the up_realease_pending() called from
-			// sched_unlock() to do this for disable preemption. But it block 
-			// itself, so it's OK.
-			if (g_pendingtasks.head) {
-				warn("Disable preemption failed for task block itself\n");
-				sched_mergepending();
-			}
-			nexttcb = (struct tcb_s*)g_readytorun.head;
-			// context switch
-			up_switchcontext(rtcb, nexttcb);
+        struct tcb_s *rtcb = current_task;
+        bool switch_needed;
+
+        /* Remove the tcb task from the ready-to-run list.  If we
+         * are blocking the task at the head of the task list (the
+         * most likely case), then a context switch to the next
+         * ready-to-run task is needed. In this case, it should
+         * also be true that rtcb == tcb.
+         */
+        switch_needed = sched_removereadytorun(tcb);
+
+        /* Add the task to the specified blocked task list */
+        sched_addblocked(tcb, (tstate_t)task_state);
+
+        /* Now, perform the context switch if one is needed */
+        if (switch_needed) {
+            struct tcb_s *nexttcb;
+            // this part should not be executed in interrupt context
+            if (up_interrupt_context()) {
+                panic("%s: %d\n", __func__, __LINE__);
+            }
+            // If there are any pending tasks, then add them to the g_readytorun
+            // task list now. It should be the up_realease_pending() called from
+            // sched_unlock() to do this for disable preemption. But it block 
+            // itself, so it's OK.
+            if (g_pendingtasks.head) {
+                warn("Disable preemption failed for task block itself\n");
+                sched_mergepending();
+            }
+            nexttcb = (struct tcb_s*)g_readytorun.head;
+            // context switch
+            up_switchcontext(rtcb, nexttcb);
         }
     }
 }
@@ -256,31 +281,31 @@ void up_unblock_task(struct tcb_s *tcb)
 {
     /* Verify that the context switch can be performed */
     if ((tcb->task_state < FIRST_BLOCKED_STATE) ||
-		(tcb->task_state > LAST_BLOCKED_STATE)) {
-		warn("%s: task sched error\n", __func__);
-		return;
+        (tcb->task_state > LAST_BLOCKED_STATE)) {
+        warn("%s: task sched error\n", __func__);
+        return;
     }
     else {
-		struct tcb_s *rtcb = current_task;
+        struct tcb_s *rtcb = current_task;
 
-		/* Remove the task from the blocked task list */
-		sched_removeblocked(tcb);
+        /* Remove the task from the blocked task list */
+        sched_removeblocked(tcb);
 
-		/* Reset its timeslice.  This is only meaningful for round
-		 * robin tasks but it doesn't here to do it for everything
-		 */
+        /* Reset its timeslice.  This is only meaningful for round
+         * robin tasks but it doesn't here to do it for everything
+         */
 #if CONFIG_RR_INTERVAL > 0
-		tcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK;
+        tcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK;
 #endif
-	
-		// Add the task in the correct location in the prioritized
-		// g_readytorun task list.
-		if (sched_addreadytorun(tcb) && !up_interrupt_context()) {
-			/* The currently active task has changed! */
-			struct tcb_s *nexttcb = (struct tcb_s*)g_readytorun.head;
-			// context switch
-			up_switchcontext(rtcb, nexttcb);
-		}
+    
+        // Add the task in the correct location in the prioritized
+        // g_readytorun task list.
+        if (sched_addreadytorun(tcb) && !up_interrupt_context()) {
+            /* The currently active task has changed! */
+            struct tcb_s *nexttcb = (struct tcb_s*)g_readytorun.head;
+            // context switch
+            up_switchcontext(rtcb, nexttcb);
+        }
     }
 }
 
@@ -295,11 +320,11 @@ void up_release_pending(void)
     /* Merge the g_pendingtasks list into the g_readytorun task list */
 
     if (sched_mergepending()) {
-		/* The currently active task has changed! */
-		struct tcb_s *nexttcb = (struct tcb_s*)g_readytorun.head;
+        /* The currently active task has changed! */
+        struct tcb_s *nexttcb = (struct tcb_s*)g_readytorun.head;
 
-		// context switch
-		up_switchcontext(rtcb, nexttcb);
+        // context switch
+        up_switchcontext(rtcb, nexttcb);
     }
 }
 
@@ -308,54 +333,54 @@ void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
     /* Verify that the caller is sane */
 
     if (tcb->task_state < FIRST_READY_TO_RUN_STATE ||
-		tcb->task_state > LAST_READY_TO_RUN_STATE
+        tcb->task_state > LAST_READY_TO_RUN_STATE
 #if SCHED_PRIORITY_MIN > UINT8_MIN
-		|| priority < SCHED_PRIORITY_MIN
+        || priority < SCHED_PRIORITY_MIN
 #endif
 #if SCHED_PRIORITY_MAX < UINT8_MAX
-		|| priority > SCHED_PRIORITY_MAX
+        || priority > SCHED_PRIORITY_MAX
 #endif
-		) {
-		warn("%s: task sched error\n", __func__);
-		return;
+        ) {
+        warn("%s: task sched error\n", __func__);
+        return;
     }
     else {
-		struct tcb_s *rtcb = current_task;
-		bool switch_needed;
-
-		/* Remove the tcb task from the ready-to-run list.
-		 * sched_removereadytorun will return true if we just
-		 * remove the head of the ready to run list.
-		 */
-		switch_needed = sched_removereadytorun(tcb);
-
-		/* Setup up the new task priority */
-		tcb->sched_priority = (uint8_t)priority;
-
-		/* Return the task to the specified blocked task list.
-		 * sched_addreadytorun will return true if the task was
-		 * added to the new list.  We will need to perform a context
-		 * switch only if the EXCLUSIVE or of the two calls is non-zero
-		 * (i.e., one and only one the calls changes the head of the
-		 * ready-to-run list).
-		 */
-		switch_needed ^= sched_addreadytorun(tcb);
-
-		/* Now, perform the context switch if one is needed */
-		if (switch_needed && !up_interrupt_context()) {
-			struct tcb_s *nexttcb;
-			// If there are any pending tasks, then add them to the g_readytorun
-			// task list now. It should be the up_realease_pending() called from
-			// sched_unlock() to do this for disable preemption. But it block 
-			// itself, so it's OK.
-			if (g_pendingtasks.head) {
-				warn("Disable preemption failed for reprioritize task\n");
-				sched_mergepending();
+        struct tcb_s *rtcb = current_task;
+        bool switch_needed;
+
+        /* Remove the tcb task from the ready-to-run list.
+         * sched_removereadytorun will return true if we just
+         * remove the head of the ready to run list.
+         */
+        switch_needed = sched_removereadytorun(tcb);
+
+        /* Setup up the new task priority */
+        tcb->sched_priority = (uint8_t)priority;
+
+        /* Return the task to the specified blocked task list.
+         * sched_addreadytorun will return true if the task was
+         * added to the new list.  We will need to perform a context
+         * switch only if the EXCLUSIVE or of the two calls is non-zero
+         * (i.e., one and only one the calls changes the head of the
+         * ready-to-run list).
+         */
+        switch_needed ^= sched_addreadytorun(tcb);
+
+        /* Now, perform the context switch if one is needed */
+        if (switch_needed && !up_interrupt_context()) {
+            struct tcb_s *nexttcb;
+            // If there are any pending tasks, then add them to the g_readytorun
+            // task list now. It should be the up_realease_pending() called from
+            // sched_unlock() to do this for disable preemption. But it block 
+            // itself, so it's OK.
+            if (g_pendingtasks.head) {
+                warn("Disable preemption failed for reprioritize task\n");
+                sched_mergepending();
             }
 
-			nexttcb = (struct tcb_s*)g_readytorun.head;
-			// context switch
-			up_switchcontext(rtcb, nexttcb);
+            nexttcb = (struct tcb_s*)g_readytorun.head;
+            // context switch
+            up_switchcontext(rtcb, nexttcb);
         }
     }
 }
@@ -387,26 +412,26 @@ void up_assert(const uint8_t *filename, int line)
     // which will stop the OS
     // if in user space just terminate the task
     if (up_interrupt_context() || current_task->pid == 0) {
-		panic("%s: %d\n", __func__, __LINE__);
+        panic("%s: %d\n", __func__, __LINE__);
     }
     else {
-		exit(EXIT_FAILURE);
+        exit(EXIT_FAILURE);
     }
 }
 
 void up_assert_code(const uint8_t *filename, int line, int code)
 {
     fprintf(stderr, "Assertion failed at file:%s line: %d error code: %d\n", 
-			filename, line, code);
+            filename, line, code);
 
     // in interrupt context or idle task means kernel error 
     // which will stop the OS
     // if in user space just terminate the task
     if (up_interrupt_context() || current_task->pid == 0) {
-		panic("%s: %d\n", __func__, __LINE__);
+        panic("%s: %d\n", __func__, __LINE__);
     }
     else {
-		exit(EXIT_FAILURE);
+        exit(EXIT_FAILURE);
     }
 }
 
@@ -417,38 +442,38 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
 {
     /* Refuse to handle nested signal actions */
     if (!tcb->xcp.sigdeliver) {
-		int flags;
-
-		/* Make sure that interrupts are disabled */
-		local_irq_save(flags);
-
-		// First, handle some special cases when the signal is
-		// being delivered to the currently executing task.
-		if (tcb == current_task) {
-			// CASE 1:  We are not in an interrupt handler and
-			// a task is signalling itself for some reason.
-			if (!up_interrupt_context()) {
-				// In this case just deliver the signal now.
-				sigdeliver(tcb);
-			}
-			// CASE 2:  We are in an interrupt handler AND the
-			// interrupted task is the same as the one that
-			// must receive the signal.
-			else {
-				tcb->xcp.sigdeliver = sigdeliver;
+        int flags;
+
+        /* Make sure that interrupts are disabled */
+        local_irq_save(flags);
+
+        // First, handle some special cases when the signal is
+        // being delivered to the currently executing task.
+        if (tcb == current_task) {
+            // CASE 1:  We are not in an interrupt handler and
+            // a task is signalling itself for some reason.
+            if (!up_interrupt_context()) {
+                // In this case just deliver the signal now.
+                sigdeliver(tcb);
+            }
+            // CASE 2:  We are in an interrupt handler AND the
+            // interrupted task is the same as the one that
+            // must receive the signal.
+            else {
+                tcb->xcp.sigdeliver = sigdeliver;
             }
         }
 
-		// Otherwise, we are (1) signaling a task is not running
-		// from an interrupt handler or (2) we are not in an
-		// interrupt handler and the running task is signalling
-		// some non-running task.
-		else {
-			tcb->xcp.sigdeliver = sigdeliver;
-			push_xcptcontext(&tcb->xcp);
+        // Otherwise, we are (1) signaling a task is not running
+        // from an interrupt handler or (2) we are not in an
+        // interrupt handler and the running task is signalling
+        // some non-running task.
+        else {
+            tcb->xcp.sigdeliver = sigdeliver;
+            push_xcptcontext(&tcb->xcp);
         }
 
-		local_irq_restore(flags);
+        local_irq_restore(flags);
     }
 }
 
@@ -458,7 +483,7 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
 bool up_interrupt_context(void)
 {
     if (nest_irq)
-		return true;
+        return true;
     return false;
 }
 
@@ -497,7 +522,7 @@ void up_sigdeliver(struct Trapframe *tf)
 
 void up_cxxinitialize(void)
 {
-	rgmp_cxx_init();
+    rgmp_cxx_init();
 }
 
 #endif
diff --git a/arch/sh/src/common/up_createstack.c b/arch/sh/src/common/up_createstack.c
index 3ffdc30509eb57602ad2fe5982e420360d2b594c..5a22fd3e6e6d758886ebd9938a9e3714c7487503 100644
--- a/arch/sh/src/common/up_createstack.c
+++ b/arch/sh/src/common/up_createstack.c
@@ -101,30 +101,52 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Is there already a stack allocated of a different size? */
+  /* Is there already a stack allocated of a different size?  Because of
+   * alignment issues, stack_size might erroneously appear to be of a
+   * different size.  Fortunately, this is not a critical operation.
+   */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
     {
-      /* Yes.. free it */
+      /* Yes.. Release the old stack */
 
-      sched_ufree(tcb->stack_alloc_ptr);
-      tcb->stack_alloc_ptr = NULL;
+      up_release_stack(tcb, ttype);
     }
 
-  /* Do we need to allocate a stack? */
-
+  /* Do we need to allocate a new stack? */
+ 
   if (!tcb->stack_alloc_ptr)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
 #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
-      tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kzalloc(stack_size);
 #else
-      tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
 #endif
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+#if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
+          tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+#else
+          tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+#endif
+        }
+
 #ifdef CONFIG_DEBUG
+      /* Was the allocation successful? */
+
       if (!tcb->stack_alloc_ptr)
         {
           sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size);
diff --git a/arch/sh/src/common/up_releasestack.c b/arch/sh/src/common/up_releasestack.c
index 83257811870587c4d8ed3244203091fdafc9b0e8..e88e06d5232a790a958e3884ae5896b0914ed6d2 100644
--- a/arch/sh/src/common/up_releasestack.c
+++ b/arch/sh/src/common/up_releasestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  *  arch/sh/src/common/up_releasestack.c
  *
- *   Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,11 +91,31 @@
 
 void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
+  /* Is there a stack allocated? */
+
   if (dtcb->stack_alloc_ptr)
     {
-      sched_ufree(dtcb->stack_alloc_ptr);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          sched_kfree(dtcb->stack_alloc_ptr);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          sched_ufree(dtcb->stack_alloc_ptr);
+        }
+
+      /* Mark the stack freed */
+
       dtcb->stack_alloc_ptr = NULL;
     }
 
+  /* The size of the allocated stack is now zero */
+
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/sh/src/common/up_usestack.c b/arch/sh/src/common/up_usestack.c
index 7c2b9586ea0d370b6377c948de1f423bc34c87fc..bcce3261cdc850819650744cc7408fd864e8f17d 100644
--- a/arch/sh/src/common/up_usestack.c
+++ b/arch/sh/src/common/up_usestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * arch/sh/src/common/up_usestack.c
  *
- *   Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -94,13 +94,17 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+  /* Is there already a stack allocated? */
+
   if (tcb->stack_alloc_ptr)
     {
-      sched_ufree(tcb->stack_alloc_ptr);
-    }
+      /* Yes.. Release the old stack allocation */
 
-  /* Save the stack allocation */
+      up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK);
+    }
 
+  /* Save the new stack allocation */
+ 
   tcb->stack_alloc_ptr = stack;
 
   /* The Arm7Tdmi uses a push-down stack:  the stack grows
diff --git a/arch/sim/src/up_createstack.c b/arch/sim/src/up_createstack.c
index fe9986e65fa1243d8fc6d988f5650d949c197377..4115dd4ede149912f3ab7382ac5d0d3ba88322bf 100644
--- a/arch/sim/src/up_createstack.c
+++ b/arch/sim/src/up_createstack.c
@@ -102,6 +102,7 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
+  uint32_t *stack_alloc_ptr;
   int ret = ERROR;
 
   /* Move up to next even word boundary if necessary */
@@ -111,7 +112,21 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 
   /* Allocate the memory for the stack */
 
-  uint32_t *stack_alloc_ptr = (uint32_t*)kumalloc(adj_stack_size);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+  /* Use the kernel allocator if this is a kernel thread */
+
+  if (ttype == TCB_FLAG_TTYPE_KERNEL)
+    {
+      stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
+    }
+  else
+#endif
+    {
+      stack_alloc_ptr = (uint32_t*)kumalloc(adj_stack_size);
+    }
+
+  /* Was the allocation successful? */
+
   if (stack_alloc_ptr)
     {
       /* This is the address of the last word in the allocation */
diff --git a/arch/sim/src/up_releasestack.c b/arch/sim/src/up_releasestack.c
index 56413f341822ba42a11e93667835469530863df2..248f6b712c2f51ce89735645cfd057a95bb84911 100644
--- a/arch/sim/src/up_releasestack.c
+++ b/arch/sim/src/up_releasestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * up_releasestack.c
  *
- *   Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -93,11 +93,28 @@
 
 void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
+  /* Is there a stack allocated? */
+
   if (dtcb->stack_alloc_ptr)
     {
-      free(dtcb->stack_alloc_ptr);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          sched_kfree(dtcb->stack_alloc_ptr);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          sched_ufree(dtcb->stack_alloc_ptr);
+        }
     }
 
+  /* Mark the stack freed */
+
   dtcb->stack_alloc_ptr = NULL;
   dtcb->adj_stack_size  = 0;
   dtcb->adj_stack_ptr   = NULL;
diff --git a/arch/x86/src/i486/up_createstack.c b/arch/x86/src/i486/up_createstack.c
index bcce5fdcc43342556639e38e4a30e0f794f69a74..ae394dea6f332f11f075b11a11e86316009b9fcb 100644
--- a/arch/x86/src/i486/up_createstack.c
+++ b/arch/x86/src/i486/up_createstack.c
@@ -103,30 +103,52 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Is there already a stack allocated of a different size? */
+  /* Is there already a stack allocated of a different size?  Because of
+   * alignment issues, stack_size might erroneously appear to be of a
+   * different size.  Fortunately, this is not a critical operation.
+   */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
     {
-      /* Yes.. free it */
+      /* Yes.. Release the old stack */
 
-      sched_ufree(tcb->stack_alloc_ptr);
-      tcb->stack_alloc_ptr = NULL;
+      up_release_stack(tcb, ttype);
     }
 
-  /* Do we need to allocate a stack? */
-
+  /* Do we need to allocate a new stack? */
+ 
   if (!tcb->stack_alloc_ptr)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
 #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
-      tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kzalloc(stack_size);
 #else
-      tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
 #endif
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+#if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
+          tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+#else
+          tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+#endif
+        }
+
 #ifdef CONFIG_DEBUG
+      /* Was the allocation successful? */
+
       if (!tcb->stack_alloc_ptr)
         {
           sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size);
diff --git a/arch/x86/src/i486/up_releasestack.c b/arch/x86/src/i486/up_releasestack.c
index 0aa43ce58c795df1e88ae1018af8fa5d223310ab..8d264641f842de1d28e31b93e3e1d9df752991f1 100644
--- a/arch/x86/src/i486/up_releasestack.c
+++ b/arch/x86/src/i486/up_releasestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  *  arch/x86/src/common/up_releasestack.c
  *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,11 +91,31 @@
 
 void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
+  /* Is there a stack allocated? */
+
   if (dtcb->stack_alloc_ptr)
     {
-      sched_ufree(dtcb->stack_alloc_ptr);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          sched_kfree(dtcb->stack_alloc_ptr);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          sched_ufree(dtcb->stack_alloc_ptr);
+        }
+
+      /* Mark the stack freed */
+
       dtcb->stack_alloc_ptr = NULL;
     }
 
+  /* The size of the allocated stack is now zero */
+
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/x86/src/i486/up_usestack.c b/arch/x86/src/i486/up_usestack.c
index f972d895064f04a2c9d17de2999f02a6c7c098a2..b391599315ca4d8020ae4e70ea97ae12ca43a53d 100644
--- a/arch/x86/src/i486/up_usestack.c
+++ b/arch/x86/src/i486/up_usestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * arch/x86/src/common/up_usestack.c
  *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -94,12 +94,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+  /* Is there already a stack allocated? */
+
   if (tcb->stack_alloc_ptr)
     {
-      sched_ufree(tcb->stack_alloc_ptr);
+      /* Yes.. Release the old stack allocation */
+
+      up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK);
     }
 
-  /* Save the stack allocation */
+  /* Save the new stack allocation */
 
   tcb->stack_alloc_ptr = stack;
 
diff --git a/arch/z16/src/common/up_createstack.c b/arch/z16/src/common/up_createstack.c
index d523181692315868fe5c71ae8adbfefd192afe2f..2bd3a89514cef52a76edc57ca54ba5c30e1350d3 100644
--- a/arch/z16/src/common/up_createstack.c
+++ b/arch/z16/src/common/up_createstack.c
@@ -102,30 +102,52 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Is there already a stack allocated of a different size? */
+  /* Is there already a stack allocated of a different size?  Because of
+   * alignment issues, stack_size might erroneously appear to be of a
+   * different size.  Fortunately, this is not a critical operation.
+   */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
     {
-      /* Yes.. free it */
+      /* Yes.. Release the old stack */
 
-      sched_ufree(tcb->stack_alloc_ptr);
-      tcb->stack_alloc_ptr = NULL;
+      up_release_stack(tcb, ttype);
     }
 
-  /* Do we need to allocate a stack? */
-
+  /* Do we need to allocate a new stack? */
+ 
   if (!tcb->stack_alloc_ptr)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
 #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
-      tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kzalloc(stack_size);
 #else
-      tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
 #endif
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+#if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
+          tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+#else
+          tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+#endif
+        }
+
 #ifdef CONFIG_DEBUG
+      /* Was the allocation successful? */
+
       if (!tcb->stack_alloc_ptr)
         {
           sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size);
diff --git a/arch/z16/src/common/up_releasestack.c b/arch/z16/src/common/up_releasestack.c
index 84cc4be7d346530600f79c5cca34b1c05b086ecd..3d0842a5bd4c462bde8613a58c1daf2a6942b865 100644
--- a/arch/z16/src/common/up_releasestack.c
+++ b/arch/z16/src/common/up_releasestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * common/up_releasestack.c
  *
- *   Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,11 +91,31 @@
 
 void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
+  /* Is there a stack allocated? */
+
   if (dtcb->stack_alloc_ptr)
     {
-      sched_ufree(dtcb->stack_alloc_ptr);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          sched_kfree(dtcb->stack_alloc_ptr);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          sched_ufree(dtcb->stack_alloc_ptr);
+        }
+
+      /* Mark the stack freed */
+
       dtcb->stack_alloc_ptr = NULL;
     }
 
+  /* The size of the allocated stack is now zero */
+
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/z16/src/common/up_usestack.c b/arch/z16/src/common/up_usestack.c
index 6396ce9c270c595396d2f870caf72f154134e7e6..7b5effc45f9dacf947373d09e8071dbbf7af2346 100644
--- a/arch/z16/src/common/up_usestack.c
+++ b/arch/z16/src/common/up_usestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * arch/z16/common/up_usestack.c
  *
- *   Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2008-2009, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -94,12 +94,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+  /* Is there already a stack allocated? */
+
   if (tcb->stack_alloc_ptr)
     {
-      sched_ufree(tcb->stack_alloc_ptr);
+      /* Yes.. Release the old stack allocation */
+
+      up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK);
     }
 
-  /* Save the stack allocation */
+  /* Save the new stack allocation */
 
   tcb->stack_alloc_ptr = stack;
 
diff --git a/arch/z80/src/common/up_createstack.c b/arch/z80/src/common/up_createstack.c
index 1e47b09bdf454de6de4ac9d0d704610548fc25e3..a36a8aa7bfc434ab88e4870a8bd9138f7da0b760 100644
--- a/arch/z80/src/common/up_createstack.c
+++ b/arch/z80/src/common/up_createstack.c
@@ -101,30 +101,52 @@
 
 int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
 {
-  /* Is there already a stack allocated of a different size? */
+  /* Is there already a stack allocated of a different size?  Because of
+   * alignment issues, stack_size might erroneously appear to be of a
+   * different size.  Fortunately, this is not a critical operation.
+   */
 
   if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size)
     {
-      /* Yes.. free it */
+      /* Yes.. Release the old stack */
 
-      sched_ufree(tcb->stack_alloc_ptr);
-      tcb->stack_alloc_ptr = NULL;
+      up_release_stack(tcb, ttype);
     }
 
-  /* Do we need to allocate a stack? */
-
+  /* Do we need to allocate a new stack? */
+ 
   if (!tcb->stack_alloc_ptr)
     {
       /* Allocate the stack.  If DEBUG is enabled (but not stack debug),
        * then create a zeroed stack to make stack dumps easier to trace.
        */
 
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
 #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
-      tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kzalloc(stack_size);
 #else
-      tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+          tcb->stack_alloc_ptr = (uint32_t *)kmalloc(stack_size);
 #endif
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+#if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK)
+          tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size);
+#else
+          tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size);
+#endif
+        }
+
 #ifdef CONFIG_DEBUG
+      /* Was the allocation successful? */
+
       if (!tcb->stack_alloc_ptr)
         {
           sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size);
diff --git a/arch/z80/src/common/up_releasestack.c b/arch/z80/src/common/up_releasestack.c
index beefc474451c8165f97a3330da1d80fb438801d0..92c7bbd0a680360c081eb3c6bfb7f0bb6038c8bc 100644
--- a/arch/z80/src/common/up_releasestack.c
+++ b/arch/z80/src/common/up_releasestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * common/up_releasestack.c
  *
- *   Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,11 +91,31 @@
 
 void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
 {
+  /* Is there a stack allocated? */
+
   if (dtcb->stack_alloc_ptr)
     {
-      sched_ufree(dtcb->stack_alloc_ptr);
+#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
+      /* Use the kernel allocator if this is a kernel thread */
+
+      if (ttype == TCB_FLAG_TTYPE_KERNEL)
+        {
+          sched_kfree(dtcb->stack_alloc_ptr);
+        }
+      else
+#endif
+        {
+          /* Use the user-space allocator if this is a task or pthread */
+
+          sched_ufree(dtcb->stack_alloc_ptr);
+        }
+
+      /* Mark the stack freed */
+
       dtcb->stack_alloc_ptr = NULL;
     }
 
+  /* The size of the allocated stack is now zero */
+
   dtcb->adj_stack_size = 0;
 }
diff --git a/arch/z80/src/common/up_usestack.c b/arch/z80/src/common/up_usestack.c
index 8d322e7056428eaec82d17a3918ee83f851054ea..095b4f5d532387d81bb0b8a2611a6985e56599df 100644
--- a/arch/z80/src/common/up_usestack.c
+++ b/arch/z80/src/common/up_usestack.c
@@ -1,7 +1,7 @@
 /****************************************************************************
  * arch/z80/src/common/up_usestack.c
  *
- *   Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -93,12 +93,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
   size_t top_of_stack;
   size_t size_of_stack;
 
+  /* Is there already a stack allocated? */
+
   if (tcb->stack_alloc_ptr)
     {
-      sched_ufree(tcb->stack_alloc_ptr);
+      /* Yes.. Release the old stack allocation */
+
+      up_release_stack(tcb, tcb->flags & TCB_FLAG_TTYPE_MASK);
     }
 
-  /* Save the stack allocation */
+  /* Save the new stack allocation */
 
   tcb->stack_alloc_ptr = stack;