On 6 September 2015 at 00:57, Timothy E Baldwin <t.e.baldwi...@members.leeds.ac.uk> wrote: > If a signal is delivered immediately before a blocking system calls the > handler will only be called after the system call returns, which may be a > long time later or never. > > This is fixed by using a function (safe_syscall_base) that checks if a guest > signal is pending prior to making a system call, and if so does not call the > system call and returns -TARGET_ERESTARTSYS. If a signal is received between > the check and the system call host_signal_handler() rewinds execution to > before the check. If the system call returns an error a guest error code > is returned. > > safe_syscall_base is implemented in assembly language with initially > only a x86-64 version, a fall back is provided keep the old behaviour. > > Also setting the SA_RESTART flag would result in host system calls being > restarted and the guest signal handler only being called when they have > completed. This is also fixed. > > This commit contains general infrastructure and safe_syscall_base for x86-64. > > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -599,6 +599,113 @@ char *target_strerror(int err) > return strerror(target_to_host_errno(err)); > } > > +abi_long convert_syscall_return_value(abi_long ret) { > + if (is_error(ret)) { > + ret = host_to_target_errno(ret);
This should be ret = -host_to_target_errno(-ret); host_to_target_errno() expects positive host errno values and returns positive guest errno values, but in this case we are converting a -errno return. This is why some of the LTP tests were failing: we were passing a negative value to host_to_target_errno, which then indexed backwards off the front of its table and into the target_to_host_errno table. So you typically got back an errno, but not the right one... thanks -- PMM