Message ID | 20210111214452.1826-4-tony.luck@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Fix infinite machine check loop in futex_wait_setup() | expand |
diff --git a/kernel/futex.c b/kernel/futex.c index c47d1015d759..b11166712a9f 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -723,7 +723,7 @@ static int get_futex_value_locked(u32 *dest, u32 __user *from) ret = __get_user(*dest, from); pagefault_enable(); - return ret ? -EFAULT : 0; + return (ret == -ENXIO) ? ret : ret ? -EFAULT : 0; } @@ -2658,6 +2658,9 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, if (ret) { queue_unlock(*hb); + if (ret == -ENXIO) + return ret; + ret = get_user(uval, uaddr); if (ret) return ret;
futex_wait_setup() first tries to read the user value with page faults disabled (because it holds a lock, and so cannot sleep). If that read fails it drops the lock and tries again. But there are now two reasons why the user space read can fail. Either: 1) legacy case of a page fault, in which case it is reasonable to retry 2) machine check on the user address, bad idea to re-read Check for the ENXIO return code from the first get_user() call and immediately return an error without re-reading the futex. Signed-off-by: Tony Luck <tony.luck@intel.com> --- kernel/futex.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)