int sock_bind_add(struct sock *sk, struct sockaddr *addr, int addr_len);
 
+int sock_get_timeout(long timeo, void *optval, bool old_timeval);
+int sock_copy_user_timeval(struct __kernel_sock_timeval *tv,
+                          sockptr_t optval, int optlen, bool old_timeval);
+
 #endif /* _SOCK_H */
 
  * timeout for a STREAM socket.
  */
 
-#define SO_VM_SOCKETS_CONNECT_TIMEOUT 6
+#define SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD 6
 
 /* Option name for using non-blocking send/receive.  Use as the option name
  * for setsockopt(3) or getsockopt(3) to set or get the non-blocking
 
 #define SO_VM_SOCKETS_NONBLOCK_TXRX 7
 
+#define SO_VM_SOCKETS_CONNECT_TIMEOUT_NEW 8
+
+#if !defined(__KERNEL__)
+#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
+#define SO_VM_SOCKETS_CONNECT_TIMEOUT SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD
+#else
+#define SO_VM_SOCKETS_CONNECT_TIMEOUT \
+       (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD : SO_VM_SOCKETS_CONNECT_TIMEOUT_NEW)
+#endif
+#endif
+
 /* The vSocket equivalent of INADDR_ANY.  This works for the svm_cid field of
  * sockaddr_vm and indicates the context ID of the current endpoint.
  */
 
 }
 EXPORT_SYMBOL(sk_error_report);
 
-static int sock_get_timeout(long timeo, void *optval, bool old_timeval)
+int sock_get_timeout(long timeo, void *optval, bool old_timeval)
 {
        struct __kernel_sock_timeval tv;
 
        *(struct __kernel_sock_timeval *)optval = tv;
        return sizeof(tv);
 }
+EXPORT_SYMBOL(sock_get_timeout);
 
-static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,
-                           bool old_timeval)
+int sock_copy_user_timeval(struct __kernel_sock_timeval *tv,
+                          sockptr_t optval, int optlen, bool old_timeval)
 {
-       struct __kernel_sock_timeval tv;
-
        if (old_timeval && in_compat_syscall() && !COMPAT_USE_64BIT_TIME) {
                struct old_timeval32 tv32;
 
 
                if (copy_from_sockptr(&tv32, optval, sizeof(tv32)))
                        return -EFAULT;
-               tv.tv_sec = tv32.tv_sec;
-               tv.tv_usec = tv32.tv_usec;
+               tv->tv_sec = tv32.tv_sec;
+               tv->tv_usec = tv32.tv_usec;
        } else if (old_timeval) {
                struct __kernel_old_timeval old_tv;
 
                        return -EINVAL;
                if (copy_from_sockptr(&old_tv, optval, sizeof(old_tv)))
                        return -EFAULT;
-               tv.tv_sec = old_tv.tv_sec;
-               tv.tv_usec = old_tv.tv_usec;
+               tv->tv_sec = old_tv.tv_sec;
+               tv->tv_usec = old_tv.tv_usec;
        } else {
-               if (optlen < sizeof(tv))
+               if (optlen < sizeof(*tv))
                        return -EINVAL;
-               if (copy_from_sockptr(&tv, optval, sizeof(tv)))
+               if (copy_from_sockptr(tv, optval, sizeof(*tv)))
                        return -EFAULT;
        }
+
+       return 0;
+}
+EXPORT_SYMBOL(sock_copy_user_timeval);
+
+static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,
+                           bool old_timeval)
+{
+       struct __kernel_sock_timeval tv;
+       int err = sock_copy_user_timeval(&tv, optval, optlen, old_timeval);
+
+       if (err)
+               return err;
+
        if (tv.tv_usec < 0 || tv.tv_usec >= USEC_PER_SEC)
                return -EDOM;
 
 
                vsock_update_buffer_size(vsk, transport, vsk->buffer_size);
                break;
 
-       case SO_VM_SOCKETS_CONNECT_TIMEOUT: {
-               struct __kernel_old_timeval tv;
-               COPY_IN(tv);
+       case SO_VM_SOCKETS_CONNECT_TIMEOUT_NEW:
+       case SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD: {
+               struct __kernel_sock_timeval tv;
+
+               err = sock_copy_user_timeval(&tv, optval, optlen,
+                                            optname == SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD);
+               if (err)
+                       break;
                if (tv.tv_sec >= 0 && tv.tv_usec < USEC_PER_SEC &&
                    tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1)) {
                        vsk->connect_timeout = tv.tv_sec * HZ +
-                           DIV_ROUND_UP(tv.tv_usec, (1000000 / HZ));
+                               DIV_ROUND_UP((unsigned long)tv.tv_usec, (USEC_PER_SEC / HZ));
                        if (vsk->connect_timeout == 0)
                                vsk->connect_timeout =
                                    VSOCK_DEFAULT_CONNECT_TIMEOUT;
 
        union {
                u64 val64;
+               struct old_timeval32 tm32;
                struct __kernel_old_timeval tm;
+               struct  __kernel_sock_timeval stm;
        } v;
 
        int lv = sizeof(v.val64);
                v.val64 = vsk->buffer_min_size;
                break;
 
-       case SO_VM_SOCKETS_CONNECT_TIMEOUT:
-               lv = sizeof(v.tm);
-               v.tm.tv_sec = vsk->connect_timeout / HZ;
-               v.tm.tv_usec =
-                   (vsk->connect_timeout -
-                    v.tm.tv_sec * HZ) * (1000000 / HZ);
+       case SO_VM_SOCKETS_CONNECT_TIMEOUT_NEW:
+       case SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD:
+               lv = sock_get_timeout(vsk->connect_timeout, &v,
+                                     optname == SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD);
                break;
 
        default: