lkml.org 
[lkml]   [2011]   [Sep]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    SubjectRe: RFD: x32 ABI system call numbers
    From
    On Mon, Sep 5, 2011 at 12:48 AM, Arnd Bergmann <arnd@arndb.de> wrote:
    > On Sunday 04 September 2011 15:13:18 H.J. Lu wrote:
    >> On Sun, Sep 4, 2011 at 2:41 PM, Arnd Bergmann <arnd@arndb.de> wrote:
    >> > On Sunday 04 September 2011 14:25:53 H.J. Lu wrote:
    >> >> >> >> #define __NR_x32_recvfrom
    >> >> >> >> #define __NR_x32_sendmsg
    >> >> >> >> #define __NR_x32_recvmsg
    >> >> >> >> #define __NR_x32_recvmmsg
    >> >> >> >> #define __NR_x32_sendmmsg
    >> >> >> >
    >> >> >> > These today use the MSG_CMSG_COMPAT flag to distinguish native and compat
    >> >> >> > calls. Do you plan to have another flag here to handle cmsg time values?
    >> >> >>
    >> >> >> I am using x86-32 calls for them.
    >> >> >
    >> >> > But isn't that broken? These all pass u64 or time_t values at some point.
    >> >> >
    >> >>
    >> >> time_t isn't a problem since time_t/timeval/timespec are identical for
    >> >> x32 and x86-64.  As for u64, I added NATIVE_LONG_TYPE, which is
    >> >> defined as long long for x32,  and use it instead of long in types for
    >> >> 64bit system calls.
    >> >
    >> > Sorry, I misread you as saying you use the compat syscalls for these.
    >> > If you use the native 64 bit syscalls, you have the opposite problem:
    >> > Some network protocols (e.g. netlink or rxrpc) use other data structures
    >> > that require conversion, e.g. 'long' members that x32 will get wrong.
    >>
    >> For those, I use x86-32 calls.
    >
    > So to ask again, what do you plan to do about SCM_TIMESTAMP*?
    >

    I added MSG_CMSG_COMPAT64 and new compat system calls with
    64bit timespec/val to support it. See the enclosed patch.

    BTW, I also added

    compat_sys_preadv64(unsigned long fd, const struct compat_iovec __user *vec,
    unsigned long vlen, loff_t pos)
    compat_sys_pwritev64(unsigned long fd, const struct compat_iovec __user *vec,
    unsigned long vlen, loff_t pos)

    to support 32bit compat_iovec * and 64bit offset.


    --
    H.J.
    diff --git a/include/linux/socket.h b/include/linux/socket.h
    index d0e77f6..86ecf27 100644
    --- a/include/linux/socket.h
    +++ b/include/linux/socket.h
    @@ -272,8 +272,10 @@ struct ucred {
    descriptor received through
    SCM_RIGHTS */
    #if defined(CONFIG_COMPAT)
    +#define MSG_CMSG_COMPAT64 0x20000000 /* This message needs 64 bit timestamp */
    #define MSG_CMSG_COMPAT 0x80000000 /* This message needs 32 bit fixups */
    #else
    +#define MSG_CMSG_COMPAT64 0 /* We never have 64 bit timestamp */
    #define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */
    #endif

    diff --git a/net/compat.c b/net/compat.c
    index c578d93..555b951 100644
    --- a/net/compat.c
    +++ b/net/compat.c
    @@ -229,24 +229,26 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
    return 0; /* XXX: return error? check spec. */
    }

    - if (level == SOL_SOCKET && type == SCM_TIMESTAMP) {
    - struct timeval *tv = (struct timeval *)data;
    - ctv.tv_sec = tv->tv_sec;
    - ctv.tv_usec = tv->tv_usec;
    - data = &ctv;
    - len = sizeof(ctv);
    - }
    - if (level == SOL_SOCKET &&
    - (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) {
    - int count = type == SCM_TIMESTAMPNS ? 1 : 3;
    - int i;
    - struct timespec *ts = (struct timespec *)data;
    - for (i = 0; i < count; i++) {
    - cts[i].tv_sec = ts[i].tv_sec;
    - cts[i].tv_nsec = ts[i].tv_nsec;
    + if ((MSG_CMSG_COMPAT64 & kmsg->msg_flags) == 0) {
    + if (level == SOL_SOCKET && type == SCM_TIMESTAMP) {
    + struct timeval *tv = (struct timeval *)data;
    + ctv.tv_sec = tv->tv_sec;
    + ctv.tv_usec = tv->tv_usec;
    + data = &ctv;
    + len = sizeof(ctv);
    + }
    + if (level == SOL_SOCKET &&
    + (type == SCM_TIMESTAMPNS || type == SCM_TIMESTAMPING)) {
    + int count = type == SCM_TIMESTAMPNS ? 1 : 3;
    + int i;
    + struct timespec *ts = (struct timespec *)data;
    + for (i = 0; i < count; i++) {
    + cts[i].tv_sec = ts[i].tv_sec;
    + cts[i].tv_nsec = ts[i].tv_nsec;
    + }
    + data = &cts;
    + len = sizeof(cts[0]) * count;
    }
    - data = &cts;
    - len = sizeof(cts[0]) * count;
    }

    cmlen = CMSG_COMPAT_LEN(len);
    @@ -781,6 +783,52 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
    return datagrams;
    }

    +asmlinkage long compat_sys_sendmsg64(int fd, struct compat_msghdr __user *msg,
    + unsigned flags)
    +{
    + return sys_sendmsg(fd, (struct msghdr __user *)msg,
    + flags | MSG_CMSG_COMPAT | MSG_CMSG_COMPAT64);
    +}
    +
    +asmlinkage long compat_sys_sendmmsg64(int fd, struct compat_mmsghdr __user *mmsg,
    + unsigned vlen, unsigned int flags)
    +{
    + return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
    + flags | MSG_CMSG_COMPAT | MSG_CMSG_COMPAT64);
    +}
    +
    +asmlinkage long compat_sys_recvmsg64(int fd, struct compat_msghdr __user *msg,
    + unsigned int flags)
    +{
    + return sys_recvmsg(fd, (struct msghdr __user *)msg,
    + flags | MSG_CMSG_COMPAT | MSG_CMSG_COMPAT64);
    +}
    +
    +asmlinkage long compat_sys_recv64(int fd, void __user *buf, size_t len,
    + unsigned flags)
    +{
    + return sys_recv(fd, buf, len,
    + flags | MSG_CMSG_COMPAT | MSG_CMSG_COMPAT64);
    +}
    +
    +asmlinkage long compat_sys_recvfrom64(int fd, void __user *buf, size_t len,
    + unsigned flags, struct sockaddr __user *addr,
    + int __user *addrlen)
    +{
    + return sys_recvfrom(fd, buf, len,
    + flags | MSG_CMSG_COMPAT | MSG_CMSG_COMPAT64,
    + addr, addrlen);
    +}
    +
    +asmlinkage long compat_sys_recvmmsg64(int fd, struct compat_mmsghdr __user *mmsg,
    + unsigned vlen, unsigned int flags,
    + struct timespec __user *timeout)
    +{
    + return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
    + flags | MSG_CMSG_COMPAT | MSG_CMSG_COMPAT64,
    + timeout);
    +}
    +
    asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
    {
    int ret;
    diff --git a/net/socket.c b/net/socket.c
    index 24a7740..fae5472 100644
    --- a/net/socket.c
    +++ b/net/socket.c
    @@ -2133,7 +2133,7 @@ static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
    total_len = err;

    cmsg_ptr = (unsigned long)msg_sys->msg_control;
    - msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
    + msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT|MSG_CMSG_COMPAT64);

    if (sock->file->f_flags & O_NONBLOCK)
    flags |= MSG_DONTWAIT;
    \
     
     \ /
      Last update: 2011-09-05 17:13    [W:0.037 / U:0.212 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site