diff options
Diffstat (limited to 'arch/s390/lib')
| -rw-r--r-- | arch/s390/lib/spinlock.c | 15 | ||||
| -rw-r--r-- | arch/s390/lib/uaccess.S | 6 | ||||
| -rw-r--r-- | arch/s390/lib/uaccess64.S | 6 |
3 files changed, 19 insertions, 8 deletions
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 60f80a4eed4e..b9b7958a226a 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c | |||
| @@ -2,8 +2,7 @@ | |||
| 2 | * arch/s390/lib/spinlock.c | 2 | * arch/s390/lib/spinlock.c |
| 3 | * Out of line spinlock code. | 3 | * Out of line spinlock code. |
| 4 | * | 4 | * |
| 5 | * S390 version | 5 | * Copyright (C) IBM Corp. 2004, 2006 |
| 6 | * Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
| 7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | 6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) |
| 8 | */ | 7 | */ |
| 9 | 8 | ||
| @@ -44,6 +43,8 @@ _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) | |||
| 44 | _diag44(); | 43 | _diag44(); |
| 45 | count = spin_retry; | 44 | count = spin_retry; |
| 46 | } | 45 | } |
| 46 | if (__raw_spin_is_locked(lp)) | ||
| 47 | continue; | ||
| 47 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) | 48 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) |
| 48 | return; | 49 | return; |
| 49 | } | 50 | } |
| @@ -56,6 +57,8 @@ _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc) | |||
| 56 | int count = spin_retry; | 57 | int count = spin_retry; |
| 57 | 58 | ||
| 58 | while (count-- > 0) { | 59 | while (count-- > 0) { |
| 60 | if (__raw_spin_is_locked(lp)) | ||
| 61 | continue; | ||
| 59 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) | 62 | if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) |
| 60 | return 1; | 63 | return 1; |
| 61 | } | 64 | } |
| @@ -74,6 +77,8 @@ _raw_read_lock_wait(raw_rwlock_t *rw) | |||
| 74 | _diag44(); | 77 | _diag44(); |
| 75 | count = spin_retry; | 78 | count = spin_retry; |
| 76 | } | 79 | } |
| 80 | if (!__raw_read_can_lock(rw)) | ||
| 81 | continue; | ||
| 77 | old = rw->lock & 0x7fffffffU; | 82 | old = rw->lock & 0x7fffffffU; |
| 78 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) | 83 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) |
| 79 | return; | 84 | return; |
| @@ -88,6 +93,8 @@ _raw_read_trylock_retry(raw_rwlock_t *rw) | |||
| 88 | int count = spin_retry; | 93 | int count = spin_retry; |
| 89 | 94 | ||
| 90 | while (count-- > 0) { | 95 | while (count-- > 0) { |
| 96 | if (!__raw_read_can_lock(rw)) | ||
| 97 | continue; | ||
| 91 | old = rw->lock & 0x7fffffffU; | 98 | old = rw->lock & 0x7fffffffU; |
| 92 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) | 99 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old) |
| 93 | return 1; | 100 | return 1; |
| @@ -106,6 +113,8 @@ _raw_write_lock_wait(raw_rwlock_t *rw) | |||
| 106 | _diag44(); | 113 | _diag44(); |
| 107 | count = spin_retry; | 114 | count = spin_retry; |
| 108 | } | 115 | } |
| 116 | if (!__raw_write_can_lock(rw)) | ||
| 117 | continue; | ||
| 109 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) | 118 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) |
| 110 | return; | 119 | return; |
| 111 | } | 120 | } |
| @@ -118,6 +127,8 @@ _raw_write_trylock_retry(raw_rwlock_t *rw) | |||
| 118 | int count = spin_retry; | 127 | int count = spin_retry; |
| 119 | 128 | ||
| 120 | while (count-- > 0) { | 129 | while (count-- > 0) { |
| 130 | if (!__raw_write_can_lock(rw)) | ||
| 131 | continue; | ||
| 121 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) | 132 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0) |
| 122 | return 1; | 133 | return 1; |
| 123 | } | 134 | } |
diff --git a/arch/s390/lib/uaccess.S b/arch/s390/lib/uaccess.S index 88fc94fe6488..5d59e2625048 100644 --- a/arch/s390/lib/uaccess.S +++ b/arch/s390/lib/uaccess.S | |||
| @@ -198,12 +198,12 @@ __strnlen_user_asm: | |||
| 198 | 0: srst %r2,%r1 | 198 | 0: srst %r2,%r1 |
| 199 | jo 0b | 199 | jo 0b |
| 200 | sacf 0 | 200 | sacf 0 |
| 201 | jh 1f # \0 found in string ? | ||
| 202 | ahi %r2,1 # strnlen_user result includes the \0 | 201 | ahi %r2,1 # strnlen_user result includes the \0 |
| 203 | 1: slr %r2,%r3 | 202 | # or return count+1 if \0 not found |
| 203 | slr %r2,%r3 | ||
| 204 | br %r14 | 204 | br %r14 |
| 205 | 2: sacf 0 | 205 | 2: sacf 0 |
| 206 | lhi %r2,-EFAULT | 206 | slr %r2,%r2 # return 0 on exception |
| 207 | br %r14 | 207 | br %r14 |
| 208 | .section __ex_table,"a" | 208 | .section __ex_table,"a" |
| 209 | .long 0b,2b | 209 | .long 0b,2b |
diff --git a/arch/s390/lib/uaccess64.S b/arch/s390/lib/uaccess64.S index 50219786fc7a..19b41a33c230 100644 --- a/arch/s390/lib/uaccess64.S +++ b/arch/s390/lib/uaccess64.S | |||
| @@ -194,12 +194,12 @@ __strnlen_user_asm: | |||
| 194 | 0: srst %r2,%r1 | 194 | 0: srst %r2,%r1 |
| 195 | jo 0b | 195 | jo 0b |
| 196 | sacf 0 | 196 | sacf 0 |
| 197 | jh 1f # \0 found in string ? | ||
| 198 | aghi %r2,1 # strnlen_user result includes the \0 | 197 | aghi %r2,1 # strnlen_user result includes the \0 |
| 199 | 1: slgr %r2,%r3 | 198 | # or return count+1 if \0 not found |
| 199 | slgr %r2,%r3 | ||
| 200 | br %r14 | 200 | br %r14 |
| 201 | 2: sacf 0 | 201 | 2: sacf 0 |
| 202 | lghi %r2,-EFAULT | 202 | slgr %r2,%r2 # return 0 on exception |
| 203 | br %r14 | 203 | br %r14 |
| 204 | .section __ex_table,"a" | 204 | .section __ex_table,"a" |
| 205 | .quad 0b,2b | 205 | .quad 0b,2b |
