Message ID | 20200319144110.3733-5-mathieu.desnoyers@efficios.com |
---|---|
State | New |
Headers | show |
Series | Restartable Sequences enablement | expand |
* Mathieu Desnoyers via Libc-alpha: > Changes since v14: > - Update copyright range to include 2020. > - Introduce __ASSUME_RSEQ defined for --enable-kernel=4.18.0 and higher. > - Use ifdef __ASSUME_RSEQ rather than ifdef __NR_rseq to discover rseq > availability. This is necessary now that the system call numbers are > integrated within glibc. It's not quite clear to me why you need __ASSUME_RSEQ. Can you use __has_include in <sys/rseq.h>, with a copy of the kernel definitions if the kernel header is not available?
----- On Mar 19, 2020, at 10:53 AM, Florian Weimer fw@deneb.enyo.de wrote: > * Mathieu Desnoyers via Libc-alpha: > >> Changes since v14: >> - Update copyright range to include 2020. >> - Introduce __ASSUME_RSEQ defined for --enable-kernel=4.18.0 and higher. >> - Use ifdef __ASSUME_RSEQ rather than ifdef __NR_rseq to discover rseq >> availability. This is necessary now that the system call numbers are >> integrated within glibc. > > It's not quite clear to me why you need __ASSUME_RSEQ. This is how I noticed other Linux features were being integrated, so I figured this is how I should do it. Monkey see, monkey do. ;-) > Can you use __has_include in <sys/rseq.h>, with a copy of the kernel > definitions if the kernel header is not available? Sure. Should I pull a verbatim copy of uapi linux/rseq.h into glibc ? If so, where should I put it ? Thanks, Mathieu
* Mathieu Desnoyers: >> Can you use __has_include in <sys/rseq.h>, with a copy of the kernel >> definitions if the kernel header is not available? > > Sure. Should I pull a verbatim copy of uapi linux/rseq.h into glibc ? > If so, where should I put it ? Probably into <sys/rseq.h>, perhaps with a construct like this (untested): #ifdef __has_include # if __has_include ("linux/rseq.h") # define __GLIBC_HAVE_KERNEL_RSEQ # endif #else # include <linux/version.h> # if LINUX_VERSION_CODE >= KERNEL_VERSION (4, 18, 0) # define __GLIBC_HAVE_KERNEL_RSEQ # endif #endif #ifdef __GLIBC_HAVE_KERNEL_RSEQ # include <linux/rseq.h> #else … (fallback goes here) #endif We have an ongoing debate whether the fallback definition should use __u64 or uint64_t. You also need to add an assert that the compiler supports __attribute__ ((aligned)) because ignoring it produces an ABI-incompatible header. The struct rseq/struct rseq_cs definitions are broken, they should not try to change the alignment. PS: I have Internet connection trouble. Nobody should be worried if I drop off the net for a while. I understand this is quite a bad time for that. 8-(
----- On Mar 19, 2020, at 12:03 PM, Florian Weimer fw@deneb.enyo.de wrote: > * Mathieu Desnoyers: > >>> Can you use __has_include in <sys/rseq.h>, with a copy of the kernel >>> definitions if the kernel header is not available? >> >> Sure. Should I pull a verbatim copy of uapi linux/rseq.h into glibc ? >> If so, where should I put it ? > > Probably into <sys/rseq.h>, perhaps with a construct like this > (untested): > > #ifdef __has_include > # if __has_include ("linux/rseq.h") > # define __GLIBC_HAVE_KERNEL_RSEQ > # endif > #else > # include <linux/version.h> > # if LINUX_VERSION_CODE >= KERNEL_VERSION (4, 18, 0) > # define __GLIBC_HAVE_KERNEL_RSEQ > # endif > #endif > > #ifdef __GLIBC_HAVE_KERNEL_RSEQ > # include <linux/rseq.h> > #else > > … (fallback goes here) > #endif OK will do. > > We have an ongoing debate whether the fallback definition should use > __u64 or uint64_t. Then I'll keep including <linux/types.h> in the fallback and use __u{32,64} for now. If this proves to be an issue we can change it later. This is the minimal change from the uapi header. > > You also need to add an assert that the compiler supports > __attribute__ ((aligned)) because ignoring it produces an > ABI-incompatible header. Are you aware of some helper macro I should use to do this, or is it done elsewhere in glibc ? > The struct rseq/struct rseq_cs definitions > are broken, they should not try to change the alignment. AFAIU, this means we should ideally not have used __attribute__((aligned)) in the uapi headers in the first place. Why is it broken ? However, now that it is in the wild, it's a bit late to change that. > PS: I have Internet connection trouble. Nobody should be worried if I > drop off the net for a while. I understand this is quite a bad time > for that. 8-( Allright, thanks for the heads up! Stay safe! Thanks, Mathieu
* Mathieu Desnoyers: >> You also need to add an assert that the compiler supports >> __attribute__ ((aligned)) because ignoring it produces an >> ABI-incompatible header. > > Are you aware of some helper macro I should use to do this, or > is it done elsewhere in glibc ? I don't think we have any such GCC-only types yet. max_align_t is provided by GCC itself. >> The struct rseq/struct rseq_cs definitions >> are broken, they should not try to change the alignment. > > AFAIU, this means we should ideally not have used __attribute__((aligned)) > in the uapi headers in the first place. Why is it broken ? Compilers which are not sufficiently GCC-compatible define __attribute__(X) as the empty expansion, so you silently get a different ABI. There is really no need to specify 32-byte alignment here. Is not even the size of a standard cache line. It can result in crashes if these structs are heap-allocated using malloc, when optimizing for AVX2. For example, clang turns void clear (struct rseq *p) { memset (p, 0, sizeof (*p)); } into: vxorps %xmm0, %xmm0, %xmm0 vmovaps %ymm0, (%rdi) vzeroupper retq My understanding is that vmovaps will trap if the pointer is misaligned (“When the source or destination operand is a memory operand, the operand must be aligned on a 32-byte boundary or a general-protection exception (#GP) will be generated.”). > However, now that it is in the wild, it's a bit late to change that. I had forgotten about the alignment crashes. I think we should seriously consider changing the types. 8-(
----- On Mar 19, 2020, at 2:16 PM, Florian Weimer fw@deneb.enyo.de wrote: > * Mathieu Desnoyers: > >>> You also need to add an assert that the compiler supports >>> __attribute__ ((aligned)) because ignoring it produces an >>> ABI-incompatible header. >> >> Are you aware of some helper macro I should use to do this, or >> is it done elsewhere in glibc ? > > I don't think we have any such GCC-only types yet. max_align_t is > provided by GCC itself. I was thinking of adding the following to sysdeps/unix/sysv/linux/rseq-internal.h: rseq_register_current_thread() + /* Ensure the compiler supports __attribute__ ((aligned)). */ + _Static_assert (__alignof__ (struct rseq_cs) >= 4 * sizeof(uint64_t), + "alignment"); + _Static_assert (__alignof__ (struct rseq) >= 4 * sizeof(uint64_t), + "alignment"); + >>> The struct rseq/struct rseq_cs definitions >>> are broken, they should not try to change the alignment. >> >> AFAIU, this means we should ideally not have used __attribute__((aligned)) >> in the uapi headers in the first place. Why is it broken ? > > Compilers which are not sufficiently GCC-compatible define > __attribute__(X) as the empty expansion, so you silently get a > different ABI. It is worth noting that rseq.h is not the only Linux uapi header which uses __attribute__ ((aligned)), so this ABI problem exists today anyway for those compilers. > > There is really no need to specify 32-byte alignment here. Is not > even the size of a standard cache line. It can result in crashes if > these structs are heap-allocated using malloc, when optimizing for > AVX2. Why would it be valid to allocate those with malloc ? Isn't it the purpose of posix_memalign() ? > > For example, clang turns > > void > clear (struct rseq *p) > { > memset (p, 0, sizeof (*p)); > } > > into: > > vxorps %xmm0, %xmm0, %xmm0 > vmovaps %ymm0, (%rdi) > vzeroupper > retq > > My understanding is that vmovaps will trap if the pointer is > misaligned (“When the source or destination operand is a memory > operand, the operand must be aligned on a 32-byte boundary or a > general-protection exception (#GP) will be generated.”). > >> However, now that it is in the wild, it's a bit late to change that. > > I had forgotten about the alignment crashes. I think we should > seriously consider changing the types. 8-( I don't think this is an option at this stage given that it is part of the Linux kernel UAPI. I am not convinced that it is valid at all to allocate struct rseq or struct rseq_cs with malloc(), because it does not guarantee any alignment. Thanks, Mathieu
* Mathieu Desnoyers: > ----- On Mar 19, 2020, at 2:16 PM, Florian Weimer fw@deneb.enyo.de wrote: > >> * Mathieu Desnoyers: >> >>>> You also need to add an assert that the compiler supports >>>> __attribute__ ((aligned)) because ignoring it produces an >>>> ABI-incompatible header. >>> >>> Are you aware of some helper macro I should use to do this, or >>> is it done elsewhere in glibc ? >> >> I don't think we have any such GCC-only types yet. max_align_t is >> provided by GCC itself. > > I was thinking of adding the following to > > sysdeps/unix/sysv/linux/rseq-internal.h: rseq_register_current_thread() > > + /* Ensure the compiler supports __attribute__ ((aligned)). */ > + _Static_assert (__alignof__ (struct rseq_cs) >= 4 * sizeof(uint64_t), > + "alignment"); > + _Static_assert (__alignof__ (struct rseq) >= 4 * sizeof(uint64_t), > + "alignment"); > + Something like it would have to go into the *public* header. Inside glibc, you can assume __attribute__ support. >>>> The struct rseq/struct rseq_cs definitions >>>> are broken, they should not try to change the alignment. >>> >>> AFAIU, this means we should ideally not have used __attribute__((aligned)) >>> in the uapi headers in the first place. Why is it broken ? >> >> Compilers which are not sufficiently GCC-compatible define >> __attribute__(X) as the empty expansion, so you silently get a >> different ABI. > > It is worth noting that rseq.h is not the only Linux uapi header > which uses __attribute__ ((aligned)), so this ABI problem exists today > anyway for those compilers. Yuck. Even with larger-than-16 alignment? >> There is really no need to specify 32-byte alignment here. Is not >> even the size of a standard cache line. It can result in crashes if >> these structs are heap-allocated using malloc, when optimizing for >> AVX2. > > Why would it be valid to allocate those with malloc ? Isn't it the > purpose of posix_memalign() ? It would not be valid, but I don't think we have diagnostics for C like we have them for C++'s operator new. >>> However, now that it is in the wild, it's a bit late to change that. >> >> I had forgotten about the alignment crashes. I think we should >> seriously consider changing the types. 8-( > > I don't think this is an option at this stage given that it is part > of the Linux kernel UAPI. I am not convinced that it is valid at all > to allocate struct rseq or struct rseq_cs with malloc(), because it > does not guarantee any alignment. The kernel ABI doesn't change. The kernel cannot use the alignment information anyway. Userspace struct layout may change in subtle ways, though.
----- On Mar 19, 2020, at 2:34 PM, Florian Weimer fw@deneb.enyo.de wrote: > * Mathieu Desnoyers: > >> ----- On Mar 19, 2020, at 2:16 PM, Florian Weimer fw@deneb.enyo.de wrote: >> >>> * Mathieu Desnoyers: >>> >>>>> You also need to add an assert that the compiler supports >>>>> __attribute__ ((aligned)) because ignoring it produces an >>>>> ABI-incompatible header. >>>> >>>> Are you aware of some helper macro I should use to do this, or >>>> is it done elsewhere in glibc ? >>> >>> I don't think we have any such GCC-only types yet. max_align_t is >>> provided by GCC itself. >> >> I was thinking of adding the following to >> >> sysdeps/unix/sysv/linux/rseq-internal.h: rseq_register_current_thread() >> >> + /* Ensure the compiler supports __attribute__ ((aligned)). */ >> + _Static_assert (__alignof__ (struct rseq_cs) >= 4 * sizeof(uint64_t), >> + "alignment"); >> + _Static_assert (__alignof__ (struct rseq) >= 4 * sizeof(uint64_t), >> + "alignment"); >> + > > Something like it would have to go into the *public* header. > > Inside glibc, you can assume __attribute__ support. OK, so the _Static_assert () could sit in sys/rseq.h > >>>>> The struct rseq/struct rseq_cs definitions >>>>> are broken, they should not try to change the alignment. >>>> >>>> AFAIU, this means we should ideally not have used __attribute__((aligned)) >>>> in the uapi headers in the first place. Why is it broken ? >>> >>> Compilers which are not sufficiently GCC-compatible define >>> __attribute__(X) as the empty expansion, so you silently get a >>> different ABI. >> >> It is worth noting that rseq.h is not the only Linux uapi header >> which uses __attribute__ ((aligned)), so this ABI problem exists today >> anyway for those compilers. > > Yuck. Even with larger-than-16 alignment? There are two: target_core_user.h 45:#define ALIGN_SIZE 64 /* Should be enough for most CPUs */ 58: __u32 cmd_tail __attribute__((__aligned__(ALIGN_SIZE))); netfilter_bridge/ebtables.h:90: char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); netfilter_bridge/ebtables.h:132: unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); netfilter_bridge/ebtables.h:145: unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); netfilter_bridge/ebtables.h:158: unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); netfilter_bridge/ebtables.h:191: unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); > >>> There is really no need to specify 32-byte alignment here. Is not >>> even the size of a standard cache line. It can result in crashes if >>> these structs are heap-allocated using malloc, when optimizing for >>> AVX2. >> >> Why would it be valid to allocate those with malloc ? Isn't it the >> purpose of posix_memalign() ? > > It would not be valid, but I don't think we have diagnostics for C > like we have them for C++'s operator new. We could at least make an effort to let people know that alignment is required here when allocating struct rseq and struct rseq_cs on the heap by adding some comments to that effect in linux/rseq.h ? > >>>> However, now that it is in the wild, it's a bit late to change that. >>> >>> I had forgotten about the alignment crashes. I think we should >>> seriously consider changing the types. 8-( >> >> I don't think this is an option at this stage given that it is part >> of the Linux kernel UAPI. I am not convinced that it is valid at all >> to allocate struct rseq or struct rseq_cs with malloc(), because it >> does not guarantee any alignment. > > The kernel ABI doesn't change. The kernel cannot use the alignment > information anyway. Userspace struct layout may change in subtle > ways, though. Considering the amount of pain this can cause in user-space, and because it can break userspace, this is not a UAPI change I am willing to consider. I'm not sure why we are even discussing the possibility of breaking a Linux UAPI considering that those are set in stone. Thanks, Mathieu
* Mathieu Desnoyers: >> Inside glibc, you can assume __attribute__ support. > > OK, so the _Static_assert () could sit in sys/rseq.h It requires a C11 compiler. In this case, you could use _Alignas. > >> >>>>>> The struct rseq/struct rseq_cs definitions >>>>>> are broken, they should not try to change the alignment. >>>>> >>>>> AFAIU, this means we should ideally not have used __attribute__((aligned)) >>>>> in the uapi headers in the first place. Why is it broken ? >>>> >>>> Compilers which are not sufficiently GCC-compatible define >>>> __attribute__(X) as the empty expansion, so you silently get a >>>> different ABI. >>> >>> It is worth noting that rseq.h is not the only Linux uapi header >>> which uses __attribute__ ((aligned)), so this ABI problem exists today >>> anyway for those compilers. >> >> Yuck. Even with larger-than-16 alignment? > > There are two: > > target_core_user.h > 45:#define ALIGN_SIZE 64 /* Should be enough for most CPUs */ > 58: __u32 cmd_tail __attribute__((__aligned__(ALIGN_SIZE))); That one is tough to figure out: struct tcmu_mailbox { __u16 version; __u16 flags; __u32 cmdr_off; __u32 cmdr_size; __u32 cmd_head; /* Updated by user. On its own cacheline */ __u32 cmd_tail __attribute__((__aligned__(ALIGN_SIZE))); } __attribute__((packed)); Apparently, the expectation is that the compiler ignores __attribute__ ((packed) in this context. Ugh. > netfilter_bridge/ebtables.h:90: char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); > netfilter_bridge/ebtables.h:132: unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); > netfilter_bridge/ebtables.h:145: unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); > netfilter_bridge/ebtables.h:158: unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); > netfilter_bridge/ebtables.h:191: unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); I think these values are lower than max_align_t, so uncritical. >>>> There is really no need to specify 32-byte alignment here. Is not >>>> even the size of a standard cache line. It can result in crashes if >>>> these structs are heap-allocated using malloc, when optimizing for >>>> AVX2. >>> >>> Why would it be valid to allocate those with malloc ? Isn't it the >>> purpose of posix_memalign() ? >> >> It would not be valid, but I don't think we have diagnostics for C >> like we have them for C++'s operator new. > > We could at least make an effort to let people know that alignment is > required here when allocating struct rseq and struct rseq_cs on the > heap by adding some comments to that effect in linux/rseq.h ? We could use different types on the glibc side, then no special programmer action will be needed. >>>>> However, now that it is in the wild, it's a bit late to change that. >>>> >>>> I had forgotten about the alignment crashes. I think we should >>>> seriously consider changing the types. 8-( >>> >>> I don't think this is an option at this stage given that it is part >>> of the Linux kernel UAPI. I am not convinced that it is valid at all >>> to allocate struct rseq or struct rseq_cs with malloc(), because it >>> does not guarantee any alignment. >> >> The kernel ABI doesn't change. The kernel cannot use the alignment >> information anyway. Userspace struct layout may change in subtle >> ways, though. > > Considering the amount of pain this can cause in user-space, and because > it can break userspace, this is not a UAPI change I am willing to consider. > I'm not sure why we are even discussing the possibility of breaking a Linux > UAPI considering that those are set in stone. Again, the kernel interface is NOT affected. Only if the struct is used in a non-top-level fashion across an ABI boundary in userspace. I think making the change now is better than dealing with the breakage in rseq users when they are built with -mavx2.
----- On Mar 19, 2020, at 3:05 PM, Florian Weimer fw@deneb.enyo.de wrote: > * Mathieu Desnoyers: > >>> Inside glibc, you can assume __attribute__ support. >> >> OK, so the _Static_assert () could sit in sys/rseq.h > > It requires a C11 compiler. In this case, you could use _Alignas. How would _Alignas replace: +_Static_assert (__alignof__ (struct rseq_cs) >= 4 * sizeof(uint64_t), + "alignment"); +_Static_assert (__alignof__ (struct rseq) >= 4 * sizeof(uint64_t), + "alignment"); ? Moreover, I notice that sys/cdefs.h implements a fallback for _Static_assert for cases where it is not supported by the compiler. So I do not think it strictly depends on C11 if I include sys/cdefs.h from sys/rseq.h. >>>>>>> The struct rseq/struct rseq_cs definitions >>>>>>> are broken, they should not try to change the alignment. >>>>>> >>>>>> AFAIU, this means we should ideally not have used __attribute__((aligned)) >>>>>> in the uapi headers in the first place. Why is it broken ? >>>>> >>>>> Compilers which are not sufficiently GCC-compatible define >>>>> __attribute__(X) as the empty expansion, so you silently get a >>>>> different ABI. >>>> [...] >>>>> There is really no need to specify 32-byte alignment here. Is not >>>>> even the size of a standard cache line. It can result in crashes if >>>>> these structs are heap-allocated using malloc, when optimizing for >>>>> AVX2. >>>> >>>> Why would it be valid to allocate those with malloc ? Isn't it the >>>> purpose of posix_memalign() ? >>> >>> It would not be valid, but I don't think we have diagnostics for C >>> like we have them for C++'s operator new. >> >> We could at least make an effort to let people know that alignment is >> required here when allocating struct rseq and struct rseq_cs on the >> heap by adding some comments to that effect in linux/rseq.h ? > > We could use different types on the glibc side, then no special > programmer action will be needed. Can't this lead to problems when mixing up compile units which have been compiled with linux/rseq.h with compile units compiled against sys/rseq.h ? Let me take a step back and try to understand. So far, there appears to be two scenarios where having a 64-byte alignment attribute on struct rseq and struct rseq_cs can cause problems: 1) A user-space programmer uses malloc() to dynamically allocate struct rseq or struct rseq_cs, which does not satisfy any of the alignment requirement of the structure. Combining this with compiler expectations that the structure needs to be aligned on 64-byte (e.g. -mavx2) breaks things. For this first scenario, I am proposing that we document that the programmer should have used posix_memalign(), which provides the required alignment guarantees. 2) A user-space programmer mixes code compiled with compilers honouring the aligned attribute with other compile units compiled with compilers which discard those GCC extension attributes silently, embeds those into a structure, and get different struct layouts. The _Static_assert in sys/rseq.h should detect the case where a compiler is not honouring the aligned attribute, right ? > >>>>>> However, now that it is in the wild, it's a bit late to change that. >>>>> >>>>> I had forgotten about the alignment crashes. I think we should >>>>> seriously consider changing the types. 8-( >>>> >>>> I don't think this is an option at this stage given that it is part >>>> of the Linux kernel UAPI. I am not convinced that it is valid at all >>>> to allocate struct rseq or struct rseq_cs with malloc(), because it >>>> does not guarantee any alignment. >>> >>> The kernel ABI doesn't change. The kernel cannot use the alignment >>> information anyway. Userspace struct layout may change in subtle >>> ways, though. >> >> Considering the amount of pain this can cause in user-space, and because >> it can break userspace, this is not a UAPI change I am willing to consider. >> I'm not sure why we are even discussing the possibility of breaking a Linux >> UAPI considering that those are set in stone. > > Again, the kernel interface is NOT affected. Only if the struct is > used in a non-top-level fashion across an ABI boundary in userspace. > I think making the change now is better than dealing with the breakage > in rseq users when they are built with -mavx2. What I am missing is what are the issues that persist once we add proper documentation of alignment requirements for heap allocation and a static assert to fail early when compiled with a compiler dismissing the aligned attribute ? As you point out, changing the currently public linux/rseq.h UAPI header to remove those attributes ends up breaking user-space in scenarios of non-top-level use across ABI boundary. This is not kernel-vs-userspace ABI, but an ABI exposed by the kernel which ends up being used to coordinate user-space objects within a program. Breaking that does not appear to be any more acceptable. As I recall, the hard requirement for Linux ABIs is to do not break userspace, period. There is not mention of kernel-vs-userspace or userspace-vs-userspace. So if the end result of this change is to break user-space, it should not be changed. Thanks, Mathieu
----- On Mar 19, 2020, at 3:46 PM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote: > ----- On Mar 19, 2020, at 3:05 PM, Florian Weimer fw@deneb.enyo.de wrote: > >> * Mathieu Desnoyers: >> >>>> Inside glibc, you can assume __attribute__ support. >>> >>> OK, so the _Static_assert () could sit in sys/rseq.h >> >> It requires a C11 compiler. In this case, you could use _Alignas. > > How would _Alignas replace: > > +_Static_assert (__alignof__ (struct rseq_cs) >= 4 * sizeof(uint64_t), > + "alignment"); > +_Static_assert (__alignof__ (struct rseq) >= 4 * sizeof(uint64_t), > + "alignment"); > > ? > > Moreover, I notice that sys/cdefs.h implements a fallback for _Static_assert > for cases where it is not supported by the compiler. So I do not think it > strictly depends on C11 if I include sys/cdefs.h from sys/rseq.h. > >>>>>>>> The struct rseq/struct rseq_cs definitions >>>>>>>> are broken, they should not try to change the alignment. >>>>>>> >>>>>>> AFAIU, this means we should ideally not have used __attribute__((aligned)) >>>>>>> in the uapi headers in the first place. Why is it broken ? >>>>>> >>>>>> Compilers which are not sufficiently GCC-compatible define >>>>>> __attribute__(X) as the empty expansion, so you silently get a >>>>>> different ABI. >>>>> > > [...] > >>>>>> There is really no need to specify 32-byte alignment here. Is not >>>>>> even the size of a standard cache line. It can result in crashes if >>>>>> these structs are heap-allocated using malloc, when optimizing for >>>>>> AVX2. >>>>> >>>>> Why would it be valid to allocate those with malloc ? Isn't it the >>>>> purpose of posix_memalign() ? >>>> >>>> It would not be valid, but I don't think we have diagnostics for C >>>> like we have them for C++'s operator new. >>> >>> We could at least make an effort to let people know that alignment is >>> required here when allocating struct rseq and struct rseq_cs on the >>> heap by adding some comments to that effect in linux/rseq.h ? >> >> We could use different types on the glibc side, then no special >> programmer action will be needed. > > Can't this lead to problems when mixing up compile units which have > been compiled with linux/rseq.h with compile units compiled against > sys/rseq.h ? > > Let me take a step back and try to understand. > > So far, there appears to be two scenarios where having a 64-byte > alignment attribute on struct rseq and struct rseq_cs can cause > problems: > > 1) A user-space programmer uses malloc() to dynamically allocate > struct rseq or struct rseq_cs, which does not satisfy any of > the alignment requirement of the structure. Combining this with > compiler expectations that the structure needs to be aligned > on 64-byte (e.g. -mavx2) breaks things. > > For this first scenario, I am proposing that we document that > the programmer should have used posix_memalign(), which provides > the required alignment guarantees. > > 2) A user-space programmer mixes code compiled with compilers > honouring the aligned attribute with other compile units compiled > with compilers which discard those GCC extension attributes silently, > embeds those into a structure, and get different struct layouts. > > The _Static_assert in sys/rseq.h should detect the case where a > compiler is not honouring the aligned attribute, right ? > >> >>>>>>> However, now that it is in the wild, it's a bit late to change that. >>>>>> >>>>>> I had forgotten about the alignment crashes. I think we should >>>>>> seriously consider changing the types. 8-( >>>>> >>>>> I don't think this is an option at this stage given that it is part >>>>> of the Linux kernel UAPI. I am not convinced that it is valid at all >>>>> to allocate struct rseq or struct rseq_cs with malloc(), because it >>>>> does not guarantee any alignment. >>>> >>>> The kernel ABI doesn't change. The kernel cannot use the alignment >>>> information anyway. Userspace struct layout may change in subtle >>>> ways, though. >>> >>> Considering the amount of pain this can cause in user-space, and because >>> it can break userspace, this is not a UAPI change I am willing to consider. >>> I'm not sure why we are even discussing the possibility of breaking a Linux >>> UAPI considering that those are set in stone. >> >> Again, the kernel interface is NOT affected. Only if the struct is >> used in a non-top-level fashion across an ABI boundary in userspace. >> I think making the change now is better than dealing with the breakage >> in rseq users when they are built with -mavx2. > > What I am missing is what are the issues that persist once we add proper > documentation of alignment requirements for heap allocation and a static > assert to fail early when compiled with a compiler dismissing the > aligned attribute ? > > As you point out, changing the currently public linux/rseq.h UAPI header > to remove those attributes ends up breaking user-space in scenarios of > non-top-level use across ABI boundary. This is not kernel-vs-userspace > ABI, but an ABI exposed by the kernel which ends up being used to > coordinate user-space objects within a program. Breaking that does not > appear to be any more acceptable. As I recall, the hard requirement for > Linux ABIs is to do not break userspace, period. There is not mention > of kernel-vs-userspace or userspace-vs-userspace. So if the end result > of this change is to break user-space, it should not be changed. Actually, here is an important clarification: the Linux kernel validates the struct rseq alignment on registration: if (!IS_ALIGNED((unsigned long)rseq, __alignof__(*rseq)) || rseq_len != sizeof(*rseq)) return -EINVAL; So removing the aligned attribute from struct rseq is actually an ABI-breaking change, because it would be incompatible with older kernels which perform the IS_ALIGNED check expecting at least at 32 bytes alignment. Thanks, Mathieu
----- On Mar 20, 2020, at 9:44 AM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote: [...] > Actually, here is an important clarification: the Linux kernel validates > the struct rseq alignment on registration: > > if (!IS_ALIGNED((unsigned long)rseq, __alignof__(*rseq)) || > rseq_len != sizeof(*rseq)) > return -EINVAL; > > So removing the aligned attribute from struct rseq is actually an > ABI-breaking change, because it would be incompatible with older > kernels which perform the IS_ALIGNED check expecting at least at > 32 bytes alignment. So I plan to add the following to glibc's sys/rseq.h: #include <sys/cdefs.h> [...] /* Ensure the compiler supports __attribute__ ((aligned)). */ _Static_assert (__alignof__ (struct rseq_cs) >= 4 * sizeof(uint64_t), "alignment"); _Static_assert (__alignof__ (struct rseq) >= 4 * sizeof(uint64_t), "alignment"); /* Allocations of struct rseq and struct rseq_cs on the heap need to be aligned on 32 bytes. Therefore, use of malloc is discouraged because it does not guarantee alignment. posix_memalign should be used instead. */ Does it help mitigating your concerns ? Thanks, Mathieu
diff --git a/NEWS b/NEWS index e0379fc53c..abc62ae5f5 100644 --- a/NEWS +++ b/NEWS @@ -61,6 +61,16 @@ Major new features: responses, indicating a lack of DNSSEC validation. (Therefore, the name servers and the network path to them are treated as untrusted.) +* Support for automatically registering threads with the Linux rseq(2) + system call has been added. This system call is implemented starting + from Linux 4.18. The Restartable Sequences ABI accelerates user-space + operations on per-cpu data. It allows user-space to perform updates + on per-cpu data without requiring heavy-weight atomic operations. + Automatically registering threads allows all libraries, including libc, + to make immediate use of the rseq(2) support by using the documented ABI. + See 'man 2 rseq' for the details of the ABI shared between libc and the + kernel. + Deprecated and removed features, and other changes affecting compatibility: * The totalorder and totalordermag functions, and the corresponding diff --git a/elf/libc_early_init.c b/elf/libc_early_init.c index 1ac66d895d..30466afea0 100644 --- a/elf/libc_early_init.c +++ b/elf/libc_early_init.c @@ -18,10 +18,13 @@ #include <ctype.h> #include <libc-early-init.h> +#include <rseq-internal.h> void __libc_early_init (void) { /* Initialize ctype data. */ __ctype_init (); + /* Register rseq ABI to the kernel. */ + (void) rseq_register_current_thread (); } diff --git a/manual/threads.texi b/manual/threads.texi index 0858ef8f92..59f634e432 100644 --- a/manual/threads.texi +++ b/manual/threads.texi @@ -9,8 +9,10 @@ This chapter describes functions used for managing threads. POSIX threads. @menu -* ISO C Threads:: Threads based on the ISO C specification. -* POSIX Threads:: Threads based on the POSIX specification. +* ISO C Threads:: Threads based on the ISO C specification. +* POSIX Threads:: Threads based on the POSIX specification. +* Restartable Sequences:: Linux-specific Restartable Sequences + integration. @end menu @@ -881,3 +883,27 @@ Behaves like @code{pthread_timedjoin_np} except that the absolute time in @c pthread_spin_unlock @c pthread_testcancel @c pthread_yield + +@node Restartable Sequences +@section Restartable Sequences +@cindex rseq + +This section describes @theglibc{} Restartable Sequences integration. + +@deftypevar {struct rseq} __rseq_abi +@standards{GNU, sys/rseq.h} +@Theglibc{} implements a @code{__rseq_abi} TLS symbol to interact with the +Restartable Sequences system call (Linux-specific). The layout of this +structure is defined by the Linux kernel @file{linux/rseq.h} UAPI. +Registration of each thread's @code{__rseq_abi} is performed by +@theglibc{} at libc initialization and pthread creation. +@end deftypevar + +@deftypevr Macro int RSEQ_SIG +@standards{GNU, sys/rseq.h} +Each supported architecture provide a @code{RSEQ_SIG} macro in +@file{sys/rseq.h} which contains a signature. That signature is expected to be +present in the code before each Restartable Sequences abort handler. Failure +to provide the expected signature may terminate the process with a Segmentation +fault. +@end deftypevr diff --git a/misc/rseq-internal.h b/misc/rseq-internal.h new file mode 100644 index 0000000000..d564cf1bc3 --- /dev/null +++ b/misc/rseq-internal.h @@ -0,0 +1,33 @@ +/* Restartable Sequences internal API. Stub version. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef RSEQ_INTERNAL_H +#define RSEQ_INTERNAL_H + +static inline int +rseq_register_current_thread (void) +{ + return -1; +} + +static inline int +rseq_unregister_current_thread (void) +{ + return -1; +} + +#endif /* rseq-internal.h */ diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index afd379e89a..1ff248042e 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -33,6 +33,7 @@ #include <default-sched.h> #include <futex-internal.h> #include <tls-setup.h> +#include <rseq-internal.h> #include "libioP.h" #include <shlib-compat.h> @@ -384,6 +385,9 @@ START_THREAD_DEFN /* Initialize pointers to locale data. */ __ctype_init (); + /* Register rseq TLS to the kernel. */ + (void) rseq_register_current_thread (); + #ifndef __ASSUME_SET_ROBUST_LIST if (__set_robust_list_avail >= 0) #endif @@ -578,6 +582,14 @@ START_THREAD_DEFN process is really dead since 'clone' got passed the CLONE_CHILD_CLEARTID flag. The 'tid' field in the TCB will be set to zero. + rseq TLS is still registered at this point. Rely on implicit unregistration + performed by the kernel on thread teardown. This is not a problem because the + rseq TLS lives on the stack, and the stack outlives the thread. If TCB + allocation is ever changed, additional steps may be required, such as + performing explicit rseq unregistration before reclaiming the rseq TLS area + memory. It is NOT sufficient to block signals because the kernel may write + to the rseq area even without signals. + The exit code is zero since in case all threads exit by calling 'pthread_exit' the exit status must be 0 (zero). */ __exit_thread (); diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 60dc5cf9e5..6c6f669d21 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -41,7 +41,7 @@ update-syscall-lists: arch-syscall.h endif ifeq ($(subdir),csu) -sysdep_routines += errno-loc +sysdep_routines += errno-loc rseq-sym endif ifeq ($(subdir),assert) @@ -92,7 +92,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \ bits/termios-baud.h bits/termios-c_cflag.h \ bits/termios-c_lflag.h bits/termios-tcflow.h \ bits/termios-misc.h \ - bits/ipc-perm.h + bits/ipc-perm.h \ + sys/rseq.h bits/rseq.h tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index d385085c61..7f0da50580 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -177,6 +177,9 @@ libc { GLIBC_2.30 { getdents64; gettid; tgkill; } + GLIBC_2.31 { + __rseq_abi; + } GLIBC_PRIVATE { # functions used in other libraries __syscall_rt_sigqueueinfo; diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/rseq.h b/sysdeps/unix/sysv/linux/aarch64/bits/rseq.h new file mode 100644 index 0000000000..e272c30446 --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/bits/rseq.h @@ -0,0 +1,43 @@ +/* Restartable Sequences Linux aarch64 architecture header. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_RSEQ_H +# error "Never use <bits/rseq.h> directly; include <sys/rseq.h> instead." +#endif + +/* RSEQ_SIG is a signature required before each abort handler code. + + It is a 32-bit value that maps to actual architecture code compiled + into applications and libraries. It needs to be defined for each + architecture. When choosing this value, it needs to be taken into + account that generating invalid instructions may have ill effects on + tools like objdump, and may also have impact on the CPU speculative + execution efficiency in some cases. + + aarch64 -mbig-endian generates mixed endianness code vs data: + little-endian code and big-endian data. Ensure the RSEQ_SIG signature + matches code endianness. */ + +#define RSEQ_SIG_CODE 0xd428bc00 /* BRK #0x45E0. */ + +#ifdef __AARCH64EB__ +#define RSEQ_SIG_DATA 0x00bc28d4 /* BRK #0x45E0. */ +#else +#define RSEQ_SIG_DATA RSEQ_SIG_CODE +#endif + +#define RSEQ_SIG RSEQ_SIG_DATA diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index a4c31932cb..6784f13c09 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2145,3 +2145,4 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index e7f2174ac2..71db8422a2 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2225,6 +2225,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index b152c0e24a..eecebc908f 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -133,6 +133,7 @@ GLIBC_2.30 twalk_r F GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/arm/bits/rseq.h b/sysdeps/unix/sysv/linux/arm/bits/rseq.h new file mode 100644 index 0000000000..45a2118dbc --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/bits/rseq.h @@ -0,0 +1,83 @@ +/* Restartable Sequences Linux arm architecture header. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_RSEQ_H +# error "Never use <bits/rseq.h> directly; include <sys/rseq.h> instead." +#endif + +/* + RSEQ_SIG is a signature required before each abort handler code. + + It is a 32-bit value that maps to actual architecture code compiled + into applications and libraries. It needs to be defined for each + architecture. When choosing this value, it needs to be taken into + account that generating invalid instructions may have ill effects on + tools like objdump, and may also have impact on the CPU speculative + execution efficiency in some cases. + + - ARM little endian + + RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand + value 0x5de3. This traps if user-space reaches this instruction by mistake, + and the uncommon operand ensures the kernel does not move the instruction + pointer to attacker-controlled code on rseq abort. + + The instruction pattern in the A32 instruction set is: + + e7f5def3 udf #24035 ; 0x5de3 + + This translates to the following instruction pattern in the T16 instruction + set: + + little endian: + def3 udf #243 ; 0xf3 + e7f5 b.n <7f5> + + - ARMv6+ big endian (BE8): + + ARMv6+ -mbig-endian generates mixed endianness code vs data: little-endian + code and big-endian data. The data value of the signature needs to have its + byte order reversed to generate the trap instruction: + + Data: 0xf3def5e7 + + Translates to this A32 instruction pattern: + + e7f5def3 udf #24035 ; 0x5de3 + + Translates to this T16 instruction pattern: + + def3 udf #243 ; 0xf3 + e7f5 b.n <7f5> + + - Prior to ARMv6 big endian (BE32): + + Prior to ARMv6, -mbig-endian generates big-endian code and data + (which match), so the endianness of the data representation of the + signature should not be reversed. However, the choice between BE32 + and BE8 is done by the linker, so we cannot know whether code and + data endianness will be mixed before the linker is invoked. So rather + than try to play tricks with the linker, the rseq signature is simply + data (not a trap instruction) prior to ARMv6 on big endian. This is + why the signature is expressed as data (.word) rather than as + instruction (.inst) in assembler. */ + +#ifdef __ARMEB__ +#define RSEQ_SIG 0xf3def5e7 /* udf #24035 ; 0x5de3 (ARMv6+) */ +#else +#define RSEQ_SIG 0xe7f5def3 /* udf #24035 ; 0x5de3 */ +#endif diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index 9371927927..3e7434d3d5 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -130,6 +130,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/bits/rseq.h b/sysdeps/unix/sysv/linux/bits/rseq.h new file mode 100644 index 0000000000..b8a63ed26d --- /dev/null +++ b/sysdeps/unix/sysv/linux/bits/rseq.h @@ -0,0 +1,29 @@ +/* Restartable Sequences architecture header. Stub version. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_RSEQ_H +# error "Never use <bits/rseq.h> directly; include <sys/rseq.h> instead." +#endif + +/* RSEQ_SIG is a signature required before each abort handler code. + + It is a 32-bit value that maps to actual architecture code compiled + into applications and libraries. It needs to be defined for each + architecture. When choosing this value, it needs to be taken into + account that generating invalid instructions may have ill effects on + tools like objdump, and may also have impact on the CPU speculative + execution efficiency in some cases. */ diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 9b3cee65bb..b7ed346b1c 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2089,3 +2089,4 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index df6d96fbae..d55b153c48 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2046,6 +2046,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index fcb625b6bf..c9061600f6 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2212,6 +2212,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index cb556c5998..f794303f0e 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2078,6 +2078,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 32533e94cf..2c15da9389 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -121,6 +121,11 @@ # define __ASSUME_STATX 1 #endif +/* Support for rseq was added in kernel 4.18. */ +#if __LINUX_KERNEL_VERSION >= 0x041200 +# define __ASSUME_RSEQ 1 +#endif + /* Support for clone call used on fork. The signature varies across the architectures with current 4 different variants: diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 5e3cdea246..e5e545f3af 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -134,6 +134,7 @@ GLIBC_2.30 twalk_r F GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 GLIBC_2.4 _IO_2_1_stdin_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index ea5e7a41af..3fc1223e2c 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2158,6 +2158,7 @@ GLIBC_2.30 twalk_r F GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index ac55b0acd7..81db30b543 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2140,3 +2140,4 @@ GLIBC_2.30 twalk_r F GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F +GLIBC_2.31 __rseq_abi T 0x20 diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index f7ced487f7..a2ce147dde 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2137,3 +2137,4 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 diff --git a/sysdeps/unix/sysv/linux/mips/bits/rseq.h b/sysdeps/unix/sysv/linux/mips/bits/rseq.h new file mode 100644 index 0000000000..4eee59265a --- /dev/null +++ b/sysdeps/unix/sysv/linux/mips/bits/rseq.h @@ -0,0 +1,62 @@ +/* Restartable Sequences Linux mips architecture header. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_RSEQ_H +# error "Never use <bits/rseq.h> directly; include <sys/rseq.h> instead." +#endif + +/* RSEQ_SIG is a signature required before each abort handler code. + + It is a 32-bit value that maps to actual architecture code compiled + into applications and libraries. It needs to be defined for each + architecture. When choosing this value, it needs to be taken into + account that generating invalid instructions may have ill effects on + tools like objdump, and may also have impact on the CPU speculative + execution efficiency in some cases. + + RSEQ_SIG uses the break instruction. The instruction pattern is: + + On MIPS: + 0350000d break 0x350 + + On nanoMIPS: + 00100350 break 0x350 + + On microMIPS: + 0000d407 break 0x350 + + For nanoMIPS32 and microMIPS, the instruction stream is encoded as + 16-bit halfwords, so the signature halfwords need to be swapped + accordingly for little-endian. */ + +#if defined(__nanomips__) +# ifdef __MIPSEL__ +# define RSEQ_SIG 0x03500010 +# else +# define RSEQ_SIG 0x00100350 +# endif +#elif defined(__mips_micromips) +# ifdef __MIPSEL__ +# define RSEQ_SIG 0xd4070000 +# else +# define RSEQ_SIG 0x0000d407 +# endif +#elif defined(__mips__) +# define RSEQ_SIG 0x0350000d +#else +/* Unknown MIPS architecture. */ +#endif diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 06c2e64edd..c0040ddd4e 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2129,6 +2129,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index bdfd073b86..61f19076eb 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2127,6 +2127,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 3d61d4974a..df4f3a3c04 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2135,6 +2135,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 675acca5db..a96de2e467 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2129,6 +2129,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index 7fec0c9670..7b2ccbe953 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2178,3 +2178,4 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/rseq.h b/sysdeps/unix/sysv/linux/powerpc/bits/rseq.h new file mode 100644 index 0000000000..9d10000a6e --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/bits/rseq.h @@ -0,0 +1,37 @@ +/* Restartable Sequences Linux powerpc architecture header. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_RSEQ_H +# error "Never use <bits/rseq.h> directly; include <sys/rseq.h> instead." +#endif + +/* RSEQ_SIG is a signature required before each abort handler code. + + It is a 32-bit value that maps to actual architecture code compiled + into applications and libraries. It needs to be defined for each + architecture. When choosing this value, it needs to be taken into + account that generating invalid instructions may have ill effects on + tools like objdump, and may also have impact on the CPU speculative + execution efficiency in some cases. + + RSEQ_SIG uses the following trap instruction: + + powerpc-be: 0f e5 00 0b twui r5,11 + powerpc64-le: 0b 00 e5 0f twui r5,11 + powerpc64-be: 0f e5 00 0b twui r5,11 */ + +#define RSEQ_SIG 0x0fe5000b diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 1e8ff6f83e..6f4c6515dc 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2185,6 +2185,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index b5a0751d90..f9875b4e22 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2218,6 +2218,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 0c86217fc6..db06080db8 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2048,6 +2048,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index 2229a1dcc0..608ad49593 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2247,3 +2247,4 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 31010e6cf7..c7657ce7f6 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2107,3 +2107,4 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h new file mode 100644 index 0000000000..3502c109b0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/rseq-internal.h @@ -0,0 +1,76 @@ +/* Restartable Sequences internal API. Linux implementation. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef RSEQ_INTERNAL_H +#define RSEQ_INTERNAL_H + +#include <sysdep.h> +#include <errno.h> +#include <kernel-features.h> + +#ifdef __ASSUME_RSEQ +#include <sys/rseq.h> +#endif + +#if defined __ASSUME_RSEQ && defined RSEQ_SIG + +static inline int +rseq_register_current_thread (void) +{ + int rc, ret = 0; + + if (__rseq_abi.cpu_id == RSEQ_CPU_ID_REGISTRATION_FAILED) + return -1; + rc = INTERNAL_SYSCALL_CALL (rseq, &__rseq_abi, sizeof (struct rseq), + 0, RSEQ_SIG); + if (!rc) + goto end; + if (INTERNAL_SYSCALL_ERRNO (rc) != EBUSY) + __rseq_abi.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED; + ret = -1; +end: + return ret; +} + +static inline int +rseq_unregister_current_thread (void) +{ + int rc, ret = 0; + + rc = INTERNAL_SYSCALL_CALL (rseq, &__rseq_abi, sizeof (struct rseq), + RSEQ_FLAG_UNREGISTER, RSEQ_SIG); + if (!rc) + goto end; + ret = -1; +end: + return ret; +} +#else +static inline int +rseq_register_current_thread (void) +{ + return -1; +} + +static inline int +rseq_unregister_current_thread (void) +{ + return -1; +} +#endif + +#endif /* rseq-internal.h */ diff --git a/sysdeps/unix/sysv/linux/rseq-sym.c b/sysdeps/unix/sysv/linux/rseq-sym.c new file mode 100644 index 0000000000..2234bd62af --- /dev/null +++ b/sysdeps/unix/sysv/linux/rseq-sym.c @@ -0,0 +1,44 @@ +/* Restartable Sequences exported symbols. Linux Implementation. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/syscall.h> +#include <stdint.h> +#include <kernel-features.h> + +#ifdef __ASSUME_RSEQ +#include <sys/rseq.h> +#else + +enum rseq_cpu_id_state { + RSEQ_CPU_ID_UNINITIALIZED = -1, + RSEQ_CPU_ID_REGISTRATION_FAILED = -2, +}; + +/* linux/rseq.h defines struct rseq as aligned on 32 bytes. The kernel ABI + size is 20 bytes. */ +struct rseq { + uint32_t cpu_id_start; + uint32_t cpu_id; + uint64_t rseq_cs; + uint32_t flags; +} __attribute__ ((aligned(4 * sizeof(uint64_t)))); + +#endif + +__thread struct rseq __rseq_abi = { + .cpu_id = RSEQ_CPU_ID_UNINITIALIZED, +}; diff --git a/sysdeps/unix/sysv/linux/s390/bits/rseq.h b/sysdeps/unix/sysv/linux/s390/bits/rseq.h new file mode 100644 index 0000000000..c25ee67ee7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/bits/rseq.h @@ -0,0 +1,37 @@ +/* Restartable Sequences Linux s390 architecture header. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_RSEQ_H +# error "Never use <bits/rseq.h> directly; include <sys/rseq.h> instead." +#endif + +/* RSEQ_SIG is a signature required before each abort handler code. + + It is a 32-bit value that maps to actual architecture code compiled + into applications and libraries. It needs to be defined for each + architecture. When choosing this value, it needs to be taken into + account that generating invalid instructions may have ill effects on + tools like objdump, and may also have impact on the CPU speculative + execution efficiency in some cases. + + RSEQ_SIG uses the trap4 instruction. As Linux does not make use of the + access-register mode nor the linkage stack this instruction will always + cause a special-operation exception (the trap-enabled bit in the DUCT + is and will stay 0). The instruction pattern is + b2 ff 0f ff trap4 4095(%r0) */ + +#define RSEQ_SIG 0xB2FF0FFF diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 4feca641b0..9c29ec0d2d 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2183,6 +2183,7 @@ GLIBC_2.30 twalk_r F GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index efe588a072..99424ceac9 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2084,6 +2084,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 6bfc2b7439..80198de5d6 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2053,6 +2053,7 @@ GLIBC_2.30 twalk_r F GLIBC_2.31 msgctl F GLIBC_2.31 semctl F GLIBC_2.31 shmctl F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index 4b057bf4a2..916aa0b7f0 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2050,6 +2050,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 49cd597fd6..9a27df8e43 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2174,6 +2174,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 95e68e0ba1..32908666c4 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2101,6 +2101,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sys/rseq.h b/sysdeps/unix/sysv/linux/sys/rseq.h new file mode 100644 index 0000000000..eb64fd41d7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sys/rseq.h @@ -0,0 +1,30 @@ +/* Restartable Sequences exported symbols. Linux header. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_RSEQ_H +#define _SYS_RSEQ_H 1 + +/* We use the structures declarations from the kernel headers. */ +#include <linux/rseq.h> +/* Architecture-specific rseq signature. */ +#include <bits/rseq.h> +#include <stdint.h> + +extern __thread struct rseq __rseq_abi +__attribute__ ((tls_model ("initial-exec"))); + +#endif /* sys/rseq.h */ diff --git a/sysdeps/unix/sysv/linux/x86/bits/rseq.h b/sysdeps/unix/sysv/linux/x86/bits/rseq.h new file mode 100644 index 0000000000..75f52d9788 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/bits/rseq.h @@ -0,0 +1,30 @@ +/* Restartable Sequences Linux x86 architecture header. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_RSEQ_H +# error "Never use <bits/rseq.h> directly; include <sys/rseq.h> instead." +#endif + +/* RSEQ_SIG is a signature required before each abort handler code. + + RSEQ_SIG is used with the following reserved undefined instructions, which + trap in user-space: + + x86-32: 0f b9 3d 53 30 05 53 ud1 0x53053053,%edi + x86-64: 0f b9 3d 53 30 05 53 ud1 0x53053053(%rip),%edi */ + +#define RSEQ_SIG 0x53053053 diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 1f2dbd1451..7366565608 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2059,6 +2059,7 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20 GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 59da85a5d8..c1aa86f06e 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2158,3 +2158,4 @@ GLIBC_2.30 getdents64 F GLIBC_2.30 gettid F GLIBC_2.30 tgkill F GLIBC_2.30 twalk_r F +GLIBC_2.31 __rseq_abi T 0x20