Hi, On Fri, 2024-01-05 at 00:05 +0100, Richard Weinberger wrote: > On Fri, Nov 10, 2023 at 12:03 PM <benja...@sipsolutions.net> wrote: > > > > From: Benjamin Berg <benja...@sipsolutions.net> > > > > These registers are saved/restored together with the other general > > registers using ptrace. In arch_set_tls we then just need to set > > the > > register and it will be synced back normally. > > > > Most of this logic was introduced in commit f355559cf7845 ("[PATCH] > > uml: > > x86_64 thread fixes"). However, at least today we can rely on > > ptrace to > > Do you know since when exactly? I don't want to break UML in subtle ways > on old kernels.
To be honest, I don't remember, and I doubt I really understood what I was doing. Anyway, I now found this commit now, which is contained in v2.6.25: commit df5d438e33d7fc914ba9b6e0d6b019a8966c5fcc Author: Roland McGrath <rol...@redhat.com> Date: Wed Jan 30 13:30:45 2008 +0100 x86: ptrace fs/gs_base The fs_base and gs_base fields are available in user_regs_struct. But reading these via ptrace (PTRACE_GETREGS or PTRACE_PEEKUSR) does not give a reliably useful value. The thread_struct fields are 0 when do_arch_prctl decided to use a GDT slot instead of MSR_FS_BASE, which it does for a value under 1<<32. This changes ptrace access to fs_base and gs_base to work like PTRACE_ARCH_PRCTL does. That is, it reads the base address that user-mode memory access using the fs/gs instruction prefixes will use, regardless of how it's being implemented in the kernel. The MSR vs GDT is an implementation detail that is pretty much hidden from userland in the actual using, and there is no reason that ptrace should give the internal implementation picture rather than the user-mode semantic picture. In the case of setting the value, this can implicitly change the fsindex/gsindex value (also separately in user_regs_struct), which is what happens when the thread calls arch_prctl itself. In a PTRACE_SETREGS, the fs_base change will come after the fsindex change due to the order of the struct, and so a change the debugger made to fs_base will have the effect intended, another part of the user_regs_struct will now differ when read back from what the debugger wrote. This makes PTRACE_ARCH_PRCTL obsolete. We could consider declaring it deprecated and removing it one day, though there is no hurry. For the foreseeable future, debuggers have to assume an old kernel that does not report reliable fs_base/gs_base values in user_regs_struct and stick to PTRACE_ARCH_PRCTL anyway. I think the last paragraph is quite straight forward in saying that we do not need anything special anymore. Note that the original commit adding the code pre-dates this commit by about a year, i.e.: commit f355559cf78455ed6be103b020e4b800230c64eb Author: Jeff Dike <jd...@addtoit.com> Date: Sat Feb 10 01:44:29 2007 -0800 [PATCH] uml: x86_64 thread fixes x86_64 needs some TLS fixes. What was missing was remembering the child thread id during clone and stuffing it into the child during each context switch. The %fs value is stored separately in the thread structure since the host controls what effect it has on the actual register file. The host also needs to store it in its own thread struct, so we need the value kept outside the register file. arch_prctl_skas was fixed to call PTRACE_ARCH_PRCTL appropriately. There is some saving and restoring of registers in the ARCH_SET_* cases so that the correct set of registers are changed on the host and restored to the process when it runs again. There was some shuffling around in the ptrace code at some point, eventually switching from doing an arch_prctl call to setting things more directly. But I don't think that matters to us. Benjamin