summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2019-04-17 16:51:48 -0400
committerDavid S. Miller <davem@davemloft.net>2019-04-19 17:07:40 -0400
commitc7cbdbf29f488a19982cd9f4a109887f18028bbb (patch)
tree74b39321c14b93411eda0939683dc9b8b713717b
parent1ab839281cf72476988901a2606378d76530f99c (diff)
net: rework SIOCGSTAMP ioctl handling
The SIOCGSTAMP/SIOCGSTAMPNS ioctl commands are implemented by many socket protocol handlers, and all of those end up calling the same sock_get_timestamp()/sock_get_timestampns() helper functions, which results in a lot of duplicate code. With the introduction of 64-bit time_t on 32-bit architectures, this gets worse, as we then need four different ioctl commands in each socket protocol implementation. To simplify that, let's add a new .gettstamp() operation in struct proto_ops, and move ioctl implementation into the common sock_ioctl()/compat_sock_ioctl_trans() functions that these all go through. We can reuse the sock_get_timestamp() implementation, but generalize it so it can deal with both native and compat mode, as well as timeval and timespec structures. Acked-by: Stefan Schmidt <stefan@datenfreihafen.org> Acked-by: Neil Horman <nhorman@tuxdriver.com> Acked-by: Marc Kleine-Budde <mkl@pengutronix.de> Link: https://lore.kernel.org/lkml/CAK8P3a038aDQQotzua_QtKGhq8O9n+rdiz2=WDCp82ys8eUT+A@mail.gmail.com/ Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/net.h2
-rw-r--r--include/net/compat.h3
-rw-r--r--include/net/sock.h4
-rw-r--r--net/appletalk/ddp.c7
-rw-r--r--net/atm/ioctl.c16
-rw-r--r--net/atm/pvc.c1
-rw-r--r--net/atm/svc.c1
-rw-r--r--net/ax25/af_ax25.c9
-rw-r--r--net/bluetooth/af_bluetooth.c8
-rw-r--r--net/bluetooth/l2cap_sock.c1
-rw-r--r--net/bluetooth/rfcomm/sock.c1
-rw-r--r--net/bluetooth/sco.c1
-rw-r--r--net/can/af_can.c6
-rw-r--r--net/can/bcm.c1
-rw-r--r--net/can/raw.c1
-rw-r--r--net/compat.c57
-rw-r--r--net/core/sock.c51
-rw-r--r--net/dccp/ipv4.c1
-rw-r--r--net/dccp/ipv6.c1
-rw-r--r--net/ieee802154/socket.c6
-rw-r--r--net/ipv4/af_inet.c9
-rw-r--r--net/ipv6/af_inet6.c8
-rw-r--r--net/ipv6/raw.c1
-rw-r--r--net/l2tp/l2tp_ip.c1
-rw-r--r--net/l2tp/l2tp_ip6.c1
-rw-r--r--net/netrom/af_netrom.c14
-rw-r--r--net/packet/af_packet.c7
-rw-r--r--net/qrtr/qrtr.c4
-rw-r--r--net/rose/af_rose.c7
-rw-r--r--net/sctp/ipv6.c1
-rw-r--r--net/sctp/protocol.c1
-rw-r--r--net/socket.c48
-rw-r--r--net/x25/af_x25.c27
33 files changed, 75 insertions, 232 deletions
diff --git a/include/linux/net.h b/include/linux/net.h
index c606c72311d0..50bf5206ead6 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -161,6 +161,8 @@ struct proto_ops {
161 int (*compat_ioctl) (struct socket *sock, unsigned int cmd, 161 int (*compat_ioctl) (struct socket *sock, unsigned int cmd,
162 unsigned long arg); 162 unsigned long arg);
163#endif 163#endif
164 int (*gettstamp) (struct socket *sock, void __user *userstamp,
165 bool timeval, bool time32);
164 int (*listen) (struct socket *sock, int len); 166 int (*listen) (struct socket *sock, int len);
165 int (*shutdown) (struct socket *sock, int flags); 167 int (*shutdown) (struct socket *sock, int flags);
166 int (*setsockopt)(struct socket *sock, int level, 168 int (*setsockopt)(struct socket *sock, int level,
diff --git a/include/net/compat.h b/include/net/compat.h
index 4c6d75612b6c..f277653c7e17 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -30,9 +30,6 @@ struct compat_cmsghdr {
30 compat_int_t cmsg_type; 30 compat_int_t cmsg_type;
31}; 31};
32 32
33int compat_sock_get_timestamp(struct sock *, struct timeval __user *);
34int compat_sock_get_timestampns(struct sock *, struct timespec __user *);
35
36#else /* defined(CONFIG_COMPAT) */ 33#else /* defined(CONFIG_COMPAT) */
37/* 34/*
38 * To avoid compiler warnings: 35 * To avoid compiler warnings:
diff --git a/include/net/sock.h b/include/net/sock.h
index bdd77bbce7d8..784cd19d5ff7 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1614,6 +1614,8 @@ int sock_setsockopt(struct socket *sock, int level, int op,
1614 1614
1615int sock_getsockopt(struct socket *sock, int level, int op, 1615int sock_getsockopt(struct socket *sock, int level, int op,
1616 char __user *optval, int __user *optlen); 1616 char __user *optval, int __user *optlen);
1617int sock_gettstamp(struct socket *sock, void __user *userstamp,
1618 bool timeval, bool time32);
1617struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, 1619struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size,
1618 int noblock, int *errcode); 1620 int noblock, int *errcode);
1619struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, 1621struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
@@ -2503,8 +2505,6 @@ static inline bool sk_listener(const struct sock *sk)
2503} 2505}
2504 2506
2505void sock_enable_timestamp(struct sock *sk, int flag); 2507void sock_enable_timestamp(struct sock *sk, int flag);
2506int sock_get_timestamp(struct sock *, struct timeval __user *);
2507int sock_get_timestampns(struct sock *, struct timespec __user *);
2508int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len, int level, 2508int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len, int level,
2509 int type); 2509 int type);
2510 2510
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 709d2542f729..e2511027d19b 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1806,12 +1806,6 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1806 rc = put_user(amount, (int __user *)argp); 1806 rc = put_user(amount, (int __user *)argp);
1807 break; 1807 break;
1808 } 1808 }
1809 case SIOCGSTAMP:
1810 rc = sock_get_timestamp(sk, argp);
1811 break;
1812 case SIOCGSTAMPNS:
1813 rc = sock_get_timestampns(sk, argp);
1814 break;
1815 /* Routing */ 1809 /* Routing */
1816 case SIOCADDRT: 1810 case SIOCADDRT:
1817 case SIOCDELRT: 1811 case SIOCDELRT:
@@ -1871,6 +1865,7 @@ static const struct proto_ops atalk_dgram_ops = {
1871 .getname = atalk_getname, 1865 .getname = atalk_getname,
1872 .poll = datagram_poll, 1866 .poll = datagram_poll,
1873 .ioctl = atalk_ioctl, 1867 .ioctl = atalk_ioctl,
1868 .gettstamp = sock_gettstamp,
1874#ifdef CONFIG_COMPAT 1869#ifdef CONFIG_COMPAT
1875 .compat_ioctl = atalk_compat_ioctl, 1870 .compat_ioctl = atalk_compat_ioctl,
1876#endif 1871#endif
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index 2ff0e5e470e3..d955b683aa7c 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -81,22 +81,6 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd,
81 (int __user *)argp) ? -EFAULT : 0; 81 (int __user *)argp) ? -EFAULT : 0;
82 goto done; 82 goto done;
83 } 83 }
84 case SIOCGSTAMP: /* borrowed from IP */
85#ifdef CONFIG_COMPAT
86 if (compat)
87 error = compat_sock_get_timestamp(sk, argp);
88 else
89#endif
90 error = sock_get_timestamp(sk, argp);
91 goto done;
92 case SIOCGSTAMPNS: /* borrowed from IP */
93#ifdef CONFIG_COMPAT
94 if (compat)
95 error = compat_sock_get_timestampns(sk, argp);
96 else
97#endif
98 error = sock_get_timestampns(sk, argp);
99 goto done;
100 case ATM_SETSC: 84 case ATM_SETSC:
101 net_warn_ratelimited("ATM_SETSC is obsolete; used by %s:%d\n", 85 net_warn_ratelimited("ATM_SETSC is obsolete; used by %s:%d\n",
102 current->comm, task_pid_nr(current)); 86 current->comm, task_pid_nr(current));
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index 2cb10af16afc..02bd2a436bdf 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -118,6 +118,7 @@ static const struct proto_ops pvc_proto_ops = {
118#ifdef CONFIG_COMPAT 118#ifdef CONFIG_COMPAT
119 .compat_ioctl = vcc_compat_ioctl, 119 .compat_ioctl = vcc_compat_ioctl,
120#endif 120#endif
121 .gettstamp = sock_gettstamp,
121 .listen = sock_no_listen, 122 .listen = sock_no_listen,
122 .shutdown = pvc_shutdown, 123 .shutdown = pvc_shutdown,
123 .setsockopt = pvc_setsockopt, 124 .setsockopt = pvc_setsockopt,
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 2f91b766ac42..908cbb8654f5 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -641,6 +641,7 @@ static const struct proto_ops svc_proto_ops = {
641#ifdef CONFIG_COMPAT 641#ifdef CONFIG_COMPAT
642 .compat_ioctl = svc_compat_ioctl, 642 .compat_ioctl = svc_compat_ioctl,
643#endif 643#endif
644 .gettstamp = sock_gettstamp,
644 .listen = svc_listen, 645 .listen = svc_listen,
645 .shutdown = svc_shutdown, 646 .shutdown = svc_shutdown,
646 .setsockopt = svc_setsockopt, 647 .setsockopt = svc_setsockopt,
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 5d01edf8d819..449e7b7190c1 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1714,14 +1714,6 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1714 break; 1714 break;
1715 } 1715 }
1716 1716
1717 case SIOCGSTAMP:
1718 res = sock_get_timestamp(sk, argp);
1719 break;
1720
1721 case SIOCGSTAMPNS:
1722 res = sock_get_timestampns(sk, argp);
1723 break;
1724
1725 case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */ 1717 case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */
1726 case SIOCAX25DELUID: /* Delete a uid from the uid/call map table */ 1718 case SIOCAX25DELUID: /* Delete a uid from the uid/call map table */
1727 case SIOCAX25GETUID: { 1719 case SIOCAX25GETUID: {
@@ -1950,6 +1942,7 @@ static const struct proto_ops ax25_proto_ops = {
1950 .getname = ax25_getname, 1942 .getname = ax25_getname,
1951 .poll = datagram_poll, 1943 .poll = datagram_poll,
1952 .ioctl = ax25_ioctl, 1944 .ioctl = ax25_ioctl,
1945 .gettstamp = sock_gettstamp,
1953 .listen = ax25_listen, 1946 .listen = ax25_listen,
1954 .shutdown = ax25_shutdown, 1947 .shutdown = ax25_shutdown,
1955 .setsockopt = ax25_setsockopt, 1948 .setsockopt = ax25_setsockopt,
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 8d12198eaa94..94ddf19998c7 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -521,14 +521,6 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
521 err = put_user(amount, (int __user *) arg); 521 err = put_user(amount, (int __user *) arg);
522 break; 522 break;
523 523
524 case SIOCGSTAMP:
525 err = sock_get_timestamp(sk, (struct timeval __user *) arg);
526 break;
527
528 case SIOCGSTAMPNS:
529 err = sock_get_timestampns(sk, (struct timespec __user *) arg);
530 break;
531
532 default: 524 default:
533 err = -ENOIOCTLCMD; 525 err = -ENOIOCTLCMD;
534 break; 526 break;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index a3a2cd55e23a..dcb14abebeba 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1655,6 +1655,7 @@ static const struct proto_ops l2cap_sock_ops = {
1655 .recvmsg = l2cap_sock_recvmsg, 1655 .recvmsg = l2cap_sock_recvmsg,
1656 .poll = bt_sock_poll, 1656 .poll = bt_sock_poll,
1657 .ioctl = bt_sock_ioctl, 1657 .ioctl = bt_sock_ioctl,
1658 .gettstamp = sock_gettstamp,
1658 .mmap = sock_no_mmap, 1659 .mmap = sock_no_mmap,
1659 .socketpair = sock_no_socketpair, 1660 .socketpair = sock_no_socketpair,
1660 .shutdown = l2cap_sock_shutdown, 1661 .shutdown = l2cap_sock_shutdown,
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index b1f49fcc0478..90bb53aa4bee 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -1039,6 +1039,7 @@ static const struct proto_ops rfcomm_sock_ops = {
1039 .setsockopt = rfcomm_sock_setsockopt, 1039 .setsockopt = rfcomm_sock_setsockopt,
1040 .getsockopt = rfcomm_sock_getsockopt, 1040 .getsockopt = rfcomm_sock_getsockopt,
1041 .ioctl = rfcomm_sock_ioctl, 1041 .ioctl = rfcomm_sock_ioctl,
1042 .gettstamp = sock_gettstamp,
1042 .poll = bt_sock_poll, 1043 .poll = bt_sock_poll,
1043 .socketpair = sock_no_socketpair, 1044 .socketpair = sock_no_socketpair,
1044 .mmap = sock_no_mmap 1045 .mmap = sock_no_mmap
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index d892b7c3cc42..b91d6b440fdf 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -1190,6 +1190,7 @@ static const struct proto_ops sco_sock_ops = {
1190 .recvmsg = sco_sock_recvmsg, 1190 .recvmsg = sco_sock_recvmsg,
1191 .poll = bt_sock_poll, 1191 .poll = bt_sock_poll,
1192 .ioctl = bt_sock_ioctl, 1192 .ioctl = bt_sock_ioctl,
1193 .gettstamp = sock_gettstamp,
1193 .mmap = sock_no_mmap, 1194 .mmap = sock_no_mmap,
1194 .socketpair = sock_no_socketpair, 1195 .socketpair = sock_no_socketpair,
1195 .shutdown = sco_sock_shutdown, 1196 .shutdown = sco_sock_shutdown,
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 1684ba5b51eb..e8fd5dc1780a 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -89,13 +89,7 @@ static atomic_t skbcounter = ATOMIC_INIT(0);
89 89
90int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 90int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
91{ 91{
92 struct sock *sk = sock->sk;
93
94 switch (cmd) { 92 switch (cmd) {
95
96 case SIOCGSTAMP:
97 return sock_get_timestamp(sk, (struct timeval __user *)arg);
98
99 default: 93 default:
100 return -ENOIOCTLCMD; 94 return -ENOIOCTLCMD;
101 } 95 }
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 79bb8afa9c0c..a34ee52f19ea 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1689,6 +1689,7 @@ static const struct proto_ops bcm_ops = {
1689 .getname = sock_no_getname, 1689 .getname = sock_no_getname,
1690 .poll = datagram_poll, 1690 .poll = datagram_poll,
1691 .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ 1691 .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
1692 .gettstamp = sock_gettstamp,
1692 .listen = sock_no_listen, 1693 .listen = sock_no_listen,
1693 .shutdown = sock_no_shutdown, 1694 .shutdown = sock_no_shutdown,
1694 .setsockopt = sock_no_setsockopt, 1695 .setsockopt = sock_no_setsockopt,
diff --git a/net/can/raw.c b/net/can/raw.c
index c70207537488..afcbff063a67 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -846,6 +846,7 @@ static const struct proto_ops raw_ops = {
846 .getname = raw_getname, 846 .getname = raw_getname,
847 .poll = datagram_poll, 847 .poll = datagram_poll,
848 .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ 848 .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
849 .gettstamp = sock_gettstamp,
849 .listen = sock_no_listen, 850 .listen = sock_no_listen,
850 .shutdown = sock_no_shutdown, 851 .shutdown = sock_no_shutdown,
851 .setsockopt = raw_setsockopt, 852 .setsockopt = raw_setsockopt,
diff --git a/net/compat.c b/net/compat.c
index eeea5eb71639..a031bd333092 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -395,63 +395,6 @@ COMPAT_SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
395 return __compat_sys_setsockopt(fd, level, optname, optval, optlen); 395 return __compat_sys_setsockopt(fd, level, optname, optval, optlen);
396} 396}
397 397
398int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
399{
400 struct compat_timeval __user *ctv;
401 int err;
402 struct timeval tv;
403
404 if (COMPAT_USE_64BIT_TIME)
405 return sock_get_timestamp(sk, userstamp);
406
407 ctv = (struct compat_timeval __user *) userstamp;
408 err = -ENOENT;
409 sock_enable_timestamp(sk, SOCK_TIMESTAMP);
410 tv = ktime_to_timeval(sock_read_timestamp(sk));
411
412 if (tv.tv_sec == -1)
413 return err;
414 if (tv.tv_sec == 0) {
415 ktime_t kt = ktime_get_real();
416 sock_write_timestamp(sk, kt);
417 tv = ktime_to_timeval(kt);
418 }
419 err = 0;
420 if (put_user(tv.tv_sec, &ctv->tv_sec) ||
421 put_user(tv.tv_usec, &ctv->tv_usec))
422 err = -EFAULT;
423 return err;
424}
425EXPORT_SYMBOL(compat_sock_get_timestamp);
426
427int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
428{
429 struct compat_timespec __user *ctv;
430 int err;
431 struct timespec ts;
432
433 if (COMPAT_USE_64BIT_TIME)
434 return sock_get_timestampns (sk, userstamp);
435
436 ctv = (struct compat_timespec __user *) userstamp;
437 err = -ENOENT;
438 sock_enable_timestamp(sk, SOCK_TIMESTAMP);
439 ts = ktime_to_timespec(sock_read_timestamp(sk));
440 if (ts.tv_sec == -1)
441 return err;
442 if (ts.tv_sec == 0) {
443 ktime_t kt = ktime_get_real();
444 sock_write_timestamp(sk, kt);
445 ts = ktime_to_timespec(kt);
446 }
447 err = 0;
448 if (put_user(ts.tv_sec, &ctv->tv_sec) ||
449 put_user(ts.tv_nsec, &ctv->tv_nsec))
450 err = -EFAULT;
451 return err;
452}
453EXPORT_SYMBOL(compat_sock_get_timestampns);
454
455static int __compat_sys_getsockopt(int fd, int level, int optname, 398static int __compat_sys_getsockopt(int fd, int level, int optname,
456 char __user *optval, 399 char __user *optval,
457 int __user *optlen) 400 int __user *optlen)
diff --git a/net/core/sock.c b/net/core/sock.c
index 067878a1e4c5..443b98d05f1e 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2977,39 +2977,44 @@ bool lock_sock_fast(struct sock *sk)
2977} 2977}
2978EXPORT_SYMBOL(lock_sock_fast); 2978EXPORT_SYMBOL(lock_sock_fast);
2979 2979
2980int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) 2980int sock_gettstamp(struct socket *sock, void __user *userstamp,
2981 bool timeval, bool time32)
2981{ 2982{
2982 struct timeval tv; 2983 struct sock *sk = sock->sk;
2984 struct timespec64 ts;
2983 2985
2984 sock_enable_timestamp(sk, SOCK_TIMESTAMP); 2986 sock_enable_timestamp(sk, SOCK_TIMESTAMP);
2985 tv = ktime_to_timeval(sock_read_timestamp(sk)); 2987 ts = ktime_to_timespec64(sock_read_timestamp(sk));
2986 if (tv.tv_sec == -1) 2988 if (ts.tv_sec == -1)
2987 return -ENOENT; 2989 return -ENOENT;
2988 if (tv.tv_sec == 0) { 2990 if (ts.tv_sec == 0) {
2989 ktime_t kt = ktime_get_real(); 2991 ktime_t kt = ktime_get_real();
2990 sock_write_timestamp(sk, kt); 2992 sock_write_timestamp(sk, kt);;
2991 tv = ktime_to_timeval(kt); 2993 ts = ktime_to_timespec64(kt);
2992 } 2994 }
2993 return copy_to_user(userstamp, &tv, sizeof(tv)) ? -EFAULT : 0;
2994}
2995EXPORT_SYMBOL(sock_get_timestamp);
2996 2995
2997int sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp) 2996 if (timeval)
2998{ 2997 ts.tv_nsec /= 1000;
2999 struct timespec ts;
3000 2998
3001 sock_enable_timestamp(sk, SOCK_TIMESTAMP); 2999#ifdef CONFIG_COMPAT_32BIT_TIME
3002 ts = ktime_to_timespec(sock_read_timestamp(sk)); 3000 if (time32)
3003 if (ts.tv_sec == -1) 3001 return put_old_timespec32(&ts, userstamp);
3004 return -ENOENT; 3002#endif
3005 if (ts.tv_sec == 0) { 3003#ifdef CONFIG_SPARC64
3006 ktime_t kt = ktime_get_real(); 3004 /* beware of padding in sparc64 timeval */
3007 sock_write_timestamp(sk, kt); 3005 if (timeval && !in_compat_syscall()) {
3008 ts = ktime_to_timespec(sk->sk_stamp); 3006 struct __kernel_old_timeval __user tv = {
3007 .tv_sec = ts.tv_sec;
3008 .tv_usec = ts.tv_nsec;
3009 };
3010 if (copy_to_user(userstamp, &tv, sizeof(tv))
3011 return -EFAULT;
3012 return 0;
3009 } 3013 }
3010 return copy_to_user(userstamp, &ts, sizeof(ts)) ? -EFAULT : 0; 3014#endif
3015 return put_timespec64(&ts, userstamp);
3011} 3016}
3012EXPORT_SYMBOL(sock_get_timestampns); 3017EXPORT_SYMBOL(sock_gettstamp);
3013 3018
3014void sock_enable_timestamp(struct sock *sk, int flag) 3019void sock_enable_timestamp(struct sock *sk, int flag)
3015{ 3020{
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 26a21d97b6b0..004535e4c070 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -991,6 +991,7 @@ static const struct proto_ops inet_dccp_ops = {
991 /* FIXME: work on tcp_poll to rename it to inet_csk_poll */ 991 /* FIXME: work on tcp_poll to rename it to inet_csk_poll */
992 .poll = dccp_poll, 992 .poll = dccp_poll,
993 .ioctl = inet_ioctl, 993 .ioctl = inet_ioctl,
994 .gettstamp = sock_gettstamp,
994 /* FIXME: work on inet_listen to rename it to sock_common_listen */ 995 /* FIXME: work on inet_listen to rename it to sock_common_listen */
995 .listen = inet_dccp_listen, 996 .listen = inet_dccp_listen,
996 .shutdown = inet_shutdown, 997 .shutdown = inet_shutdown,
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 57d84e9b7b6f..c4e4d1301062 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -1075,6 +1075,7 @@ static const struct proto_ops inet6_dccp_ops = {
1075 .getname = inet6_getname, 1075 .getname = inet6_getname,
1076 .poll = dccp_poll, 1076 .poll = dccp_poll,
1077 .ioctl = inet6_ioctl, 1077 .ioctl = inet6_ioctl,
1078 .gettstamp = sock_gettstamp,
1078 .listen = inet_dccp_listen, 1079 .listen = inet_dccp_listen,
1079 .shutdown = inet_shutdown, 1080 .shutdown = inet_shutdown,
1080 .setsockopt = sock_common_setsockopt, 1081 .setsockopt = sock_common_setsockopt,
diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
index bc6b912603f1..ce2dfb997537 100644
--- a/net/ieee802154/socket.c
+++ b/net/ieee802154/socket.c
@@ -164,10 +164,6 @@ static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd,
164 struct sock *sk = sock->sk; 164 struct sock *sk = sock->sk;
165 165
166 switch (cmd) { 166 switch (cmd) {
167 case SIOCGSTAMP:
168 return sock_get_timestamp(sk, (struct timeval __user *)arg);
169 case SIOCGSTAMPNS:
170 return sock_get_timestampns(sk, (struct timespec __user *)arg);
171 case SIOCGIFADDR: 167 case SIOCGIFADDR:
172 case SIOCSIFADDR: 168 case SIOCSIFADDR:
173 return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg, 169 return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg,
@@ -426,6 +422,7 @@ static const struct proto_ops ieee802154_raw_ops = {
426 .getname = sock_no_getname, 422 .getname = sock_no_getname,
427 .poll = datagram_poll, 423 .poll = datagram_poll,
428 .ioctl = ieee802154_sock_ioctl, 424 .ioctl = ieee802154_sock_ioctl,
425 .gettstamp = sock_gettstamp,
429 .listen = sock_no_listen, 426 .listen = sock_no_listen,
430 .shutdown = sock_no_shutdown, 427 .shutdown = sock_no_shutdown,
431 .setsockopt = sock_common_setsockopt, 428 .setsockopt = sock_common_setsockopt,
@@ -988,6 +985,7 @@ static const struct proto_ops ieee802154_dgram_ops = {
988 .getname = sock_no_getname, 985 .getname = sock_no_getname,
989 .poll = datagram_poll, 986 .poll = datagram_poll,
990 .ioctl = ieee802154_sock_ioctl, 987 .ioctl = ieee802154_sock_ioctl,
988 .gettstamp = sock_gettstamp,
991 .listen = sock_no_listen, 989 .listen = sock_no_listen,
992 .shutdown = sock_no_shutdown, 990 .shutdown = sock_no_shutdown,
993 .setsockopt = sock_common_setsockopt, 991 .setsockopt = sock_common_setsockopt,
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 08a8430f5647..5183a2daba64 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -915,12 +915,6 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
915 struct rtentry rt; 915 struct rtentry rt;
916 916
917 switch (cmd) { 917 switch (cmd) {
918 case SIOCGSTAMP:
919 err = sock_get_timestamp(sk, (struct timeval __user *)arg);
920 break;
921 case SIOCGSTAMPNS:
922 err = sock_get_timestampns(sk, (struct timespec __user *)arg);
923 break;
924 case SIOCADDRT: 918 case SIOCADDRT:
925 case SIOCDELRT: 919 case SIOCDELRT:
926 if (copy_from_user(&rt, p, sizeof(struct rtentry))) 920 if (copy_from_user(&rt, p, sizeof(struct rtentry)))
@@ -992,6 +986,7 @@ const struct proto_ops inet_stream_ops = {
992 .getname = inet_getname, 986 .getname = inet_getname,
993 .poll = tcp_poll, 987 .poll = tcp_poll,
994 .ioctl = inet_ioctl, 988 .ioctl = inet_ioctl,
989 .gettstamp = sock_gettstamp,
995 .listen = inet_listen, 990 .listen = inet_listen,
996 .shutdown = inet_shutdown, 991 .shutdown = inet_shutdown,
997 .setsockopt = sock_common_setsockopt, 992 .setsockopt = sock_common_setsockopt,
@@ -1027,6 +1022,7 @@ const struct proto_ops inet_dgram_ops = {
1027 .getname = inet_getname, 1022 .getname = inet_getname,
1028 .poll = udp_poll, 1023 .poll = udp_poll,
1029 .ioctl = inet_ioctl, 1024 .ioctl = inet_ioctl,
1025 .gettstamp = sock_gettstamp,
1030 .listen = sock_no_listen, 1026 .listen = sock_no_listen,
1031 .shutdown = inet_shutdown, 1027 .shutdown = inet_shutdown,
1032 .setsockopt = sock_common_setsockopt, 1028 .setsockopt = sock_common_setsockopt,
@@ -1059,6 +1055,7 @@ static const struct proto_ops inet_sockraw_ops = {
1059 .getname = inet_getname, 1055 .getname = inet_getname,
1060 .poll = datagram_poll, 1056 .poll = datagram_poll,
1061 .ioctl = inet_ioctl, 1057 .ioctl = inet_ioctl,
1058 .gettstamp = sock_gettstamp,
1062 .listen = sock_no_listen, 1059 .listen = sock_no_listen,
1063 .shutdown = inet_shutdown, 1060 .shutdown = inet_shutdown,
1064 .setsockopt = sock_common_setsockopt, 1061 .setsockopt = sock_common_setsockopt,
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 3d1de28aaa9e..c04ae282f4e4 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -547,12 +547,6 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
547 struct net *net = sock_net(sk); 547 struct net *net = sock_net(sk);
548 548
549 switch (cmd) { 549 switch (cmd) {
550 case SIOCGSTAMP:
551 return sock_get_timestamp(sk, (struct timeval __user *)arg);
552
553 case SIOCGSTAMPNS:
554 return sock_get_timestampns(sk, (struct timespec __user *)arg);
555
556 case SIOCADDRT: 550 case SIOCADDRT:
557 case SIOCDELRT: 551 case SIOCDELRT:
558 552
@@ -585,6 +579,7 @@ const struct proto_ops inet6_stream_ops = {
585 .getname = inet6_getname, 579 .getname = inet6_getname,
586 .poll = tcp_poll, /* ok */ 580 .poll = tcp_poll, /* ok */
587 .ioctl = inet6_ioctl, /* must change */ 581 .ioctl = inet6_ioctl, /* must change */
582 .gettstamp = sock_gettstamp,
588 .listen = inet_listen, /* ok */ 583 .listen = inet_listen, /* ok */
589 .shutdown = inet_shutdown, /* ok */ 584 .shutdown = inet_shutdown, /* ok */
590 .setsockopt = sock_common_setsockopt, /* ok */ 585 .setsockopt = sock_common_setsockopt, /* ok */
@@ -618,6 +613,7 @@ const struct proto_ops inet6_dgram_ops = {
618 .getname = inet6_getname, 613 .getname = inet6_getname,
619 .poll = udp_poll, /* ok */ 614 .poll = udp_poll, /* ok */
620 .ioctl = inet6_ioctl, /* must change */ 615 .ioctl = inet6_ioctl, /* must change */
616 .gettstamp = sock_gettstamp,
621 .listen = sock_no_listen, /* ok */ 617 .listen = sock_no_listen, /* ok */
622 .shutdown = inet_shutdown, /* ok */ 618 .shutdown = inet_shutdown, /* ok */
623 .setsockopt = sock_common_setsockopt, /* ok */ 619 .setsockopt = sock_common_setsockopt, /* ok */
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 5a426226c762..84dbe21b71e5 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1356,6 +1356,7 @@ const struct proto_ops inet6_sockraw_ops = {
1356 .getname = inet6_getname, 1356 .getname = inet6_getname,
1357 .poll = datagram_poll, /* ok */ 1357 .poll = datagram_poll, /* ok */
1358 .ioctl = inet6_ioctl, /* must change */ 1358 .ioctl = inet6_ioctl, /* must change */
1359 .gettstamp = sock_gettstamp,
1359 .listen = sock_no_listen, /* ok */ 1360 .listen = sock_no_listen, /* ok */
1360 .shutdown = inet_shutdown, /* ok */ 1361 .shutdown = inet_shutdown, /* ok */
1361 .setsockopt = sock_common_setsockopt, /* ok */ 1362 .setsockopt = sock_common_setsockopt, /* ok */
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index d4c60523c549..2cac910c1cd4 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -618,6 +618,7 @@ static const struct proto_ops l2tp_ip_ops = {
618 .getname = l2tp_ip_getname, 618 .getname = l2tp_ip_getname,
619 .poll = datagram_poll, 619 .poll = datagram_poll,
620 .ioctl = inet_ioctl, 620 .ioctl = inet_ioctl,
621 .gettstamp = sock_gettstamp,
621 .listen = sock_no_listen, 622 .listen = sock_no_listen,
622 .shutdown = inet_shutdown, 623 .shutdown = inet_shutdown,
623 .setsockopt = sock_common_setsockopt, 624 .setsockopt = sock_common_setsockopt,
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 37a69df17cab..4ec546cc1dd6 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -752,6 +752,7 @@ static const struct proto_ops l2tp_ip6_ops = {
752 .getname = l2tp_ip6_getname, 752 .getname = l2tp_ip6_getname,
753 .poll = datagram_poll, 753 .poll = datagram_poll,
754 .ioctl = inet6_ioctl, 754 .ioctl = inet6_ioctl,
755 .gettstamp = sock_gettstamp,
755 .listen = sock_no_listen, 756 .listen = sock_no_listen,
756 .shutdown = inet_shutdown, 757 .shutdown = inet_shutdown,
757 .setsockopt = sock_common_setsockopt, 758 .setsockopt = sock_common_setsockopt,
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 71ffd1a6dc7c..167c09e1ea90 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1199,7 +1199,6 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1199{ 1199{
1200 struct sock *sk = sock->sk; 1200 struct sock *sk = sock->sk;
1201 void __user *argp = (void __user *)arg; 1201 void __user *argp = (void __user *)arg;
1202 int ret;
1203 1202
1204 switch (cmd) { 1203 switch (cmd) {
1205 case TIOCOUTQ: { 1204 case TIOCOUTQ: {
@@ -1225,18 +1224,6 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1225 return put_user(amount, (int __user *)argp); 1224 return put_user(amount, (int __user *)argp);
1226 } 1225 }
1227 1226
1228 case SIOCGSTAMP:
1229 lock_sock(sk);
1230 ret = sock_get_timestamp(sk, argp);
1231 release_sock(sk);
1232 return ret;
1233
1234 case SIOCGSTAMPNS:
1235 lock_sock(sk);
1236 ret = sock_get_timestampns(sk, argp);
1237 release_sock(sk);
1238 return ret;
1239
1240 case SIOCGIFADDR: 1227 case SIOCGIFADDR:
1241 case SIOCSIFADDR: 1228 case SIOCSIFADDR:
1242 case SIOCGIFDSTADDR: 1229 case SIOCGIFDSTADDR:
@@ -1362,6 +1349,7 @@ static const struct proto_ops nr_proto_ops = {
1362 .getname = nr_getname, 1349 .getname = nr_getname,
1363 .poll = datagram_poll, 1350 .poll = datagram_poll,
1364 .ioctl = nr_ioctl, 1351 .ioctl = nr_ioctl,
1352 .gettstamp = sock_gettstamp,
1365 .listen = nr_listen, 1353 .listen = nr_listen,
1366 .shutdown = sock_no_shutdown, 1354 .shutdown = sock_no_shutdown,
1367 .setsockopt = nr_setsockopt, 1355 .setsockopt = nr_setsockopt,
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 08fe8b79c0bf..5c4a118d6f96 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -4075,11 +4075,6 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
4075 spin_unlock_bh(&sk->sk_receive_queue.lock); 4075 spin_unlock_bh(&sk->sk_receive_queue.lock);
4076 return put_user(amount, (int __user *)arg); 4076 return put_user(amount, (int __user *)arg);
4077 } 4077 }
4078 case SIOCGSTAMP:
4079 return sock_get_timestamp(sk, (struct timeval __user *)arg);
4080 case SIOCGSTAMPNS:
4081 return sock_get_timestampns(sk, (struct timespec __user *)arg);
4082
4083#ifdef CONFIG_INET 4078#ifdef CONFIG_INET
4084 case SIOCADDRT: 4079 case SIOCADDRT:
4085 case SIOCDELRT: 4080 case SIOCDELRT:
@@ -4455,6 +4450,7 @@ static const struct proto_ops packet_ops_spkt = {
4455 .getname = packet_getname_spkt, 4450 .getname = packet_getname_spkt,
4456 .poll = datagram_poll, 4451 .poll = datagram_poll,
4457 .ioctl = packet_ioctl, 4452 .ioctl = packet_ioctl,
4453 .gettstamp = sock_gettstamp,
4458 .listen = sock_no_listen, 4454 .listen = sock_no_listen,
4459 .shutdown = sock_no_shutdown, 4455 .shutdown = sock_no_shutdown,
4460 .setsockopt = sock_no_setsockopt, 4456 .setsockopt = sock_no_setsockopt,
@@ -4476,6 +4472,7 @@ static const struct proto_ops packet_ops = {
4476 .getname = packet_getname, 4472 .getname = packet_getname,
4477 .poll = packet_poll, 4473 .poll = packet_poll,
4478 .ioctl = packet_ioctl, 4474 .ioctl = packet_ioctl,
4475 .gettstamp = sock_gettstamp,
4479 .listen = sock_no_listen, 4476 .listen = sock_no_listen,
4480 .shutdown = sock_no_shutdown, 4477 .shutdown = sock_no_shutdown,
4481 .setsockopt = packet_setsockopt, 4478 .setsockopt = packet_setsockopt,
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index b37e6e0a1026..7c5e8292cc0a 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -968,9 +968,6 @@ static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
968 break; 968 break;
969 } 969 }
970 break; 970 break;
971 case SIOCGSTAMP:
972 rc = sock_get_timestamp(sk, argp);
973 break;
974 case SIOCADDRT: 971 case SIOCADDRT:
975 case SIOCDELRT: 972 case SIOCDELRT:
976 case SIOCSIFADDR: 973 case SIOCSIFADDR:
@@ -1033,6 +1030,7 @@ static const struct proto_ops qrtr_proto_ops = {
1033 .recvmsg = qrtr_recvmsg, 1030 .recvmsg = qrtr_recvmsg,
1034 .getname = qrtr_getname, 1031 .getname = qrtr_getname,
1035 .ioctl = qrtr_ioctl, 1032 .ioctl = qrtr_ioctl,
1033 .gettstamp = sock_gettstamp,
1036 .poll = datagram_poll, 1034 .poll = datagram_poll,
1037 .shutdown = sock_no_shutdown, 1035 .shutdown = sock_no_shutdown,
1038 .setsockopt = sock_no_setsockopt, 1036 .setsockopt = sock_no_setsockopt,
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index c96f63ffe31e..e274bc6e1458 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1301,12 +1301,6 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1301 return put_user(amount, (unsigned int __user *) argp); 1301 return put_user(amount, (unsigned int __user *) argp);
1302 } 1302 }
1303 1303
1304 case SIOCGSTAMP:
1305 return sock_get_timestamp(sk, (struct timeval __user *) argp);
1306
1307 case SIOCGSTAMPNS:
1308 return sock_get_timestampns(sk, (struct timespec __user *) argp);
1309
1310 case SIOCGIFADDR: 1304 case SIOCGIFADDR:
1311 case SIOCSIFADDR: 1305 case SIOCSIFADDR:
1312 case SIOCGIFDSTADDR: 1306 case SIOCGIFDSTADDR:
@@ -1474,6 +1468,7 @@ static const struct proto_ops rose_proto_ops = {
1474 .getname = rose_getname, 1468 .getname = rose_getname,
1475 .poll = datagram_poll, 1469 .poll = datagram_poll,
1476 .ioctl = rose_ioctl, 1470 .ioctl = rose_ioctl,
1471 .gettstamp = sock_gettstamp,
1477 .listen = rose_listen, 1472 .listen = rose_listen,
1478 .shutdown = sock_no_shutdown, 1473 .shutdown = sock_no_shutdown,
1479 .setsockopt = rose_setsockopt, 1474 .setsockopt = rose_setsockopt,
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 6200cd2b4b99..188c47eb206e 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -1030,6 +1030,7 @@ static const struct proto_ops inet6_seqpacket_ops = {
1030 .getname = sctp_getname, 1030 .getname = sctp_getname,
1031 .poll = sctp_poll, 1031 .poll = sctp_poll,
1032 .ioctl = inet6_ioctl, 1032 .ioctl = inet6_ioctl,
1033 .gettstamp = sock_gettstamp,
1033 .listen = sctp_inet_listen, 1034 .listen = sctp_inet_listen,
1034 .shutdown = inet_shutdown, 1035 .shutdown = inet_shutdown,
1035 .setsockopt = sock_common_setsockopt, 1036 .setsockopt = sock_common_setsockopt,
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 951afdeea5e9..f0631bf486b6 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1026,6 +1026,7 @@ static const struct proto_ops inet_seqpacket_ops = {
1026 .getname = inet_getname, /* Semantics are different. */ 1026 .getname = inet_getname, /* Semantics are different. */
1027 .poll = sctp_poll, 1027 .poll = sctp_poll,
1028 .ioctl = inet_ioctl, 1028 .ioctl = inet_ioctl,
1029 .gettstamp = sock_gettstamp,
1029 .listen = sctp_inet_listen, 1030 .listen = sctp_inet_listen,
1030 .shutdown = inet_shutdown, /* Looks harmless. */ 1031 .shutdown = inet_shutdown, /* Looks harmless. */
1031 .setsockopt = sock_common_setsockopt, /* IP_SOL IP_OPTION is a problem */ 1032 .setsockopt = sock_common_setsockopt, /* IP_SOL IP_OPTION is a problem */
diff --git a/net/socket.c b/net/socket.c
index 8255f5bda0aa..ab624d42ead5 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1164,6 +1164,15 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
1164 1164
1165 err = open_related_ns(&net->ns, get_net_ns); 1165 err = open_related_ns(&net->ns, get_net_ns);
1166 break; 1166 break;
1167 case SIOCGSTAMP:
1168 case SIOCGSTAMPNS:
1169 if (!sock->ops->gettstamp) {
1170 err = -ENOIOCTLCMD;
1171 break;
1172 }
1173 err = sock->ops->gettstamp(sock, argp,
1174 cmd == SIOCGSTAMP, false);
1175 break;
1167 default: 1176 default:
1168 err = sock_do_ioctl(net, sock, cmd, arg); 1177 err = sock_do_ioctl(net, sock, cmd, arg);
1169 break; 1178 break;
@@ -2916,38 +2925,6 @@ void socket_seq_show(struct seq_file *seq)
2916#endif /* CONFIG_PROC_FS */ 2925#endif /* CONFIG_PROC_FS */
2917 2926
2918#ifdef CONFIG_COMPAT 2927#ifdef CONFIG_COMPAT
2919static int do_siocgstamp(struct net *net, struct socket *sock,
2920 unsigned int cmd, void __user *up)
2921{
2922 mm_segment_t old_fs = get_fs();
2923 struct timeval ktv;
2924 int err;
2925
2926 set_fs(KERNEL_DS);
2927 err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
2928 set_fs(old_fs);
2929 if (!err)
2930 err = compat_put_timeval(&ktv, up);
2931
2932 return err;
2933}
2934
2935static int do_siocgstampns(struct net *net, struct socket *sock,
2936 unsigned int cmd, void __user *up)
2937{
2938 mm_segment_t old_fs = get_fs();
2939 struct timespec kts;
2940 int err;
2941
2942 set_fs(KERNEL_DS);
2943 err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
2944 set_fs(old_fs);
2945 if (!err)
2946 err = compat_put_timespec(&kts, up);
2947
2948 return err;
2949}
2950
2951static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32) 2928static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
2952{ 2929{
2953 struct compat_ifconf ifc32; 2930 struct compat_ifconf ifc32;
@@ -3348,9 +3325,12 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
3348 case SIOCDELRT: 3325 case SIOCDELRT:
3349 return routing_ioctl(net, sock, cmd, argp); 3326 return routing_ioctl(net, sock, cmd, argp);
3350 case SIOCGSTAMP: 3327 case SIOCGSTAMP:
3351 return do_siocgstamp(net, sock, cmd, argp);
3352 case SIOCGSTAMPNS: 3328 case SIOCGSTAMPNS:
3353 return do_siocgstampns(net, sock, cmd, argp); 3329 if (!sock->ops->gettstamp)
3330 return -ENOIOCTLCMD;
3331 return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP,
3332 !COMPAT_USE_64BIT_TIME);
3333
3354 case SIOCBONDSLAVEINFOQUERY: 3334 case SIOCBONDSLAVEINFOQUERY:
3355 case SIOCBONDINFOQUERY: 3335 case SIOCBONDINFOQUERY:
3356 case SIOCSHWTSTAMP: 3336 case SIOCSHWTSTAMP:
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 20a511398389..0ea48a52ce79 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1398,18 +1398,6 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1398 break; 1398 break;
1399 } 1399 }
1400 1400
1401 case SIOCGSTAMP:
1402 rc = -EINVAL;
1403 if (sk)
1404 rc = sock_get_timestamp(sk,
1405 (struct timeval __user *)argp);
1406 break;
1407 case SIOCGSTAMPNS:
1408 rc = -EINVAL;
1409 if (sk)
1410 rc = sock_get_timestampns(sk,
1411 (struct timespec __user *)argp);
1412 break;
1413 case SIOCGIFADDR: 1401 case SIOCGIFADDR:
1414 case SIOCSIFADDR: 1402 case SIOCSIFADDR:
1415 case SIOCGIFDSTADDR: 1403 case SIOCGIFDSTADDR:
@@ -1681,8 +1669,6 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
1681 unsigned long arg) 1669 unsigned long arg)
1682{ 1670{
1683 void __user *argp = compat_ptr(arg); 1671 void __user *argp = compat_ptr(arg);
1684 struct sock *sk = sock->sk;
1685
1686 int rc = -ENOIOCTLCMD; 1672 int rc = -ENOIOCTLCMD;
1687 1673
1688 switch(cmd) { 1674 switch(cmd) {
@@ -1690,18 +1676,6 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
1690 case TIOCINQ: 1676 case TIOCINQ:
1691 rc = x25_ioctl(sock, cmd, (unsigned long)argp); 1677 rc = x25_ioctl(sock, cmd, (unsigned long)argp);
1692 break; 1678 break;
1693 case SIOCGSTAMP:
1694 rc = -EINVAL;
1695 if (sk)
1696 rc = compat_sock_get_timestamp(sk,
1697 (struct timeval __user*)argp);
1698 break;
1699 case SIOCGSTAMPNS:
1700 rc = -EINVAL;
1701 if (sk)
1702 rc = compat_sock_get_timestampns(sk,
1703 (struct timespec __user*)argp);
1704 break;
1705 case SIOCGIFADDR: 1679 case SIOCGIFADDR:
1706 case SIOCSIFADDR: 1680 case SIOCSIFADDR:
1707 case SIOCGIFDSTADDR: 1681 case SIOCGIFDSTADDR:
@@ -1765,6 +1739,7 @@ static const struct proto_ops x25_proto_ops = {
1765#ifdef CONFIG_COMPAT 1739#ifdef CONFIG_COMPAT
1766 .compat_ioctl = compat_x25_ioctl, 1740 .compat_ioctl = compat_x25_ioctl,
1767#endif 1741#endif
1742 .gettstamp = sock_gettstamp,
1768 .listen = x25_listen, 1743 .listen = x25_listen,
1769 .shutdown = sock_no_shutdown, 1744 .shutdown = sock_no_shutdown,
1770 .setsockopt = x25_setsockopt, 1745 .setsockopt = x25_setsockopt,