All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4] linux-user: add signalfd/signalfd4 syscalls
@ 2015-10-02 12:48 Laurent Vivier
  2015-10-06  8:16 ` Riku Voipio
  2016-01-18 10:30 ` Paolo Bonzini
  0 siblings, 2 replies; 6+ messages in thread
From: Laurent Vivier @ 2015-10-02 12:48 UTC (permalink / raw)
  To: peter.maydell, riku.voipio; +Cc: qemu-devel, Laurent Vivier

This patch introduces a system very similar to the one used in the kernel
to attach specific functions to a given file descriptor.

In this case, we attach a specific "host_to_target()" translator to the fd
returned by signalfd() to be able to byte-swap the signalfd_siginfo
structure provided by read().

This patch allows to execute the example program given by
man signalfd(2):

 #include <sys/signalfd.h>
 #include <signal.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>

 #define handle_error(msg) \
     do { perror(msg); exit(EXIT_FAILURE); } while (0)

 int
 main(int argc, char *argv[])
 {
     sigset_t mask;
     int sfd;
     struct signalfd_siginfo fdsi;
     ssize_t s;

     sigemptyset(&mask);
     sigaddset(&mask, SIGINT);
     sigaddset(&mask, SIGQUIT);

     /* Block signals so that they aren't handled
        according to their default dispositions */

     if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
         handle_error("sigprocmask");

     sfd = signalfd(-1, &mask, 0);
     if (sfd == -1)
         handle_error("signalfd");

     for (;;) {
         s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
         if (s != sizeof(struct signalfd_siginfo))
             handle_error("read");

         if (fdsi.ssi_signo == SIGINT) {
             printf("Got SIGINT\n");
         } else if (fdsi.ssi_signo == SIGQUIT) {
             printf("Got SIGQUIT\n");
             exit(EXIT_SUCCESS);
         } else {
             printf("Read unexpected signal\n");
         }
     }
 }

 $ ./signalfd_demo
 ^CGot SIGINT
 ^CGot SIGINT
 ^\Got SIGQUIT

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
v4: rebase on top of Riku's linux-user-for-upstream
    add fd_trans_unregister() for open_by_handle_at.
v3: Combine struct definition and typedef
    replace a = x ? y : z by if () { }
    clear extra memory from g_realloc()
    remove useless management of O_CLOEXEC
    swap ssi_addr_lsb
    fix host_flags checking
v2: Update commit message with example from man page
    Use CamelCase for struct
    Allocate entries in the fd array on demand
    Clear fd entries on open(), close(),...
    Swap ssi_errno
    Try to manage dup() and O_CLOEXEC cases
    Fix signalfd() parameters
    merge signalfd() and signalfd4()
    Change the API to only provide functions to process
    data stream.

    TargetFdTrans has an unused field, target_to_host, for symmetry
    and which could used later with netlink() functions.

 linux-user/syscall.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 167 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 98b5766..f4121af 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -60,6 +60,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include <sys/statfs.h>
 #include <utime.h>
 #include <sys/sysinfo.h>
+#include <sys/signalfd.h>
 //#include <sys/user.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
@@ -294,6 +295,54 @@ static bitmask_transtbl fcntl_flags_tbl[] = {
   { 0, 0, 0, 0 }
 };
 
