Commit e124670f authored by Jim Shu's avatar Jim Shu Committed by Anas Nashif
Browse files

kernel/spinlock: Fix a SMP race condition of SPIN_VALIDATE



z_spin_lock_valid() reads shared variable twice to do two checkings. If
this variable is modified by other CPU between two read accesses, the
checking value is inconsistent. This inconsistency causes the error
that CPU0 can pass the checking when it doesn't hold spinlock because
zeroed-out thread_cpu value is ambiguous with the CPU0 ID.

Fix the inconsistency by only reading shared variable once and using
local variable value to do two checkings.

Fixes #19299.

Signed-off-by: default avatarJim Shu <cwshu@andestech.com>
parent 14c200d0
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -805,8 +805,10 @@ FUNC_NORETURN void k_thread_user_mode_enter(k_thread_entry_t entry,
#ifdef SPIN_VALIDATE
bool z_spin_lock_valid(struct k_spinlock *l)
{
	if (l->thread_cpu) {
		if ((l->thread_cpu & 3) == _current_cpu->id) {
	uintptr_t thread_cpu = l->thread_cpu;

	if (thread_cpu) {
		if ((thread_cpu & 3) == _current_cpu->id) {
			return false;
		}
	}