diff mbox series

safe_syscall design guidance

Message ID 20191029000757.r2ma5qt3zoic5ynd@shiva.audeuro.com
State New
Headers show
Series safe_syscall design guidance | expand

Commit Message

Kyle Evans Oct. 29, 2019, 12:07 a.m. UTC
Hi,

We're working on improving bsd-user in a local tree and rebasing forward
to get our work suitable for upstreaming. I'm porting the safe_syscall stuff
over to bsd-user, and would like to get some design guidance as it may best
be implemented with some refactoring of linux-user.

Below is an example of the refactoring my initial approach takes. I'm
omitting !x86_64 in this e-mail because it's all along the same lines and
only including the part relevant to linux-user. Effectively, linux-user/host
is moved to qemu-user/host along with ^/linux-user/safe-syscall.S.

Some bits specific to FreeBSD, also likely other *BSD but I've not yet
verified, are sprinkled throughout host/*/* parts; this is the main point I
suspect may be objectionable. FreeBSD indicates syscall error differently
than Linux, and *context bits are also different. Other OS-specific bits
for other arch are similar to the diff below.

A full version of this can be found in my tree, currently only available on
GitHub: https://github.com/kevans91/qemu-bsd-user/tree/safe_syscall -- this
is applied to our version, currently based on qemu 3.1.

Thoughts?

Thanks,

Kyle Evans

Comments

Kyle Evans Dec. 5, 2019, 7:03 p.m. UTC | #1
On Mon, Oct 28, 2019 at 7:08 PM Kyle Evans <kevans@freebsd.org> wrote:
>
> Hi,
>
> We're working on improving bsd-user in a local tree and rebasing forward
> to get our work suitable for upstreaming. I'm porting the safe_syscall stuff
> over to bsd-user, and would like to get some design guidance as it may best
> be implemented with some refactoring of linux-user.
>
> Below is an example of the refactoring my initial approach takes. I'm
> omitting !x86_64 in this e-mail because it's all along the same lines and
> only including the part relevant to linux-user. Effectively, linux-user/host
> is moved to qemu-user/host along with ^/linux-user/safe-syscall.S.
>
> Some bits specific to FreeBSD, also likely other *BSD but I've not yet
> verified, are sprinkled throughout host/*/* parts; this is the main point I
> suspect may be objectionable. FreeBSD indicates syscall error differently
> than Linux, and *context bits are also different. Other OS-specific bits
> for other arch are similar to the diff below.
>
> A full version of this can be found in my tree, currently only available on
> GitHub: https://github.com/kevans91/qemu-bsd-user/tree/safe_syscall -- this
> is applied to our version, currently based on qemu 3.1.
>
> Thoughts?
>

We've settled on duplicating the linux-user side over to bsd-user for
now to make progress, and make another attempt to solicit design
feedback later when we've rebased the rest of our work forward to
modern qemu.

Thanks,

Kyle Evans
diff mbox series

Patch

diff --git a/Makefile.target b/Makefile.target
index 61f28d3722..13b3b13706 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -113,7 +113,7 @@  obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 ifdef CONFIG_LINUX_USER
 
 QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) \
-             -I$(SRC_PATH)/linux-user/host/$(ARCH) \
+             -I$(SRC_PATH)/qemu-user/host/$(ARCH) \
              -I$(SRC_PATH)/linux-user
 
 obj-y += linux-user/
@@ -128,6 +128,7 @@  ifdef CONFIG_BSD_USER
 
 QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR) \
              -I$(SRC_PATH)/bsd-user/$(HOST_VARIANT_DIR) \
+             -I$(SRC_PATH)/qemu-user/host/$(ARCH) \
              -I$(SRC_PATH)/bsd-user \
              -D_WANT_SEMUN
 obj-y += bsd-user/
diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
index 769b8d8336..6089fc3a06 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -1,6 +1,6 @@ 
 obj-y = main.o syscall.o strace.o mmap.o signal.o \
 	elfload.o linuxload.o uaccess.o uname.o \
-	safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
+	../qemu-user/safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
         $(TARGET_ABI_DIR)/cpu_loop.o exit.o fd-trans.o
 
 obj-$(TARGET_HAS_BFLT) += flatload.o
diff --git a/linux-user/host/x86_64/hostdep.h b/qemu-user/host/x86_64/hostdep.h
similarity index 78%
rename from linux-user/host/x86_64/hostdep.h
rename to qemu-user/host/x86_64/hostdep.h
index a4fefb5114..7aa233a116 100644
--- a/linux-user/host/x86_64/hostdep.h
+++ b/qemu-user/host/x86_64/hostdep.h
@@ -21,11 +21,17 @@ 
 extern char safe_syscall_start[];
 extern char safe_syscall_end[];
 
+#ifndef __FreeBSD__
+#define DEFINE_PCREG(puc)	&((ucontext_t *)(puc))->uc_mcontext.gregs[REG_RIP]
+#else
+typedef __register_t greg_t;
+#define DEFINE_PCREG(puc)   &((ucontext_t *)(puc))->uc_mcontext.mc_rip
+#endif
+
 /* Adjust the signal context to rewind out of safe-syscall if we're in it */
 static inline void rewind_if_in_safe_syscall(void *puc)
 {
-    ucontext_t *uc = puc;
-    greg_t *pcreg = &uc->uc_mcontext.gregs[REG_RIP];
+    greg_t *pcreg = DEFINE_PCREG(puc);
 
     if (*pcreg > (uintptr_t)safe_syscall_start
         && *pcreg < (uintptr_t)safe_syscall_end) {
diff --git a/linux-user/host/x86_64/safe-syscall.inc.S b/qemu-user/host/x86_64/safe-syscall.inc.S
similarity index 98%
rename from linux-user/host/x86_64/safe-syscall.inc.S
rename to qemu-user/host/x86_64/safe-syscall.inc.S
index f36992daa3..2b52e122d4 100644
--- a/linux-user/host/x86_64/safe-syscall.inc.S
+++ b/qemu-user/host/x86_64/safe-syscall.inc.S
@@ -72,6 +72,11 @@  safe_syscall_start:
         syscall
 safe_syscall_end:
         /* code path for having successfully executed the syscall */
+#ifdef __FreeBSD__
+        jnb 2f
+        neg	%rax
+2:
+#endif
         pop     %rbp
         .cfi_remember_state
         .cfi_def_cfa_offset 8
diff --git a/linux-user/safe-syscall.S b/qemu-user/safe-syscall.S
similarity index 100%
rename from linux-user/safe-syscall.S
rename to qemu-user/safe-syscall.S