arch/x86_64: Poison instruction pointer of running threads

There was a bug where double-dispatch of a single thread on multiple
SMP CPUs was possible.  This can be mind-bending to diagnose, so when
CONFIG_ASSERT is enabled add an extra instruction to __resume (the
shared code path for both interupt return and context switch) that
poisons the shared RIP of the now-running thread with a recognizable
invalid value.

Now attempts to run the thread again will crash instantly with a
discoverable cookie in their instruction pointer, and this will remain
true until it gets a new RIP at the next interrupt or switch.

This is under CONFIG_ASSERT because it meets the same design goals of
"a cheap test for impossible situations", not because it's part of the
assertion framework.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
Andy Ross 2020-01-23 12:54:52 -08:00 committed by Anas Nashif
commit 5b85d6da6a

View file

@ -263,6 +263,16 @@ __resume:
#endif
pushq _thread_offset_to_rip(%rdi) /* RIP */
#ifdef CONFIG_ASSERT
/* Poison the old thread's saved RIP pointer with a
* recognizable value near NULL, to easily catch reuse of the
* thread object across CPUs in SMP. Strictly speaking this
* is not an assertion, but it's very cheap and worth having
* on during routine testing.
*/
movq $0xB9, _thread_offset_to_rip(%rdi)
#endif
movq _thread_offset_to_rbx(%rdi), %rbx
movq _thread_offset_to_rbp(%rdi), %rbp
movq _thread_offset_to_r12(%rdi), %r12