[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