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 29abc8adc025 ("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>
diff --git a/arch/xtensa/core/xtensa-asm2-util.S b/arch/xtensa/core/xtensa-asm2-util.S
index d46ea5e..0646c33 100644
--- a/arch/xtensa/core/xtensa-asm2-util.S
+++ b/arch/xtensa/core/xtensa-asm2-util.S
@@ -248,14 +248,17 @@
 
 #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
diff --git a/arch/xtensa/include/kernel_arch_func.h b/arch/xtensa/include/kernel_arch_func.h
index 061b6a4..b69f951 100644
--- a/arch/xtensa/include/kernel_arch_func.h
+++ b/arch/xtensa/include/kernel_arch_func.h
@@ -111,7 +111,7 @@
 	/* 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;
 	}