Some of the clone tests use loop check on status flag to determine if the child exited normally. However, this may cause infinite looping if the data handshake does not happen properly due to compiler optimization as observed with Morello Gcc.
Replace the busy loop with the lightweight waitpid() syscall (Instead of existing waitid()) to wait for the child to exit normally.
Signed-off-by: Amit Daniel Kachhap amit.kachhap@arm.com --- tools/testing/selftests/arm64/morello/clone.c | 16 +++++----------- .../selftests/arm64/morello/freestanding.h | 8 ++++++++ 2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/tools/testing/selftests/arm64/morello/clone.c b/tools/testing/selftests/arm64/morello/clone.c index 730811f9b7c2..7146ff9889f6 100644 --- a/tools/testing/selftests/arm64/morello/clone.c +++ b/tools/testing/selftests/arm64/morello/clone.c @@ -18,9 +18,6 @@ #define in_restricted() \ (!(cheri_perms_get(cheri_pcc_get()) & ARM_CAP_PERMISSION_EXECUTIVE))
- -#define MAGIC_NR 0x3562 /* whatever really ..... */ - #ifndef MAX_PID_NS_LEVEL #define MAX_PID_NS_LEVEL 32 #endif @@ -36,7 +33,6 @@ #define CLONE_TH_RUSAGE BIT(3)
struct test_fixture { - int status; int flags; void *sp; int result; @@ -89,14 +85,13 @@ static int clone_base_fn(void *data) !!(__data->flags & CLONE_TH_RESTRICTED) != in_restricted() ? CTR_FAILED : CTR_SUCCESS; done: - __data->status = MAGIC_NR; return 0; }
static inline __attribute__((always_inline)) void clone_single(struct test_fixture *data) { - int ppid = 0, cpid = 0; + int ppid = 0, cpid = 0, wstatus; int result = -EINVAL; void *ptr = clone_base_fn;
@@ -108,7 +103,7 @@ void clone_single(struct test_fixture *data) CAP_LOAD_PERMS | CAP_STORE_PERMS) : NULL;
- int clone_flags = CLONE_VM | CLONE_PARENT_SETTID | CLONE_CHILD_SETTID; + int clone_flags = CLONE_VM | CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | SIGCHLD;
ASSERT_NE(new_stack, NULL); /* For stack probing .... */ @@ -139,10 +134,9 @@ void clone_single(struct test_fixture *data) goto leave; }
- /* Wait substitute ... */ - while (data->status != MAGIC_NR) { - asm(""); - } + /* Wait for the child */ + waitpid(cpid, &wstatus, 0); + ASSERT_TRUE(WIFEXITED(wstatus)); /* * CLONE_CHILD_SETTID sets child's thread ID to provided child's * memory but as VM is being shared, it's all good at this point. diff --git a/tools/testing/selftests/arm64/morello/freestanding.h b/tools/testing/selftests/arm64/morello/freestanding.h index 19611b315de9..135150701b0d 100644 --- a/tools/testing/selftests/arm64/morello/freestanding.h +++ b/tools/testing/selftests/arm64/morello/freestanding.h @@ -31,6 +31,10 @@ typedef __uintcap_t uintcap_t;
#define EXIT_SUCCESS 0
+#ifndef WIFEXITED +#define WIFEXITED(status) (((status) & 0x7f) == 0) +#endif + struct __test_meta { int message; }; @@ -213,4 +217,8 @@ static inline int waitid(int id_type, pid_t id, siginfo_t *info, int options, st return syscall(__NR_waitid, id_type, id, info, options, ru); }
+static inline int waitpid(pid_t pid, int *wstatus, int options) +{ + return syscall(__NR_wait4, pid, wstatus, options, 0); +} #endif