aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-s390
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2005-09-03 18:58:05 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:06:29 -0400
commit9513e5e3f5a6b429da8a9fd4330f71f1e547c8e0 (patch)
tree7585e2271d2fc3393aa2368cd7dad85d7552cd97 /include/asm-s390
parentc563077e526d130b8c9aab4e75116551eb5fdc2d (diff)
[PATCH] s390: spinlock corner case
On s390 the lock value used for spinlocks consists of the lower 32 bits of the PSW that holds the lock. If this address happens to be on a four gigabyte boundary the lock is left unlocked. This allows other cpus to grab the same lock and enter a lock protected code path concurrently. In theory this can happen if the vmalloc area for the code of a module crosses a 4 GB boundary. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/asm-s390')
-rw-r--r--include/asm-s390/spinlock.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h
index 8ff10300f7ee..321b23bba1ec 100644
--- a/include/asm-s390/spinlock.h
+++ b/include/asm-s390/spinlock.h
@@ -47,7 +47,7 @@ extern int _raw_spin_trylock_retry(spinlock_t *lp, unsigned int pc);
47 47
48static inline void _raw_spin_lock(spinlock_t *lp) 48static inline void _raw_spin_lock(spinlock_t *lp)
49{ 49{
50 unsigned long pc = (unsigned long) __builtin_return_address(0); 50 unsigned long pc = 1 | (unsigned long) __builtin_return_address(0);
51 51
52 if (unlikely(_raw_compare_and_swap(&lp->lock, 0, pc) != 0)) 52 if (unlikely(_raw_compare_and_swap(&lp->lock, 0, pc) != 0))
53 _raw_spin_lock_wait(lp, pc); 53 _raw_spin_lock_wait(lp, pc);
@@ -55,7 +55,7 @@ static inline void _raw_spin_lock(spinlock_t *lp)
55 55
56static inline int _raw_spin_trylock(spinlock_t *lp) 56static inline int _raw_spin_trylock(spinlock_t *lp)
57{ 57{
58 unsigned long pc = (unsigned long) __builtin_return_address(0); 58 unsigned long pc = 1 | (unsigned long) __builtin_return_address(0);
59 59
60 if (likely(_raw_compare_and_swap(&lp->lock, 0, pc) == 0)) 60 if (likely(_raw_compare_and_swap(&lp->lock, 0, pc) == 0))
61 return 1; 61 return 1;