arch/xtensa: Fix outgoing stack flush for dummy threads

On CPU startup, When we reach the cache flush code in arch_switch(),
the outgoing thread is a dummy.  The behavior of the existing code was
to leave the existing value in the SR unchanged (probably NULL at
startup).  Then the context switch would walk from that address up to
the top of the outgoing stack, flushing everything in between.  That's
wrong, because the outgoing stack is a real pointer (generally the
interrupt stack of the current CPU), and we're flushing everything in
memory underneath it.

This also reverts commit 29abc8adc0 ("xtensa: fix booting secondary
cores on the dummy thread"), which appears to have been an early
attempt to address this issue.  It worked (modulo all the extra and
potentially incorrect flushing) on cavs v1.5/1.8 because of the way
the entry code worked there.  But on 2.5 we now hit the first context
switch in a case where those extra lines are in address space already
marked unwritable by the CPU, so the flush explodes.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2021-08-12 12:45:23 -07:00 committed by Anas Nashif
commit b76bc6c80d
2 changed files with 5 additions and 2 deletions

View file

@ -248,14 +248,17 @@ xtensa_switch:
#ifdef CONFIG_KERNEL_COHERENCE
/* Flush the stack. The top of stack was stored for us in
* EXCSAVE3 (FIXME: shouldn't be hardcoded!) by arch_cohere_stacks().
* EXCSAVE3 (FIXME: shouldn't be hardcoded!) by
* arch_cohere_stacks(). It can be NULL for a dummy thread.
*/
rsr.EXCSAVE3 a0
beqz a0, noflush
mov a3, a1
flushloop:
dhwb a3, 0
addi a3, a3, XCHAL_DCACHE_LINESIZE
blt a3, a0, flushloop
noflush:
#endif
/* Restore the A3 argument we spilled earlier (via the base

View file

@ -111,7 +111,7 @@ static ALWAYS_INLINE void arch_cohere_stacks(struct k_thread *old_thread,
/* Dummy threads appear at system initialization, but don't
* have stack_info data and will never be saved. Ignore.
*/
if (!osz) {
if (old_thread->base.thread_state & _THREAD_DUMMY) {
return;
}