From: Alexandru Elisei <alexandru.elisei@xxxxxxx> The vmalloc allocator returns non-id mapped addresses, where the virtual address is different than the physical address. As a result, it's impossible to access the stack of the secondary CPUs while the MMU is disabled (if AUXINFO_MMU_OFF is set, a test disables the MMU or an exception happens on the secondary before the MMU is enabled). It turns out that kvm-unit-tests always configures the stack size to be a power-of-two multiple of PAGE_SIZE: on arm, THREAD_SIZE is 16K and PAGE_SIZE is 4K; on arm64, THREAD_SIZE is 16K when PAGE_SIZE is 4K or 16K, and 64K when PAGE_SIZE is 64K. Use memalign_pages_flags() as a drop-in replacement for vmalloc's vm_memalign(), which is the value for alloc_ops->memalign when the stack is allocated, as it has the benefits: 1. The secondary CPUs' stack can be used with the MMU off. 2. The secondary CPUs' stack is identity mapped, just like the stack for the primary CPU, making the configuration of the all the CPUs consistent. 3. start_usr(), which can take a new stack to use at EL0/in user mode, now works if the function is called after the MMU has been disabled. This doesn't affect the vectors-user test, as the only way to run the test with the MMU disabled is by setting AUXINFO_MMU_INFO, in which case the vmalloc allocator is not initialized and alloc_ops->memalign resolves to memalign_pages(). memalign_pages_flags() has been used instead of memalign_pages() to instruct the allocator not to zero the stack, as it's already zeroed in the entry code. Reviewed-by: Andrew Jones <andrew.jones@xxxxxxxxx> Signed-off-by: Alexandru Elisei <alexandru.elisei@xxxxxxx> --- lib/arm/asm/thread_info.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/arm/asm/thread_info.h b/lib/arm/asm/thread_info.h index eaa72582..190e082c 100644 --- a/lib/arm/asm/thread_info.h +++ b/lib/arm/asm/thread_info.h @@ -25,6 +25,7 @@ #ifndef __ASSEMBLY__ #include <asm/processor.h> #include <alloc.h> +#include <alloc_page.h> #ifdef __arm__ #include <asm/ptrace.h> @@ -40,7 +41,7 @@ static inline void *thread_stack_alloc(void) { - void *sp = memalign(THREAD_ALIGNMENT, THREAD_SIZE); + void *sp = memalign_pages_flags(THREAD_ALIGNMENT, THREAD_SIZE, FLAG_DONTZERO); return sp + THREAD_START_SP; } -- 2.40.1