+typedef abi_long (*TargetFdFunc)(void *, size_t);
+typedef struct TargetFdTrans {
+    TargetFdFunc host_to_target;
+    TargetFdFunc target_to_host;
+} TargetFdTrans;
+
+static TargetFdTrans **target_fd_trans;
+
+static unsigned int target_fd_max;
+
+static TargetFdFunc fd_trans_host_to_target(int fd)
+{
+    if (fd < target_fd_max && target_fd_trans[fd]) {
+        return target_fd_trans[fd]->host_to_target;
+    }
+    return NULL;
+}
+
+static void fd_trans_register(int fd, TargetFdTrans *trans)
+{
+    unsigned int oldmax;
+
+    if (fd >= target_fd_max) {
+        oldmax = target_fd_max;
+        target_fd_max = ((fd >> 6) + 1) << 6; /* by slice of 64 entries */
+        target_fd_trans = g_realloc(target_fd_trans,
+                                    target_fd_max * sizeof(TargetFdTrans));
+        memset((void *)(target_fd_trans + oldmax), 0,
+               (target_fd_max - oldmax) * sizeof(TargetFdTrans *));
+    }
+    target_fd_trans[fd] = trans;
+}
+
+static void fd_trans_unregister(int fd)
+{
+    if (fd >= 0 && fd < target_fd_max) {
+        target_fd_trans[fd] = NULL;
+    }
+}
+
+static void fd_trans_dup(int oldfd, int newfd)
+{
+    fd_trans_unregister(newfd);
+    if (oldfd < target_fd_max && target_fd_trans[oldfd]) {
+        fd_trans_register(newfd, target_fd_trans[oldfd]);
+    }
+}
+
 static int sys_getcwd1(char *buf, size_t size)
 {
   if (getcwd(buf, size) == NULL) {
@@ -5341,6 +5390,92 @@ static abi_long do_open_by_handle_at(abi_long mount_fd, abi_long handle,
 }
 #endif
 
+#if defined(TARGET_NR_signalfd) || defined(TARGET_NR_signalfd4)
+
+/* signalfd siginfo conversion */
+
+static void
+host_to_target_signalfd_siginfo(struct signalfd_siginfo *tinfo,
+                                const struct signalfd_siginfo *info)
+{
+    int sig = host_to_target_signal(info->ssi_signo);
+
+    /* linux/signalfd.h defines a ssi_addr_lsb
+     * not defined in sys/signalfd.h but used by some kernels
+     */
+
+#ifdef BUS_MCEERR_AO
+    if (tinfo->ssi_signo == SIGBUS &&
+        (tinfo->ssi_code == BUS_MCEERR_AR ||
+         tinfo->ssi_code == BUS_MCEERR_AO)) {
+        uint16_t *ssi_addr_lsb = (uint16_t *)(&info->ssi_addr + 1);
+        uint16_t *tssi_addr_lsb = (uint16_t *)(&tinfo->ssi_addr + 1);
+        *tssi_addr_lsb = tswap16(*ssi_addr_lsb);
+    }
+#endif
+
+    tinfo->ssi_signo = tswap32(sig);
+    tinfo->ssi_errno = tswap32(tinfo->ssi_errno);
+    tinfo->ssi_code = tswap32(info->ssi_code);
+    tinfo->ssi_pid = tswap32(info->ssi_pid);
+    tinfo->ssi_uid = tswap32(info->ssi_uid);
+    tinfo->ssi_fd = tswap32(info->ssi_fd);
+    tinfo->ssi_tid = tswap32(info->ssi_tid);
+    tinfo->ssi_band = tswap32(info->ssi_band);
+    tinfo->ssi_overrun = tswap32(info->ssi_overrun);
+    tinfo->ssi_trapno = tswap32(info->ssi_trapno);
+    tinfo->ssi_status = tswap32(info->ssi_status);
+    tinfo->ssi_int = tswap32(info->ssi_int);
+    tinfo->ssi_ptr = tswap64(info->ssi_ptr);
+    tinfo->ssi_utime = tswap64(info->ssi_utime);
+    tinfo->ssi_stime = tswap64(info->ssi_stime);
+    tinfo->ssi_addr = tswap64(info->ssi_addr);
+}
+
+static abi_long host_to_target_signalfd(void *buf, size_t len)
+{
+    int i;
+
+    for (i = 0; i < len; i += sizeof(struct signalfd_siginfo)) {
+        host_to_target_signalfd_siginfo(buf + i, buf + i);
+    }
+
+    return len;
+}
+
+static TargetFdTrans target_signalfd_trans = {
+    .host_to_target = host_to_target_signalfd,
+};
+
+static abi_long do_signalfd4(int fd, abi_long mask, int flags)
+{
+    int host_flags;
+    target_sigset_t *target_mask;
+    sigset_t host_mask;
+    abi_long ret;
+
+    if (flags & ~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC)) {
+        return -TARGET_EINVAL;
+    }
+    if (!lock_user_struct(VERIFY_READ, target_mask, mask, 1)) {
+        return -TARGET_EFAULT;
+    }
+
+    target_to_host_sigset(&host_mask, target_mask);
+
+    host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
+
+    ret = get_errno(signalfd(fd, &host_mask, host_flags));
+    if (ret >= 0) {
+        fd_trans_register(ret, &target_signalfd_trans);
+    }
+
+    unlock_user_struct(target_mask, mask, 0);
+
+    return ret;
+}
+#endif
+
 /* Map host to target signal numbers for the wait family of syscalls.
    Assume all other status bits are the same.  */
 int host_to_target_waitstatus(int status)
@@ -5725,6 +5860,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
                 goto efault;
             ret = get_errno(read(arg1, p, arg3));
+            if (ret >= 0 &&
+                fd_trans_host_to_target(arg1)) {
+                ret = fd_trans_host_to_target(arg1)(p, ret);
+            }
             unlock_user(p, arg2, ret);
         }
         break;
@@ -5741,6 +5880,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
                                   target_to_host_bitmask(arg2, fcntl_flags_tbl),
                                   arg3));
+        fd_trans_unregister(ret);
         unlock_user(p, arg1, 0);
         break;
 #endif
@@ -5750,6 +5890,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(do_openat(cpu_env, arg1, p,
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
                                   arg4));
+        fd_trans_unregister(ret);
         unlock_user(p, arg2, 0);
         break;
 #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
@@ -5760,9 +5901,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
     case TARGET_NR_open_by_handle_at:
         ret = do_open_by_handle_at(arg1, arg2, arg3);
+        fd_trans_unregister(ret);
         break;
 #endif
     case TARGET_NR_close:
+        fd_trans_unregister(arg1);
         ret = get_errno(close(arg1));
         break;
     case TARGET_NR_brk:
@@ -5804,6 +5947,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(creat(p, arg2));
+        fd_trans_unregister(ret);
         unlock_user(p, arg1, 0);
         break;
 #endif
@@ -6251,6 +6395,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
     case TARGET_NR_dup:
         ret = get_errno(dup(arg1));
+        if (ret >= 0) {
+            fd_trans_dup(arg1, ret);
+        }
         break;
 #ifdef TARGET_NR_pipe
     case TARGET_NR_pipe:
@@ -6348,11 +6495,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_dup2
     case TARGET_NR_dup2:
         ret = get_errno(dup2(arg1, arg2));
+        if (ret >= 0) {
+            fd_trans_dup(arg1, arg2);
+        }
         break;
 #endif
 #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
     case TARGET_NR_dup3:
         ret = get_errno(dup3(arg1, arg2, arg3));
+        if (ret >= 0) {
+            fd_trans_dup(arg1, arg2);
+        }
         break;
 #endif
 #ifdef TARGET_NR_getppid /* not on alpha */
@@ -7348,6 +7501,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #ifdef TARGET_NR_socket
     case TARGET_NR_socket:
         ret = do_socket(arg1, arg2, arg3);
+        fd_trans_unregister(ret);
         break;
 #endif
 #ifdef TARGET_NR_socketpair
@@ -9601,6 +9755,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_eventfd)
     case TARGET_NR_eventfd:
         ret = get_errno(eventfd(arg1, 0));
+        fd_trans_unregister(ret);
         break;
 #endif
 #if defined(TARGET_NR_eventfd2)
@@ -9614,6 +9769,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             host_flags |= O_CLOEXEC;
         }
         ret = get_errno(eventfd(arg1, host_flags));
+        fd_trans_unregister(ret);
         break;
     }
 #endif
@@ -9656,6 +9812,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #endif
 #endif
