[PATCH 2/4 - 2.6.15]net: 32 bit (socket layer) ioctl emulation for 64 bit kernels
Provides a 32 bit conversion function for SIOCGSTAMP diff -uprN -X dontdiff linux-2.6.15-vanilla/include/net/compat.h linux-2.6.15/include/net/compat.h --- linux-2.6.15-vanilla/include/net/compat.h 2006-01-03 14:21:10.0 +1100 +++ linux-2.6.15/include/net/compat.h 2006-01-17 09:52:50.0 +1100 @@ -23,6 +23,8 @@ struct compat_cmsghdr { compat_int_tcmsg_type; }; +extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *); + #else /* defined(CONFIG_COMPAT) */ #define compat_msghdr msghdr /* to avoid compiler warnings */ #endif /* defined(CONFIG_COMPAT) */ diff -uprN -X dontdiff linux-2.6.15-vanilla/net/compat.c linux-2.6.15/net/compat.c --- linux-2.6.15-vanilla/net/compat.c 2006-01-03 14:21:10.0 +1100 +++ linux-2.6.15/net/compat.c 2006-01-17 09:52:50.0 +1100 @@ -503,6 +503,23 @@ static int do_get_sock_timeout(int fd, i return err; } +int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) +{ + struct compat_timeval __user *ctv + = (struct compat_timeval __user*) userstamp; + int err = -ENOENT; + if(!sock_flag(sk, SOCK_TIMESTAMP)) + sock_enable_timestamp(sk); + if(sk-sk_stamp.tv_sec == -1) + return err; + if(sk-sk_stamp.tv_sec == 0) + do_gettimeofday(sk-sk_stamp); + if (put_user(sk-sk_stamp.tv_sec, ctv-tv_sec) | + put_user(sk-sk_stamp.tv_usec, ctv-tv_usec)) + err = -EFAULT; + return err; +} + asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen) { @@ -602,3 +619,5 @@ asmlinkage long compat_sys_socketcall(in } return ret; } + +EXPORT_SYMBOL(compat_sock_get_timestamp); - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4 - 2.6.15]net: 32 bit (socket layer) ioctl emulation for 64 bit kernels
On Friday 13 January 2006 03:14, Shaun Pereira wrote: Thank you for reviewing that bit of code. I had a look at compat_sys_gettimeofday and sys32_gettimeofday codes. They seem to work in a similar way, casting a pointer to the structure from user space to a compat_timeval type. The part with the case is ok, except that you don't have to write struct compat_timeval __user *ctv; ctv = (struct compat_timeval __user*) userstamp; Instead, struct compat_timeval __user *ctv = userstamp; is the more common way to write it. The result is the same, since userstamp is a 'void __user *'. But to make sure I have tested the routine by forcing the sk- sk_stamp.tv_sec value to 0 in the x25_module ( for testing purposes only, as it is initialised to -1). Now when I make a 32 bit userspace SIOCGSTAMP ioctl to the 64 bit kernel I should get the current time back in user space. This seems to work, the ioctl returns the system time (just after TEST6:) So I have left the patch as is for now. However if necessary to use the element-by-element __put_user routine as in put_tv32, then I can make the change, just let me know. You need to to exactly that, yes. I'm not sure what exactly you have tested, but the expected result of your code would be that you see the sk_stamp.tv_sec value in the output, but not the tv_usec value. On little-endian system like x86_64, that is not much of a difference (less than a second) that you might miss in a test case, but on big-endian, it would be fatal. The layout of the structures on most systems is 64 bit LE 64 bit BE 32 bit bytes 0-3 tv_sec low tv_sec high tv_sec low bytes 4-7 tv_sec high tv_sec low tv_usec low bytes 8-11 tv_usec low tv_usec high bytes 12-15 tv_usec hightv_usec low You code copies the first eight bytes of the 64 bit data structure into the 32 bit data structure. Arnd - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4 - 2.6.15]net: 32 bit (socket layer) ioctl emulation for 64 bit kernels
On Thursday 12 January 2006 06:02, Shaun Pereira wrote: +int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) +{ + struct compat_timeval __user *ctv; + ctv = (struct compat_timeval __user*) userstamp; + if(!sock_flag(sk, SOCK_TIMESTAMP)) + sock_enable_timestamp(sk); + if(sk-sk_stamp.tv_sec == -1) + return -ENOENT; + if(sk-sk_stamp.tv_sec == 0) + do_gettimeofday(sk-sk_stamp); + return copy_to_user(ctv, sk-sk_stamp, sizeof(struct compat_timeval)) ? + -EFAULT : 0; +} This looks wrong, you're not doing any conversion here. You cannot just copy sk_stamp to ctv, they are not compatible. See compat_sys_gettimeofday on how to copy a struct timeval correctly. The other patches look good. Arnd - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4 - 2.6.15]net: 32 bit (socket layer) ioctl emulation for 64 bit kernels
Hi Arnd Thank you for reviewing that bit of code. I had a look at compat_sys_gettimeofday and sys32_gettimeofday codes. They seem to work in a similar way, casting a pointer to the structure from user space to a compat_timeval type. But to make sure I have tested the routine by forcing the sk- sk_stamp.tv_sec value to 0 in the x25_module ( for testing purposes only, as it is initialised to -1). Now when I make a 32 bit userspace SIOCGSTAMP ioctl to the 64 bit kernel I should get the current time back in user space. This seems to work, the ioctl returns the system time (just after TEST6:) So I have left the patch as is for now. However if necessary to use the element-by-element __put_user routine as in put_tv32, then I can make the change, just let me know. Lastly, if anyone following this mail can help with adding this into the next release, that would be really helpful. We are building a network management application on linux for a telco and while they have the support of the SuSE's and Redhat's, any patches accepted by the kernel community makes a difference, besides saving us from building custom patches. (BTW, the application used to run on HP-UX, we are now porting it to linux). Many Thanks Shaun -- ghostview:/home/spereira/x25_32/src/func_tests/server # uname -a Linux ghostview 2.6.15-smp #9 SMP Fri Jan 13 12:43:27 EST 2006 x86_64 x86_64 x86_64 GNU/Linux ghostview:/home/spereira/x25_32/src/func_tests/server # file server server: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), not stripped ghostview:/home/spereira/x25_32/src/func_tests/server # ./server usage: server local X.121 address interface name ghostview:/home/spereira/x25_32/src/func_tests/server # ./server 0505238450 x25tap0 TEST1: create socket : passed TEST2: bind socket : passed TEST3: set subscription: passed TEST4: set facilities: passed ** Window size in = 2 Window size out = 2 Packet size in = 7 Packet size out = 7 Reverse flag = 00 Throughput = DD ** TEST5: set call user data on listen passed cud[ 0 ] = 02 cud[ 1 ] = 03 TEST6: set matchlength on listen socket handle passed The time stamp is Fri Jan 13 13:37:17 2006 TEST7: listen on socket: passed Waiting for X25 packets --- On Thu, 2006-01-12 at 19:24 +, Arnd Bergmann wrote: On Thursday 12 January 2006 06:02, Shaun Pereira wrote: +int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) +{ + struct compat_timeval __user *ctv; + ctv = (struct compat_timeval __user*) userstamp; + if(!sock_flag(sk, SOCK_TIMESTAMP)) + sock_enable_timestamp(sk); + if(sk-sk_stamp.tv_sec == -1) + return -ENOENT; + if(sk-sk_stamp.tv_sec == 0) + do_gettimeofday(sk-sk_stamp); + return copy_to_user(ctv, sk-sk_stamp, sizeof(struct compat_timeval)) ? + -EFAULT : 0; +} This looks wrong, you're not doing any conversion here. You cannot just copy sk_stamp to ctv, they are not compatible. See compat_sys_gettimeofday on how to copy a struct timeval correctly. The other patches look good. Arnd - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4 - 2.6.15]net: 32 bit (socket layer) ioctl emulation for 64 bit kernels
The second part of this series. This routine is needed by the x25 module (32-64 bit patch), as recommended it has been added to compat.c diff -uprN -X dontdiff linux-2.6.15-vanilla/include/net/compat.h linux-2.6.15/include/net/compat.h --- linux-2.6.15-vanilla/include/net/compat.h 2006-01-03 14:21:10.0 +1100 +++ linux-2.6.15/include/net/compat.h 2006-01-12 16:01:09.0 +1100 @@ -23,6 +23,8 @@ struct compat_cmsghdr { compat_int_tcmsg_type; }; +extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *); + #else /* defined(CONFIG_COMPAT) */ #define compat_msghdr msghdr /* to avoid compiler warnings */ #endif /* defined(CONFIG_COMPAT) */ diff -uprN -X dontdiff linux-2.6.15-vanilla/net/compat.c linux-2.6.15/net/compat.c --- linux-2.6.15-vanilla/net/compat.c 2006-01-03 14:21:10.0 +1100 +++ linux-2.6.15/net/compat.c 2006-01-12 16:01:09.0 +1100 @@ -503,6 +503,20 @@ static int do_get_sock_timeout(int fd, i return err; } +int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) +{ + struct compat_timeval __user *ctv; + ctv = (struct compat_timeval __user*) userstamp; + if(!sock_flag(sk, SOCK_TIMESTAMP)) + sock_enable_timestamp(sk); + if(sk-sk_stamp.tv_sec == -1) + return -ENOENT; + if(sk-sk_stamp.tv_sec == 0) + do_gettimeofday(sk-sk_stamp); + return copy_to_user(ctv, sk-sk_stamp, sizeof(struct compat_timeval)) ? + -EFAULT : 0; +} + asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen) { @@ -602,3 +616,5 @@ asmlinkage long compat_sys_socketcall(in } return ret; } + +EXPORT_SYMBOL(compat_sock_get_timestamp); - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html