···284284 drop_futex_key_refs(key);285285}286286287287+/*288288+ * fault_in_user_writeable - fault in user address and verify RW access289289+ * @uaddr: pointer to faulting user space address290290+ *291291+ * Slow path to fixup the fault we just took in the atomic write292292+ * access to @uaddr.293293+ *294294+ * We have no generic implementation of a non destructive write to the295295+ * user address. We know that we faulted in the atomic pagefault296296+ * disabled section so we can as well avoid the #PF overhead by297297+ * calling get_user_pages() right away.298298+ */299299+static int fault_in_user_writeable(u32 __user *uaddr)300300+{301301+ int ret = get_user_pages(current, current->mm, (unsigned long)uaddr,302302+ sizeof(*uaddr), 1, 0, NULL, NULL);303303+ return ret < 0 ? ret : 0;304304+}305305+287306/**288307 * futex_top_waiter() - Return the highest priority waiter on a futex289308 * @hb: the hash bucket the futex_q's reside in···915896retry_private:916897 op_ret = futex_atomic_op_inuser(op, uaddr2);917898 if (unlikely(op_ret < 0)) {918918- u32 dummy;919899920900 double_unlock_hb(hb1, hb2);921901···932914 goto out_put_keys;933915 }934916935935- ret = get_user(dummy, uaddr2);917917+ ret = fault_in_user_writeable(uaddr2);936918 if (ret)937919 goto out_put_keys;938920···12221204 double_unlock_hb(hb1, hb2);12231205 put_futex_key(fshared, &key2);12241206 put_futex_key(fshared, &key1);12251225- ret = get_user(curval2, uaddr2);12071207+ ret = fault_in_user_writeable(uaddr2);12261208 if (!ret)12271209 goto retry;12281210 goto out;···15001482handle_fault:15011483 spin_unlock(q->lock_ptr);1502148415031503- ret = get_user(uval, uaddr);14851485+ ret = fault_in_user_writeable(uaddr);1504148615051487 spin_lock(q->lock_ptr);15061488···18251807{18261808 struct hrtimer_sleeper timeout, *to = NULL;18271809 struct futex_hash_bucket *hb;18281828- u32 uval;18291810 struct futex_q q;18301811 int res, ret;18311812···19261909 return ret != -EINTR ? ret : -ERESTARTNOINTR;1927191019281911uaddr_faulted:19291929- /*19301930- * We have to r/w *(int __user *)uaddr, and we have to modify it19311931- * atomically. Therefore, if we continue to fault after get_user()19321932- * below, we need to handle the fault ourselves, while still holding19331933- * the mmap_sem. This can occur if the uaddr is under contention as19341934- * we have to drop the mmap_sem in order to call get_user().19351935- */19361912 queue_unlock(&q, hb);1937191319381938- ret = get_user(uval, uaddr);19141914+ ret = fault_in_user_writeable(uaddr);19391915 if (ret)19401916 goto out_put_key;19411917···20232013 return ret;2024201420252015pi_faulted:20262026- /*20272027- * We have to r/w *(int __user *)uaddr, and we have to modify it20282028- * atomically. Therefore, if we continue to fault after get_user()20292029- * below, we need to handle the fault ourselves, while still holding20302030- * the mmap_sem. This can occur if the uaddr is under contention as20312031- * we have to drop the mmap_sem in order to call get_user().20322032- */20332016 spin_unlock(&hb->lock);20342017 put_futex_key(fshared, &key);2035201820362036- ret = get_user(uval, uaddr);20192019+ ret = fault_in_user_writeable(uaddr);20372020 if (!ret)20382021 goto retry;20392022