Add support for privileged heap to ARMV8-M ports (#85)

If xTaskCreate API is used to create a task, the task's stack is
allocated on heap using pvPortMalloc. This places the task's stack
in the privileged data section, if the heap is placed in the
privileged data section.

We use a separate MPU region to grant a task access to its stack.
If the task's stack is in the privileged data section, this results in
overlapping MPU regions as privileged data section is already protected
using a separate MPU region. ARMv8-M does not allow overlapping MPU
regions and this results in a fault. This commit ensures to not use a
separate MPU region for the task's stack if it lies within the
privileged data section.

Note that if the heap memory is placed in the privileged data section,
the xTaskCreate API cannot be used to create an unprivileged task as
the task's stack will be in the privileged data section and the task
won't have access to it. xTaskCreateRestricted and
xTaskCreateRestrictedStatic API should be used to create unprivileged
tasks.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c
index 3e42fab..e6089ca 100644
--- a/portable/ARMv8M/non_secure/port.c
+++ b/portable/ARMv8M/non_secure/port.c
@@ -1051,6 +1051,16 @@
     {

         uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;

         int32_t lIndex = 0;

+        #if defined( __ARMCC_VERSION )

+            /* Declaration when these variable are defined in code instead of being

+             * exported from linker scripts. */

+            extern uint32_t * __privileged_sram_start__;

+            extern uint32_t * __privileged_sram_end__;

+        #else

+            /* Declaration when these variable are exported from linker scripts. */

+            extern uint32_t __privileged_sram_start__[];

+            extern uint32_t __privileged_sram_end__[];

+        #endif /* defined( __ARMCC_VERSION ) */

 

         /* Setup MAIR0. */

         xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );

@@ -1062,19 +1072,34 @@
          * the stack region has already been configured. */

         if( ulStackDepth > 0 )

         {

-            /* Define the region that allows access to the stack. */

-            ulRegionStartAddress = ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK;

+            ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;

             ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;

-            ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

-                                                         ( portMPU_REGION_NON_SHAREABLE ) |

-                                                         ( portMPU_REGION_READ_WRITE ) |

-                                                         ( portMPU_REGION_EXECUTE_NEVER );

+            /* If the stack is within the privileged SRAM, do not protect it

+             * using a separate MPU region. This is needed because privileged

+             * SRAM is already protected using an MPU region and ARMv8-M does

+             * not allow overlapping MPU regions. */

+            if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&

+                ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )

+            {

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;

+            }

+            else

+            {

+                /* Define the region that allows access to the stack. */

+                ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;

+                ulRegionEndAddress  &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

-                                                         ( portMPU_RLAR_ATTR_INDEX0 ) |

-                                                         ( portMPU_RLAR_REGION_ENABLE );

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

+                                                             ( portMPU_REGION_NON_SHAREABLE ) |

+                                                             ( portMPU_REGION_READ_WRITE ) |

+                                                             ( portMPU_REGION_EXECUTE_NEVER );

+

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

+                                                             ( portMPU_RLAR_ATTR_INDEX0 ) |

+                                                             ( portMPU_RLAR_REGION_ENABLE );

+            }

         }

 

         /* User supplied configurable regions. */

diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c
index 3e42fab..e6089ca 100644
--- a/portable/GCC/ARM_CM23/non_secure/port.c
+++ b/portable/GCC/ARM_CM23/non_secure/port.c
@@ -1051,6 +1051,16 @@
     {

         uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;

         int32_t lIndex = 0;

+        #if defined( __ARMCC_VERSION )

+            /* Declaration when these variable are defined in code instead of being

+             * exported from linker scripts. */

+            extern uint32_t * __privileged_sram_start__;

+            extern uint32_t * __privileged_sram_end__;

+        #else

+            /* Declaration when these variable are exported from linker scripts. */

+            extern uint32_t __privileged_sram_start__[];

+            extern uint32_t __privileged_sram_end__[];

+        #endif /* defined( __ARMCC_VERSION ) */

 

         /* Setup MAIR0. */

         xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );

