[kvm-unit-tests PATCH v1 10/18] arm/arm64: Allocate secondaries' stack using the page allocator

Shaoqin Huang
2023-11-30T09:07:59Z

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@linux.dev>
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
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