Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F101990124
D31474.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D31474.diff
View Options
diff --git a/sys/amd64/linux/linux_machdep.c b/sys/amd64/linux/linux_machdep.c
--- a/sys/amd64/linux/linux_machdep.c
+++ b/sys/amd64/linux/linux_machdep.c
@@ -88,6 +88,7 @@
#include <amd64/linux/linux_proto.h>
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_file.h>
+#include <compat/linux/linux_fork.h>
#include <compat/linux/linux_ipc.h>
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_mmap.h>
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -77,6 +77,7 @@
#include <amd64/linux/linux.h>
#include <amd64/linux/linux_proto.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_fork.h>
#include <compat/linux/linux_ioctl.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_misc.h>
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -76,6 +76,7 @@
#include <amd64/linux32/linux.h>
#include <amd64/linux32/linux32_proto.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_fork.h>
#include <compat/linux/linux_ipc.h>
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_mmap.h>
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -83,6 +83,7 @@
#include <amd64/linux32/linux.h>
#include <amd64/linux32/linux32_proto.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_fork.h>
#include <compat/linux/linux_ioctl.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_misc.h>
diff --git a/sys/arm64/linux/linux_machdep.c b/sys/arm64/linux/linux_machdep.c
--- a/sys/arm64/linux/linux_machdep.c
+++ b/sys/arm64/linux/linux_machdep.c
@@ -46,6 +46,7 @@
#include <arm64/linux/linux_proto.h>
#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_fork.h>
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_mmap.h>
#include <compat/linux/linux_util.h>
diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c
--- a/sys/arm64/linux/linux_sysvec.c
+++ b/sys/arm64/linux/linux_sysvec.c
@@ -60,6 +60,7 @@
#include <arm64/linux/linux_proto.h>
#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_fork.h>
#include <compat/linux/linux_ioctl.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_misc.h>
diff --git a/sys/compat/linux/linux.h b/sys/compat/linux/linux.h
--- a/sys/compat/linux/linux.h
+++ b/sys/compat/linux/linux.h
@@ -265,4 +265,6 @@
uint64_t __spare2[13];
};
+#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffff))
+
#endif /* _LINUX_MI_H_ */
diff --git a/sys/compat/linux/linux_emul.h b/sys/compat/linux/linux_emul.h
--- a/sys/compat/linux/linux_emul.h
+++ b/sys/compat/linux/linux_emul.h
@@ -55,12 +55,11 @@
struct linux_emuldata *em_find(struct thread *);
int linux_exec_imgact_try(struct image_params *);
-void linux_proc_init(struct thread *, struct thread *, int);
+void linux_proc_init(struct thread *, struct thread *, bool);
void linux_on_exit(struct proc *);
void linux_schedtail(struct thread *);
void linux_on_exec(struct proc *, struct image_params *);
void linux_thread_dtor(struct thread *);
-void linux_thread_detach(struct thread *);
int linux_common_execve(struct thread *, struct image_args *);
void linux32_prepare_notes(struct thread *, struct note_info_list *, size_t *);
void linux64_prepare_notes(struct thread *, struct note_info_list *, size_t *);
diff --git a/sys/compat/linux/linux_emul.c b/sys/compat/linux/linux_emul.c
--- a/sys/compat/linux/linux_emul.c
+++ b/sys/compat/linux/linux_emul.c
@@ -139,7 +139,7 @@
}
void
-linux_proc_init(struct thread *td, struct thread *newtd, int flags)
+linux_proc_init(struct thread *td, struct thread *newtd, bool init_thread)
{
struct linux_emuldata *em;
struct linux_pemuldata *pem;
@@ -150,7 +150,7 @@
/* non-exec call */
em = malloc(sizeof(*em), M_TEMP, M_WAITOK | M_ZERO);
- if (flags & LINUX_CLONE_THREAD) {
+ if (init_thread) {
LINUX_CTR1(proc_init, "thread newtd(%d)",
newtd->td_tid);
@@ -312,12 +312,12 @@
* before exec. Update emuldata to reflect
* single-threaded cleaned state after exec.
*/
- linux_proc_init(td, NULL, 0);
+ linux_proc_init(td, NULL, false);
} else {
/*
* We are switching the process to Linux emulator.
*/
- linux_proc_init(td, td, 0);
+ linux_proc_init(td, td, false);
/*
* Create a transient td_emuldata for all suspended
@@ -328,7 +328,7 @@
FOREACH_THREAD_IN_PROC(td->td_proc, othertd) {
if (othertd == td)
continue;
- linux_proc_init(td, othertd, LINUX_CLONE_THREAD);
+ linux_proc_init(td, othertd, true);
}
}
#if defined(__amd64__)
diff --git a/sys/compat/linux/linux_fork.h b/sys/compat/linux/linux_fork.h
new file mode 100644
--- /dev/null
+++ b/sys/compat/linux/linux_fork.h
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 2021 Dmitry Chagin <dchagin@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LINUX_FORK_H_
+#define _LINUX_FORK_H_
+
+#define LINUX_CLONE_VM 0x00000100
+#define LINUX_CLONE_FS 0x00000200
+#define LINUX_CLONE_FILES 0x00000400
+#define LINUX_CLONE_SIGHAND 0x00000800
+#define LINUX_CLONE_PID 0x00001000 /* No longer exist in Linux */
+#define LINUX_CLONE_PTRACE 0x00002000
+#define LINUX_CLONE_VFORK 0x00004000
+#define LINUX_CLONE_PARENT 0x00008000
+#define LINUX_CLONE_THREAD 0x00010000
+#define LINUX_CLONE_NEWNS 0x00020000 /* New mount NS */
+#define LINUX_CLONE_SYSVSEM 0x00040000
+#define LINUX_CLONE_SETTLS 0x00080000
+#define LINUX_CLONE_PARENT_SETTID 0x00100000
+#define LINUX_CLONE_CHILD_CLEARTID 0x00200000
+#define LINUX_CLONE_DETACHED 0x00400000 /* Unused */
+#define LINUX_CLONE_UNTRACED 0x00800000
+#define LINUX_CLONE_CHILD_SETTID 0x01000000
+#define LINUX_CLONE_NEWCGROUP 0x02000000 /* New cgroup NS */
+#define LINUX_CLONE_NEWUTS 0x04000000
+#define LINUX_CLONE_NEWIPC 0x08000000
+#define LINUX_CLONE_NEWUSER 0x10000000
+#define LINUX_CLONE_NEWPID 0x20000000
+#define LINUX_CLONE_NEWNET 0x40000000
+#define LINUX_CLONE_IO 0x80000000
+
+#define LINUX_CSIGNAL 0x000000ff
+
+/*
+ * User-space clone3 args layout.
+ */
+struct l_user_clone_args {
+ uint64_t flags;
+ uint64_t pidfd;
+ uint64_t child_tid;
+ uint64_t parent_tid;
+ uint64_t exit_signal;
+ uint64_t stack;
+ uint64_t stack_size;
+ uint64_t tls;
+ uint64_t set_tid;
+ uint64_t set_tid_size;
+ uint64_t cgroup;
+};
+
+/*
+ * Kernel clone3 args layout.
+ */
+struct l_clone_args {
+ uint64_t flags;
+ l_int *child_tid;
+ l_int *parent_tid;
+ l_int exit_signal;
+ l_ulong stack;
+ l_ulong stack_size;
+ l_ulong tls;
+};
+
+int linux_set_upcall(struct thread *, register_t);
+int linux_set_cloned_tls(struct thread *, void *);
+void linux_thread_detach(struct thread *);
+
+#endif /* _LINUX_FORK_H_ */
diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c
--- a/sys/compat/linux/linux_fork.c
+++ b/sys/compat/linux/linux_fork.c
@@ -60,7 +60,9 @@
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#endif
+#include <compat/linux/linux.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_fork.h>
#include <compat/linux/linux_futex.h>
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_util.h>
@@ -82,7 +84,7 @@
td2 = FIRST_THREAD_IN_PROC(p2);
- linux_proc_init(td, td2, 0);
+ linux_proc_init(td, td2, false);
td->td_retval[0] = p2->p_pid;
@@ -112,7 +114,7 @@
td2 = FIRST_THREAD_IN_PROC(p2);
- linux_proc_init(td, td2, 0);
+ linux_proc_init(td, td2, false);
td->td_retval[0] = p2->p_pid;
@@ -128,7 +130,7 @@
#endif
static int
-linux_clone_proc(struct thread *td, struct linux_clone_args *args)
+linux_clone_proc(struct thread *td, struct l_clone_args *args)
{
struct fork_req fr;
int error, ff = RFPROC | RFSTOPPED, f2;
@@ -138,11 +140,12 @@
struct linux_emuldata *em;
f2 = 0;
- exit_signal = args->flags & 0x000000ff;
- if (LINUX_SIG_VALID(exit_signal)) {
- exit_signal = linux_to_bsd_signal(exit_signal);
- } else if (exit_signal != 0)
+ if (LINUX_SIG_VALID(args->exit_signal)) {
+ exit_signal = linux_to_bsd_signal(args->exit_signal);
+ } else if (args->exit_signal != 0)
return (EINVAL);
+ else
+ exit_signal = 0;
if (args->flags & LINUX_CLONE_VM)
ff |= RFMEM;
@@ -158,7 +161,7 @@
}
if (args->flags & LINUX_CLONE_PARENT_SETTID)
- if (args->parent_tidptr == NULL)
+ if (args->parent_tid == NULL)
return (EINVAL);
if (args->flags & LINUX_CLONE_VFORK)
@@ -175,23 +178,23 @@
td2 = FIRST_THREAD_IN_PROC(p2);
/* create the emuldata */
- linux_proc_init(td, td2, args->flags);
+ linux_proc_init(td, td2, false);
em = em_find(td2);
KASSERT(em != NULL, ("clone_proc: emuldata not found.\n"));
if (args->flags & LINUX_CLONE_CHILD_SETTID)
- em->child_set_tid = args->child_tidptr;
+ em->child_set_tid = args->child_tid;
else
em->child_set_tid = NULL;
if (args->flags & LINUX_CLONE_CHILD_CLEARTID)
- em->child_clear_tid = args->child_tidptr;
+ em->child_clear_tid = args->child_tid;
else
em->child_clear_tid = NULL;
if (args->flags & LINUX_CLONE_PARENT_SETTID) {
- error = copyout(&p2->p_pid, args->parent_tidptr,
+ error = copyout(&p2->p_pid, args->parent_tid,
sizeof(p2->p_pid));
if (error)
linux_msg(td, "copyout p_pid failed!");
@@ -235,7 +238,7 @@
}
static int
-linux_clone_thread(struct thread *td, struct linux_clone_args *args)
+linux_clone_thread(struct thread *td, struct l_clone_args *args)
{
struct linux_emuldata *em;
struct thread *newtd;
@@ -244,12 +247,12 @@
LINUX_CTR4(clone_thread, "thread(%d) flags %x ptid %p ctid %p",
td->td_tid, (unsigned)args->flags,
- args->parent_tidptr, args->child_tidptr);
+ args->parent_tid, args->child_tid);
if ((args->flags & LINUX_CLONE_PARENT) != 0)
return (EINVAL);
if (args->flags & LINUX_CLONE_PARENT_SETTID)
- if (args->parent_tidptr == NULL)
+ if (args->parent_tid == NULL)
return (EINVAL);
/* Threads should be created with own stack */
@@ -284,7 +287,7 @@
thread_cow_get(newtd, td);
/* create the emuldata */
- linux_proc_init(td, newtd, args->flags);
+ linux_proc_init(td, newtd, true);
em = em_find(newtd);
KASSERT(em != NULL, ("clone_thread: emuldata not found.\n"));
@@ -293,12 +296,12 @@
linux_set_cloned_tls(newtd, PTRIN(args->tls));
if (args->flags & LINUX_CLONE_CHILD_SETTID)
- em->child_set_tid = args->child_tidptr;
+ em->child_set_tid = args->child_tid;
else
em->child_set_tid = NULL;
if (args->flags & LINUX_CLONE_CHILD_CLEARTID)
- em->child_clear_tid = args->child_tidptr;
+ em->child_clear_tid = args->child_tid;
else
em->child_clear_tid = NULL;
@@ -328,7 +331,7 @@
td->td_tid, newtd->td_tid);
if (args->flags & LINUX_CLONE_PARENT_SETTID) {
- error = copyout(&newtd->td_tid, args->parent_tidptr,
+ error = copyout(&newtd->td_tid, args->parent_tid,
sizeof(newtd->td_tid));
if (error)
linux_msg(td, "clone_thread: copyout td_tid failed!");
@@ -359,11 +362,19 @@
int
linux_clone(struct thread *td, struct linux_clone_args *args)
{
+ struct l_clone_args ca = {
+ .flags = (lower_32_bits(args->flags) & ~LINUX_CSIGNAL),
+ .child_tid = args->child_tidptr,
+ .parent_tid = args->parent_tidptr,
+ .exit_signal = (lower_32_bits(args->flags) & LINUX_CSIGNAL),
+ .stack = args->stack,
+ .tls = args->tls,
+ };
if (args->flags & LINUX_CLONE_THREAD)
- return (linux_clone_thread(td, args));
+ return (linux_clone_thread(td, &ca));
else
- return (linux_clone_proc(td, args));
+ return (linux_clone_proc(td, &ca));
}
int
diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h
--- a/sys/compat/linux/linux_misc.h
+++ b/sys/compat/linux/linux_misc.h
@@ -98,31 +98,6 @@
#define __LINUX_NPXCW__ 0x37f
#endif
-#define LINUX_CLONE_VM 0x00000100
-#define LINUX_CLONE_FS 0x00000200
-#define LINUX_CLONE_FILES 0x00000400
-#define LINUX_CLONE_SIGHAND 0x00000800
-#define LINUX_CLONE_PID 0x00001000 /* No longer exist in Linux */
-#define LINUX_CLONE_PTRACE 0x00002000
-#define LINUX_CLONE_VFORK 0x00004000
-#define LINUX_CLONE_PARENT 0x00008000
-#define LINUX_CLONE_THREAD 0x00010000
-#define LINUX_CLONE_NEWNS 0x00020000 /* New mount NS */
-#define LINUX_CLONE_SYSVSEM 0x00040000
-#define LINUX_CLONE_SETTLS 0x00080000
-#define LINUX_CLONE_PARENT_SETTID 0x00100000
-#define LINUX_CLONE_CHILD_CLEARTID 0x00200000
-#define LINUX_CLONE_DETACHED 0x00400000 /* Unused */
-#define LINUX_CLONE_UNTRACED 0x00800000
-#define LINUX_CLONE_CHILD_SETTID 0x01000000
-#define LINUX_CLONE_NEWCGROUP 0x02000000 /* New cgroup NS */
-#define LINUX_CLONE_NEWUTS 0x04000000
-#define LINUX_CLONE_NEWIPC 0x08000000
-#define LINUX_CLONE_NEWUSER 0x10000000
-#define LINUX_CLONE_NEWPID 0x20000000
-#define LINUX_CLONE_NEWNET 0x40000000
-#define LINUX_CLONE_IO 0x80000000
-
/* Scheduling policies */
#define LINUX_SCHED_OTHER 0
#define LINUX_SCHED_FIFO 1
@@ -180,8 +155,6 @@
int linux_ptrace_status(struct thread *td, int pid, int status);
#endif
void linux_to_bsd_waitopts(int options, int *bsdopts);
-int linux_set_upcall(struct thread *td, register_t stack);
-int linux_set_cloned_tls(struct thread *td, void *desc);
struct thread *linux_tdfind(struct thread *, lwpid_t, pid_t);
#endif /* _LINUX_MISC_H_ */
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c
--- a/sys/i386/linux/linux_machdep.c
+++ b/sys/i386/linux/linux_machdep.c
@@ -66,6 +66,7 @@
#include <i386/linux/linux.h>
#include <i386/linux/linux_proto.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_fork.h>
#include <compat/linux/linux_ipc.h>
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_mmap.h>
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -66,6 +66,7 @@
#include <i386/linux/linux.h>
#include <i386/linux/linux_proto.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_fork.h>
#include <compat/linux/linux_ioctl.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_misc.h>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 7, 6:25 AM (21 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14506069
Default Alt Text
D31474.diff (15 KB)
Attached To
Mode
D31474: linux(4): Add struct clone_args for future clone3 system call.
Attached
Detach File
Event Timeline
Log In to Comment