Message ID | 20220809091558.14379-17-alexandru.elisei@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm/arm64: Rework cache maintenance at boot | expand |
On Tue, Aug 09, 2022 at 10:15:55AM +0100, Alexandru Elisei wrote: > The vmalloc allocator returns non-id mapped addresses, where the virtual > address is different than the physical address. This makes it impossible > to access the stack of the secondary CPUs while the MMU is disabled. > > On arm, THREAD_SIZE is 16K and PAGE_SIZE is 4K, which makes THREAD_SIZE > a power of two multiple of PAGE_SIZE. On arm64, THREAD_SIZE is 16 when > PAGE_SIZE is 4K or 16K, and 64K when PAGE_SIZE is 64K. In all cases, > THREAD_SIZE is a power of two multiple of PAGE_SIZE. As a result, using > memalign_pages() for the stack won't lead to wasted memory. > > memalign_pages() allocates memory in chunks of power of two number of > pages, aligned to the allocation size, which makes it a drop-in > replacement for vm_memalign (which is the value for alloc_ops->memalign > when the stack is allocated). > > Using memalign_pages() has two distinct benefits: > > 1. The secondary CPUs' stack can be used with the MMU off. > > 2. The secondary CPUs' stack is identify mapped similar to the stack for > the primary CPU, which makes the configuration of the CPUs consistent. > > 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. > > 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 eaa72582af86..190e082cbba0 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.37.1 > Reviewed-by: Andrew Jones <andrew.jones@linux.dev>
diff --git a/lib/arm/asm/thread_info.h b/lib/arm/asm/thread_info.h index eaa72582af86..190e082cbba0 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; }
The vmalloc allocator returns non-id mapped addresses, where the virtual address is different than the physical address. This makes it impossible to access the stack of the secondary CPUs while the MMU is disabled. On arm, THREAD_SIZE is 16K and PAGE_SIZE is 4K, which makes THREAD_SIZE a power of two multiple of PAGE_SIZE. On arm64, THREAD_SIZE is 16 when PAGE_SIZE is 4K or 16K, and 64K when PAGE_SIZE is 64K. In all cases, THREAD_SIZE is a power of two multiple of PAGE_SIZE. As a result, using memalign_pages() for the stack won't lead to wasted memory. memalign_pages() allocates memory in chunks of power of two number of pages, aligned to the allocation size, which makes it a drop-in replacement for vm_memalign (which is the value for alloc_ops->memalign when the stack is allocated). Using memalign_pages() has two distinct benefits: 1. The secondary CPUs' stack can be used with the MMU off. 2. The secondary CPUs' stack is identify mapped similar to the stack for the primary CPU, which makes the configuration of the CPUs consistent. 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. Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com> --- lib/arm/asm/thread_info.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)