Patchwork Trying to add usermode support for signalfd (but failing)

login
register
mail settings
Submitter Alex Barcelo
Date Jan. 26, 2012, 6:32 p.m.
Message ID <CAFKAgTeuF+5A9Av6=5YR26iTPFcYqLQje24gPp-zxM=NWx1sRQ@mail.gmail.com>
Download mbox | patch
Permalink /patch/138106/
State New
Headers show

Comments

Alex Barcelo - Jan. 26, 2012, 6:32 p.m.
I was trying to add signalfd support on qemu-ppc (specifically, I'm
doing a configure with "--enable-debug-tcg --enable-debug
--disable-strip --disable-kvm --disable-bsd-user --disable-darwin-user
--enable-profiler --target-list=ppc-linux-user --disable-curl
--enable-nptl").

At first I thought that it should be straightforward, so I simply
added the syscall to the "do_syscall" code. See the patch at the end.

The test program used is the example that can be found on the
signalfd(2) manpage.

It fails with a "qemu: Unsupported syscall: 313"... but the syscall
313 IS supported (it's the splice syscall, which the configure detects
and enables the CONFIG_SPLICE and it seems correct). I checked with a
splice-specific test --it worked as it should. I debugged a bit and it
seems that the switch ignores this syscall, but only when this 313
syscall is called from inside the signalfd syscall (it seems that
internally signalfd calls a splice). I am completely lost, I was
hoping that somebody could point me some directions.

 #else
@@ -8141,6 +8144,17 @@ abi_long do_syscall(void *cpu_env, int num,
abi_long arg1,
         break;
     }
 #endif
+    case TARGET_NR_signalfd:
+    {
+        sigset_t set, *set_ptr;
+
+        if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
+            goto efault;
+        target_to_host_old_sigset(&set, p);
+        set_ptr = &set;
+    	ret = get_errno(sys_signalfd(arg1,set_ptr,arg3) );
+    	break;
+    }
     default:
     unimplemented:
         gemu_log("qemu: Unsupported syscall: %d\n", num);
Alex Barcelo - June 1, 2012, 7:15 p.m.
for the sake of archive (maybe someone does the same mistake and finds
this old thread).

My fault. The syscall numbers changes between PPC and i386. And I did
not think about it and was using some i386 kernel headers to check the
syscalls. Yes, very n00b :(

Sorry for necromancing a thread.

On Thu, Jan 26, 2012 at 7:32 PM, Alex Barcelo <abarcelo@ac.upc.edu> wrote:
> I was trying to add signalfd support on qemu-ppc (specifically, I'm
> doing a configure with "--enable-debug-tcg --enable-debug
> --disable-strip --disable-kvm --disable-bsd-user --disable-darwin-user
> --enable-profiler --target-list=ppc-linux-user --disable-curl
> --enable-nptl").
>
> At first I thought that it should be straightforward, so I simply
> added the syscall to the "do_syscall" code. See the patch at the end.
>
> The test program used is the example that can be found on the
> signalfd(2) manpage.
>
> It fails with a "qemu: Unsupported syscall: 313"... but the syscall
> 313 IS supported (it's the splice syscall, which the configure detects
> and enables the CONFIG_SPLICE and it seems correct). I checked with a
> splice-specific test --it worked as it should. I debugged a bit and it
> seems that the switch ignores this syscall, but only when this 313
> syscall is called from inside the signalfd syscall (it seems that
> internally signalfd calls a splice). I am completely lost, I was
> hoping that somebody could point me some directions.
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 2bf9e7e..bcf527f 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -57,6 +57,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
>  #include <sys/sysinfo.h>
>  #include <sys/utsname.h>
>  //#include <sys/user.h>
> +#include <sys/signalfd.h>
>  #include <netinet/ip.h>
>  #include <netinet/tcp.h>
>  #include <linux/wireless.h>
> @@ -198,12 +199,14 @@ static type name (type1 arg1,type2 arg2,type3
> arg3,type4 arg4,type5 arg5,     \
>  #define __NR_sys_inotify_init __NR_inotify_init
>  #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
>  #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
> +#define __NR_sys_signalfd __NR_signalfd
>
>  #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
>     defined(__s390x__)
>  #define __NR__llseek __NR_lseek
>  #endif
>
> +_syscall3(int, sys_signalfd, int, fd, const sigset_t * , mask , int, flags);
>  #ifdef __NR_gettid
>  _syscall0(int, gettid)
>  #else
> @@ -8141,6 +8144,17 @@ abi_long do_syscall(void *cpu_env, int num,
> abi_long arg1,
>         break;
>     }
>  #endif
> +    case TARGET_NR_signalfd:
> +    {
> +        sigset_t set, *set_ptr;
> +
> +        if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
> +            goto efault;
> +        target_to_host_old_sigset(&set, p);
> +        set_ptr = &set;
> +       ret = get_errno(sys_signalfd(arg1,set_ptr,arg3) );
> +       break;
> +    }
>     default:
>     unimplemented:
>         gemu_log("qemu: Unsupported syscall: %d\n", num);

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 2bf9e7e..bcf527f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -57,6 +57,7 @@  int __clone2(int (*fn)(void *), void *child_stack_base,
 #include <sys/sysinfo.h>
 #include <sys/utsname.h>
 //#include <sys/user.h>
+#include <sys/signalfd.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
 #include <linux/wireless.h>
@@ -198,12 +199,14 @@  static type name (type1 arg1,type2 arg2,type3
arg3,type4 arg4,type5 arg5,	\
 #define __NR_sys_inotify_init __NR_inotify_init
 #define __NR_sys_inotify_add_watch __NR_inotify_add_watch
 #define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
+#define __NR_sys_signalfd __NR_signalfd

 #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
     defined(__s390x__)
 #define __NR__llseek __NR_lseek
 #endif

+_syscall3(int, sys_signalfd, int, fd, const sigset_t * , mask , int, flags);
 #ifdef __NR_gettid
 _syscall0(int, gettid)