qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 13/34] linux-user: Fix signal before blocking sy


From: Peter Maydell
Subject: Re: [Qemu-devel] [PATCH 13/34] linux-user: Fix signal before blocking system calls race and SA_RESTART
Date: Fri, 11 Sep 2015 11:57:41 +0100

On 6 September 2015 at 00:57, Timothy E Baldwin
<address@hidden> 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

[Prev in Thread] Current Thread [Next in Thread]