All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] bsd-user upstreaming: read, write and exit
@ 2022-06-08 21:17 Warner Losh
  2022-06-08 21:17 ` [PATCH v2 1/6] bsd-user/freebsd/os-syscall.c: lock_iovec Warner Losh
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Warner Losh @ 2022-06-08 21:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: jrtc27, def, Warner Losh, arrowd, Kyle Evans

This series of patches continues the effort to get system calls working
upstream. This series was cleaved off a prior series to give me time to rework
based on the feedback from the first time I posted these.

       o bsd-user/freebsd/os-syscall.c: lock_iovec
I rewored to use g_try_new, as well as fixing bugs in the 'after a FAULT
handling code' Created a common routine to cleanup after errors that can
be used for the unlock_iovec.

       o bsd-user/freebsd/os-syscall.c: unlock_iovec
Fixed the error handling to be consistent with a normal unlock_iovec.

       o bsd-user/freebsd/os-syscall.c: Tracing and error boilerplate
Created the wrapper function as suggested in prior reviews.

V2: Use g_try_new0 and simplify based on not needing to initialize things
to zero that are already zero. Only affects the 'lock_iovec' hunk.

V2: Remove inline tags from do_bsd_* routines.

V2: Clean up logging a little

Now all the patches, except the last one, need to be reviewed.

Warner Losh (6):
  bsd-user/freebsd/os-syscall.c: lock_iovec
  bsd-user/freebsd/os-syscall.c: unlock_iovec
  bsd-user/freebsd/os-syscall.c: Tracing and error boilerplate
  bsd-user/bsd-file.h: Add implementations for read, pread, readv and
    preadv
  bsd-user/bsd-file.h: Meat of the write system calls
  bsd-user/freebsd/os-syscall.c: Implement exit

 bsd-user/bsd-file.h           | 163 +++++++++++++++++++++++++
 bsd-user/bsd-proc.h           |  43 +++++++
 bsd-user/freebsd/os-syscall.c | 217 +++++++++++++++++++++++++++++++++-
 3 files changed, 419 insertions(+), 4 deletions(-)
 create mode 100644 bsd-user/bsd-proc.h

-- 
2.33.1



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/6] bsd-user/freebsd/os-syscall.c: lock_iovec
  2022-06-08 21:17 [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Warner Losh
@ 2022-06-08 21:17 ` Warner Losh
  2022-06-08 21:17 ` [PATCH v2 2/6] bsd-user/freebsd/os-syscall.c: unlock_iovec Warner Losh
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Warner Losh @ 2022-06-08 21:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: jrtc27, def, Warner Losh, arrowd, Kyle Evans

lock_iovec will lock an I/O vec and the memory to which it refers and
create a iovec in the host space that refers to it, with full error
unwinding. Add helper_iovec_unlock to unlock the partially locked iovec
in case there's an error. The code will be used in iovec_unlock when
that is committed.

Note: memory handling likely could be rewritten to use q_autofree. That
will be explored in the future since what we have now works well enough.

Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/freebsd/os-syscall.c | 102 ++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index d272478e7b0..67851937a8f 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -73,6 +73,108 @@ bool is_error(abi_long ret)
     return (abi_ulong)ret >= (abi_ulong)(-4096);
 }
 
+/*
+ * Unlocks a iovec. Unlike unlock_iovec, it assumes the tvec array itself is
+ * already locked from target_addr. It will be unlocked as well as all the iovec
+ * elements.
+ */
+static void helper_unlock_iovec(struct target_iovec *target_vec,
+                                abi_ulong target_addr, struct iovec *vec,
+                                int count, int copy)
+{
+    for (int i = 0; i < count; i++) {
+        abi_ulong base = tswapal(target_vec[i].iov_base);
+
+        if (vec[i].iov_base) {
+            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
+        }
+    }
+    unlock_user(target_vec, target_addr, 0);
+}
+
+struct iovec *lock_iovec(int type, abi_ulong target_addr,
+        int count, int copy)
+{
+    struct target_iovec *target_vec;
+    struct iovec *vec;
+    abi_ulong total_len, max_len;
+    int i;
+    int err = 0;
+
+    if (count == 0) {
+        errno = 0;
+        return NULL;
+    }
+    if (count < 0 || count > IOV_MAX) {
+        errno = EINVAL;
+        return NULL;
+    }
+
+    vec = g_try_new0(struct iovec, count);
+    if (vec == NULL) {
+        errno = ENOMEM;
+        return NULL;
+    }
+
+    target_vec = lock_user(VERIFY_READ, target_addr,
+                           count * sizeof(struct target_iovec), 1);
+    if (target_vec == NULL) {
+        err = EFAULT;
+        goto fail2;
+    }
+
+    max_len = 0x7fffffff & MIN(TARGET_PAGE_MASK, PAGE_MASK);
+    total_len = 0;
+
+    for (i = 0; i < count; i++) {
+        abi_ulong base = tswapal(target_vec[i].iov_base);
+        abi_long len = tswapal(target_vec[i].iov_len);
+
+        if (len < 0) {
+            err = EINVAL;
+            goto fail;
+        } else if (len == 0) {
+            /* Zero length pointer is ignored. */
+            vec[i].iov_base = 0;
+        } else {
+            vec[i].iov_base = lock_user(type, base, len, copy);
+            /*
+             * If the first buffer pointer is bad, this is a fault.  But
+             * subsequent bad buffers will result in a partial write; this is
+             * realized by filling the vector with null pointers and zero
+             * lengths.
+             */
+            if (!vec[i].iov_base) {
+                if (i == 0) {
+                    err = EFAULT;
+                    goto fail;
+                } else {
+                    /*
+                     * Fail all the subsequent addresses, they are already
+                     * zero'd.
+                     */
+                    goto out;
+                }
+            }
+            if (len > max_len - total_len) {
+                len = max_len - total_len;
+            }
+        }
+        vec[i].iov_len = len;
+        total_len += len;
+    }
+out:
+    unlock_user(target_vec, target_addr, 0);
+    return vec;
+
+fail:
+    helper_unlock_iovec(target_vec, target_addr, vec, i, copy);
+fail2:
+    g_free(vec);
+    errno = err;
+    return NULL;
+}
+
 /*
  * do_syscall() should always have a single exit point at the end so that
  * actions, such as logging of syscall results, can be performed.  All errnos
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/6] bsd-user/freebsd/os-syscall.c: unlock_iovec
  2022-06-08 21:17 [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Warner Losh
  2022-06-08 21:17 ` [PATCH v2 1/6] bsd-user/freebsd/os-syscall.c: lock_iovec Warner Losh