@@ -1062,19 +1072,34 @@
          * the stack region has already been configured. */

         if( ulStackDepth > 0 )

         {

-            /* Define the region that allows access to the stack. */

-            ulRegionStartAddress = ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK;

+            ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;

             ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;

-            ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

-                                                         ( portMPU_REGION_NON_SHAREABLE ) |

-                                                         ( portMPU_REGION_READ_WRITE ) |

-                                                         ( portMPU_REGION_EXECUTE_NEVER );

+            /* If the stack is within the privileged SRAM, do not protect it

+             * using a separate MPU region. This is needed because privileged

+             * SRAM is already protected using an MPU region and ARMv8-M does

+             * not allow overlapping MPU regions. */

+            if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&

+                ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )

+            {

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;

+            }

+            else

+            {

+                /* Define the region that allows access to the stack. */

+                ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;

+                ulRegionEndAddress  &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

-                                                         ( portMPU_RLAR_ATTR_INDEX0 ) |

-                                                         ( portMPU_RLAR_REGION_ENABLE );

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

+                                                             ( portMPU_REGION_NON_SHAREABLE ) |

+                                                             ( portMPU_REGION_READ_WRITE ) |

+                                                             ( portMPU_REGION_EXECUTE_NEVER );

+

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

+                                                             ( portMPU_RLAR_ATTR_INDEX0 ) |

+                                                             ( portMPU_RLAR_REGION_ENABLE );

+            }

         }

 

         /* User supplied configurable regions. */

diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c
index 3e42fab..e6089ca 100644
--- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c
+++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c
@@ -1051,6 +1051,16 @@
     {

         uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;

         int32_t lIndex = 0;

+        #if defined( __ARMCC_VERSION )

+            /* Declaration when these variable are defined in code instead of being

+             * exported from linker scripts. */

+            extern uint32_t * __privileged_sram_start__;

+            extern uint32_t * __privileged_sram_end__;

+        #else

+            /* Declaration when these variable are exported from linker scripts. */

+            extern uint32_t __privileged_sram_start__[];

+            extern uint32_t __privileged_sram_end__[];

+        #endif /* defined( __ARMCC_VERSION ) */

 

         /* Setup MAIR0. */

         xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );

@@ -1062,19 +1072,34 @@
          * the stack region has already been configured. */

         if( ulStackDepth > 0 )

         {

-            /* Define the region that allows access to the stack. */

-            ulRegionStartAddress = ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK;

+            ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;

             ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;

-            ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

-                                                         ( portMPU_REGION_NON_SHAREABLE ) |

-                                                         ( portMPU_REGION_READ_WRITE ) |

-                                                         ( portMPU_REGION_EXECUTE_NEVER );

+            /* If the stack is within the privileged SRAM, do not protect it

+             * using a separate MPU region. This is needed because privileged

+             * SRAM is already protected using an MPU region and ARMv8-M does

+             * not allow overlapping MPU regions. */

+            if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&

+                ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )

+            {

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;

+            }

+            else

+            {

+                /* Define the region that allows access to the stack. */

+                ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;

+                ulRegionEndAddress  &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

-                                                         ( portMPU_RLAR_ATTR_INDEX0 ) |

-                                                         ( portMPU_RLAR_REGION_ENABLE );

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

+                                                             ( portMPU_REGION_NON_SHAREABLE ) |

+                                                             ( portMPU_REGION_READ_WRITE ) |

+                                                             ( portMPU_REGION_EXECUTE_NEVER );

+

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

+                                                             ( portMPU_RLAR_ATTR_INDEX0 ) |

+                                                             ( portMPU_RLAR_REGION_ENABLE );

+            }

         }

 

         /* User supplied configurable regions. */

diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c
index 3e42fab..e6089ca 100644
--- a/portable/GCC/ARM_CM33/non_secure/port.c
+++ b/portable/GCC/ARM_CM33/non_secure/port.c
@@ -1051,6 +1051,16 @@
     {

         uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;

         int32_t lIndex = 0;

+        #if defined( __ARMCC_VERSION )

+            /* Declaration when these variable are defined in code instead of being

+             * exported from linker scripts. */

+            extern uint32_t * __privileged_sram_start__;

+            extern uint32_t * __privileged_sram_end__;

+        #else

+            /* Declaration when these variable are exported from linker scripts. */

+            extern uint32_t __privileged_sram_start__[];

+            extern uint32_t __privileged_sram_end__[];

+        #endif /* defined( __ARMCC_VERSION ) */

 

         /* Setup MAIR0. */

         xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );

@@ -1062,19 +1072,34 @@
          * the stack region has already been configured. */

         if( ulStackDepth > 0 )

         {

-            /* Define the region that allows access to the stack. */

-            ulRegionStartAddress = ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK;

+            ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;

             ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;

-            ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

-                                                         ( portMPU_REGION_NON_SHAREABLE ) |

-                                                         ( portMPU_REGION_READ_WRITE ) |

-                                                         ( portMPU_REGION_EXECUTE_NEVER );

+            /* If the stack is within the privileged SRAM, do not protect it

+             * using a separate MPU region. This is needed because privileged

+             * SRAM is already protected using an MPU region and ARMv8-M does

+             * not allow overlapping MPU regions. */

+            if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&

+                ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )

+            {

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;

+            }

+            else

+            {

+                /* Define the region that allows access to the stack. */

+                ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;

+                ulRegionEndAddress  &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

-                                                         ( portMPU_RLAR_ATTR_INDEX0 ) |

-                                                         ( portMPU_RLAR_REGION_ENABLE );

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

+                                                             ( portMPU_REGION_NON_SHAREABLE ) |

+                                                             ( portMPU_REGION_READ_WRITE ) |

+                                                             ( portMPU_REGION_EXECUTE_NEVER );

+

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

+                                                             ( portMPU_RLAR_ATTR_INDEX0 ) |

+                                                             ( portMPU_RLAR_REGION_ENABLE );

+            }

         }

 

         /* User supplied configurable regions. */

diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c
index 3e42fab..e6089ca 100644
--- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c
+++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c
@@ -1051,6 +1051,16 @@
     {

         uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;

         int32_t lIndex = 0;

+        #if defined( __ARMCC_VERSION )

+            /* Declaration when these variable are defined in code instead of being

+             * exported from linker scripts. */

+            extern uint32_t * __privileged_sram_start__;

+            extern uint32_t * __privileged_sram_end__;

+        #else

+            /* Declaration when these variable are exported from linker scripts. */

+            extern uint32_t __privileged_sram_start__[];

+            extern uint32_t __privileged_sram_end__[];

+        #endif /* defined( __ARMCC_VERSION ) */

 

         /* Setup MAIR0. */

         xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );

@@ -1062,19 +1072,34 @@
          * the stack region has already been configured. */

         if( ulStackDepth > 0 )

         {

-            /* Define the region that allows access to the stack. */

-            ulRegionStartAddress = ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK;

+            ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;

             ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;

-            ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

-                                                         ( portMPU_REGION_NON_SHAREABLE ) |

-                                                         ( portMPU_REGION_READ_WRITE ) |

-                                                         ( portMPU_REGION_EXECUTE_NEVER );

+            /* If the stack is within the privileged SRAM, do not protect it

+             * using a separate MPU region. This is needed because privileged

+             * SRAM is already protected using an MPU region and ARMv8-M does

+             * not allow overlapping MPU regions. */

+            if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&

+                ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )

+            {

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;

+            }

+            else

+            {

+                /* Define the region that allows access to the stack. */

+                ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;

+                ulRegionEndAddress  &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

-                                                         ( portMPU_RLAR_ATTR_INDEX0 ) |

-                                                         ( portMPU_RLAR_REGION_ENABLE );

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

+                                                             ( portMPU_REGION_NON_SHAREABLE ) |

+                                                             ( portMPU_REGION_READ_WRITE ) |

+                                                             ( portMPU_REGION_EXECUTE_NEVER );

+

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

+                                                             ( portMPU_RLAR_ATTR_INDEX0 ) |

+                                                             ( portMPU_RLAR_REGION_ENABLE );

+            }

         }

 

         /* User supplied configurable regions. */

diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c
index 3e42fab..e6089ca 100644
--- a/portable/IAR/ARM_CM23/non_secure/port.c
+++ b/portable/IAR/ARM_CM23/non_secure/port.c
@@ -1051,6 +1051,16 @@
     {

         uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;

         int32_t lIndex = 0;

+        #if defined( __ARMCC_VERSION )

+            /* Declaration when these variable are defined in code instead of being

+             * exported from linker scripts. */

+            extern uint32_t * __privileged_sram_start__;

+            extern uint32_t * __privileged_sram_end__;

+        #else

+            /* Declaration when these variable are exported from linker scripts. */

+            extern uint32_t __privileged_sram_start__[];

+            extern uint32_t __privileged_sram_end__[];

+        #endif /* defined( __ARMCC_VERSION ) */

 

         /* Setup MAIR0. */

         xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );

@@ -1062,19 +1072,34 @@
          * the stack region has already been configured. */

         if( ulStackDepth > 0 )

         {

-            /* Define the region that allows access to the stack. */

-            ulRegionStartAddress = ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK;

+            ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;

             ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;

-            ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

-                                                         ( portMPU_REGION_NON_SHAREABLE ) |

-                                                         ( portMPU_REGION_READ_WRITE ) |

-                                                         ( portMPU_REGION_EXECUTE_NEVER );

+            /* If the stack is within the privileged SRAM, do not protect it

+             * using a separate MPU region. This is needed because privileged

+             * SRAM is already protected using an MPU region and ARMv8-M does

+             * not allow overlapping MPU regions. */

+            if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&

+                ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )

+            {

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;

+            }

+            else

+            {

+                /* Define the region that allows access to the stack. */

+                ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;

+                ulRegionEndAddress  &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

-                                                         ( portMPU_RLAR_ATTR_INDEX0 ) |

-                                                         ( portMPU_RLAR_REGION_ENABLE );

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

+                                                             ( portMPU_REGION_NON_SHAREABLE ) |

+                                                             ( portMPU_REGION_READ_WRITE ) |

+                                                             ( portMPU_REGION_EXECUTE_NEVER );

+

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

+                                                             ( portMPU_RLAR_ATTR_INDEX0 ) |

+                                                             ( portMPU_RLAR_REGION_ENABLE );

+            }

         }

 

         /* User supplied configurable regions. */

diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c
index 3e42fab..e6089ca 100644
--- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c
+++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c
@@ -1051,6 +1051,16 @@
     {

         uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;

         int32_t lIndex = 0;

+        #if defined( __ARMCC_VERSION )

+            /* Declaration when these variable are defined in code instead of being

+             * exported from linker scripts. */

+            extern uint32_t * __privileged_sram_start__;

+            extern uint32_t * __privileged_sram_end__;

+        #else

+            /* Declaration when these variable are exported from linker scripts. */

+            extern uint32_t __privileged_sram_start__[];

+            extern uint32_t __privileged_sram_end__[];

+        #endif /* defined( __ARMCC_VERSION ) */

 

         /* Setup MAIR0. */

         xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );

@@ -1062,19 +1072,34 @@
          * the stack region has already been configured. */

         if( ulStackDepth > 0 )

         {

-            /* Define the region that allows access to the stack. */

-            ulRegionStartAddress = ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK;

+            ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;

             ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;

-            ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

-                                                         ( portMPU_REGION_NON_SHAREABLE ) |

-                                                         ( portMPU_REGION_READ_WRITE ) |

-                                                         ( portMPU_REGION_EXECUTE_NEVER );

+            /* If the stack is within the privileged SRAM, do not protect it

+             * using a separate MPU region. This is needed because privileged

+             * SRAM is already protected using an MPU region and ARMv8-M does

+             * not allow overlapping MPU regions. */

+            if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&

+                ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )

+            {

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;

+            }

+            else

+            {

+                /* Define the region that allows access to the stack. */

+                ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;

+                ulRegionEndAddress  &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

-                                                         ( portMPU_RLAR_ATTR_INDEX0 ) |

-                                                         ( portMPU_RLAR_REGION_ENABLE );

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

+                                                             ( portMPU_REGION_NON_SHAREABLE ) |

+                                                             ( portMPU_REGION_READ_WRITE ) |

+                                                             ( portMPU_REGION_EXECUTE_NEVER );

+

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

+                                                             ( portMPU_RLAR_ATTR_INDEX0 ) |

+                                                             ( portMPU_RLAR_REGION_ENABLE );

+            }

         }

 

         /* User supplied configurable regions. */

diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c
index 3e42fab..e6089ca 100644
--- a/portable/IAR/ARM_CM33/non_secure/port.c
+++ b/portable/IAR/ARM_CM33/non_secure/port.c
@@ -1051,6 +1051,16 @@
     {

         uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;

         int32_t lIndex = 0;

+        #if defined( __ARMCC_VERSION )

+            /* Declaration when these variable are defined in code instead of being

+             * exported from linker scripts. */

+            extern uint32_t * __privileged_sram_start__;

+            extern uint32_t * __privileged_sram_end__;

+        #else

+            /* Declaration when these variable are exported from linker scripts. */

+            extern uint32_t __privileged_sram_start__[];

+            extern uint32_t __privileged_sram_end__[];

+        #endif /* defined( __ARMCC_VERSION ) */

 

         /* Setup MAIR0. */

         xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );

@@ -1062,19 +1072,34 @@
          * the stack region has already been configured. */

         if( ulStackDepth > 0 )

         {

-            /* Define the region that allows access to the stack. */

-            ulRegionStartAddress = ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK;

+            ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;

             ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;

-            ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

-                                                         ( portMPU_REGION_NON_SHAREABLE ) |

-                                                         ( portMPU_REGION_READ_WRITE ) |

-                                                         ( portMPU_REGION_EXECUTE_NEVER );

+            /* If the stack is within the privileged SRAM, do not protect it

+             * using a separate MPU region. This is needed because privileged

+             * SRAM is already protected using an MPU region and ARMv8-M does

+             * not allow overlapping MPU regions. */

+            if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&

+                ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )

+            {

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;

+            }

+            else

+            {

+                /* Define the region that allows access to the stack. */

+                ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;

+                ulRegionEndAddress  &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

-                                                         ( portMPU_RLAR_ATTR_INDEX0 ) |

-                                                         ( portMPU_RLAR_REGION_ENABLE );

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

+                                                             ( portMPU_REGION_NON_SHAREABLE ) |

+                                                             ( portMPU_REGION_READ_WRITE ) |

+                                                             ( portMPU_REGION_EXECUTE_NEVER );

+

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

+                                                             ( portMPU_RLAR_ATTR_INDEX0 ) |

+                                                             ( portMPU_RLAR_REGION_ENABLE );

+            }

         }

 

         /* User supplied configurable regions. */

diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c
index 3e42fab..e6089ca 100644
--- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c
+++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c
@@ -1051,6 +1051,16 @@
     {

         uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;

         int32_t lIndex = 0;

+        #if defined( __ARMCC_VERSION )

+            /* Declaration when these variable are defined in code instead of being

+             * exported from linker scripts. */

+            extern uint32_t * __privileged_sram_start__;

+            extern uint32_t * __privileged_sram_end__;

+        #else

+            /* Declaration when these variable are exported from linker scripts. */

+            extern uint32_t __privileged_sram_start__[];

+            extern uint32_t __privileged_sram_end__[];

+        #endif /* defined( __ARMCC_VERSION ) */

 

         /* Setup MAIR0. */

         xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );

@@ -1062,19 +1072,34 @@
          * the stack region has already been configured. */

         if( ulStackDepth > 0 )

         {

-            /* Define the region that allows access to the stack. */

-            ulRegionStartAddress = ( ( uint32_t ) pxBottomOfStack ) & portMPU_RBAR_ADDRESS_MASK;

+            ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;

             ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;

-            ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

-                                                         ( portMPU_REGION_NON_SHAREABLE ) |

-                                                         ( portMPU_REGION_READ_WRITE ) |

-                                                         ( portMPU_REGION_EXECUTE_NEVER );

+            /* If the stack is within the privileged SRAM, do not protect it

+             * using a separate MPU region. This is needed because privileged

+             * SRAM is already protected using an MPU region and ARMv8-M does

+             * not allow overlapping MPU regions. */

+            if( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ &&

+                ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ )

+            {

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;

+            }

+            else

+            {

+                /* Define the region that allows access to the stack. */

+                ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;

+                ulRegionEndAddress  &= portMPU_RLAR_ADDRESS_MASK;

 

-            xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

-                                                         ( portMPU_RLAR_ATTR_INDEX0 ) |

-                                                         ( portMPU_RLAR_REGION_ENABLE );

+                xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |

+                                                             ( portMPU_REGION_NON_SHAREABLE ) |

+                                                             ( portMPU_REGION_READ_WRITE ) |

+                                                             ( portMPU_REGION_EXECUTE_NEVER );

+

+                xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |

+                                                             ( portMPU_RLAR_ATTR_INDEX0 ) |

+                                                             ( portMPU_RLAR_REGION_ENABLE );

+            }

         }

 

         /* User supplied configurable regions. */