diff options
author | Will Deacon <will.deacon@arm.com> | 2013-02-28 20:47:36 +0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-03-04 02:54:14 +0400 |
commit | 8a4e3a9ead7e37ce1505602b564c15da09ac039f (patch) | |
tree | 5cc8ad188810649ea0739c769977451b825e4325 /arch/arm/kernel/asm-offsets.c | |
parent | 37f47e3d62533c931b04cb409f2eb299e6342331 (diff) | |
download | linux-8a4e3a9ead7e37ce1505602b564c15da09ac039f.tar.xz |
ARM: 7659/1: mm: make mm->context.id an atomic64_t variable
mm->context.id is updated under asid_lock when a new ASID is allocated
to an mm_struct. However, it is also read without the lock when a task
is being scheduled and checking whether or not the current ASID
generation is up-to-date.
If two threads of the same process are being scheduled in parallel and
the bottom bits of the generation in their mm->context.id match the
current generation (that is, the mm_struct has not been used for ~2^24
rollovers) then the non-atomic, lockless access to mm->context.id may
yield the incorrect ASID.
This patch fixes this issue by making mm->context.id and atomic64_t,
ensuring that the generation is always read consistently. For code that
only requires access to the ASID bits (e.g. TLB flushing by mm), then
the value is accessed directly, which GCC converts to an ldrb.
Cc: <stable@vger.kernel.org> # 3.8
Reviewed-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>
Diffstat (limited to 'arch/arm/kernel/asm-offsets.c')
-rw-r--r-- | arch/arm/kernel/asm-offsets.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 5ce738b43508..923eec7105cf 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -110,7 +110,7 @@ int main(void) BLANK(); #endif #ifdef CONFIG_CPU_HAS_ASID - DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id)); + DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter)); BLANK(); #endif DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); |