+#if defined(TARGET_NR_signalfd4)
+    case TARGET_NR_signalfd4:
+        ret = do_signalfd4(arg1, arg2, arg4);
+        break;
+#endif
+#if defined(TARGET_NR_signalfd)
+    case TARGET_NR_signalfd:
+        ret = do_signalfd4(arg1, arg2, 0);
+        break;
+#endif
 #if defined(CONFIG_EPOLL)
 #if defined(TARGET_NR_epoll_create)
     case TARGET_NR_epoll_create:
@@ -9927,6 +10093,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             timer_t htimer = g_posix_timers[timerid];
             ret = get_errno(timer_getoverrun(htimer));
         }
+        fd_trans_unregister(ret);
         break;
     }
 #endif
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v4] linux-user: add signalfd/signalfd4 syscalls
  2015-10-02 12:48 [Qemu-devel] [PATCH v4] linux-user: add signalfd/signalfd4 syscalls Laurent Vivier
@ 2015-10-06  8:16 ` Riku Voipio
  2015-11-21 21:57   ` Laurent Vivier
  2015-12-18 15:11   ` Laurent Vivier
  2016-01-18 10:30 ` Paolo Bonzini
  1 sibling, 2 replies; 6+ messages in thread
From: Riku Voipio @ 2015-10-06  8:16 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: peter.maydell, qemu-devel

On perjantaina 2. lokakuuta 2015 15.48.09 EEST, Laurent Vivier wrote:
> This patch introduces a system very similar to the one used in the kernel
> to attach specific functions to a given file descriptor.

Thanks, applied to linux-user

