[PATCH] severing skbuff.h -> highmem.h
[powerpc.git] / fs / compat.c
index 4d3fbcb..fde52d4 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/personality.h>
 #include <linux/rwsem.h>
 #include <linux/tsacct_kern.h>
+#include <linux/highmem.h>
 #include <linux/mm.h>
 
 #include <net/sock.h>          /* siocdevprivate_ioctl */
@@ -1316,7 +1317,7 @@ compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32,
                    unsigned int nr_segs, unsigned int flags)
 {
        unsigned i;
-       struct iovec *iov;
+       struct iovec __user *iov;
        if (nr_segs > UIO_MAXIOV)
                return -EINVAL;
        iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec));
@@ -1835,9 +1836,12 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
 
        } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec));
 
-       if (ret == 0 && tsp && !(current->personality & STICKY_TIMEOUTS)) {
+       if (tsp) {
                struct compat_timespec rts;
 
+               if (current->personality & STICKY_TIMEOUTS)
+                       goto sticky;
+
                rts.tv_sec = timeout / HZ;
                rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ);
                if (rts.tv_nsec >= NSEC_PER_SEC) {
@@ -1846,8 +1850,19 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
                }
                if (compat_timespec_compare(&rts, &ts) >= 0)
                        rts = ts;
-               if (copy_to_user(tsp, &rts, sizeof(rts)))
-                       ret = -EFAULT;
+               if (copy_to_user(tsp, &rts, sizeof(rts))) {
+sticky:
+                       /*
+                        * If an application puts its timeval in read-only
+                        * memory, we don't want the Linux-specific update to
+                        * the timeval to cause a fault after the select has
+                        * completed successfully. However, because we're not
+                        * updating the timeval, we can't restart the system
+                        * call.
+                        */
+                       if (ret == -ERESTARTNOHAND)
+                               ret = -EINTR;
+               }
        }
 
        if (ret == -ERESTARTNOHAND) {