qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v2 1/2] linux-user: added support for preadv() s


From: Peter Maydell
Subject: Re: [Qemu-devel] [PATCH v2 1/2] linux-user: added support for preadv() system call.
Date: Thu, 6 Oct 2016 17:15:25 +0100

On 6 October 2016 at 16:49, Dejan Jovicevic <address@hidden> wrote:
> v1 -> v2:
>         - Using safe_preadv() instead of calling preadv() directly.
>
> This system call performs the same task as the readv system call,
> with the exception of having the fourth argument, offset, which
> specifes the file offset at which the input operation is to be performed.
>
> This implementation is based on the existing readv implementation.
>
> Signed-off-by: Dejan Jovicevic <address@hidden>
> ---
>  linux-user/syscall.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 0815f30..c7619f6 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -908,6 +908,8 @@ safe_syscall2(int, tkill, int, tid, int, sig)
>  safe_syscall3(int, tgkill, int, tgid, int, pid, int, sig)
>  safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, 
> iovcnt)
>  safe_syscall3(ssize_t, writev, int, fd, const struct iovec *, iov, int, 
> iovcnt)
> +safe_syscall4(ssize_t, preadv, int, fd, const struct iovec *, iov, int, 
> iovcnt,
> +              off_t, offset)
>  safe_syscall3(int, connect, int, fd, const struct sockaddr *, addr,
>                socklen_t, addrlen)
>  safe_syscall6(ssize_t, sendto, int, fd, const void *, buf, size_t, len,
> @@ -9894,6 +9896,19 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
> arg1,
>              }
>          }
>          break;
> +#if defined(TARGET_NR_preadv)
> +    case TARGET_NR_preadv:
> +        {
> +            struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
> +            if (vec != NULL) {
> +                ret = get_errno(safe_preadv(arg1, vec, arg3, arg4));
> +                unlock_iovec(vec, arg2, arg3, 1);
> +            } else {
> +                ret = -host_to_target_errno(errno);
> +           }
> +        }
> +        break;
> +#endif

Looking at the kernel implementation I think this is not quite right
(sorry for not checking the first time around).
preadv is a 5-argument syscall:
SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
                unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)

and the 64-bit offset is obtained by combining the pos_l and
pos_h arguments via pos_from_hilo():
http://lxr.free-electrons.com/source/fs/read_write.c#L927

So we need to handle 5 arguments in the inputs from the guest,
and we need to pass 5 arguments to the host syscall. (Watch out
for the case where guest and host have different ideas of
the size of long, when converting the input pos_l/pos_h
to the host pos_l/pos_h.)

Similarly for pwritev.

thanks
-- PMM



reply via email to

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