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

Reply via email to