* [PATCH 1/2] tools/nolibc: s390: provide custom implementation for sys_fork
2023-04-15 21:28 [PATCH 0/2] tools/nolibc: fork: fix on s390 and add test Thomas Weißschuh
@ 2023-04-15 21:28 ` Thomas Weißschuh
2023-05-09 7:53 ` Sven Schnelle
2023-04-15 21:28 ` [PATCH 2/2] tools/nolibc: add testcase for fork()/waitpid() Thomas Weißschuh
2023-04-16 5:33 ` [PATCH 0/2] tools/nolibc: fork: fix on s390 and add test Willy Tarreau
2 siblings, 1 reply; 5+ messages in thread
From: Thomas Weißschuh @ 2023-04-15 21:28 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: linux-kernel, linux-kselftest, Thomas Weißschuh
On s390 the first two arguments to the clone() syscall are swapped,
as documented in clone(2).
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/include/nolibc/arch-s390.h | 8 ++++++++
tools/include/nolibc/sys.h | 2 ++
2 files changed, 10 insertions(+)
diff --git a/tools/include/nolibc/arch-s390.h b/tools/include/nolibc/arch-s390.h
index 6b0e54ed543d..db4ea51a4dbb 100644
--- a/tools/include/nolibc/arch-s390.h
+++ b/tools/include/nolibc/arch-s390.h
@@ -5,6 +5,7 @@
#ifndef _NOLIBC_ARCH_S390_H
#define _NOLIBC_ARCH_S390_H
+#include <asm/signal.h>
#include <asm/unistd.h>
/* The struct returned by the stat() syscall, equivalent to stat64(). The
@@ -223,4 +224,11 @@ void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
return (void *)my_syscall1(__NR_mmap, &args);
}
#define sys_mmap sys_mmap
+
+static __attribute__((unused))
+pid_t sys_fork(void)
+{
+ return my_syscall5(__NR_clone, 0, SIGCHLD, 0, 0, 0);
+}
+#define sys_fork sys_fork
#endif // _NOLIBC_ARCH_S390_H
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index bea9760dbd16..f5a450153a63 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -336,6 +336,7 @@ void exit(int status)
* pid_t fork(void);
*/
+#ifndef sys_fork
static __attribute__((unused))
pid_t sys_fork(void)
{
@@ -351,6 +352,7 @@ pid_t sys_fork(void)
#error Neither __NR_clone nor __NR_fork defined, cannot implement sys_fork()
#endif
}
+#endif
static __attribute__((unused))
pid_t fork(void)
--
2.40.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/2] tools/nolibc: add testcase for fork()/waitpid()
2023-04-15 21:28 [PATCH 0/2] tools/nolibc: fork: fix on s390 and add test Thomas Weißschuh
2023-04-15 21:28 ` [PATCH 1/2] tools/nolibc: s390: provide custom implementation for sys_fork Thomas Weißschuh
@ 2023-04-15 21:28 ` Thomas Weißschuh
2023-04-16 5:33 ` [PATCH 0/2] tools/nolibc: fork: fix on s390 and add test Willy Tarreau
2 siblings, 0 replies; 5+ messages in thread
From: Thomas Weißschuh @ 2023-04-15 21:28 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: linux-kernel, linux-kselftest, Thomas Weißschuh
On s390 the arguments to clone() which is used by fork() are different
than other archs.
Make sure everything works correctly.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
tools/testing/selftests/nolibc/nolibc-test.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 888da60eb5ba..d294338cf141 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -474,6 +474,25 @@ static int test_getpagesize(void)
return !c;
}
+static int test_fork(void)
+{
+ int status;
+ pid_t pid = fork();
+
+ switch (pid) {
+ case -1:
+ return 1;
+
+ case 0:
+ exit(123);
+
+ default:
+ pid = waitpid(pid, &status, 0);
+
+ return pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 123;
+ }
+}
+
/* Run syscall tests between IDs <min> and <max>.
* Return 0 on success, non-zero on failure.
*/
@@ -530,6 +549,7 @@ int run_syscall(int min, int max)
CASE_TEST(dup3_0); tmp = dup3(0, 100, 0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
CASE_TEST(dup3_m1); tmp = dup3(-1, 100, 0); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
CASE_TEST(execve_root); EXPECT_SYSER(1, execve("/", (char*[]){ [0] = "/", [1] = NULL }, NULL), -1, EACCES); break;
+ CASE_TEST(fork); EXPECT_SYSZR(1, test_fork()); break;
CASE_TEST(getdents64_root); EXPECT_SYSNE(1, test_getdents64("/"), -1); break;
CASE_TEST(getdents64_null); EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break;
CASE_TEST(gettimeofday_null); EXPECT_SYSZR(1, gettimeofday(NULL, NULL)); break;
--
2.40.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 0/2] tools/nolibc: fork: fix on s390 and add test
2023-04-15 21:28 [PATCH 0/2] tools/nolibc: fork: fix on s390 and add test Thomas Weißschuh
2023-04-15 21:28 ` [PATCH 1/2] tools/nolibc: s390: provide custom implementation for sys_fork Thomas Weißschuh
2023-04-15 21:28 ` [PATCH 2/2] tools/nolibc: add testcase for fork()/waitpid() Thomas Weißschuh
@ 2023-04-16 5:33 ` Willy Tarreau
2 siblings, 0 replies; 5+ messages in thread
From: Willy Tarreau @ 2023-04-16 5:33 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Shuah Khan, linux-kernel, linux-kselftest, Sven Schnelle
Hi Thomas,
On Sat, Apr 15, 2023 at 11:28:46PM +0200, Thomas Weißschuh wrote:
> The generic fork() implementation in nolibc falls back to the clone()
> syscall. On s390 the first two arguments to clone() are swapped compared
> to other architectures, breaking the implementation in nolibc.
>
> Add a custom implementation of fork() to s390 that works.
>
> While at it also add a testcase for fork().
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Thanks for these. Please always Cc the authors of code you're fixing
(e.g. there could be more subtle details that only the author knows
about). Here I think it's OK, but I've CCed Sven and will add him to
your fix.
Thank you!
Willy
^ permalink raw reply [flat|nested] 5+ messages in thread