From 85f0bc591e6cecd616c01d06a4abe943a71f7faf Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Wed, 19 May 2021 13:02:13 -0700 Subject: [PATCH] mm:initialize ensure alignment. Broken by 635cfa. On an stm32 the heap is formed from const uintptr_t g_idle_topstack = HEAP_BASE; where HEAP_BASE is &_bss + CONFIG_IDLE_STACKSIZE. Both these values are not deterministic. One comes from the compiler, the other the system configurator. a 3 byte bss and 250 byte stack would lead to and unaligned address used as the heap to be. The compiler used clever `strd r1,r3,[r5,#8]` to store 2 values in one memory cycle into the heap_impl struct. Resulting in a hardfault. Change the amount of bss or the CONFIG_IDLE_STACKSIZE could lead to a non-functional NuttX system. --- mm/mm_heap/mm_initialize.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c index 62759e9586..0801eae5d5 100644 --- a/mm/mm_heap/mm_initialize.c +++ b/mm/mm_heap/mm_initialize.c @@ -165,17 +165,23 @@ void mm_initialize(FAR struct mm_heap_s *heap, FAR void *heapstart, size_t heapsize) { FAR struct mm_heap_impl_s *heap_impl; - int i; + uintptr_t heap_adj; + int i; minfo("Heap: start=%p size=%zu\n", heapstart, heapsize); + /* First ensure the memory to be used is aligned */ + + heap_adj = MM_ALIGN_UP((uintptr_t) heapstart); + heapsize -= heap_adj - (uintptr_t) heapstart; + /* Reserve a block space for mm_heap_impl_s context */ DEBUGASSERT(heapsize > sizeof(struct mm_heap_impl_s)); - heap->mm_impl = (FAR struct mm_heap_impl_s *)heapstart; + heap->mm_impl = (FAR struct mm_heap_impl_s *)heap_adj; heap_impl = heap->mm_impl; heapsize -= sizeof(struct mm_heap_impl_s); - heapstart = (FAR char *)heapstart + sizeof(struct mm_heap_impl_s); + heapstart = (FAR char *)heap_adj + sizeof(struct mm_heap_impl_s); /* The following two lines have cause problems for some older ZiLog * compilers in the past (but not the more recent). Life is easier if we