@ 2022-06-08 21:17 ` Warner Losh
  2022-06-08 21:17 ` [PATCH v2 3/6] bsd-user/freebsd/os-syscall.c: Tracing and error boilerplate Warner Losh
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Warner Losh @ 2022-06-08 21:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: jrtc27, def, Warner Losh, arrowd, Kyle Evans

Releases the references to the iovec created by lock_iovec.

Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/freebsd/os-syscall.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index 67851937a8f..52093d479d8 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -175,6 +175,20 @@ fail2:
     return NULL;
 }
 
+void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
+        int count, int copy)
+{
+    struct target_iovec *target_vec;
+
+    target_vec = lock_user(VERIFY_READ, target_addr,
+                           count * sizeof(struct target_iovec), 1);
+    if (target_vec) {
+        helper_unlock_iovec(target_vec, target_addr, vec, count, copy);
+    }
+
+    g_free(vec);
+}
+
 /*
  * do_syscall() should always have a single exit point at the end so that
  * actions, such as logging of syscall results, can be performed.  All errnos
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/6] bsd-user/freebsd/os-syscall.c: Tracing and error boilerplate
  2022-06-08 21:17 [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Warner Losh
  2022-06-08 21:17 ` [PATCH v2 1/6] bsd-user/freebsd/os-syscall.c: lock_iovec Warner Losh
  2022-06-08 21:17 ` [PATCH v2 2/6] bsd-user/freebsd/os-syscall.c: unlock_iovec Warner Losh
@ 2022-06-08 21:17 ` Warner Losh
  2022-06-08 21:17 ` [PATCH v2 4/6] bsd-user/bsd-file.h: Add implementations for read, pread, readv and preadv Warner Losh
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Warner Losh @ 2022-06-08 21:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: jrtc27, def, Warner Losh, arrowd, Kyle Evans

Add in the tracing and this system call not implemented boilerplate. Do
this by moving the guts of do_freebsd_syscall to freebsd_syscall. Put
the tracing in the wrapper function. Since freebsd_syscall is a
singleton static function, it will almost certainly be inlined. Fix
comments that referred to do_syscall since that was renamed some tie
ago.

Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/freebsd/os-syscall.c | 44 +++++++++++++++++++++++++++++++----
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index 52093d479d8..1c4c9983f1a 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -190,16 +190,52 @@ void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
 }
 
 /*
- * do_syscall() should always have a single exit point at the end so that
- * actions, such as logging of syscall results, can be performed.  All errnos
- * that do_syscall() returns must be -TARGET_<errcode>.
+ * All errnos that freebsd_syscall() returns must be -TARGET_<errcode>.
+ */
+static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1,
+                                abi_long arg2, abi_long arg3, abi_long arg4,
+                                abi_long arg5, abi_long arg6, abi_long arg7,
+                                abi_long arg8)
+{
+    abi_long ret;
+
+    switch (num) {
+    default:
+        qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
+        ret = -TARGET_ENOSYS;
+        break;
+    }
+
+    return ret;
+}
+
+/*
+ * do_freebsd_syscall() should always have a single exit point at the end so
+ * that actions, such as logging of syscall results, can be performed. This
+ * as a wrapper around freebsd_syscall() so that actually happens. Since
+ * that is a singleton, modern compilers will inline it anyway...
  */
 abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
                             abi_long arg2, abi_long arg3, abi_long arg4,
                             abi_long arg5, abi_long arg6, abi_long arg7,
                             abi_long arg8)
 {
-    return 0;
+    CPUState *cpu = env_cpu(cpu_env);
+    int ret;
+
+    trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+    if (do_strace) {
+        print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
+    }
+
+    ret = freebsd_syscall(cpu_env, num, arg1, arg2, arg3, arg4, arg5, arg6,
+                          arg7, arg8);
+    if (do_strace) {
+        print_freebsd_syscall_ret(num, ret);
+    }
+    trace_guest_user_syscall_ret(cpu, num, ret);
+
+    return ret;
 }
 
 void syscall_init(void)
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 4/6] bsd-user/bsd-file.h: Add implementations for read, pread, readv and preadv
  2022-06-08 21:17 [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Warner Losh
                   ` (2 preceding siblings ...)
  2022-06-08 21:17 ` [PATCH v2 3/6] bsd-user/freebsd/os-syscall.c: Tracing and error boilerplate Warner Losh
@ 2022-06-08 21:17 ` Warner Losh
  2022-06-08 21:17 ` [PATCH v2 5/6] bsd-user/bsd-file.h: Meat of the write system calls Warner Losh
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Warner Losh @ 2022-06-08 21:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: jrtc27, def, Warner Losh, arrowd, Kyle Evans, Stacey Son, Kyle Evans

Implement do_bsd_{read,pread,readv,preadv}. Connect them to the system
call table.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/bsd-file.h           | 79 +++++++++++++++++++++++++++++++++++
 bsd-user/freebsd/os-syscall.c | 28 +++++++++++++
 2 files changed, 107 insertions(+)

diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
index a6bff3b8c26..839f8c5c55a 100644
--- a/bsd-user/bsd-file.h
+++ b/bsd-user/bsd-file.h
@@ -27,4 +27,83 @@ extern struct iovec *lock_iovec(int type, abi_ulong target_addr, int count,
 extern void unlock_iovec(struct iovec *vec, abi_ulong target_addr, int count,
         int copy);
 
+ssize_t safe_read(int fd, void *buf, size_t nbytes);
+ssize_t safe_pread(int fd, void *buf, size_t nbytes, off_t offset);
+ssize_t safe_readv(int fd, const struct iovec *iov, int iovcnt);
+ssize_t safe_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+
+/* read(2) */
+static abi_long do_bsd_read(abi_long arg1, abi_long arg2, abi_long arg3)
+{
+    abi_long ret;
+    void *p;
+
+    p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+    if (p == NULL) {
+        return -TARGET_EFAULT;
+    }
+    ret = get_errno(safe_read(arg1, p, arg3));
+    unlock_user(p, arg2, ret);
+
+    return ret;
+}
+
+/* pread(2) */
+static abi_long do_bsd_pread(void *cpu_env, abi_long arg1,
+    abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+    abi_long ret;
+    void *p;
+
+    p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+    if (p == NULL) {
+        return -TARGET_EFAULT;
+    }
+    if (regpairs_aligned(cpu_env) != 0) {
+        arg4 = arg5;
+        arg5 = arg6;
+    }
+    ret = get_errno(safe_pread(arg1, p, arg3, target_arg64(arg4, arg5)));
+    unlock_user(p, arg2, ret);
+
+    return ret;
+}
+
+/* readv(2) */
+static abi_long do_bsd_readv(abi_long arg1, abi_long arg2, abi_long arg3)
+{
+    abi_long ret;
+    struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0);
+
+    if (vec != NULL) {
+        ret = get_errno(safe_readv(arg1, vec, arg3));
+        unlock_iovec(vec, arg2, arg3, 1);
+    } else {
+        ret = -host_to_target_errno(errno);
+    }
+
+    return ret;
+}
+
+/* preadv(2) */
+static abi_long do_bsd_preadv(void *cpu_env, abi_long arg1,
+    abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+    abi_long ret;
+    struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 1);
+
+    if (vec != NULL) {
+        if (regpairs_aligned(cpu_env) != 0) {
+            arg4 = arg5;
+            arg5 = arg6;
+        }
+        ret = get_errno(safe_preadv(arg1, vec, arg3, target_arg64(arg4, arg5)));
+        unlock_iovec(vec, arg2, arg3, 0);
+    } else {
+        ret = -host_to_target_errno(errno);
+    }
+
+    return ret;
+}
+
 #endif /* BSD_FILE_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index 1c4c9983f1a..8ca92f29857 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -42,6 +42,14 @@
 
 #include "bsd-file.h"
 
