diff options
Diffstat (limited to 'kernel/futex.c')
-rw-r--r-- | kernel/futex.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index 93ef30ba209f..95989a3b4168 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -282,9 +282,9 @@ static inline int get_futex_value_locked(u32 *dest, u32 __user *from) | |||
282 | { | 282 | { |
283 | int ret; | 283 | int ret; |
284 | 284 | ||
285 | inc_preempt_count(); | 285 | pagefault_disable(); |
286 | ret = __copy_from_user_inatomic(dest, from, sizeof(u32)); | 286 | ret = __copy_from_user_inatomic(dest, from, sizeof(u32)); |
287 | dec_preempt_count(); | 287 | pagefault_enable(); |
288 | 288 | ||
289 | return ret ? -EFAULT : 0; | 289 | return ret ? -EFAULT : 0; |
290 | } | 290 | } |
@@ -324,12 +324,11 @@ static int refill_pi_state_cache(void) | |||
324 | if (likely(current->pi_state_cache)) | 324 | if (likely(current->pi_state_cache)) |
325 | return 0; | 325 | return 0; |
326 | 326 | ||
327 | pi_state = kmalloc(sizeof(*pi_state), GFP_KERNEL); | 327 | pi_state = kzalloc(sizeof(*pi_state), GFP_KERNEL); |
328 | 328 | ||
329 | if (!pi_state) | 329 | if (!pi_state) |
330 | return -ENOMEM; | 330 | return -ENOMEM; |
331 | 331 | ||
332 | memset(pi_state, 0, sizeof(*pi_state)); | ||
333 | INIT_LIST_HEAD(&pi_state->list); | 332 | INIT_LIST_HEAD(&pi_state->list); |
334 | /* pi_mutex gets initialized later */ | 333 | /* pi_mutex gets initialized later */ |
335 | pi_state->owner = NULL; | 334 | pi_state->owner = NULL; |
@@ -553,7 +552,7 @@ static void wake_futex(struct futex_q *q) | |||
553 | * at the end of wake_up_all() does not prevent this store from | 552 | * at the end of wake_up_all() does not prevent this store from |
554 | * moving. | 553 | * moving. |
555 | */ | 554 | */ |
556 | wmb(); | 555 | smp_wmb(); |
557 | q->lock_ptr = NULL; | 556 | q->lock_ptr = NULL; |
558 | } | 557 | } |
559 | 558 | ||
@@ -585,9 +584,9 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) | |||
585 | if (!(uval & FUTEX_OWNER_DIED)) { | 584 | if (!(uval & FUTEX_OWNER_DIED)) { |
586 | newval = FUTEX_WAITERS | new_owner->pid; | 585 | newval = FUTEX_WAITERS | new_owner->pid; |
587 | 586 | ||
588 | inc_preempt_count(); | 587 | pagefault_disable(); |
589 | curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); | 588 | curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); |
590 | dec_preempt_count(); | 589 | pagefault_enable(); |
591 | if (curval == -EFAULT) | 590 | if (curval == -EFAULT) |
592 | return -EFAULT; | 591 | return -EFAULT; |
593 | if (curval != uval) | 592 | if (curval != uval) |
@@ -618,9 +617,9 @@ static int unlock_futex_pi(u32 __user *uaddr, u32 uval) | |||
618 | * There is no waiter, so we unlock the futex. The owner died | 617 | * There is no waiter, so we unlock the futex. The owner died |
619 | * bit has not to be preserved here. We are the owner: | 618 | * bit has not to be preserved here. We are the owner: |
620 | */ | 619 | */ |
621 | inc_preempt_count(); | 620 | pagefault_disable(); |
622 | oldval = futex_atomic_cmpxchg_inatomic(uaddr, uval, 0); | 621 | oldval = futex_atomic_cmpxchg_inatomic(uaddr, uval, 0); |
623 | dec_preempt_count(); | 622 | pagefault_enable(); |
624 | 623 | ||
625 | if (oldval == -EFAULT) | 624 | if (oldval == -EFAULT) |
626 | return oldval; | 625 | return oldval; |
@@ -1158,9 +1157,9 @@ static int futex_lock_pi(u32 __user *uaddr, int detect, unsigned long sec, | |||
1158 | */ | 1157 | */ |
1159 | newval = current->pid; | 1158 | newval = current->pid; |
1160 | 1159 | ||
1161 | inc_preempt_count(); | 1160 | pagefault_disable(); |
1162 | curval = futex_atomic_cmpxchg_inatomic(uaddr, 0, newval); | 1161 | curval = futex_atomic_cmpxchg_inatomic(uaddr, 0, newval); |
1163 | dec_preempt_count(); | 1162 | pagefault_enable(); |
1164 | 1163 | ||
1165 | if (unlikely(curval == -EFAULT)) | 1164 | if (unlikely(curval == -EFAULT)) |
1166 | goto uaddr_faulted; | 1165 | goto uaddr_faulted; |
@@ -1183,9 +1182,9 @@ static int futex_lock_pi(u32 __user *uaddr, int detect, unsigned long sec, | |||
1183 | uval = curval; | 1182 | uval = curval; |
1184 | newval = uval | FUTEX_WAITERS; | 1183 | newval = uval | FUTEX_WAITERS; |
1185 | 1184 | ||
1186 | inc_preempt_count(); | 1185 | pagefault_disable(); |
1187 | curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); | 1186 | curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); |
1188 | dec_preempt_count(); | 1187 | pagefault_enable(); |
1189 | 1188 | ||
1190 | if (unlikely(curval == -EFAULT)) | 1189 | if (unlikely(curval == -EFAULT)) |
1191 | goto uaddr_faulted; | 1190 | goto uaddr_faulted; |
@@ -1215,10 +1214,10 @@ static int futex_lock_pi(u32 __user *uaddr, int detect, unsigned long sec, | |||
1215 | newval = current->pid | | 1214 | newval = current->pid | |
1216 | FUTEX_OWNER_DIED | FUTEX_WAITERS; | 1215 | FUTEX_OWNER_DIED | FUTEX_WAITERS; |
1217 | 1216 | ||
1218 | inc_preempt_count(); | 1217 | pagefault_disable(); |
1219 | curval = futex_atomic_cmpxchg_inatomic(uaddr, | 1218 | curval = futex_atomic_cmpxchg_inatomic(uaddr, |
1220 | uval, newval); | 1219 | uval, newval); |
1221 | dec_preempt_count(); | 1220 | pagefault_enable(); |
1222 | 1221 | ||
1223 | if (unlikely(curval == -EFAULT)) | 1222 | if (unlikely(curval == -EFAULT)) |
1224 | goto uaddr_faulted; | 1223 | goto uaddr_faulted; |
@@ -1390,9 +1389,9 @@ retry_locked: | |||
1390 | * anyone else up: | 1389 | * anyone else up: |
1391 | */ | 1390 | */ |
1392 | if (!(uval & FUTEX_OWNER_DIED)) { | 1391 | if (!(uval & FUTEX_OWNER_DIED)) { |
1393 | inc_preempt_count(); | 1392 | pagefault_disable(); |
1394 | uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0); | 1393 | uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0); |
1395 | dec_preempt_count(); | 1394 | pagefault_enable(); |
1396 | } | 1395 | } |
1397 | 1396 | ||
1398 | if (unlikely(uval == -EFAULT)) | 1397 | if (unlikely(uval == -EFAULT)) |
@@ -1493,7 +1492,7 @@ static unsigned int futex_poll(struct file *filp, | |||
1493 | return ret; | 1492 | return ret; |
1494 | } | 1493 | } |
1495 | 1494 | ||
1496 | static struct file_operations futex_fops = { | 1495 | static const struct file_operations futex_fops = { |
1497 | .release = futex_close, | 1496 | .release = futex_close, |
1498 | .poll = futex_poll, | 1497 | .poll = futex_poll, |
1499 | }; | 1498 | }; |
@@ -1858,10 +1857,16 @@ static struct file_system_type futex_fs_type = { | |||
1858 | 1857 | ||
1859 | static int __init init(void) | 1858 | static int __init init(void) |
1860 | { | 1859 | { |
1861 | unsigned int i; | 1860 | int i = register_filesystem(&futex_fs_type); |
1861 | |||
1862 | if (i) | ||
1863 | return i; | ||
1862 | 1864 | ||
1863 | register_filesystem(&futex_fs_type); | ||
1864 | futex_mnt = kern_mount(&futex_fs_type); | 1865 | futex_mnt = kern_mount(&futex_fs_type); |
1866 | if (IS_ERR(futex_mnt)) { | ||
1867 | unregister_filesystem(&futex_fs_type); | ||
1868 | return PTR_ERR(futex_mnt); | ||
1869 | } | ||
1865 | 1870 | ||
1866 | for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { | 1871 | for (i = 0; i < ARRAY_SIZE(futex_queues); i++) { |
1867 | INIT_LIST_HEAD(&futex_queues[i].chain); | 1872 | INIT_LIST_HEAD(&futex_queues[i].chain); |