hw arm: avoid shared cache lines during MP init

When bringing up the kernel on multiple cores, there is a time span
where some cores already have caches enabled and some don't. Core-local
storage that may be used during this time must be aligned at least to
the maximum line size among global caches. Otherwise, a cached core may
unintentionally prefetch data of a yet uncached core into a global
cache. This may corrupt the view of the uncached core as soon as it
enables caches. However, to determine the exact alignment for every
single ARM platform isn't sensible. Instead, we can align to the minimum
page size assuming that a cache never wants to prefetch from multiple
pages at once and thus fulfills "line size <= page size".

Fixes #1937
This commit is contained in:
Martin Stein 2016-04-08 12:22:44 +02:00 committed by Christian Helmuth
parent 9508f397a2
commit 4ef2b0ed2e
1 changed files with 11 additions and 1 deletions

View File

@ -194,11 +194,21 @@ Cpu_domain_update::Cpu_domain_update() {
/**
* Enable kernel-entry assembly to get an exclusive stack for every CPU
*
* The stack alignment is determined as follows:
*
* 1) There is an architectural minimum alignment for stacks that originates
* from the assumptions that some instructions make.
* 2) Shared cache lines between yet uncached and already cached
* CPUs during multiprocessor bring-up must be avoided. Thus, the alignment
* must be at least the maximum line size of global caches.
* 3) The alignment that originates from 1) and 2) is assumed to be always
* less or equal to the minimum page size.
*/
enum { KERNEL_STACK_SIZE = 16 * 1024 * sizeof(Genode::addr_t) };
Genode::size_t kernel_stack_size = KERNEL_STACK_SIZE;
Genode::uint8_t kernel_stack[NR_OF_CPUS][KERNEL_STACK_SIZE]
__attribute__((aligned(16)));
__attribute__((aligned(Genode::get_page_size())));
Cpu_context::Cpu_context(Genode::Translation_table * const table)
{