+/* I/O */
+safe_syscall3(ssize_t, read, int, fd, void *, buf, size_t, nbytes);
+safe_syscall4(ssize_t, pread, int, fd, void *, buf, size_t, nbytes, off_t,
+    offset);
+safe_syscall3(ssize_t, readv, int, fd, const struct iovec *, iov, int, iovcnt);
+safe_syscall4(ssize_t, preadv, int, fd, const struct iovec *, iov, int, iovcnt,
+    off_t, offset);
+
 void target_set_brk(abi_ulong new_brk)
 {
 }
@@ -200,6 +208,26 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1,
     abi_long ret;
 
     switch (num) {
+
+        /*
+         * File system calls.
+         */
+    case TARGET_FREEBSD_NR_read: /* read(2) */
+        ret = do_bsd_read(arg1, arg2, arg3);
+        break;
+
+    case TARGET_FREEBSD_NR_pread: /* pread(2) */
+        ret = do_bsd_pread(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
+        break;
+
+    case TARGET_FREEBSD_NR_readv: /* readv(2) */
+        ret = do_bsd_readv(arg1, arg2, arg3);
+        break;
+
+    case TARGET_FREEBSD_NR_preadv: /* preadv(2) */
+        ret = do_bsd_preadv(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
+        break;
+
     default:
         qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
         ret = -TARGET_ENOSYS;
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 5/6] bsd-user/bsd-file.h: Meat of the write system calls
  2022-06-08 21:17 [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Warner Losh
                   ` (3 preceding siblings ...)
  2022-06-08 21:17 ` [PATCH v2 4/6] bsd-user/bsd-file.h: Add implementations for read, pread, readv and preadv Warner Losh
@ 2022-06-08 21:17 ` Warner Losh
  2022-06-08 21:17 ` [PATCH v2 6/6] bsd-user/freebsd/os-syscall.c: Implement exit Warner Losh
  2022-06-09 14:16 ` [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Richard Henderson
  6 siblings, 0 replies; 9+ messages in thread
From: Warner Losh @ 2022-06-08 21:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: jrtc27, def, Warner Losh, arrowd, Kyle Evans, Stacey Son, Kyle Evans

Implement write, writev, pwrite and pwritev and connect them to the
system call dispatch routine.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
---
 bsd-user/bsd-file.h           | 84 +++++++++++++++++++++++++++++++++++
 bsd-user/freebsd/os-syscall.c | 22 +++++++++
 2 files changed, 106 insertions(+)

diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
index 839f8c5c55a..e9e2c85eb67 100644
--- a/bsd-user/bsd-file.h
+++ b/bsd-user/bsd-file.h
@@ -32,6 +32,11 @@ ssize_t safe_pread(int fd, void *buf, size_t nbytes, off_t offset);
 ssize_t safe_readv(int fd, const struct iovec *iov, int iovcnt);
 ssize_t safe_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
 
+ssize_t safe_write(int fd, void *buf, size_t nbytes);
+ssize_t safe_pwrite(int fd, void *buf, size_t nbytes, off_t offset);
+ssize_t safe_writev(int fd, const struct iovec *iov, int iovcnt);
+ssize_t safe_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+
 /* read(2) */
 static abi_long do_bsd_read(abi_long arg1, abi_long arg2, abi_long arg3)
 {
@@ -106,4 +111,83 @@ static abi_long do_bsd_preadv(void *cpu_env, abi_long arg1,
     return ret;
 }
 
+/* write(2) */
+static abi_long do_bsd_write(abi_long arg1, abi_long arg2, abi_long arg3)
+{
+    abi_long nbytes, ret;
+    void *p;
+
+    /* nbytes < 0 implies that it was larger than SIZE_MAX. */
+    nbytes = arg3;
+    if (nbytes < 0) {
+        return -TARGET_EINVAL;
+    }
+    p = lock_user(VERIFY_READ, arg2, nbytes, 1);
+    if (p == NULL) {
+        return -TARGET_EFAULT;
+    }
+    ret = get_errno(safe_write(arg1, p, arg3));
+    unlock_user(p, arg2, 0);
+
+    return ret;
+}
+
+/* pwrite(2) */
+static abi_long do_bsd_pwrite(void *cpu_env, abi_long arg1,
+    abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+    abi_long ret;
+    void *p;
+
+    p = lock_user(VERIFY_READ, arg2, arg3, 1);
+    if (p == NULL) {
+        return -TARGET_EFAULT;
+    }
+    if (regpairs_aligned(cpu_env) != 0) {
+        arg4 = arg5;
+        arg5 = arg6;
+    }
+    ret = get_errno(safe_pwrite(arg1, p, arg3, target_arg64(arg4, arg5)));
+    unlock_user(p, arg2, 0);
+
+    return ret;
+}
+
+/* writev(2) */
+static abi_long do_bsd_writev(abi_long arg1, abi_long arg2, abi_long arg3)
+{
+    abi_long ret;
+    struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
+
+    if (vec != NULL) {
+        ret = get_errno(safe_writev(arg1, vec, arg3));
+        unlock_iovec(vec, arg2, arg3, 0);
+    } else {
+        ret = -host_to_target_errno(errno);
+    }
+
+    return ret;
+}
+
+/* pwritev(2) */
+static abi_long do_bsd_pwritev(void *cpu_env, abi_long arg1,
+    abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+    abi_long ret;
+    struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1);
+
+    if (vec != NULL) {
+        if (regpairs_aligned(cpu_env) != 0) {
+            arg4 = arg5;
+            arg5 = arg6;
+        }
+        ret = get_errno(safe_pwritev(arg1, vec, arg3, target_arg64(arg4, arg5)));
+        unlock_iovec(vec, arg2, arg3, 0);
+    } else {
+        ret = -host_to_target_errno(errno);
+    }
+
+    return ret;
+}
+
 #endif /* BSD_FILE_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index 8ca92f29857..3a33d54fa4d 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -50,6 +50,13 @@ safe_syscall3(ssize_t, readv, 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(ssize_t, write, int, fd, void *, buf, size_t, nbytes);
+safe_syscall4(ssize_t, pwrite, int, fd, void *, buf, size_t, nbytes, off_t,
+    offset);
+safe_syscall3(ssize_t, writev, int, fd, const struct iovec *, iov, int, iovcnt);
+safe_syscall4(ssize_t, pwritev, int, fd, const struct iovec *, iov, int, iovcnt,
+    off_t, offset);
+
 void target_set_brk(abi_ulong new_brk)
 {
 }
@@ -226,6 +233,21 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1,
 
     case TARGET_FREEBSD_NR_preadv: /* preadv(2) */
         ret = do_bsd_preadv(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
+
+    case TARGET_FREEBSD_NR_write: /* write(2) */
+        ret = do_bsd_write(arg1, arg2, arg3);
+        break;
+
+    case TARGET_FREEBSD_NR_pwrite: /* pwrite(2) */
+        ret = do_bsd_pwrite(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
+        break;
+
+    case TARGET_FREEBSD_NR_writev: /* writev(2) */
+        ret = do_bsd_writev(arg1, arg2, arg3);
+        break;
+
+    case TARGET_FREEBSD_NR_pwritev: /* pwritev(2) */
+        ret = do_bsd_pwritev(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
         break;
 
     default:
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 6/6] bsd-user/freebsd/os-syscall.c: Implement exit
  2022-06-08 21:17 [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Warner Losh
                   ` (4 preceding siblings ...)
  2022-06-08 21:17 ` [PATCH v2 5/6] bsd-user/bsd-file.h: Meat of the write system calls Warner Losh
@ 2022-06-08 21:17 ` Warner Losh
  2022-06-09 14:15   ` Richard Henderson
  2022-06-09 14:16 ` [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Richard Henderson
  6 siblings, 1 reply; 9+ messages in thread
From: Warner Losh @ 2022-06-08 21:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: jrtc27, def, Warner Losh, arrowd, Kyle Evans, Stacey Son,
	Kyle Evans, Richard Henderson

Implement the exit system call. Bring in bsd-proc.h to contain all the
process system call implementation and helper routines.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Kyle Evans <kevans@FreeBSD.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 bsd-user/bsd-proc.h           | 43 +++++++++++++++++++++++++++++++++++
 bsd-user/freebsd/os-syscall.c |  7 ++++++
 2 files changed, 50 insertions(+)
 create mode 100644 bsd-user/bsd-proc.h

diff --git a/bsd-user/bsd-proc.h b/bsd-user/bsd-proc.h
new file mode 100644
index 00000000000..8f0b6990d14
--- /dev/null
+++ b/bsd-user/bsd-proc.h
@@ -0,0 +1,43 @@
+/*
+ *  process related system call shims and definitions
+ *
+ *  Copyright (c) 2013-2014 Stacey D. Son
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef BSD_PROC_H_
+#define BSD_PROC_H_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+/* exit(2) */
+static inline abi_long do_bsd_exit(void *cpu_env, abi_long arg1)
+{
+#ifdef TARGET_GPROF
+    _mcleanup();
+#endif
+    gdb_exit(arg1);
+    qemu_plugin_user_exit();
+    /* XXX: should free thread stack and CPU env here  */
+    _exit(arg1);
+
+    return 0;
+}
+
+#endif /* !BSD_PROC_H_ */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index 3a33d54fa4d..71aa0d38e03 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -41,6 +41,7 @@
 #include "user/syscall-trace.h"
 
 #include "bsd-file.h"
+#include "bsd-proc.h"
 
 /* I/O */
 safe_syscall3(ssize_t, read, int, fd, void *, buf, size_t, nbytes);
@@ -215,6 +216,12 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1,
     abi_long ret;
 
     switch (num) {
+        /*
+         * process system calls
+         */
+    case TARGET_FREEBSD_NR_exit: /* exit(2) */
+        ret = do_bsd_exit(cpu_env, arg1);
+        break;
 
         /*
          * File system calls.
-- 
2.33.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 6/6] bsd-user/freebsd/os-syscall.c: Implement exit
  2022-06-08 21:17 ` [PATCH v2 6/6] bsd-user/freebsd/os-syscall.c: Implement exit Warner Losh
@ 2022-06-09 14:15   ` Richard Henderson
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2022-06-09 14:15 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: jrtc27, def, arrowd, Kyle Evans, Stacey Son

On 6/8/22 14:17, Warner Losh wrote:
> +static inline abi_long do_bsd_exit(void *cpu_env, abi_long arg1)
> +{
> +#ifdef TARGET_GPROF
> +    _mcleanup();
> +#endif
> +    gdb_exit(arg1);
> +    qemu_plugin_user_exit();
> +    /* XXX: should free thread stack and CPU env here  */
> +    _exit(arg1);
> +

I think you can ditch the comment.  There's no point in that just before exit.


r~


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/6] bsd-user upstreaming: read, write and exit
  2022-06-08 21:17 [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Warner Losh
                   ` (5 preceding siblings ...)
  2022-06-08 21:17 ` [PATCH v2 6/6] bsd-user/freebsd/os-syscall.c: Implement exit Warner Losh
@ 2022-06-09 14:16 ` Richard Henderson
  6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2022-06-09 14:16 UTC (permalink / raw)
  To: Warner Losh, qemu-devel; +Cc: jrtc27, def, arrowd, Kyle Evans

On 6/8/22 14:17, Warner Losh wrote:
> Warner Losh (6):
>    bsd-user/freebsd/os-syscall.c: lock_iovec
>    bsd-user/freebsd/os-syscall.c: unlock_iovec
>    bsd-user/freebsd/os-syscall.c: Tracing and error boilerplate
>    bsd-user/bsd-file.h: Add implementations for read, pread, readv and
>      preadv
>    bsd-user/bsd-file.h: Meat of the write system calls
>    bsd-user/freebsd/os-syscall.c: Implement exit
> 
>   bsd-user/bsd-file.h           | 163 +++++++++++++++++++++++++
>   bsd-user/bsd-proc.h           |  43 +++++++
>   bsd-user/freebsd/os-syscall.c | 217 +++++++++++++++++++++++++++++++++-
>   3 files changed, 419 insertions(+), 4 deletions(-)
>   create mode 100644 bsd-user/bsd-proc.h
> 

Series,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-06-09 15:41 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 21:17 [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Warner Losh
2022-06-08 21:17 ` [PATCH v2 1/6] bsd-user/freebsd/os-syscall.c: lock_iovec Warner Losh
2022-06-08 21:17 ` [PATCH v2 2/6] bsd-user/freebsd/os-syscall.c: unlock_iovec Warner Losh
2022-06-08 21:17 ` [PATCH v2 3/6] bsd-user/freebsd/os-syscall.c: Tracing and error boilerplate Warner Losh
2022-06-08 21:17 ` [PATCH v2 4/6] bsd-user/bsd-file.h: Add implementations for read, pread, readv and preadv Warner Losh
2022-06-08 21:17 ` [PATCH v2 5/6] bsd-user/bsd-file.h: Meat of the write system calls Warner Losh
2022-06-08 21:17 ` [PATCH v2 6/6] bsd-user/freebsd/os-syscall.c: Implement exit Warner Losh
2022-06-09 14:15   ` Richard Henderson
2022-06-09 14:16 ` [PATCH v2 0/6] bsd-user upstreaming: read, write and exit Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.