<div dir="ltr">Kindly ignore this patch. It breaks the build.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jul 16, 2020 at 4:54 PM Utkarsh Rai <<a href="mailto:utkarsh.rai60@gmail.com">utkarsh.rai60@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">- This is the complete set of changes for strict isolation of thread stacks.<br>
- There needs to be a confiuration operation,(#if defined(USE_THREAD_STACK_PROTECTION) for simple configuration can be used)<br>
- The stack attributes are allocated through malloc, this needs to be done through score unlimited objects.<br>
<br>
Mechanism for thread-stack isolation<br>
- Whenever a stack is allocated we assign READ_WRITE  memory attributes to the memory region, the stack attribute structure is appended to a chain for tracking<br>
- On each context switch, the executing stack is marked as 'not-current' and we unset its memory attributes. The heir stack is marked as 'current'<br>
- On context restore we set the memory attributes of the heir stack and iterate thorugh the chain to check for any other 'current' stack and unset its memory<br>
  attribute (This requires some refinement, so that we don't have to iterate over the chain).<br>
---<br>
 .../include/bsp/arm-cp15-set-ttb-entries.h    |   0<br>
 bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c   |  79 ++++++++<br>
 bsps/shared/start/stackalloc.c                |  16 ++<br>
 c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am  |   5 +-<br>
 cpukit/Makefile.am                            |   1 +<br>
 cpukit/<a href="http://headers.am" rel="noreferrer" target="_blank">headers.am</a>                             |   2 +<br>
 cpukit/include/rtems/score/memorymanagement.h |  89 +++++++++<br>
 cpukit/include/rtems/score/stackprotection.h  | 149 ++++++++++++++<br>
 cpukit/score/cpu/arm/cpu.c                    |   4 +<br>
 cpukit/score/cpu/arm/cpu_asm.S                |  45 ++++-<br>
 .../score/cpu/arm/include/rtems/score/cpu.h   |  18 ++<br>
 cpukit/score/src/stackprotection.c            | 188 ++++++++++++++++++<br>
 12 files changed, 593 insertions(+), 3 deletions(-)<br>
 create mode 100644 bsps/arm/include/bsp/arm-cp15-set-ttb-entries.h<br>
 create mode 100644 bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c<br>
 create mode 100644 cpukit/include/rtems/score/memorymanagement.h<br>
 create mode 100644 cpukit/include/rtems/score/stackprotection.h<br>
 create mode 100644 cpukit/score/src/stackprotection.c<br>
<br>
diff --git a/bsps/arm/include/bsp/arm-cp15-set-ttb-entries.h b/bsps/arm/include/bsp/arm-cp15-set-ttb-entries.h<br>
new file mode 100644<br>
index 0000000000..e69de29bb2<br>
diff --git a/bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c b/bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c<br>
new file mode 100644<br>
index 0000000000..0c82f113a9<br>
--- /dev/null<br>
+++ b/bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c<br>
@@ -0,0 +1,79 @@<br>
+#include <bsp/arm-cp15-start.h><br>
+#include <rtems/score/memorymanagement.h><br>
+#include <libcpu/arm-cp15.h><br>
+#include <rtems.h><br>
+<br>
+#ifdef USE_THREAD_STACK_PROTECTION<br>
+  #define ARM_MMU_USE_SMALL_PAGES<br>
+#endif<br>
+    <br>
+void Memorymanagement_Set_entries(uintptr_t begin, size_t size, Memorymanagement_flags flags)<br>
+{<br>
+   <br>
+    uintptr_t end;<br>
+    rtems_interrupt_level irq_level;<br>
+    uint32_t access_flags;<br>
+<br>
+    end = begin + size;<br>
+    access_flags = Memorymanagement_Translate_flags(flags);<br>
+    <br>
+    /**<br>
+     *  The ARM reference manual instructs to disable all the interrupts before<br>
+     * setting up page table entries.<br>
+    */<br>
+    rtems_interrupt_disable(irq_level);<br>
+    arm_cp15_set_translation_table_entries(begin, end, access_flags); <br>
+    rtems_interrupt_enable(irq_level);<br>
+}<br>
+<br>
+void Memorymanagement_Unset_entries(uintptr_t begin, size_t size)<br>
+{<br>
+  uint32_t access_flags;<br>
+  uintptr_t end;<br>
+  rtems_interrupt_level irq_level;<br>
+<br>
+  end = begin + size;<br>
+  access_flags = Memorymanagement_Translate_flags(NO_ACCESS);<br>
+<br>
+   /**<br>
+     *  The ARM reference manual instructs to disable all the interrupts before<br>
+     * setting up page table entries.<br>
+    */<br>
+  rtems_interrupt_disable(irq_level);<br>
+  arm_cp15_set_translation_table_entries(begin, end, access_flags); <br>
+  rtems_interrupt_enable(irq_level);<br>
+}<br>
+<br>
+<br>
+uint32_t Memorymanagement_Translate_flags(Memorymanagement_flags attr_flags)<br>
+{<br>
+  uint32_t flags;<br>
+  switch (attr_flags)<br>
+  {<br>
+  case READ_WRITE: <br>
+     flags = ARMV7_MMU_READ_WRITE;<br>
+  break;<br>
+<br>
+  case READ_WRITE_CACHED:<br>
+    flags = ARMV7_MMU_DATA_READ_WRITE_CACHED;<br>
+  break;<br>
+<br>
+  case READ_ONLY:<br>
+    flags = ARMV7_MMU_READ_ONLY;<br>
+  break;<br>
+<br>
+  case READ_ONLY_CACHED:<br>
+    flags = ARMV7_MMU_READ_ONLY_CACHED;<br>
+  break;<br>
+<br>
+  case NO_ACCESS:<br>
+    flags = 0;<br>
+  break;<br>
+  <br>
+  default:<br>
+     return 0;<br>
+  break;<br>
+  }<br>
+<br>
+  return flags;<br>
+}<br>
\ No newline at end of file<br>
diff --git a/bsps/shared/start/stackalloc.c b/bsps/shared/start/stackalloc.c<br>
index f7cf7be0f1..ea8028c8db 100644<br>
--- a/bsps/shared/start/stackalloc.c<br>
+++ b/bsps/shared/start/stackalloc.c<br>
@@ -25,6 +25,7 @@<br>
 #include <rtems.h><br>
 #include <rtems/score/heapimpl.h><br>
 #include <rtems/score/wkspace.h><br>
+#include <rtems/score/stackprotection.h><br>
<br>
 #include <bsp/linker-symbols.h><br>
<br>
@@ -43,6 +44,7 @@ void bsp_stack_allocate_init(size_t stack_space_size)<br>
 void *bsp_stack_allocate(size_t size)<br>
 {<br>
   void *stack = NULL;<br>
+  uintptr_t  page_table_base;<br>
<br>
   if (bsp_stack_heap.area_begin != 0) {<br>
     stack = _Heap_Allocate(&bsp_stack_heap, size);<br>
@@ -52,6 +54,20 @@ void *bsp_stack_allocate(size_t size)<br>
     stack = _Workspace_Allocate(size);<br>
   }<br>
<br>
+#ifdef USE_THREAD_STACK_PROTECTION<br>
+  /**<br>
+   *  Although we are not performing page table switching, still we assign a value <br>
+   * to avoid compiler warniing. <br>
+  */<br>
+  page_table_base = (uintptr_t)0x1000;   <br>
+<br>
+  /**<br>
+   * The current way to get protected stack is to assign memory attributes<br>
+   *  to the allocated memory.<br>
+  */<br>
+  _Stackprotection_Allocate_attr( (uintptr_t)stack, size, page_table_base );<br>
+<br>
+#endif<br>
   return stack;<br>
 }<br>
<br>
diff --git a/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am b/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am<br>
index cfd59475c2..490f99792e 100644<br>
--- a/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am<br>
+++ b/c/src/lib/libbsp/arm/xilinx-zynq/Makefile.am<br>
@@ -74,6 +74,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/i2c/cadence-i2c.<br>
 # Cache<br>
 librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/cache/cache-l2c-310.c<br>
<br>
+#MMU<br>
+librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/mmu/bsp-set-mmu-attr.c<br>
+<br>
 # Start hooks<br>
 librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/start/bspstarthooks.c<br>
 librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/start/bspstartmmu.c<br>
@@ -85,4 +88,4 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/xilinx-zynq/start/bspstartmm<br>
<br>
 include $(srcdir)/../../../../../../bsps/shared/<a href="http://irq-sources.am" rel="noreferrer" target="_blank">irq-sources.am</a><br>
 include $(srcdir)/../../../../../../bsps/shared/<a href="http://shared-sources.am" rel="noreferrer" target="_blank">shared-sources.am</a><br>
-include $(srcdir)/../../../../../../bsps/arm/xilinx-zynq/<a href="http://headers.am" rel="noreferrer" target="_blank">headers.am</a><br>
+include $(srcdir)/../../../../../../bsps/arm/xilinx-zynq/<a href="http://headers.am" rel="noreferrer" target="_blank">headers.am</a><br>
\ No newline at end of file<br>
diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am<br>
index 51f38c84c7..83f9bfb3ef 100644<br>
--- a/cpukit/Makefile.am<br>
+++ b/cpukit/Makefile.am<br>
@@ -929,6 +929,7 @@ librtemscpu_a_SOURCES += score/src/schedulercbsgetserverid.c<br>
 librtemscpu_a_SOURCES += score/src/schedulercbssetparameters.c<br>
 librtemscpu_a_SOURCES += score/src/schedulercbsreleasejob.c<br>
 librtemscpu_a_SOURCES += score/src/schedulercbsunblock.c<br>
+librtemscpu_a_SOURCES += score/src/stackprotection.c<br>
 librtemscpu_a_SOURCES += score/src/stackallocator.c<br>
 librtemscpu_a_SOURCES += score/src/pheapallocate.c<br>
 librtemscpu_a_SOURCES += score/src/pheapextend.c<br>
diff --git a/cpukit/<a href="http://headers.am" rel="noreferrer" target="_blank">headers.am</a> b/cpukit/<a href="http://headers.am" rel="noreferrer" target="_blank">headers.am</a><br>
index fcf679f09d..2f16c71d9c 100644<br>
--- a/cpukit/<a href="http://headers.am" rel="noreferrer" target="_blank">headers.am</a><br>
+++ b/cpukit/<a href="http://headers.am" rel="noreferrer" target="_blank">headers.am</a><br>
@@ -352,6 +352,7 @@ include_rtems_score_HEADERS += include/rtems/score/isr.h<br>
 include_rtems_score_HEADERS += include/rtems/score/isrlevel.h<br>
 include_rtems_score_HEADERS += include/rtems/score/isrlock.h<br>
 include_rtems_score_HEADERS += include/rtems/score/memory.h<br>
+include_rtems_score_HEADERS += include/rtems/score/memorymanagement.h<br>
 include_rtems_score_HEADERS += include/rtems/score/mpci.h<br>
 include_rtems_score_HEADERS += include/rtems/score/mpciimpl.h<br>
 include_rtems_score_HEADERS += include/rtems/score/mppkt.h<br>
@@ -405,6 +406,7 @@ include_rtems_score_HEADERS += include/rtems/score/smplockstats.h<br>
 include_rtems_score_HEADERS += include/rtems/score/smplockticket.h<br>
 include_rtems_score_HEADERS += include/rtems/score/stack.h<br>
 include_rtems_score_HEADERS += include/rtems/score/stackimpl.h<br>
+include_rtems_score_HEADERS += include/rtems/score/stackprotection.h<br>
 include_rtems_score_HEADERS += include/rtems/score/states.h<br>
 include_rtems_score_HEADERS += include/rtems/score/statesimpl.h<br>
 include_rtems_score_HEADERS += include/rtems/score/status.h<br>
diff --git a/cpukit/include/rtems/score/memorymanagement.h b/cpukit/include/rtems/score/memorymanagement.h<br>
new file mode 100644<br>
index 0000000000..2a5490c680<br>
--- /dev/null<br>
+++ b/cpukit/include/rtems/score/memorymanagement.h<br>
@@ -0,0 +1,89 @@<br>
+/* SPDX-License-Identifier: BSD-2-Clause */<br>
+<br>
+/**<br>
+ * @file<br>
+ *<br>
+ * @ingroup RTEMSScoreMemorymanagement<br>
+ *<br>
+ * @brief This file provodes APIs for high-level memory management<br>
+ * <br>
+ */<br>
+<br>
+/*<br>
+ * Copyright (C) 2020 Utkarsh Rai<br>
+ *<br>
+ * Redistribution and use in source and binary forms, with or without<br>
+ * modification, are permitted provided that the following conditions<br>
+ * are met:<br>
+ * 1. Redistributions of source code must retain the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer.<br>
+ * 2. Redistributions in binary form must reproduce the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer in the<br>
+ *    documentation and/or other materials provided with the distribution.<br>
+ *<br>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"<br>
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE<br>
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE<br>
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE<br>
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR<br>
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF<br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS<br>
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN<br>
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)<br>
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE<br>
+ * POSSIBILITY OF SUCH DAMAGE.<br>
+ */<br>
+<br>
+#ifndef _RTEMS_SCORE_MEMORYMANAGEMENT_H<br>
+#define _RTEMS_SCORE_MEMORYMANAGEMENT_H<br>
+<br>
+#include <rtems/score/basedefs.h><br>
+<br>
+#ifdef __cplusplus<br>
+extern "C" {<br>
+#endif<br>
+<br>
+/** This defines the various high-level memory access flags.*/<br>
+typedef enum<br>
+{<br>
+    READ_WRITE,<br>
+    READ_WRITE_CACHED,<br>
+    READ_ONLY,<br>
+    READ_ONLY_CACHED,<br>
+    NO_ACCESS<br>
+} Memorymanagement_flags;<br>
+<br>
+/**<br>
+ * @brief Define the memory access permission for the specified memory region<br>
+ * <br>
+ * @param begin_addr Begining of the memory region<br>
+ * @param size Size of the memory region<br>
+ * @param flag Memory access flag<br>
+ * <br>
+ */<br>
+void Memorymanagement_Set_entries(uintptr_t begin_addr, size_t size, Memorymanagement_flags flag);<br>
+<br>
+/**<br>
+ * @brief Unset the memory access permission for the specified memory region<br>
+ * This operation implcitly sets the specified memory region with 'NO_ACCESS'<br>
+ * flag.<br>
+ * <br>
+ * @param begin_addr Begining of the memory region<br>
+ * @param size Size of the memory region<br>
+ */<br>
+void Memorymanagement_Unset_entries(uintptr_t begin_addr, size_t size);<br>
+<br>
+/**<br>
+ * @brief Translate the high-level flags to BSP-specifc MMU flags.<br>
+ * <br>
+ * @param attr_flags High-level memory access flags.<br>
+ * <br>
+ * @retval flag BSP-specifc MMU flag<br>
+ */<br>
+uint32_t Memorymanagement_Translate_flags(Memorymanagement_flags attr_flags);<br>
+<br>
+#ifdef __cplusplus<br>
+}<br>
+#endif<br>
+<br>
+#endif<br>
\ No newline at end of file<br>
diff --git a/cpukit/include/rtems/score/stackprotection.h b/cpukit/include/rtems/score/stackprotection.h<br>
new file mode 100644<br>
index 0000000000..91e3f6daba<br>
--- /dev/null<br>
+++ b/cpukit/include/rtems/score/stackprotection.h<br>
@@ -0,0 +1,149 @@<br>
+/**<br>
+ * @file<br>
+ *<br>
+ * @ingroup RTEMSScoreStackprotection<br>
+ *<br>
+ * @brief Stackprotection API<br>
+ *<br>
+ * This include file provides the API for the management of protected thread-<br>
+ * stacks<br>
+ */<br>
+<br>
+/*<br>
+ *  COPYRIGHT (c) 2020 Utkarsh Rai.<br>
+ * <br>
+ * Redistribution and use in source and binary forms, with or without <br>
+ * modification, are permitted provided that the following conditions <br>
+ * are met: <br>
+ * 1. Redistributions of source code must retain the above copyright <br>
+ * notice, this list of conditions and the following disclaimer.<br>
+ * 2. Redistributions in binary form must reproduce the above copyright <br>
+ * notice, this list of conditions and the following disclaimer in the<br>
+ * documentation and/or other materials provided with the distribution.<br>
+ * <br>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" <br>
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE <br>
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE <br>
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE <br>
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR <br>
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF <br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS <br>
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN <br>
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) <br>
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE <br>
+ * POSSIBILITY OF SUCH DAMAGE.<br>
+ * <br>
+ */<br>
+<br>
+#ifndef _RTEMS_SCORE_STACKPROTECTION_H<br>
+#define _RTEMS_SCORE_STACKPROTECTION_H<br>
+<br>
+#if defined ( ASM )<br>
+#include <rtems/asm.h><br>
+#else<br>
+  #include <rtems/score/basedefs.h><br>
+  #include <rtems/score/memorymanagement.h><br>
+  #include <rtems/score/chainimpl.h><br>
+#endif<br>
+<br>
+#ifdef __cplusplus<br>
+extern "C" {<br>
+#endif<br>
+<br>
+#if !defined ( ASM )<br>
+<br>
+/**<br>
+ * The following defines the attributes of a protected stack<br>
+ */<br>
+typedef struct<br>
+{<br>
+  /** This is the node to the chain for tracking each allocated/shared stack */<br>
+  Chain_Node    node; <br>
+  /** This is the stack address */<br>
+  uintptr_t        stack_address;<br>
+  /** This is the stack size */<br>
+  size_t        size;<br>
+  /** This is the pointer to the page table base */<br>
+  uintptr_t      page_table_base;<br>
+  /**Memory flag for the alllocated/shared stack */<br>
+  Memorymanagement_flags  access_flags;<br>
+} Stackprotection_Attr;<br>
+<br>
+/**<br>
+ * The following defines the control block  of a shared stack<br>
+ */<br>
+typedef struct <br>
+{<br>
+  /** This is the attribute of a shared stack*/<br>
+  Stackprotection_Attr    Base;<br>
+} Stackprotection_Shared_stack;<br>
+<br>
+/**<br>
+ * The following defines the control block of an allocated stack <br>
+ */<br>
+typedef struct<br>
+{ <br>
+  /** This is the attribute of an allocated stack*/<br>
+  Stackprotection_Attr    Base;<br>
+  /** This is the pointer to the attributes of a stack shared with the stack <br>
+   * in question<br>
+   */<br>
+  Stackprotection_Shared_stack  *shared_stacks; <br>
+  /**This marks if the stack in question belongs to an executing thread*/<br>
+  bool          current_stack;  <br>
+} Stackprotection_The_stack;<br>
+<br>
+/**<br>
+ * @brief Allocate the attributes of the stack in question.<br>
+ *<br>
+ * @param freechain The stack address.<br>
+ * @param size Size of the stack.<br>
+ * @param page_table_base Pointer to the start of a page table<br>
+ */<br>
+void _Stackprotection_Allocate_attr(uintptr_t stack_address, size_t size, uintptr_t page_table_base);<br>
+<br>
+/**<br>
+ * @brief Share a stack with another stack.<br>
+ * <br>
+ * @param shared_stack The stack to be shared<br>
+ * @param target_stack The stack with which to share<br>
+ */<br>
+void _Stackprotection_Share_stack(Stackprotection_The_stack *shared_stack, Stackprotection_The_stack* target_stack);<br>
+<br>
+/**<br>
+ * @brief Initialize the context of a thread with the control block of a <br>
+ * protected stack<br>
+ * <br>
+ * @retval the_stack The protected stack<br>
+ */ <br>
+Stackprotection_The_stack *_Stackprotection_Context_initialize(void);<br>
+<br>
+/**<br>
+ * @brief Swap out the executing protected stack from the page table during <br>
+ * context switch<br>
+ * <br>
+ * The current method of switching the protected stack is to mark the switched<br>
+ * out stack as 'NO ACCESS'<br>
+ * <br>
+ * @param excuting_stack Control block of the executing stack<br>
+ */<br>
+void _Stackprotection_Context_switch(Stackprotection_The_stack *executing_stack, Stackprotection_The_stack *heir_stack);<br>
+<br>
+/**<br>
+ * @brief Swap the restored protected stack  in the page table during context<br>
+ * restoration<br>
+ * <br>
+ * We set the entries of the restored stack and mark all the remainig stacks as<br>
+ * 'NO-ACCESS'.<br>
+ * <br>
+ * @param Control block of the restored stack<br>
+ */ <br>
+void _Stackprotection_Context_restore(Stackprotection_The_stack *restored_stack);<br>
+<br>
+#endif /* !defined ( ASM ) */<br>
+<br>
+#ifdef __cplusplus<br>
+}<br>
+#endif<br>
+<br>
+#endif<br>
diff --git a/cpukit/score/cpu/arm/cpu.c b/cpukit/score/cpu/arm/cpu.c<br>
index 07b9588afd..cbb62d45e5 100644<br>
--- a/cpukit/score/cpu/arm/cpu.c<br>
+++ b/cpukit/score/cpu/arm/cpu.c<br>
@@ -28,6 +28,7 @@<br>
<br>
 #include <rtems/score/assert.h><br>
 #include <rtems/score/cpu.h><br>
+#include <rtems/score/stackprotection.h><br>
 #include <rtems/score/thread.h><br>
 #include <rtems/score/tls.h><br>
<br>
@@ -97,6 +98,9 @@ void _CPU_Context_Initialize(<br>
 {<br>
   (void) new_level;<br>
<br>
+ #if defined (USE_THREAD_STACK_PROTECTION)<br>
+  the_context->the_stack = _Stackprotection_Context_initialize();<br>
+  #endif<br>
   the_context->register_sp = (uint32_t) stack_area_begin + stack_area_size;<br>
   the_context->register_lr = (uint32_t) entry_point;<br>
   the_context->isr_dispatch_disable = 0;<br>
diff --git a/cpukit/score/cpu/arm/cpu_asm.S b/cpukit/score/cpu/arm/cpu_asm.S<br>
index 66f8ba6032..7473303f02 100644<br>
--- a/cpukit/score/cpu/arm/cpu_asm.S<br>
+++ b/cpukit/score/cpu/arm/cpu_asm.S<br>
@@ -36,7 +36,7 @@<br>
 #ifdef ARM_MULTILIB_ARCH_V4<br>
<br>
         .text<br>
-<br>
+               <br>
 /*<br>
  *  void _CPU_Context_switch( run_context, heir_context )<br>
  *  void _CPU_Context_restore( run_context, heir_context )<br>
@@ -66,6 +66,27 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch)<br>
<br>
        str     r3, [r0, #ARM_CONTEXT_CONTROL_ISR_DISPATCH_DISABLE]<br>
<br>
+#if defined ( USE_THREAD_STACK_PROTECTION )<br>
+   /*<br>
+    * Save the registers modifed during function call<br>
+    */<br>
+    mov r8, r0<br>
+       mov r9, r1<br>
+       mov r10, r2<br>
+       /*<br>
+        * Load the parameters to be passed<br>
+        */<br>
+       ldr r0, [r0, #ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET]<br>
+       ldr r1, [r1, #ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET]<br>
+       bl  _Stackprotection_Context_switch<br>
+       /*<br>
+       * Restore the saved registers<br>
+       */<br>
+       mov r0, r8<br>
+       mov r1, r9<br>
+       mov r2, r10<br>
+#endif<br>
+<br>
 #ifdef RTEMS_SMP<br>
        /*<br>
         * The executing thread no longer executes on this processor.  Switch<br>
@@ -132,7 +153,27 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch)<br>
  *<br>
  */<br>
 DEFINE_FUNCTION_ARM(_CPU_Context_restore)<br>
-        mov     r1, r0<br>
+<br>
+    mov     r1, r0<br>
+#if defined( USE_THREAD_STACK_PROTECTION )<br>
+   /*<br>
+    * Save the registers modifed during function call<br>
+    */<br>
+       mov r8, r0<br>
+       mov r9, r1<br>
+       mov r10, r2<br>
+       /*<br>
+        * Load the parameters to be passed<br>
+        */<br>
+       ldr     r0, [r0, #ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET]<br>
+       bl  _Stackprotection_Context_switch     <br>
+       /*<br>
+       * Restore the saved registers<br>
+       */      <br>
+       mov r0, r8<br>
+       mov r1, r9<br>
+       mov r2, r10     <br>
+#endif<br>
        GET_SELF_CPU_CONTROL    r2<br>
         b       .L_restore<br>
<br>
diff --git a/cpukit/score/cpu/arm/include/rtems/score/cpu.h b/cpukit/score/cpu/arm/include/rtems/score/cpu.h<br>
index b7b48a3ac3..df13fed258 100644<br>
--- a/cpukit/score/cpu/arm/include/rtems/score/cpu.h<br>
+++ b/cpukit/score/cpu/arm/include/rtems/score/cpu.h<br>
@@ -34,6 +34,7 @@<br>
 #include <rtems/score/paravirt.h><br>
 #endif<br>
 #include <rtems/score/arm.h><br>
+#include <rtems/score/stackprotection.h><br>
<br>
 /**<br>
  * @addtogroup RTEMSScoreCPUARM<br>
@@ -157,6 +158,21 @@<br>
<br>
 #ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER<br>
   #define ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET 44<br>
+  #ifdef ARM_MULITLIB_VFP<br>
+    #define ARM_STACK_PROT_ATTR_OFFSET   112<br>
+  #else<br>
+    #define ARM_STACK_PROT_ATTR_OFFSET  48<br>
+  #endif <br>
+#endif<br>
+<br>
+#ifdef USE_THREAD_STACK_PROTECTION<br>
+  #if defined ARM_MULITLIB_VFP<br>
+    #define ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET   112<br>
+  #elif ARM_MULTILIB_HAS_THREAD_ID_REGISTER<br>
+    #define ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET 48<br>
+  #else <br>
+    #define ARM_CONTEXT_CONTROL_STACK_ATTR_OFFSET 44<br>
+  #endif <br>
 #endif<br>
<br>
 #ifdef ARM_MULTILIB_VFP<br>
@@ -185,6 +201,7 @@<br>
<br>
 #define ARM_VFP_CONTEXT_SIZE 264<br>
<br>
+<br>
 #ifndef ASM<br>
<br>
 #ifdef __cplusplus<br>
@@ -235,6 +252,7 @@ typedef struct {<br>
 #ifdef RTEMS_SMP<br>
   volatile bool is_executing;<br>
 #endif<br>
+Stackprotection_The_stack *the_stack;<br>
 } Context_Control;<br>
<br>
 static inline void _ARM_Data_memory_barrier( void )<br>
diff --git a/cpukit/score/src/stackprotection.c b/cpukit/score/src/stackprotection.c<br>
new file mode 100644<br>
index 0000000000..20c5a17b0e<br>
--- /dev/null<br>
+++ b/cpukit/score/src/stackprotection.c<br>
@@ -0,0 +1,188 @@<br>
+/* SPDX-License-Identifier: BSD-2-Clause */<br>
+<br>
+/**<br>
+ * @file<br>
+ *<br>
+ * @ingroup RTEMSScoreStackprotection<br>
+ *<br>
+ * @brief Short "Table of Contents" Description of File Contents<br>
+ *<br>
+ * A short description of the purpose of this file.<br>
+ */<br>
+<br>
+/*<br>
+ * Copyright (C) 2020 Utkarsh Rai<br>
+ *<br>
+ * Redistribution and use in source and binary forms, with or without<br>
+ * modification, are permitted provided that the following conditions<br>
+ * are met:<br>
+ * 1. Redistributions of source code must retain the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer.<br>
+ * 2. Redistributions in binary form must reproduce the above copyright<br>
+ *    notice, this list of conditions and the following disclaimer in the<br>
+ *    documentation and/or other materials provided with the distribution.<br>
+ *<br>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"<br>
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE<br>
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE<br>
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE<br>
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR<br>
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF<br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS<br>
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN<br>
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)<br>
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE<br>
+ * POSSIBILITY OF SUCH DAMAGE.<br>
+ */<br>
+<br>
+<br>
+#ifdef HAVE_CONFIG_H<br>
+#include "config.h"<br>
+#endif<br>
+<br>
+#include <rtems/score/stackprotection.h><br>
+<br>
+Chain_Control _Stackprotection_node_control = CHAIN_INITIALIZER_EMPTY(_Stackprotection_node_control);<br>
+<br>
+static void _Stackprotection_Remove_prev_entry(void)<br>
+{<br>
+<br>
+ Chain_Node *node;<br>
+ Stackprotection_The_stack *prot_stack;<br>
+<br>
+  if( _Chain_Is_empty(&_Stackprotection_node_control) == true ) {<br>
+      _Chain_Initialize_empty(&_Stackprotection_node_control);<br>
+  }<br>
+     node = _Chain_First( &_Stackprotection_node_control );<br>
+ <br>
+     while(_Chain_Is_tail(&_Stackprotection_node_control, node) == false) {<br>
+<br>
+        prot_stack = RTEMS_CONTAINER_OF(node,Stackprotection_The_stack, Base.node); <br>
+        <br>
+        if( prot_stack->current_stack == false ) {<br>
+            Memorymanagement_Unset_entries(prot_stack->Base.stack_address, prot_stack->Base.size);<br>
+        }<br>
+        node =  _Chain_Immutable_next( node );<br>
+     }<br>
+<br>
+}<br>
+<br>
+/*<br>
+Iterate to the end of the chain and mark all the 'currnet' stack as false<br>
+Append the current stack attribute to the end of the chain<br>
+*/<br>
+static void _Stackprotection_Append_chain (Chain_Control *control, Stackprotection_The_stack *stack_append_attr)<br>
+{<br>
+    Chain_Node *node;<br>
+    Stackprotection_The_stack *present_stacks_attr;<br>
+<br>
+    if(_Chain_Is_empty(&_Stackprotection_node_control) == true ) {<br>
+<br>
+    _Chain_Initialize_one(&_Stackprotection_node_control, &stack_append_attr->Base.node);<br>
+    } else {<br>
+        _Chain_Append_unprotected(&_Stackprotection_node_control, &stack_append_attr->Base.node);<br>
+    }<br>
+}<br>
+<br>
+void _Stackprotection_Allocate_attr(uintptr_t  stack_address, size_t size, uintptr_t  page_table_base)<br>
+{<br>
+    Stackprotection_The_stack *prot_stack;<br>
+    <br>
+/*This field will be refactored and score objects will be used for dynamic allocation*/<br>
+    prot_stack = malloc(sizeof(Stackprotection_The_stack));<br>
+<br>
+    if(prot_stack != NULL) {<br>
+    prot_stack->Base.stack_address = stack_address;<br>
+    prot_stack->Base.size = size;<br>
+    prot_stack->Base.page_table_base = page_table_base;<br>
+    prot_stack->Base.access_flags = READ_WRITE_CACHED;<br>
+    prot_stack->current_stack = true;<br>
+    }<br>
+<br>
+    /*<br>
+    Add the attribute field to the end of the chain, remove the memory entries of<br>
+    previously allocated stack and set the memory entry of the currnet stack.<br>
+    */<br>
+   _Stackprotection_Append_chain(&_Stackprotection_node_control, prot_stack );<br>
+    Memorymanagement_Set_entries(stack_address, size, READ_WRITE_CACHED);<br>
+    <br>
+}<br>
+<br>
+Stackprotection_The_stack *_Stackprotection_Context_initialize(void)<br>
+{<br>
+    Chain_Node *node;<br>
+    Stackprotection_The_stack *prot_stack;<br>
+<br>
+    if(   _Chain_Is_empty(&_Stackprotection_node_control) == false ) {<br>
+        node = _Chain_First( &_Stackprotection_node_control );<br>
+<br>
+        while( _Chain_Is_tail(&_Stackprotection_node_control, node ) == false) {<br>
+            prot_stack = RTEMS_CONTAINER_OF( node, Stackprotection_The_stack, Base.node);<br>
+<br>
+            if(prot_stack->current_stack == true) {<br>
+                return prot_stack;<br>
+            } else {<br>
+                node = _Chain_Immutable_next( node );<br>
+            }<br>
+        }<br>
+    }<br>
+<br>
+    return prot_stack;<br>
+}<br>
+<br>
+void _Stackprotection_Context_switch(Stackprotection_The_stack *executing_stack, Stackprotection_The_stack *heir_stack)<br>
+{<br>
+    void *stack_address;<br>
+    size_t  size;<br>
+    Chain_Node *node;<br>
+    Chain_Control *shared_node_control;<br>
+<br>
+     /*<br>
+      Remove the stacks shared with the current stack by iterating the chain<br>
+     */<br>
+    if( executing_stack != NULL) {<br>
+<br>
+    stack_address = executing_stack->Base.stack_address;<br>
+    size = executing_stack->Base.size;<br>
+<br>
+        if(executing_stack->current_stack == true) {<br>
+            executing_stack->current_stack = false;    <br>
+            Memorymanagement_Unset_entries(stack_address, size);<br>
+        }<br>
+    }<br>
+    <br>
+    _Stackprotection_Context_restore(heir_stack);<br>
+    <br>
+}<br>
+<br>
+void _Stackprotection_Context_restore(Stackprotection_The_stack *heir_stack)<br>
+{<br>
+    void *stack_address;<br>
+    size_t  size;<br>
+    Chain_Node *node;<br>
+    Memorymanagement_flags flags;<br>
+    Chain_Control *shared_node_control;<br>
+    Stackprotection_The_stack *present_stacks_attr;<br>
+<br>
+    if(heir_stack != NULL) {<br>
+             heir_stack->current_stack = true;<br>
+             stack_address = heir_stack->Base.stack_address;<br>
+             size = heir_stack->Base.size;<br>
+             flags = heir_stack->Base.access_flags;<br>
+             Memorymanagement_Set_entries(stack_address, size, flags);<br>
+    }<br>
+<br>
+      node = _Chain_First(&_Stackprotection_node_control);<br>
+    /** Iterate through the chain and unset memory entries of all the<br>
+     *  previous thread-stacks <br>
+    */<br>
+    while(_Chain_Is_tail(&_Stackprotection_node_control,node) == false) {<br>
+            <br>
+            present_stacks_attr = RTEMS_CONTAINER_OF(node, Stackprotection_The_stack, Base.node);<br>
+<br>
+            if(present_stacks_attr->current_stack == true && present_stacks_attr != heir_stack) <br>
+            present_stacks_attr->current_stack = false;  <br>
+            Memorymanagement_Unset_entries(present_stacks_attr->Base.stack_address, present_stacks_attr->Base.size);<br>
+            node = _Chain_Immutable_next( node );   <br>
+    }<br>
+}<br>
-- <br>
2.17.1<br>
<br>
</blockquote></div>