commit 088c48490555cd05a2250ea88234ee373e027dc1
tree ab5c84b88eb2722dd80213ab855cc35a52c181cd
parent bb0502898c0805dfffbc3577fce8881c60ae03cc
author Li Wang <liwang@redhat.com> 2026-01-21 17:01:59 +0800
committer Li Wang <liwang@redhat.com> 2026-01-22 08:39:17 +0800

    lapi/tls: remove the TLS support from i386
    
    Using a LTP naked clone() to verify that CLONE_SETTLS is unreliable
    when running 32-bit on x86_64, since TLS requires two steps: writing
    the descriptor and switching the selector. But CLONE_SETTLS on i386
    only overrides the former:
    
     kernel_clone()
        copy_process()
           copy_thread()
              set_new_tls()
                 do_set_thread_area()
    
    In copy_thread(), the child's register frame is copied from the parent
    *childregs = *current_pt_regs(); and on the 32-bit side it also does
    savesegment(gs, p->thread.gs); saving the current %gs into thread_struct.
    
    Together, this means that unless something explicitly overwrites it later,
    the child's initial %gs selector is inherited from the parent.
    
      https://elixir.bootlin.com/linux/v6.18/source/arch/x86/kernel/process.c#L243
    
    Then, in do_set_thread_area(), the kernel updates the TLS descriptor
    set_tls_desc(p, idx, &info, 1); However, when (p != current), the x86_32 path
    does not update or refresh any segment selector. So it updates the descriptor
    but does not switch the child's %gs selector to the new modified_sel.
    
      https://elixir.bootlin.com/linux/v6.18/source/arch/x86/kernel/tls.c#L150
    
    Therefore, on i386, relying on CLONE_SETTLS alone can leave the child
    executing with the parent's %gs selector, so TLS accesses still resolve
    to the old TLS base.
    
    ===============
    
    The behavior above explains why clone10 fails even if we update the TLS
    descriptor base (either hard-coding or via set_thread_area()).
    
    Example (x86_64 kernel running a 32-bit ELF):
    
      # uname -rm
      6.19.0-rc2.liwang x86_64
    
      # readelf -h clone10 |grep Class
      Class:                             ELF32
    
      # ./clone10
      ...
      clone10.c:48: TINFO: Child (PID: 5262, TID: 5263): TLS value set to: 101
      clone10.c:72: TFAIL: Parent (PID: 5262, TID: 5262): TLS value mismatch: got 101, expected 100
    
    Reported-by: Wei Gao <wegao@suse.com>
    Signed-off-by: Li Wang <liwang@redhat.com>
    Reviewed-by: Wei Gao <wegao@suse.com>
    Acked-by: Cyril Hrubis <chrubis@suse.cz>


:100644 100644 a067872e0f3a93d4e7bb7563884d1d0032d3e0ce f7e2f483fe9e623e669d3f0e9f09d9218b42f216 M	include/lapi/tls.h