> In this case, we attach a specific "host_to_target()" translator to the fd
> returned by signalfd() to be able to byte-swap the signalfd_siginfo
> structure provided by read().
>
> This patch allows to execute the example program given by
> man signalfd(2):
>
>  #include <sys/signalfd.h>
>  #include <signal.h>
>  #include <unistd.h>
>  #include <stdlib.h>
>  #include <stdio.h>
>
>  #define handle_error(msg) \
>      do { perror(msg); exit(EXIT_FAILURE); } while (0)
>
>  int
>  main(int argc, char *argv[])
>  {
>      sigset_t mask;
>      int sfd;
>      struct signalfd_siginfo fdsi;
>      ssize_t s;
>
>      sigemptyset(&mask);
>      sigaddset(&mask, SIGINT);
>      sigaddset(&mask, SIGQUIT);
>
>      /* Block signals so that they aren't handled
>         according to their default dispositions */
>
>      if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
>          handle_error("sigprocmask");
>
>      sfd = signalfd(-1, &mask, 0);
>      if (sfd == -1)
>          handle_error("signalfd");
>
>      for (;;) {
>          s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
>          if (s != sizeof(struct signalfd_siginfo))
>              handle_error("read");
>
>          if (fdsi.ssi_signo == SIGINT) {
>              printf("Got SIGINT\n");
>          } else if (fdsi.ssi_signo == SIGQUIT) {
>              printf("Got SIGQUIT\n");
>              exit(EXIT_SUCCESS);
>          } else {
>              printf("Read unexpected signal\n");
>          }
>      }
>  }
>
>  $ ./signalfd_demo
>  ^CGot SIGINT
>  ^CGot SIGINT
>  ^\Got SIGQUIT
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
> v4: rebase on top of Riku's linux-user-for-upstream
>     add fd_trans_unregister() for open_by_handle_at.
> v3: Combine struct definition and typedef
>     replace a = x ? y : z by if () { }
>     clear extra memory from g_realloc()
>     remove useless management of O_CLOEXEC
>     swap ssi_addr_lsb
>     fix host_flags checking
> v2: Update commit message with example from man page
>     Use CamelCase for struct
>     Allocate entries in the fd array on demand
>     Clear fd entries on open(), close(),...
>     Swap ssi_errno
>     Try to manage dup() and O_CLOEXEC cases
>     Fix signalfd() parameters
>     merge signalfd() and signalfd4()
>     Change the API to only provide functions to process
>     data stream.
>
>     TargetFdTrans has an unused field, target_to_host, for symmetry
>     and which could used later with netlink() functions.
>
>  linux-user/syscall.c | 167 
> +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 167 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 98b5766..f4121af 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -60,6 +60,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
>  #include <sys/statfs.h>
>  #include <utime.h>
>  #include <sys/sysinfo.h>
> +#include <sys/signalfd.h>
>  //#include <sys/user.h>
>  #include <netinet/ip.h>
>  #include <netinet/tcp.h>
> @@ -294,6 +295,54 @@ static bitmask_transtbl fcntl_flags_tbl[] = {
>    { 0, 0, 0, 0 }
>  };
>  
> +typedef abi_long (*TargetFdFunc)(void *, size_t);
> +typedef struct TargetFdTrans {
> +    TargetFdFunc host_to_target;
> +    TargetFdFunc target_to_host;
> +} TargetFdTrans;
> +
> +static TargetFdTrans **target_fd_trans;
> +
> +static unsigned int target_fd_max;
> +
> +static TargetFdFunc fd_trans_host_to_target(int fd)
> +{
> +    if (fd < target_fd_max && target_fd_trans[fd]) {
> +        return target_fd_trans[fd]->host_to_target;
> +    }
> +    return NULL;
> +}
> +
> +static void fd_trans_register(int fd, TargetFdTrans *trans)
> +{
> +    unsigned int oldmax;
> +
> +    if (fd >= target_fd_max) {
> +        oldmax = target_fd_max;
> +        target_fd_max = ((fd >> 6) + 1) << 6; /* by slice of 64 entries */
> +        target_fd_trans = g_realloc(target_fd_trans,
> +                                    target_fd_max * sizeof(TargetFdTrans));
> +        memset((void *)(target_fd_trans + oldmax), 0,
> +               (target_fd_max - oldmax) * sizeof(TargetFdTrans *));
> +    }
> +    target_fd_trans[fd] = trans;
> +}
> +
> +static void fd_trans_unregister(int fd)
> +{
> +    if (fd >= 0 && fd < target_fd_max) {
> +        target_fd_trans[fd] = NULL;
> +    }
> +}
> +
> +static void fd_trans_dup(int oldfd, int newfd)
> +{
> +    fd_trans_unregister(newfd);
> +    if (oldfd < target_fd_max && target_fd_trans[oldfd]) {
> +        fd_trans_register(newfd, target_fd_trans[oldfd]);
> +    }
> +}
> +
>  static int sys_getcwd1(char *buf, size_t size)
>  {
>    if (getcwd(buf, size) == NULL) {
> @@ -5341,6 +5390,92 @@ static abi_long 
> do_open_by_handle_at(abi_long mount_fd, abi_long handle,
>  }
>  #endif
>  
> +#if defined(TARGET_NR_signalfd) || defined(TARGET_NR_signalfd4)
> +
> +/* signalfd siginfo conversion */
> +
> +static void
> +host_to_target_signalfd_siginfo(struct signalfd_siginfo *tinfo,
> +                                const struct signalfd_siginfo *info)
> +{
> +    int sig = host_to_target_signal(info->ssi_signo);
> +
> +    /* linux/signalfd.h defines a ssi_addr_lsb
> +     * not defined in sys/signalfd.h but used by some kernels
> +     */
> +
> +#ifdef BUS_MCEERR_AO
> +    if (tinfo->ssi_signo == SIGBUS &&
> +        (tinfo->ssi_code == BUS_MCEERR_AR ||
> +         tinfo->ssi_code == BUS_MCEERR_AO)) {
> +        uint16_t *ssi_addr_lsb = (uint16_t *)(&info->ssi_addr + 1);
> +        uint16_t *tssi_addr_lsb = (uint16_t *)(&tinfo->ssi_addr + 1);
> +        *tssi_addr_lsb = tswap16(*ssi_addr_lsb);
> +    }
> +#endif
> +
> +    tinfo->ssi_signo = tswap32(sig);
> +    tinfo->ssi_errno = tswap32(tinfo->ssi_errno);
> +    tinfo->ssi_code = tswap32(info->ssi_code);
> +    tinfo->ssi_pid = tswap32(info->ssi_pid);
> +    tinfo->ssi_uid = tswap32(info->ssi_uid);
> +    tinfo->ssi_fd = tswap32(info->ssi_fd);
> +    tinfo->ssi_tid = tswap32(info->ssi_tid);
> +    tinfo->ssi_band = tswap32(info->ssi_band);
> +    tinfo->ssi_overrun = tswap32(info->ssi_overrun);
> +    tinfo->ssi_trapno = tswap32(info->ssi_trapno);
> +    tinfo->ssi_status = tswap32(info->ssi_status);
> +    tinfo->ssi_int = tswap32(info->ssi_int);
> +    tinfo->ssi_ptr = tswap64(info->ssi_ptr);
> +    tinfo->ssi_utime = tswap64(info->ssi_utime);
> +    tinfo->ssi_stime = tswap64(info->ssi_stime);
> +    tinfo->ssi_addr = tswap64(info->ssi_addr);
> +}
> +
> +static abi_long host_to_target_signalfd(void *buf, size_t len)
> +{
> +    int i;
> +
> +    for (i = 0; i < len; i += sizeof(struct signalfd_siginfo)) {
> +        host_to_target_signalfd_siginfo(buf + i, buf + i);
> +    }
> +
> +    return len;
> +}
> +
> +static TargetFdTrans target_signalfd_trans = {
> +    .host_to_target = host_to_target_signalfd,
> +};
> +
> +static abi_long do_signalfd4(int fd, abi_long mask, int flags)
> +{
> +    int host_flags;
> +    target_sigset_t *target_mask;
> +    sigset_t host_mask;
> +    abi_long ret;
> +
> +    if (flags & ~(TARGET_O_NONBLOCK | TARGET_O_CLOEXEC)) {
> +        return -TARGET_EINVAL;
> +    }
> +    if (!lock_user_struct(VERIFY_READ, target_mask, mask, 1)) {
> +        return -TARGET_EFAULT;
> +    }
> +
> +    target_to_host_sigset(&host_mask, target_mask);
> +
> +    host_flags = target_to_host_bitmask(flags, fcntl_flags_tbl);
> +
> +    ret = get_errno(signalfd(fd, &host_mask, host_flags));
> +    if (ret >= 0) {
> +        fd_trans_register(ret, &target_signalfd_trans);
> +    }
> +
> +    unlock_user_struct(target_mask, mask, 0);
> +
> +    return ret;
> +}
> +#endif
> +
>  /* Map host to target signal numbers for the wait family of syscalls.
>     Assume all other status bits are the same.  */
>  int host_to_target_waitstatus(int status)
> @@ -5725,6 +5860,10 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>              if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
>                  goto efault;
>              ret = get_errno(read(arg1, p, arg3));
> +            if (ret >= 0 &&
> +                fd_trans_host_to_target(arg1)) {
> +                ret = fd_trans_host_to_target(arg1)(p, ret);
> +            }
>              unlock_user(p, arg2, ret);
>          }
>          break;
> @@ -5741,6 +5880,7 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>          ret = get_errno(do_openat(cpu_env, AT_FDCWD, p,
>                                    target_to_host_bitmask(arg2, 
> fcntl_flags_tbl),
>                                    arg3));
> +        fd_trans_unregister(ret);
>          unlock_user(p, arg1, 0);
>          break;
>  #endif
> @@ -5750,6 +5890,7 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>          ret = get_errno(do_openat(cpu_env, arg1, p,
>                                    target_to_host_bitmask(arg3, 
> fcntl_flags_tbl),
>                                    arg4));
> +        fd_trans_unregister(ret);
>          unlock_user(p, arg2, 0);
>          break;
>  #if defined(TARGET_NR_name_to_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
> @@ -5760,9 +5901,11 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>  #if defined(TARGET_NR_open_by_handle_at) && defined(CONFIG_OPEN_BY_HANDLE)
>      case TARGET_NR_open_by_handle_at:
>          ret = do_open_by_handle_at(arg1, arg2, arg3);
> +        fd_trans_unregister(ret);
>          break;
>  #endif
>      case TARGET_NR_close:
> +        fd_trans_unregister(arg1);
>          ret = get_errno(close(arg1));
>          break;
>      case TARGET_NR_brk:
> @@ -5804,6 +5947,7 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>          if (!(p = lock_user_string(arg1)))
>              goto efault;
>          ret = get_errno(creat(p, arg2));
> +        fd_trans_unregister(ret);
>          unlock_user(p, arg1, 0);
>          break;
>  #endif
> @@ -6251,6 +6395,9 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>  #endif
>      case TARGET_NR_dup:
>          ret = get_errno(dup(arg1));
> +        if (ret >= 0) {
> +            fd_trans_dup(arg1, ret);
> +        }
>          break;
>  #ifdef TARGET_NR_pipe
>      case TARGET_NR_pipe:
> @@ -6348,11 +6495,17 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>  #ifdef TARGET_NR_dup2
>      case TARGET_NR_dup2:
>          ret = get_errno(dup2(arg1, arg2));
> +        if (ret >= 0) {
> +            fd_trans_dup(arg1, arg2);
> +        }
>          break;
>  #endif
>  #if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
>      case TARGET_NR_dup3:
>          ret = get_errno(dup3(arg1, arg2, arg3));
> +        if (ret >= 0) {
> +            fd_trans_dup(arg1, arg2);
> +        }
>          break;
>  #endif
>  #ifdef TARGET_NR_getppid /* not on alpha */
> @@ -7348,6 +7501,7 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>  #ifdef TARGET_NR_socket
>      case TARGET_NR_socket:
>          ret = do_socket(arg1, arg2, arg3);
> +        fd_trans_unregister(ret);
>          break;
>  #endif
>  #ifdef TARGET_NR_socketpair
> @@ -9601,6 +9755,7 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>  #if defined(TARGET_NR_eventfd)
>      case TARGET_NR_eventfd:
>          ret = get_errno(eventfd(arg1, 0));
> +        fd_trans_unregister(ret);
>          break;
>  #endif
>  #if defined(TARGET_NR_eventfd2)
> @@ -9614,6 +9769,7 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>              host_flags |= O_CLOEXEC;
>          }
>          ret = get_errno(eventfd(arg1, host_flags));
> +        fd_trans_unregister(ret);
>          break;
>      }
>  #endif
> @@ -9656,6 +9812,16 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>          break;
>  #endif
>  #endif
> +#if defined(TARGET_NR_signalfd4)
> +    case TARGET_NR_signalfd4:
> +        ret = do_signalfd4(arg1, arg2, arg4);
> +        break;
> +#endif
> +#if defined(TARGET_NR_signalfd)
> +    case TARGET_NR_signalfd:
> +        ret = do_signalfd4(arg1, arg2, 0);
> +        break;
> +#endif
>  #if defined(CONFIG_EPOLL)
>  #if defined(TARGET_NR_epoll_create)
>      case TARGET_NR_epoll_create:
> @@ -9927,6 +10093,7 @@ abi_long do_syscall(void *cpu_env, int 
> num, abi_long arg1,
>              timer_t htimer = g_posix_timers[timerid];
>              ret = get_errno(timer_getoverrun(htimer));
>          }
> +        fd_trans_unregister(ret);
>          break;
>      }
>  #endif

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v4] linux-user: add signalfd/signalfd4 syscalls
  2015-10-06  8:16 ` Riku Voipio
@ 2015-11-21 21:57   ` Laurent Vivier
  2015-12-18 15:11   ` Laurent Vivier
  1 sibling, 0 replies; 6+ messages in thread
From: Laurent Vivier @ 2015-11-21 21:57 UTC (permalink / raw)
  To: Riku Voipio; +Cc: peter.maydell, qemu-devel



Le 06/10/2015 10:16, Riku Voipio a écrit :
> On perjantaina 2. lokakuuta 2015 15.48.09 EEST, Laurent Vivier wrote:
>> This patch introduces a system very similar to the one used in the kernel
>> to attach specific functions to a given file descriptor.
> 
> Thanks, applied to linux-user

As I don't find this patch in origin/master, I guess linux-user has
missed the 2.5 soft feature freeze ?

Laurent

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v4] linux-user: add signalfd/signalfd4 syscalls
  2015-10-06  8:16 ` Riku Voipio
  2015-11-21 21:57   ` Laurent Vivier
@ 2015-12-18 15:11   ` Laurent Vivier
  1 sibling, 0 replies; 6+ messages in thread
