|
@@ -1565,12 +1565,11 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
|
|
|
|
|
|
uaddr_faulted:
|
|
uaddr_faulted:
|
|
/*
|
|
/*
|
|
- * We have to r/w *(int __user *)uaddr, but we can't modify it
|
|
|
|
- * non-atomically. Therefore, if get_user below is not
|
|
|
|
- * enough, we need to handle the fault ourselves, while
|
|
|
|
- * still holding the mmap_sem.
|
|
|
|
- *
|
|
|
|
- * ... and hb->lock. :-) --ANK
|
|
|
|
|
|
+ * We have to r/w *(int __user *)uaddr, and we have to modify it
|
|
|
|
+ * atomically. Therefore, if we continue to fault after get_user()
|
|
|
|
+ * below, we need to handle the fault ourselves, while still holding
|
|
|
|
+ * the mmap_sem. This can occur if the uaddr is under contention as
|
|
|
|
+ * we have to drop the mmap_sem in order to call get_user().
|
|
*/
|
|
*/
|
|
queue_unlock(&q, hb);
|
|
queue_unlock(&q, hb);
|
|
|
|
|
|
@@ -1582,7 +1581,7 @@ static int futex_lock_pi(u32 __user *uaddr, int fshared,
|
|
}
|
|
}
|
|
|
|
|
|
ret = get_user(uval, uaddr);
|
|
ret = get_user(uval, uaddr);
|
|
- if (!ret && (uval != -EFAULT))
|
|
|
|
|
|
+ if (!ret)
|
|
goto retry;
|
|
goto retry;
|
|
|
|
|
|
if (to)
|
|
if (to)
|
|
@@ -1676,12 +1675,11 @@ out:
|
|
|
|
|
|
pi_faulted:
|
|
pi_faulted:
|
|
/*
|
|
/*
|
|
- * We have to r/w *(int __user *)uaddr, but we can't modify it
|
|
|
|
- * non-atomically. Therefore, if get_user below is not
|
|
|
|
- * enough, we need to handle the fault ourselves, while
|
|
|
|
- * still holding the mmap_sem.
|
|
|
|
- *
|
|
|
|
- * ... and hb->lock. --ANK
|
|
|
|
|
|
+ * We have to r/w *(int __user *)uaddr, and we have to modify it
|
|
|
|
+ * atomically. Therefore, if we continue to fault after get_user()
|
|
|
|
+ * below, we need to handle the fault ourselves, while still holding
|
|
|
|
+ * the mmap_sem. This can occur if the uaddr is under contention as
|
|
|
|
+ * we have to drop the mmap_sem in order to call get_user().
|
|
*/
|
|
*/
|
|
spin_unlock(&hb->lock);
|
|
spin_unlock(&hb->lock);
|
|
|
|
|
|
@@ -1694,7 +1692,7 @@ pi_faulted:
|
|
}
|
|
}
|
|
|
|
|
|
ret = get_user(uval, uaddr);
|
|
ret = get_user(uval, uaddr);
|
|
- if (!ret && (uval != -EFAULT))
|
|
|
|
|
|
+ if (!ret)
|
|
goto retry;
|
|
goto retry;
|
|
|
|
|
|
return ret;
|
|
return ret;
|