Browse Source

Add missing barriers to Bakery Locks

With the current implementation, it's possible for a contender to
observe accesses in the Critical Section before acquiring or releasing
the lock. Insert fencing in the locking and release codes to prevent any
reorder.

Fixes ARM-software/tf-issues#609

Change-Id: I773b82aa41dd544a2d3dbacb9a4b42c9eb767bbb
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
pull/1561/head
Jeenu Viswambharan 6 years ago
parent
commit
24dc970915
  1. 15
      lib/locks/bakery/bakery_lock_coherent.c
  2. 13
      lib/locks/bakery/bakery_lock_normal.c

15
lib/locks/bakery/bakery_lock_coherent.c

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -133,7 +133,12 @@ void bakery_lock_get(bakery_lock_t *bakery)
bakery_ticket_number(bakery->lock_data[they]));
}
}
/* Lock acquired */
/*
* Lock acquired. Ensure that any reads from a shared resource in the
* critical section read values after the lock is acquired.
*/
dmbld();
}
@ -146,9 +151,11 @@ void bakery_lock_release(bakery_lock_t *bakery)
assert(bakery_ticket_number(bakery->lock_data[me]));
/*
* Release lock by resetting ticket. Then signal other
* waiting contenders
* Ensure that other observers see any stores in the critical section
* before releasing the lock. Release the lock by resetting ticket.
* Then signal other waiting contenders.
*/
dmbst();
bakery->lock_data[me] = 0;
dsb();
sev();

13
lib/locks/bakery/bakery_lock_normal.c

@ -204,7 +204,12 @@ void bakery_lock_get(bakery_lock_t *lock)
== bakery_ticket_number(their_bakery_info->lock_data));
}
}
/* Lock acquired */
/*
* Lock acquired. Ensure that any reads from a shared resource in the
* critical section read values after the lock is acquired.
*/
dmbld();
}
void bakery_lock_release(bakery_lock_t *lock)
@ -220,6 +225,12 @@ void bakery_lock_release(bakery_lock_t *lock)
assert(is_lock_acquired(my_bakery_info, is_cached));
/*
* Ensure that other observers see any stores in the critical section
* before releasing the lock. Release the lock by resetting ticket.
* Then signal other waiting contenders.
*/
dmbst();
my_bakery_info->lock_data = 0;
write_cache_op(my_bakery_info, is_cached);
sev();

Loading…
Cancel
Save