From: Laurent Vivier @ 2015-12-18 15:11 UTC (permalink / raw)
  To: Riku Voipio; +Cc: peter.maydell, qemu-devel



Le 06/10/2015 10:16, Riku Voipio a écrit :
> On perjantaina 2. lokakuuta 2015 15.48.09 EEST, Laurent Vivier wrote:
>> This patch introduces a system very similar to the one used in the kernel
>> to attach specific functions to a given file descriptor.
> 
> Thanks, applied to linux-user

When will linux-user branch be pulled to master ?

Laurent

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v4] linux-user: add signalfd/signalfd4 syscalls
  2015-10-02 12:48 [Qemu-devel] [PATCH v4] linux-user: add signalfd/signalfd4 syscalls Laurent Vivier
  2015-10-06  8:16 ` Riku Voipio
@ 2016-01-18 10:30 ` Paolo Bonzini
  2016-01-18 10:36   ` Laurent Vivier
  1 sibling, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2016-01-18 10:30 UTC (permalink / raw)
  To: Laurent Vivier, peter.maydell, riku.voipio; +Cc: qemu-devel



On 02/10/2015 14:48, Laurent Vivier wrote:
> +        target_fd_trans = g_realloc(target_fd_trans,
> +                                    target_fd_max * sizeof(TargetFdTrans));

This should be TargetFdTrans * (reported by Coverity).  Even better you
could use g_renew.

It's harmless because sizeof(TargetFdTrans) > sizeof(TargetFdTrans *),
but it should be fixed nevertheless.

Paolo

> +        memset((void *)(target_fd_trans + oldmax), 0,
> +               (target_fd_max - oldmax) * sizeof(TargetFdTrans *));

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v4] linux-user: add signalfd/signalfd4 syscalls
  2016-01-18 10:30 ` Paolo Bonzini
