KVM: selftests: test KVM_GET_SUPPORTED_HV_CPUID as a system ioctl
[linux-2.6-microblaze.git] / kernel / futex.c
index 39681bf..ac32887 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/freezer.h>
 #include <linux/memblock.h>
 #include <linux/fault-inject.h>
+#include <linux/time_namespace.h>
 
 #include <asm/futex.h>
 
@@ -916,7 +917,7 @@ static inline void exit_pi_state_list(struct task_struct *curr) { }
  * [10] Found  | Found    | task      | !=taskTID | 0/1    | Invalid
  *
  * [1] Indicates that the kernel can acquire the futex atomically. We
- *     came came here due to a stale FUTEX_WAITERS/FUTEX_OWNER_DIED bit.
+ *     came here due to a stale FUTEX_WAITERS/FUTEX_OWNER_DIED bit.
  *
  * [2] Valid, if TID does not belong to a kernel thread. If no matching
  *      thread is found then it indicates that the owner TID has died.
@@ -2379,10 +2380,22 @@ retry:
                }
 
                /*
-                * Since we just failed the trylock; there must be an owner.
+                * The trylock just failed, so either there is an owner or
+                * there is a higher priority waiter than this one.
                 */
                newowner = rt_mutex_owner(&pi_state->pi_mutex);
-               BUG_ON(!newowner);
+               /*
+                * If the higher priority waiter has not yet taken over the
+                * rtmutex then newowner is NULL. We can't return here with
+                * that state because it's inconsistent vs. the user space
+                * state. So drop the locks and try again. It's a valid
+                * situation and not any different from the other retry
+                * conditions.
+                */
+               if (unlikely(!newowner)) {
+                       err = -EAGAIN;
+                       goto handle_err;
+               }
        } else {
                WARN_ON_ONCE(argowner != current);
                if (oldowner == current) {
@@ -3799,6 +3812,8 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val,
                t = timespec64_to_ktime(ts);
                if (cmd == FUTEX_WAIT)
                        t = ktime_add_safe(ktime_get(), t);
+               else if (!(op & FUTEX_CLOCK_REALTIME))
+                       t = timens_ktime_to_host(CLOCK_MONOTONIC, t);
                tp = &t;
        }
        /*
@@ -3991,6 +4006,8 @@ SYSCALL_DEFINE6(futex_time32, u32 __user *, uaddr, int, op, u32, val,
                t = timespec64_to_ktime(ts);
                if (cmd == FUTEX_WAIT)
                        t = ktime_add_safe(ktime_get(), t);
+               else if (!(op & FUTEX_CLOCK_REALTIME))
+                       t = timens_ktime_to_host(CLOCK_MONOTONIC, t);
                tp = &t;
        }
        if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE ||