ARM: 6784/1: errata: no automatic Store Buffer drain on Cortex-A9

On revisions of the Cortex-A9 prior to r2p0, the Store Buffer does not
have any automatic draining mechanism and therefore a livelock may occur
if an external agent continuously polls a memory location waiting to
observe an update.

This workaround defines cpu_relax() as smp_mb(), preventing correctly
written polling loops from denying visibility of updates to memory.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
Will Deacon 2011-03-04 12:38:54 +01:00 committed by Russell King
commit 5dab26af1b
2 changed files with 12 additions and 1 deletions

View file

@ -1213,6 +1213,17 @@ config ARM_ERRATA_754322
the new ASID. This workaround places two dsb instructions in the mm the new ASID. This workaround places two dsb instructions in the mm
switching code so that no page table walks can cross the ASID switch. switching code so that no page table walks can cross the ASID switch.
config ARM_ERRATA_754327
bool "ARM errata: no automatic Store Buffer drain"
depends on CPU_V7 && SMP
help
This option enables the workaround for the 754327 Cortex-A9 (prior to
r2p0) erratum. The Store Buffer does not have any automatic draining
mechanism and therefore a livelock may occur if an external agent
continuously polls a memory location waiting to observe an update.
This workaround defines cpu_relax() as smp_mb(), preventing correctly
written polling loops from denying visibility of updates to memory.
endmenu endmenu
source "arch/arm/common/Kconfig" source "arch/arm/common/Kconfig"

View file

@ -95,7 +95,7 @@ extern void release_thread(struct task_struct *);
unsigned long get_wchan(struct task_struct *p); unsigned long get_wchan(struct task_struct *p);
#if __LINUX_ARM_ARCH__ == 6 #if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327)
#define cpu_relax() smp_mb() #define cpu_relax() smp_mb()
#else #else
#define cpu_relax() barrier() #define cpu_relax() barrier()