@ 2016-01-18 10:36   ` Laurent Vivier
  0 siblings, 0 replies; 6+ messages in thread
From: Laurent Vivier @ 2016-01-18 10:36 UTC (permalink / raw)
  To: Paolo Bonzini, peter.maydell, riku.voipio; +Cc: qemu-devel



Le 18/01/2016 11:30, Paolo Bonzini a écrit :
> 
> 
> On 02/10/2015 14:48, Laurent Vivier wrote:
>> +        target_fd_trans = g_realloc(target_fd_trans,
>> +                                    target_fd_max * sizeof(TargetFdTrans));
> 
> This should be TargetFdTrans * (reported by Coverity).  Even better you
> could use g_renew.
> 
> It's harmless because sizeof(TargetFdTrans) > sizeof(TargetFdTrans *),
> but it should be fixed nevertheless.

OK, thank you Paolo.

I will fix that.

Laurent

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-01-18 10:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-02 12:48 [Qemu-devel] [PATCH v4] linux-user: add signalfd/signalfd4 syscalls Laurent Vivier
2015-10-06  8:16 ` Riku Voipio
2015-11-21 21:57   ` Laurent Vivier
2015-12-18 15:11   ` Laurent Vivier
2016-01-18 10:30 ` Paolo Bonzini
2016-01-18 10:36   ` Laurent Vivier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.