[LTP] [PATCH v10] Add tls parameter and flag:CLONE_SETTLS cover for clone and clone3 syscall

Chunfu Wen chwen@redhat.com
Fri Jul 18 11:07:01 CEST 2025


Hello,

Thanks for reviewing!
The two comments are addressed in the v11 patch:
https://lists.linux.it/pipermail/ltp/2025-July/044398.html

Best Regards,
Chunfu Wen

On Thu, Jul 17, 2025 at 8:01 PM Cyril Hrubis <chrubis@suse.cz> wrote:

> Hi!
> > tls parameter and related flag:CLONE_SETTLS are missed in the testing,
> > so add them into existed test case
> >
> > Signed-off-by: chunfuwen <chwen@redhat.com>
> > ---
> > Changes in v10:
> > - Fix fedora42 failure by adding tcb
> > - Add missing usleep(1000) in free_tls
> >
> > Changes in v9:
> > - allow small delay by using usleep before call free_tls
> > - validate ./clone10 -i 10 on aarch64 and x86_64, both pass
> >
> > Changes in v8:
> > - call free_tls() in touch_tls_in_child instead of cleanup
> > - remove CFLAGS += -fsanitize=address in Makefile to fix memory double
> free
> >   issue
> >
> > Changes in v7:
> > - remove unnecessary in verify_tls()
> > - add CFLAGS += -fsanitize=address in Makefile to fix memory double free
> >   issue
> >
> > Changes in v6:
> > - update flag to effective combination
> > - combine x86_64 with other arches
> > - rename child function
> > - remove inproper exit
> > - remove unused code lines
> > - remove sleep statement
> >
> > Changes in v5:
> > - wrap duplicate code into one single methold
> > - remove duplicately malloc
> >
> > Changes in v4:
> > - remove riscv and loongarch definition
> >
> > Changes in v3:
> > - fix missing head file for x86
> >
> > Changes in v2:
> > - create separate files for clone and clone3
> >
> > ---
> >  runtest/syscalls                            |   2 +
> >  testcases/kernel/syscalls/clone/.gitignore  |   1 +
> >  testcases/kernel/syscalls/clone/clone10.c   | 170 ++++++++++++++++++++
> >  testcases/kernel/syscalls/clone3/.gitignore |   1 +
> >  testcases/kernel/syscalls/clone3/clone304.c | 158 ++++++++++++++++++
> >  5 files changed, 332 insertions(+)
> >  create mode 100644 testcases/kernel/syscalls/clone/clone10.c
> >  create mode 100644 testcases/kernel/syscalls/clone3/clone304.c
> >
> > diff --git a/runtest/syscalls b/runtest/syscalls
> > index 844ae7a13..10f64270a 100644
> > --- a/runtest/syscalls
> > +++ b/runtest/syscalls
> > @@ -122,10 +122,12 @@ clone06 clone06
> >  clone07 clone07
> >  clone08 clone08
> >  clone09 clone09
> > +clone10 clone10
> >
> >  clone301 clone301
> >  clone302 clone302
> >  clone303 clone303
> > +clone304 clone304
> >
> >  close01 close01
> >  close02 close02
> > diff --git a/testcases/kernel/syscalls/clone/.gitignore
> b/testcases/kernel/syscalls/clone/.gitignore
> > index 900cac19c..adfb8257d 100644
> > --- a/testcases/kernel/syscalls/clone/.gitignore
> > +++ b/testcases/kernel/syscalls/clone/.gitignore
> > @@ -7,3 +7,4 @@
> >  /clone07
> >  /clone08
> >  /clone09
> > +/clone10
> > diff --git a/testcases/kernel/syscalls/clone/clone10.c
> b/testcases/kernel/syscalls/clone/clone10.c
> > new file mode 100644
> > index 000000000..badcf263d
> > --- /dev/null
> > +++ b/testcases/kernel/syscalls/clone/clone10.c
> > @@ -0,0 +1,170 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (c) 2025 Red Hat Inc. All Rights Reserved.
> > + * Author: Chunfu Wen <chwen@redhat.com>
> > + */
> > +
> > +/*\
> > + * Add tls parameter and flag:CLONE_SETTLS cover for clone
> > + */
> > +
> > +#define _GNU_SOURCE
> > +#include <stdlib.h>
> > +#include <stdio.h>
> > +#include <errno.h>
> > +#include <sched.h>
> > +#include <sys/wait.h>
> > +
> > +#if defined(__i386__)
> > +#include <asm/ldt.h>
> > +#endif
> > +
> > +#include "tst_test.h"
> > +#include "clone_platform.h"
> > +#include "lapi/syscalls.h"
> > +
> > +#define TLS_EXP 100
> > +#define TLS_SIZE 4096
> > +#define TLS_ALIGN 16
> > +
> > +#ifndef ARCH_SET_FS
> > +#define ARCH_SET_FS 0x1002
> > +#endif
> > +
> > +#if defined(__x86_64__)
> > +
> > +// Structure mimicking glibc's TCB to be simplified for x86_64
> > +typedef struct {
> > +    void *tcb;
> > +    void *dtv;
> > +    void *self;
> > +    int multiple_threads;
> > +    char padding[64];
> > +} tcb_t;
> > +
> > +#endif /* __x86_64__ */
> > +
> > +static __thread int tls_var = 0;
> > +
> > +static void *tls_ptr;
> > +static struct user_desc *tls_desc;
> > +static char *child_stack;
> > +static volatile int child_done = 0;
> > +
> > +static int flags = CLONE_THREAD |  CLONE_VM | CLONE_FS | CLONE_FILES |
> CLONE_SIGHAND | CLONE_SETTLS;
> > +
> > +static void *allocate_tls_area(void)
> > +{
> > +     void *tls_area = aligned_alloc(TLS_ALIGN, TLS_SIZE);
> > +     if (!tls_area)
> > +             tst_brk(TBROK | TERRNO, "aligned_alloc failed");
> > +     memset(tls_area, 0, TLS_SIZE);
> > +
> > +#if defined(__x86_64__)
> > +     // Set up a minimal TCB for x86_64
> > +     tcb_t *tcb = (tcb_t *)tls_area;
> > +     tcb->tcb = tls_area;
> > +     tcb->self = tls_area;
> > +     tcb->multiple_threads = 1;
> > +#endif
> > +
> > +     return tls_area;
> > +}
> > +
> > +static void init_tls(void)
> > +{
> > +#if defined(__x86_64__) || defined(__aarch64__) || defined(__s390x__)
> > +     tls_ptr = allocate_tls_area();
> > +
> > +#elif defined(__i386__)
> > +     tls_ptr = allocate_tls_area();
> > +     tls_desc = SAFE_MALLOC(sizeof(*tls_desc));
> > +     memset(tls_desc, 0, sizeof(*tls_desc));
> > +     tls_desc->entry_number = -1;
> > +     tls_desc->base_addr = (unsigned long)tls_ptr;
> > +     tls_desc->limit = TLS_SIZE;
> > +     tls_desc->seg_32bit = 1;
> > +     tls_desc->contents = 0;
> > +     tls_desc->read_exec_only = 0;
> > +     tls_desc->limit_in_pages = 0;
> > +     tls_desc->seg_not_present = 0;
> > +     tls_desc->useable = 1;
> > +
> > +#else
> > +     tst_brk(TCONF, "Unsupported architecture for TLS");
> > +#endif
> > +}
> > +
> > +static void free_tls(void)
> > +{
> > +     usleep(1000);
> > +#if defined(__x86_64__) || defined(__aarch64__) || defined(__s390x__)
> > +     if (tls_ptr) {
> > +             free(tls_ptr);
> > +             tls_ptr = NULL;
> > +     }
> > +#elif defined(__i386__)
> > +     if (tls_desc) {
> > +             free((void *)(uintptr_t)tls_desc->base_addr);
> > +             free(tls_desc);
> > +             tls_desc = NULL;
> > +     }
> > +#endif
> > +
> > +}
>
> All these functions seems to be duplicated in both tests. It should be
> better if we put the tls init/alloc/free functions into a common header
> in lapi/tls.h
>
> > +static int touch_tls_in_child(void *arg LTP_ATTRIBUTE_UNUSED)
> > +{
> > +#if defined(__x86_64__)
> > +     // Set the %fs register to point to the TCB
> > +     if (syscall(SYS_arch_prctl, ARCH_SET_FS, tls_ptr) == -1) {
> > +         exit(EXIT_FAILURE);
> > +     }
> > +#endif
> > +     tls_var = TLS_EXP + 1;
> > +     tst_res(TINFO, "Child (PID: %d, TID: %d): TLS value set to: %d",
> getpid(),  gettid(), tls_var);
> > +
> > +     child_done = 1;
> > +     free_tls();
> > +     return 0;
> > +}
> > +
> > +static void verify_tls(void)
> > +{
> > +     tls_var = TLS_EXP;
> > +
> > +     TEST(ltp_clone7(flags, touch_tls_in_child, NULL, CHILD_STACK_SIZE,
> child_stack, NULL, tls_ptr, NULL));
> > +
> > +     if (TST_RET == -1)
> > +             tst_brk(TBROK | TTERRNO, "clone() failed");
> > +
> > +     while (!child_done)
> > +             sched_yield();
>
> We have TST_CHECKPOINT_* for parent/child synchronization:
>
>
> https://linux-test-project.readthedocs.io/en/latest/developers/api_c_tests.html#checkpoints
>
>
> --
> Cyril Hrubis
> chrubis@suse.cz
>
>


More information about the ltp mailing list