[08/21] ARC: Linux Syscall Interface

Message ID 1545167083-16764-9-git-send-email-vgupta@synopsys.com
State New, archived
Headers

Commit Message

Vineet Gupta Dec. 18, 2018, 9:04 p.m. UTC
  Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 ChangeLog                                     |  12 ++
 sysdeps/unix/sysv/linux/arc/cacheflush.c      |  29 +++
 sysdeps/unix/sysv/linux/arc/clone.S           | 100 ++++++++++
 sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h  |   6 +
 sysdeps/unix/sysv/linux/arc/kernel-features.h |  28 +++
 sysdeps/unix/sysv/linux/arc/mmap_internal.h   |  26 +++
 sysdeps/unix/sysv/linux/arc/profil-counter.h  |   2 +
 sysdeps/unix/sysv/linux/arc/pt-vfork.S        |   1 +
 sysdeps/unix/sysv/linux/arc/sigaction.c       |  69 +++++++
 sysdeps/unix/sysv/linux/arc/syscall.S         |  38 ++++
 sysdeps/unix/sysv/linux/arc/sysdep.c          |  33 ++++
 sysdeps/unix/sysv/linux/arc/sysdep.h          | 259 ++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/arc/vfork.S           |  42 +++++
 13 files changed, 645 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/arc/cacheflush.c
 create mode 100644 sysdeps/unix/sysv/linux/arc/clone.S
 create mode 100644 sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h
 create mode 100644 sysdeps/unix/sysv/linux/arc/kernel-features.h
 create mode 100644 sysdeps/unix/sysv/linux/arc/mmap_internal.h
 create mode 100644 sysdeps/unix/sysv/linux/arc/profil-counter.h
 create mode 100644 sysdeps/unix/sysv/linux/arc/pt-vfork.S
 create mode 100644 sysdeps/unix/sysv/linux/arc/sigaction.c
 create mode 100644 sysdeps/unix/sysv/linux/arc/syscall.S
 create mode 100644 sysdeps/unix/sysv/linux/arc/sysdep.c
 create mode 100644 sysdeps/unix/sysv/linux/arc/sysdep.h
 create mode 100644 sysdeps/unix/sysv/linux/arc/vfork.S
  

Comments

Joseph Myers Dec. 18, 2018, 11:30 p.m. UTC | #1
On Tue, 18 Dec 2018, Vineet Gupta wrote:

> +/* Flush cache(s).  */
> +int
> +_flush_cache (char *addr, const int nbytes, const int op)
> +{
> +  return INLINE_SYSCALL (cacheflush, 3, addr, nbytes, op);
> +}
> +weak_alias (_flush_cache, cacheflush)

Can't this use a syscalls.list entry instead of needing its own .c file?

> diff --git a/sysdeps/unix/sysv/linux/arc/pt-vfork.S b/sysdeps/unix/sysv/linux/arc/pt-vfork.S
> new file mode 100644
> index 000000000000..65cc3823ac87
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/arc/pt-vfork.S
> @@ -0,0 +1 @@
> +#include <sysdeps/unix/sysv/linux/alpha/pt-vfork.S>

This does nothing for a new port (it's just defining compat symbols).  I'd 
expect

/* Not needed.  */

instead, as for RISC-V.

> diff --git a/sysdeps/unix/sysv/linux/arc/sigaction.c b/sysdeps/unix/sysv/linux/arc/sigaction.c

Why do you need this, rather than using the unified version (possibly with 
a few macros defined first)?

> +/* All syscall handler come here to avoid generated code bloat due to
> + * GOT reference  to errno_location or it's equivalent
> + */
> +int __syscall_error(int err_no)

Return type goes on a separate line to the function name in a function 
definition.  (This is in addition to the formatting issues that have been 
noted elsewhere in the patch series, of which this code has at least three 
- '*' at start of comment lines, missing '.' at end of comment and missing 
space before '('.)
  
Vineet Gupta Dec. 19, 2018, 2:39 a.m. UTC | #2
On 12/18/18 3:30 PM, Joseph Myers wrote:
> On Tue, 18 Dec 2018, Vineet Gupta wrote:
> 
>> +/* Flush cache(s).  */
>> +int
>> +_flush_cache (char *addr, const int nbytes, const int op)
>> +{
>> +  return INLINE_SYSCALL (cacheflush, 3, addr, nbytes, op);
>> +}
>> +weak_alias (_flush_cache, cacheflush)
> 
> Can't this use a syscalls.list entry instead of needing its own .c file?

Sure it can ! Done now.

>> diff --git a/sysdeps/unix/sysv/linux/arc/pt-vfork.S b/sysdeps/unix/sysv/linux/arc/pt-vfork.S
>> new file mode 100644
>> index 000000000000..65cc3823ac87
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/arc/pt-vfork.S
>> @@ -0,0 +1 @@
>> +#include <sysdeps/unix/sysv/linux/alpha/pt-vfork.S>
> 
> This does nothing for a new port (it's just defining compat symbols).  I'd 
> expect
> 
> /* Not needed.  */
> 
> instead, as for RISC-V.

Done !

>> diff --git a/sysdeps/unix/sysv/linux/arc/sigaction.c b/sysdeps/unix/sysv/linux/arc/sigaction.c
> 
> Why do you need this, rather than using the unified version (possibly with 
> a few macros defined first)?

The only syscall ABI requirement is that we pass our our own SA_RESTORER stub
(rather than inject one in kernel, and deal with cache sync etc etc). Indeed the
common code can be used - likely was not the case when I started with ARC port, or
more likely the port that I started ARC port from ;-)

I'll update this.


>> +/* All syscall handler come here to avoid generated code bloat due to
>> + * GOT reference  to errno_location or it's equivalent
>> + */
>> +int __syscall_error(int err_no)
> 
> Return type goes on a separate line to the function name in a function 
> definition.

Oops sorry fixed.

> (This is in addition to the formatting issues that have been 
> noted elsewhere in the patch series, of which this code has at least three 
> - '*' at start of comment lines, missing '.' at end of comment and missing 
> space before '('.)

Sorry again. I can sense your valid frustration, but then a lint file or kernel's
checkpatch style tools ill go a long way. Anyhow for now I've fixed annoyances
(hopefully all of them).
  
Vineet Gupta Dec. 19, 2018, 5:58 p.m. UTC | #3
On 12/18/18 6:39 PM, Vineet Gupta wrote:
>>> diff --git a/sysdeps/unix/sysv/linux/arc/sigaction.c b/sysdeps/unix/sysv/linux/arc/sigaction.c
>> Why do you need this, rather than using the unified version (possibly with 
>> a few macros defined first)?
>
> The only syscall ABI requirement is that we pass our our own SA_RESTORER stub
> (rather than inject one in kernel, and deal with cache sync etc etc). Indeed the
> common code can be used - likely was not the case when I started with ARC port, or
> more likely the port that I started ARC port from ;-)
> 
> I'll update this.

I took a stab at this but not really happy with taking this approach.

(1). Common code assumes disparate kernel and userland sigaction struct even
though there's no reason for a *new* port to be: its not like all glibc code is
shared/common although I agree it is best to do so as much as possible
So this requires explicit copy over of 1 struct into other, when it could have
been avoided altogether for some cases atleast (!SA_RESTORER).

(2)  Linux kernel asm-generic syscall ABI expects sigset_t to be 2 words

| kernel: include/uapi/asm-generic/signal.h
|
| #define _NSIG		64
| typedef struct {
|	unsigned long sig[_NSIG_WORDS];
| } sigset_t;

And that is what we pretend at the time of syscall itself, e.g. snippet below from
generic sigaction()

|     /* XXX The size argument hopefully will have to be changed to the
|     real size of the user-level sigset_t.  */
|   result = INLINE_SYSCALL_CALL (rt_sigaction, sig,
|				act ? &kact : NULL,
|				oact ? &koact : NULL, STUB(act) _NSIG / 8);
                                                                ^^^^^^^^^

However glibc assumes sigset_to to be 128 words which is fine, however the memcpy
for 256 words seems pointless when kernel is not supposed to be even looking at
beyond 2nd word (although I realize my SA_RESTORE case was doing the implicit copy
as well)

(3) Consider me a micro-optimization freak :-) but this memcpy seems waste of
cycles and will atleast show up LMBench lat_sig <install> micro-benchmarks.


I don't have strong feelings either ways, but wanted to express my concerns anyways.

Thx,
-Vineet
  
Joseph Myers Dec. 19, 2018, 6:07 p.m. UTC | #4
On Wed, 19 Dec 2018, Vineet Gupta wrote:

> I took a stab at this but not really happy with taking this approach.
> 
> (1). Common code assumes disparate kernel and userland sigaction struct even
> though there's no reason for a *new* port to be: its not like all glibc code is
> shared/common although I agree it is best to do so as much as possible
> So this requires explicit copy over of 1 struct into other, when it could have
> been avoided altogether for some cases atleast (!SA_RESTORER).

So make the generic code optimize those cases based on appropriate 
conditionals (making sure to verify those conditionals are right for every 
architecture in glibc).

Any new architecture having much architecture-specific code for the kernel 
interface in glibc, beyond the basic definitions of how to call a syscall, 
is suspect, given that the kernel structures should be consistent across 
asm-generic architectures; we ought to make the defaults work so they are 
genuinely suitable as defaults for new architectures.  This may require 
changes to the sysdeps/unix/sysv/linux/ code if it's currently "generic" 
to old architectures but not so good for asm-generic ones.
  
Adhemerval Zanella Dec. 19, 2018, 10 p.m. UTC | #5
On 19/12/2018 15:58, Vineet Gupta wrote:
> On 12/18/18 6:39 PM, Vineet Gupta wrote:
>>>> diff --git a/sysdeps/unix/sysv/linux/arc/sigaction.c b/sysdeps/unix/sysv/linux/arc/sigaction.c
>>> Why do you need this, rather than using the unified version (possibly with 
>>> a few macros defined first)?
>>
>> The only syscall ABI requirement is that we pass our our own SA_RESTORER stub
>> (rather than inject one in kernel, and deal with cache sync etc etc). Indeed the
>> common code can be used - likely was not the case when I started with ARC port, or
>> more likely the port that I started ARC port from ;-)
>>
>> I'll update this.
> 
> I took a stab at this but not really happy with taking this approach.
> 
> (1). Common code assumes disparate kernel and userland sigaction struct even
> though there's no reason for a *new* port to be: its not like all glibc code is
> shared/common although I agree it is best to do so as much as possible
> So this requires explicit copy over of 1 struct into other, when it could have
> been avoided altogether for some cases atleast (!SA_RESTORER).
> 
> (2)  Linux kernel asm-generic syscall ABI expects sigset_t to be 2 words
> 
> | kernel: include/uapi/asm-generic/signal.h
> |
> | #define _NSIG		64
> | typedef struct {
> |	unsigned long sig[_NSIG_WORDS];
> | } sigset_t;
> 
> And that is what we pretend at the time of syscall itself, e.g. snippet below from
> generic sigaction()
> 
> |     /* XXX The size argument hopefully will have to be changed to the
> |     real size of the user-level sigset_t.  */
> |   result = INLINE_SYSCALL_CALL (rt_sigaction, sig,
> |				act ? &kact : NULL,
> |				oact ? &koact : NULL, STUB(act) _NSIG / 8);
>                                                                 ^^^^^^^^^
> 
> However glibc assumes sigset_to to be 128 words which is fine, however the memcpy
> for 256 words seems pointless when kernel is not supposed to be even looking at
> beyond 2nd word (although I realize my SA_RESTORE case was doing the implicit copy
> as well)
> 
> (3) Consider me a micro-optimization freak :-) but this memcpy seems waste of
> cycles and will atleast show up LMBench lat_sig <install> micro-benchmarks.
> 
> 
> I don't have strong feelings either ways, but wanted to express my concerns anyways.
> 

One possibility is to define an arch-specific __sigset_t.h with a custom 
_SIGSET_NWORDS value and add an optimization on Linux sigaction.c to check
if both kernel_sigaction and glibc sigaction share same size and internal
layout to use the struct as-is for syscall instead of copy to a temporary
value (similar to what we used to have on getdents).  ARC would still have
arch-specific code and would be the only ABI to have a different sigset_t
though.

However I *hardly* think sigaction is a hotspot in real world cases, usually
the signal action is defined once or in a very limited number of times.  I am
not considering synthetic benchmarks, specially lmbench which in most cases
does not measure any useful metric. Even for other sigset_t usage case I still
think an arch-specific definition should not make much difference:

  1. setcontext: it would incur just in larger ucontext_t (kernel get/set
     mask is done using kernel expected size).  Also, taking in consideration
     these interfaces were removed from POSIX.1-2008, the inherent performance
     issues (signal set/restore will most likely dominate the overhead), and
     some implementation issues (BZ#18135 for instance), I would say to not
     bother to optimize it.

  2. pselect, ppoll, epoll_pwait, posix_spawn (posix_spawnattr_t), sig*: 
     for functions that accept sigset as an argument it would incur in just
     larger memory utilization without much performance overhead. Again,
     runtime for these calls would be mostly dominate by syscall overhead
     or kernel wait-time for events.

  3. raise, etc: for function that might allocate a sigset_t internally it
     will similar to 2.

Now, if ARC intention is just to follow generic glibc linux ABI definitions,
it could just define its sigaction as (not tested):

* sysdeps/unix/sysv/linux/arc/sigaction.c

---
#define SA_RESTORER 0x04000000
#include <kernel_sigaction.h>

extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;

#define SET_SA_RESTORER(kact, act)                      \
  (kact)->sa_flags = (act)->sa_flags | SA_RESTORER;     \
  (kact)->sa_restorer = &__default_rt_sa_restorer

#define RESET_SA_RESTORER(act, kact)                    \
  (act)->sa_restorer = (kact)->sa_restorer

static void __default_rt_sa_restorer(void)
{
  INTERNAL_SYSCALL_DECL (err);
  INTERNAL_SYSCALL_CALL (__NR_rt_sigreturn, err);
}

#include <sysdeps/unix/sysv/linux/sigaction.c>
---
  
Vineet Gupta Dec. 19, 2018, 10:23 p.m. UTC | #6
On 12/19/18 2:00 PM, Adhemerval Zanella wrote:
> 
> 
> One possibility is to define an arch-specific __sigset_t.h with a custom 
> _SIGSET_NWORDS value and add an optimization on Linux sigaction.c to check
> if both kernel_sigaction and glibc sigaction share same size and internal
> layout to use the struct as-is for syscall instead of copy to a temporary
> value (similar to what we used to have on getdents).  ARC would still have
> arch-specific code and would be the only ABI to have a different sigset_t
> though.

I don't like ARC to single out either. But as Joseph suggests could this be
starting point for arches of future. Assuming it does, would rather see this or
the approach Joseph alluded to earlier [1]

[1] http://lists.infradead.org/pipermail/linux-snps-arc/2018-December/005122.html

> 
> However I *hardly* think sigaction is a hotspot in real world cases, usually
> the signal action is defined once or in a very limited number of times.  I am
> not considering synthetic benchmarks, specially lmbench which in most cases
> does not measure any useful metric. 

I tend to disagree. Coming from embedded linux background, I've found it immensely
useful to compare 2 minimal systems: especially when distos, out-of-box packages,
fancy benchmarks don't even exist.

At any rate, my disagreement with status quo is not so much of optimize for ARC,
but rather pointless spending of electrons. When we know that there are 64 signals
at max, which need 64-bits, why bother shuffling around 1k bits, specially when
one is starting afresh and there's no legacy crap getting in the way.

The case of adding more signals in future is indeed theoretically possible but
that will be an ABI change anyways.

> Even for other sigset_t usage case I still
> think an arch-specific definition should not make much difference:
> 
>   1. setcontext: it would incur just in larger ucontext_t (kernel get/set
>      mask is done using kernel expected size).  Also, taking in consideration
>      these interfaces were removed from POSIX.1-2008, the inherent performance
>      issues (signal set/restore will most likely dominate the overhead), and
>      some implementation issues (BZ#18135 for instance), I would say to not
>      bother to optimize it.
> 
>   2. pselect, ppoll, epoll_pwait, posix_spawn (posix_spawnattr_t), sig*: 
>      for functions that accept sigset as an argument it would incur in just
>      larger memory utilization without much performance overhead. Again,
>      runtime for these calls would be mostly dominate by syscall overhead
>      or kernel wait-time for events.
> 
>   3. raise, etc: for function that might allocate a sigset_t internally it
>      will similar to 2.

I agree that that in libc, pretty much anything will be dominated by syscall
overhead, but still...


> Now, if ARC intention is just to follow generic glibc linux ABI definitions,
> it could just define its sigaction as (not tested):

Indeed the ABI is etched in stone and I have a very similar code now, with slight
difference.

> * sysdeps/unix/sysv/linux/arc/sigaction.c
> 
> ---
> #define SA_RESTORER 0x04000000
> #include <kernel_sigaction.h>
> 
> extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
> 
> #define SET_SA_RESTORER(kact, act)                      \
>   (kact)->sa_flags = (act)->sa_flags | SA_RESTORER;     \
>   (kact)->sa_restorer = &__default_rt_sa_restorer

+#define SET_SA_RESTORER(kact, act)				\
+ ({								\
+   if (!((kact)->sa_flags & SA_RESTORER))			\
+     {								\
+       (kact)->sa_restorer = __default_rt_sa_restorer;		\
+       (kact)->sa_flags |= SA_RESTORER;			\
+     }								\
+   else							\
+     (kact)->sa_restorer = (act)->sa_restorer;			\
+ })

> 
> #define RESET_SA_RESTORER(act, kact)                    \
>   (act)->sa_restorer = (kact)->sa_restorer
> 
> static void __default_rt_sa_restorer(void)
> {
>   INTERNAL_SYSCALL_DECL (err);
>   INTERNAL_SYSCALL_CALL (__NR_rt_sigreturn, err);
> }
> 
> #include <sysdeps/unix/sysv/linux/sigaction.c>
  
Adhemerval Zanella Dec. 20, 2018, 11:19 a.m. UTC | #7
On 19/12/2018 20:23, Vineet Gupta wrote:
> On 12/19/18 2:00 PM, Adhemerval Zanella wrote:
>>
>>
>> One possibility is to define an arch-specific __sigset_t.h with a custom 
>> _SIGSET_NWORDS value and add an optimization on Linux sigaction.c to check
>> if both kernel_sigaction and glibc sigaction share same size and internal
>> layout to use the struct as-is for syscall instead of copy to a temporary
>> value (similar to what we used to have on getdents).  ARC would still have
>> arch-specific code and would be the only ABI to have a different sigset_t
>> though.
> 
> I don't like ARC to single out either. But as Joseph suggests could this be
> starting point for arches of future. Assuming it does, would rather see this or
> the approach Joseph alluded to earlier [1]
> 
> [1] http://lists.infradead.org/pipermail/linux-snps-arc/2018-December/005122.html
> 
>>
>> However I *hardly* think sigaction is a hotspot in real world cases, usually
>> the signal action is defined once or in a very limited number of times.  I am
>> not considering synthetic benchmarks, specially lmbench which in most cases
>> does not measure any useful metric. 
> 
> I tend to disagree. Coming from embedded linux background, I've found it immensely
> useful to compare 2 minimal systems: especially when distos, out-of-box packages,
> fancy benchmarks don't even exist.
> 
> At any rate, my disagreement with status quo is not so much of optimize for ARC,
> but rather pointless spending of electrons. When we know that there are 64 signals
> at max, which need 64-bits, why bother shuffling around 1k bits, specially when
> one is starting afresh and there's no legacy crap getting in the way.
> 
> The case of adding more signals in future is indeed theoretically possible but
> that will be an ABI change anyways.

The only advantage of using a larger sigset_t from glibc standpoint is if
kernel ever change it maximum number of supported signals it would not be
a ABI change (it would be if glibc provided sigset_t need to be extended).

My point was that this change would hardly help in performance or memory 
utilization due the signal set common utilization in exported and internal
API.  But at the same time the signal set hasn't been changed for a *long* time 
and I don't see indication that it will any time soon. So a new architecture 
might indeed assume it won't change and set its default to follow Linux user 
ABI.

> 
>> Even for other sigset_t usage case I still
>> think an arch-specific definition should not make much difference:
>>
>>   1. setcontext: it would incur just in larger ucontext_t (kernel get/set
>>      mask is done using kernel expected size).  Also, taking in consideration
>>      these interfaces were removed from POSIX.1-2008, the inherent performance
>>      issues (signal set/restore will most likely dominate the overhead), and
>>      some implementation issues (BZ#18135 for instance), I would say to not
>>      bother to optimize it.
>>
>>   2. pselect, ppoll, epoll_pwait, posix_spawn (posix_spawnattr_t), sig*: 
>>      for functions that accept sigset as an argument it would incur in just
>>      larger memory utilization without much performance overhead. Again,
>>      runtime for these calls would be mostly dominate by syscall overhead
>>      or kernel wait-time for events.
>>
>>   3. raise, etc: for function that might allocate a sigset_t internally it
>>      will similar to 2.
> 
> I agree that that in libc, pretty much anything will be dominated by syscall
> overhead, but still...
> 
> 
>> Now, if ARC intention is just to follow generic glibc linux ABI definitions,
>> it could just define its sigaction as (not tested):
> 
> Indeed the ABI is etched in stone and I have a very similar code now, with slight
> difference.
> 
>> * sysdeps/unix/sysv/linux/arc/sigaction.c
>>
>> ---
>> #define SA_RESTORER 0x04000000
>> #include <kernel_sigaction.h>
>>
>> extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
>>
>> #define SET_SA_RESTORER(kact, act)                      \
>>   (kact)->sa_flags = (act)->sa_flags | SA_RESTORER;     \
>>   (kact)->sa_restorer = &__default_rt_sa_restorer
> 
> +#define SET_SA_RESTORER(kact, act)				\
> + ({								\
> +   if (!((kact)->sa_flags & SA_RESTORER))			\
> +     {								\
> +       (kact)->sa_restorer = __default_rt_sa_restorer;		\
> +       (kact)->sa_flags |= SA_RESTORER;			\
> +     }								\
> +   else							\
> +     (kact)->sa_restorer = (act)->sa_restorer;			\
> + })

What is so special about ARC sa_restorer that an application should provide
an specialized one? Can't it follow other abi where they issue __NR_sigreturn
for !SA_SIGINFO or __NR_rt_sigreturn otherwise?

As for other architecture I do think we should hide the sa_restorer usage
from application.

> 
>>
>> #define RESET_SA_RESTORER(act, kact)                    \
>>   (act)->sa_restorer = (kact)->sa_restorer
>>
>> static void __default_rt_sa_restorer(void)
>> {
>>   INTERNAL_SYSCALL_DECL (err);
>>   INTERNAL_SYSCALL_CALL (__NR_rt_sigreturn, err);
>> }
>>
>> #include <sysdeps/unix/sysv/linux/sigaction.c>
> 
>
  
Arnd Bergmann Dec. 20, 2018, 12:06 p.m. UTC | #8
On Thu, Dec 20, 2018 at 12:19 PM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
> On 19/12/2018 20:23, Vineet Gupta wrote:
> > On 12/19/18 2:00 PM, Adhemerval Zanella wrote:
> >> One possibility is to define an arch-specific __sigset_t.h with a custom
> >> _SIGSET_NWORDS value and add an optimization on Linux sigaction.c to check
> >> if both kernel_sigaction and glibc sigaction share same size and internal
> >> layout to use the struct as-is for syscall instead of copy to a temporary
> >> value (similar to what we used to have on getdents).  ARC would still have
> >> arch-specific code and would be the only ABI to have a different sigset_t
> >> though.
> >
> > I don't like ARC to single out either. But as Joseph suggests could this be
> > starting point for arches of future. Assuming it does, would rather see this or
> > the approach Joseph alluded to earlier [1]
> >
> > [1] http://lists.infradead.org/pipermail/linux-snps-arc/2018-December/005122.html
> >
> >>
> >> However I *hardly* think sigaction is a hotspot in real world cases, usually
> >> the signal action is defined once or in a very limited number of times.  I am
> >> not considering synthetic benchmarks, specially lmbench which in most cases
> >> does not measure any useful metric.
> >
> > I tend to disagree. Coming from embedded linux background, I've found it immensely
> > useful to compare 2 minimal systems: especially when distos, out-of-box packages,
> > fancy benchmarks don't even exist.
> >
> > At any rate, my disagreement with status quo is not so much of optimize for ARC,
> > but rather pointless spending of electrons. When we know that there are 64 signals
> > at max, which need 64-bits, why bother shuffling around 1k bits, specially when
> > one is starting afresh and there's no legacy crap getting in the way.
> >
> > The case of adding more signals in future is indeed theoretically possible but
> > that will be an ABI change anyways.
>
> The only advantage of using a larger sigset_t from glibc standpoint is if
> kernel ever change it maximum number of supported signals it would not be
> a ABI change (it would be if glibc provided sigset_t need to be extended).
>
> My point was that this change would hardly help in performance or memory
> utilization due the signal set common utilization in exported and internal
> API.  But at the same time the signal set hasn't been changed for a *long* time
> and I don't see indication that it will any time soon. So a new architecture
> might indeed assume it won't change and set its default to follow Linux user
> ABI.

I just checked again what we actually use in the kernel.
With very few exceptions, all architectures in current kernels use

#define _NSIG             64
#define _NSIG_WORDS       (_NSIG / _NSIG_BPW)
typedef struct {
    /* this sucks for big-endian 32-bit compat mode */
    unsigned long sig[_NSIG_WORDS];
} sigset_t;

The only two exceptions I see are:

- alpha uses a scalar 'unsigned long' instead of the struct+array, but
  the effect is the same layout.
- For unknown reasons, all three MIPS ABIs now use _NSIG=128.
  This changed during linux-2.1.x from 65, to 32 and then the current
  value...

All users of sigset_t that I could find in the kernel just check
the size argument to ensure it matches _NSIG, and return
EINVAL otherwise.

      Arnd
  
Florian Weimer Dec. 20, 2018, 12:40 p.m. UTC | #9
* Adhemerval Zanella:

> The only advantage of using a larger sigset_t from glibc standpoint is if
> kernel ever change it maximum number of supported signals it would not be
> a ABI change (it would be if glibc provided sigset_t need to be extended).

It's not just the kernel.  We might want to restore additional state in
sigsetjmp, and historically, the excess signal space in sigset_t has
provided a way to do that even if there is no other space left in the
jump buffer.

Thanks,
Florian
  
Vineet Gupta Dec. 20, 2018, 6:48 p.m. UTC | #10
On 12/20/18 4:40 AM, Florian Weimer wrote:
> * Adhemerval Zanella:
>
>> The only advantage of using a larger sigset_t from glibc standpoint is if
>> kernel ever change it maximum number of supported signals it would not be
>> a ABI change (it would be if glibc provided sigset_t need to be extended).
> It's not just the kernel.  We might want to restore additional state in
> sigsetjmp, and historically, the excess signal space in sigset_t has
> provided a way to do that even if there is no other space left in the
> jump buffer.

And that additional state is architectural state (more FPU regs etc etc) or
something libc generic. On both counts, that doesn't sound like a clean interface
design !
  
Vineet Gupta Dec. 20, 2018, 7:23 p.m. UTC | #11
On 12/20/18 3:19 AM, Adhemerval Zanella wrote:
>>> #define SET_SA_RESTORER(kact, act)                      \
>>>   (kact)->sa_flags = (act)->sa_flags | SA_RESTORER;     \
>>>   (kact)->sa_restorer = &__default_rt_sa_restorer
>> +#define SET_SA_RESTORER(kact, act)				\
>> + ({								\
>> +   if (!((kact)->sa_flags & SA_RESTORER))			\
>> +     {								\
>> +       (kact)->sa_restorer = __default_rt_sa_restorer;		\
>> +       (kact)->sa_flags |= SA_RESTORER;			\
>> +     }								\
>> +   else							\
>> +     (kact)->sa_restorer = (act)->sa_restorer;			\
>> + })
> What is so special about ARC sa_restorer that an application should provide
> an specialized one?

Its the other way around. Only if application provides it's own restorer, we honor
it, otherwise default restorer is used. This logic goes back many many years ago
to how ARC uClibc did this and likely inherited it from the port it was copied
from. But I don't know if say POSIX allows apps to provide their own restorer or
not. We could very well remove it; although per other discussion if we intend to
use the same struct sigaction for kernel/userland, the placeholder would exist and
we could choose to just ignore it.


> Can't it follow other abi where they issue __NR_sigreturn
> for !SA_SIGINFO or __NR_rt_sigreturn otherwise?

With Linux UAPI ABI, __NR_sigreturn doesn't exist, but your concern is about
restorer ?

> As for other architecture I do think we should hide the sa_restorer usage
> from application.

As mentioned above, the placeholder could exist, we can choose to ignore it.
  
Vineet Gupta Dec. 20, 2018, 7:25 p.m. UTC | #12
On 12/20/18 4:07 AM, Arnd Bergmann wrote:
> All users of sigset_t that I could find in the kernel just check
> the size argument to ensure it matches _NSIG, and return
> EINVAL otherwise.

Indeed that was one of the very first problem ARC glibc port ran into with stock
sizeof(sigset_t) passed in sigaction syscall.
  
Adhemerval Zanella Dec. 20, 2018, 8:06 p.m. UTC | #13
On 20/12/2018 17:23, Vineet Gupta wrote:
> On 12/20/18 3:19 AM, Adhemerval Zanella wrote:
>>>> #define SET_SA_RESTORER(kact, act)                      \
>>>>   (kact)->sa_flags = (act)->sa_flags | SA_RESTORER;     \
>>>>   (kact)->sa_restorer = &__default_rt_sa_restorer
>>> +#define SET_SA_RESTORER(kact, act)				\
>>> + ({								\
>>> +   if (!((kact)->sa_flags & SA_RESTORER))			\
>>> +     {								\
>>> +       (kact)->sa_restorer = __default_rt_sa_restorer;		\
>>> +       (kact)->sa_flags |= SA_RESTORER;			\
>>> +     }								\
>>> +   else							\
>>> +     (kact)->sa_restorer = (act)->sa_restorer;			\
>>> + })
>> What is so special about ARC sa_restorer that an application should provide
>> an specialized one?
> 
> Its the other way around. Only if application provides it's own restorer, we honor
> it, otherwise default restorer is used. This logic goes back many many years ago
> to how ARC uClibc did this and likely inherited it from the port it was copied
> from. But I don't know if say POSIX allows apps to provide their own restorer or
> not. We could very well remove it; although per other discussion if we intend to
> use the same struct sigaction for kernel/userland, the placeholder would exist and
> we could choose to just ignore it.
> 

The 'should' should be indeed 'might' in my question. And SA_RESTORER is a Linux
specific ABI not intended to be used by applications, so my question is in fact
what kind of specialized sa_restorer applications might provided that would
require the libc to honour it. 

The placeholder existence is not an issue itself (POSIX states the minimum
fields sigaction should provide, not its specific fields neither their
layout).

> 
>> Can't it follow other abi where they issue __NR_sigreturn
>> for !SA_SIGINFO or __NR_rt_sigreturn otherwise?
> 
> With Linux UAPI ABI, __NR_sigreturn doesn't exist, but your concern is about
> restorer ?

Right, so ARC at least is not pulling old compat stuff. Is it safe to just zero
the sa_restorer for sa_flags without SA_RESTORER?

> 
>> As for other architecture I do think we should hide the sa_restorer usage
>> from application.
> 
> As mentioned above, the placeholder could exist, we can choose to ignore it.
  
Vineet Gupta Dec. 20, 2018, 8:46 p.m. UTC | #14
On 12/20/18 12:06 PM, Adhemerval Zanella wrote:
> 
> 
> On 20/12/2018 17:23, Vineet Gupta wrote:
>> On 12/20/18 3:19 AM, Adhemerval Zanella wrote:
>>>>> #define SET_SA_RESTORER(kact, act)                      \
>>>>>   (kact)->sa_flags = (act)->sa_flags | SA_RESTORER;     \
>>>>>   (kact)->sa_restorer = &__default_rt_sa_restorer
>>>> +#define SET_SA_RESTORER(kact, act)				\
>>>> + ({								\
>>>> +   if (!((kact)->sa_flags & SA_RESTORER))			\
>>>> +     {								\
>>>> +       (kact)->sa_restorer = __default_rt_sa_restorer;		\
>>>> +       (kact)->sa_flags |= SA_RESTORER;			\
>>>> +     }								\
>>>> +   else							\
>>>> +     (kact)->sa_restorer = (act)->sa_restorer;			\
>>>> + })
>>> What is so special about ARC sa_restorer that an application should provide
>>> an specialized one?
>>
>> Its the other way around. Only if application provides it's own restorer, we honor
>> it, otherwise default restorer is used. This logic goes back many many years ago
>> to how ARC uClibc did this and likely inherited it from the port it was copied
>> from. But I don't know if say POSIX allows apps to provide their own restorer or
>> not. We could very well remove it; although per other discussion if we intend to
>> use the same struct sigaction for kernel/userland, the placeholder would exist and
>> we could choose to just ignore it.
>>
> 
> The 'should' should be indeed 'might' in my question. And SA_RESTORER is a Linux
> specific ABI not intended to be used by applications, 

What do u mean here. It is ABI between userspace and kernel, but not necessarily
between applications and glibc, although the same "carrier" sa_flags is in play ?
IOW, SA_RESTORER is not intended to be set by applications, but only by glibc ?

> so my question is in fact
> what kind of specialized sa_restorer applications might provided that would
> require the libc to honour it. 

Indeed, applications should not be allowed to change it. The exact signature of
default sigreturn is hardwired in signal unwinding etc etc and any deviation from
that is recipe for issues: but like I mentioned I didn't invent that interface for
ARC.

> The placeholder existence is not an issue itself (POSIX states the minimum
> fields sigaction should provide, not its specific fields neither their
> layout).

OK !

>>> Can't it follow other abi where they issue __NR_sigreturn
>>> for !SA_SIGINFO or __NR_rt_sigreturn otherwise?
>>
>> With Linux UAPI ABI, __NR_sigreturn doesn't exist, but your concern is about
>> restorer ?
> 
> Right, so ARC at least is not pulling old compat stuff. Is it safe to just zero
> the sa_restorer for sa_flags without SA_RESTORER?

Thing is ARC signal return depends on a restorer. Meaning !SA_RESTORER doesn't
effectively exist (between libc and kernel). We currently honor user provided
value, instead we could simply overwrite it with default_rt_restorer and on the
way out, zero it out to avoid leaking the glibc guts to curious users.
  
Adhemerval Zanella Dec. 21, 2018, 12:05 p.m. UTC | #15
On 20/12/2018 18:46, Vineet Gupta wrote:
> On 12/20/18 12:06 PM, Adhemerval Zanella wrote:
>>
>>
>> On 20/12/2018 17:23, Vineet Gupta wrote:
>>> On 12/20/18 3:19 AM, Adhemerval Zanella wrote:
>>>>>> #define SET_SA_RESTORER(kact, act)                      \
>>>>>>   (kact)->sa_flags = (act)->sa_flags | SA_RESTORER;     \
>>>>>>   (kact)->sa_restorer = &__default_rt_sa_restorer
>>>>> +#define SET_SA_RESTORER(kact, act)				\
>>>>> + ({								\
>>>>> +   if (!((kact)->sa_flags & SA_RESTORER))			\
>>>>> +     {								\
>>>>> +       (kact)->sa_restorer = __default_rt_sa_restorer;		\
>>>>> +       (kact)->sa_flags |= SA_RESTORER;			\
>>>>> +     }								\
>>>>> +   else							\
>>>>> +     (kact)->sa_restorer = (act)->sa_restorer;			\
>>>>> + })
>>>> What is so special about ARC sa_restorer that an application should provide
>>>> an specialized one?
>>>
>>> Its the other way around. Only if application provides it's own restorer, we honor
>>> it, otherwise default restorer is used. This logic goes back many many years ago
>>> to how ARC uClibc did this and likely inherited it from the port it was copied
>>> from. But I don't know if say POSIX allows apps to provide their own restorer or
>>> not. We could very well remove it; although per other discussion if we intend to
>>> use the same struct sigaction for kernel/userland, the placeholder would exist and
>>> we could choose to just ignore it.
>>>
>>
>> The 'should' should be indeed 'might' in my question. And SA_RESTORER is a Linux
>> specific ABI not intended to be used by applications, 
> 
> What do u mean here. It is ABI between userspace and kernel, but not necessarily
> between applications and glibc, although the same "carrier" sa_flags is in play ?
> IOW, SA_RESTORER is not intended to be set by applications, but only by glibc ?

AFAIK SA_RESTORER is meant to be used by libc or alike environments to setup
the required code to handle signal handling, it should not be up to programs
to mess up with sa_restorer to provide custom routines.

> 
>> so my question is in fact
>> what kind of specialized sa_restorer applications might provided that would
>> require the libc to honour it. 
> 
> Indeed, applications should not be allowed to change it. The exact signature of
> default sigreturn is hardwired in signal unwinding etc etc and any deviation from
> that is recipe for issues: but like I mentioned I didn't invent that interface for
> ARC.

So my suggestion is not allow user code to mess with sa_restore regardless 
if sa_flags contain SA_RESTORER.  If kernel allows it to be zero in case of
!SA_RESTORER, set it to zero as other architectures.  If it requires an
special routine, add an arch-specific one within glibc.

> 
>> The placeholder existence is not an issue itself (POSIX states the minimum
>> fields sigaction should provide, not its specific fields neither their
>> layout).
> 
> OK !
> 
>>>> Can't it follow other abi where they issue __NR_sigreturn
>>>> for !SA_SIGINFO or __NR_rt_sigreturn otherwise?
>>>
>>> With Linux UAPI ABI, __NR_sigreturn doesn't exist, but your concern is about
>>> restorer ?
>>
>> Right, so ARC at least is not pulling old compat stuff. Is it safe to just zero
>> the sa_restorer for sa_flags without SA_RESTORER?
> 
> Thing is ARC signal return depends on a restorer. Meaning !SA_RESTORER doesn't
> effectively exist (between libc and kernel). We currently honor user provided
> value, instead we could simply overwrite it with default_rt_restorer and on the
> way out, zero it out to avoid leaking the glibc guts to curious users.
> 

Yes, this is what I suggest ARC should do.
  
Florian Weimer Jan. 3, 2019, 1:10 p.m. UTC | #16
* Vineet Gupta:

> On 12/20/18 4:40 AM, Florian Weimer wrote:
>> * Adhemerval Zanella:
>>
>>> The only advantage of using a larger sigset_t from glibc standpoint is if
>>> kernel ever change it maximum number of supported signals it would not be
>>> a ABI change (it would be if glibc provided sigset_t need to be extended).
>> It's not just the kernel.  We might want to restore additional state in
>> sigsetjmp, and historically, the excess signal space in sigset_t has
>> provided a way to do that even if there is no other space left in the
>> jump buffer.
>
> And that additional state is architectural state (more FPU regs etc
> etc) or something libc generic. On both counts, that doesn't sound
> like a clean interface design !

Sure, setjmp/longjmp is quite horrible as an interface, considering that
register files do evolve.  But it's what we have in C, and it's good to
have at least some extension space there (but it could be expressed in a
better way, definitely).

Thanks,
Florian
  
Vineet Gupta Jan. 9, 2019, 9:49 p.m. UTC | #17
On 12/21/18 4:05 AM, Adhemerval Zanella wrote:
>> Thing is ARC signal return depends on a restorer. Meaning !SA_RESTORER doesn't
>> effectively exist (between libc and kernel). We currently honor user provided
>> value, instead we could simply overwrite it with default_rt_restorer and on the
>> way out, zero it out to avoid leaking the glibc guts to curious users.
>>
> Yes, this is what I suggest ARC should do.

So I was able to

(1) switch ARC to __sigset_t [2] vs. [128]

(2) create a generic patch to breakout struct sigaction into bits/sigaction-arch.h
(3) update generic __libc_sigaction to avoid itemized copy if sa_mask, sa_flags et
    al offsets matched for struct kernel_signal and struct sigaction
(4) create arc/bits/sigaction-arch.h

However it turned out to be futile as the passthru won't work anyways :-(
@act in sigaction(sig, act, oact) is a const and can't be modified in place for
sticking in sa_restorer for kernel, thus needs to be copied over anyways.

This means we have [1] but have to drop [2-4]. Oh well !
  

Patch

diff --git a/ChangeLog b/ChangeLog
index b946f57204b6..08a3ac7e8064 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -44,6 +44,18 @@ 
 	* sysdeps/arc/nofpu/math-tests-exception.h: New file.
 	* sysdeps/arc/nofpu/math-tests-rounding.h: New file.
 	* sysdeps/arc/sfp-machine.h: New file.
+	* sysdeps/unix/sysv/linux/arc/cacheflush.c: New file.
+	* sysdeps/unix/sysv/linux/arc/clone.S: New file.
+	* sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h: New file.
+	* sysdeps/unix/sysv/linux/arc/kernel-features.h: New file.
+	* sysdeps/unix/sysv/linux/arc/mmap_internal.h: New file.
+	* sysdeps/unix/sysv/linux/arc/profil-counter.h: New file.
+	* sysdeps/unix/sysv/linux/arc/pt-vfork.S: New file.
+	* sysdeps/unix/sysv/linux/arc/sigaction.c: New file.
+	* sysdeps/unix/sysv/linux/arc/syscall.S: New file.
+	* sysdeps/unix/sysv/linux/arc/sysdep.c: New file.
+	* sysdeps/unix/sysv/linux/arc/sysdep.h: New file.
+	* sysdeps/unix/sysv/linux/arc/vfork.S: New file.
 
 2018-12-17  Joseph Myers  <joseph@codesourcery.com>
 
diff --git a/sysdeps/unix/sysv/linux/arc/cacheflush.c b/sysdeps/unix/sysv/linux/arc/cacheflush.c
new file mode 100644
index 000000000000..7b14211eccf7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/cacheflush.c
@@ -0,0 +1,29 @@ 
+/* cacheflush system call for ARC Linux.
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 <sysdep.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/* Flush cache(s).  */
+int
+_flush_cache (char *addr, const int nbytes, const int op)
+{
+  return INLINE_SYSCALL (cacheflush, 3, addr, nbytes, op);
+}
+weak_alias (_flush_cache, cacheflush)
diff --git a/sysdeps/unix/sysv/linux/arc/clone.S b/sysdeps/unix/sysv/linux/arc/clone.S
new file mode 100644
index 000000000000..04f2df5ef06d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/clone.S
@@ -0,0 +1,100 @@ 
+/* clone() implementation for ARC.
+   Copyright (C) 2008-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andrew Jenner <andrew@codesourcery.com>, 2008.
+
+   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 <sysdep.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <tcb-offsets.h>
+
+#define CLONE_SETTLS		0x00080000
+
+; int clone(int (*fn)(void *), void *child_stack,
+;           int flags, void *arg, ...
+;           /* pid_t *ptid, struct user_desc *tls, pid_t *ctid */);
+;
+; NOTE: I'm assuming that the last 3 args are NOT var-args and in case all
+;	3 are not relevant, caller will nevertheless pass those as NULL.
+;       Current (Jul 2012) upstream powerpc/clone.S assumes similarly.
+;	Our LTP (from 2007) doesn't seem to have tests to prove otherwise
+
+; clone syscall in kernel (ABI: CONFIG_CLONE_BACKWARDS)
+;
+; int sys_clone(unsigned long clone_flags,
+;		unsigned long newsp,
+;		int __user *parent_tidptr,
+;		void *tls,
+;		int __user *child_tidptr)
+
+ENTRY(__clone)
+	cmp	r0, 0		; @fn can't be NULL
+	cmp.ne	r1, 0		; @child_stack can't be NULL
+	bz	.L__sys_err
+
+	; save some of the orig args
+	; r0 containg @fn will be clobbered AFTER syscall (with ret val)
+	; rest are clobbered BEFORE syscall due to different arg ordering
+	mov	r10, r0		; @fn
+	mov	r11, r3		; @args
+	mov	r12, r2		; @clone_flags
+	mov	r9,  r5		; @tls
+
+	; adjust libc args for syscall
+
+	mov 	r0, r2		; libc @flags is 1st syscall arg
+	mov	r2, r4		; libc @ptid
+	mov	r3, r5		; libc @tls
+	mov	r4, r6		; libc @ctid
+	mov	r8, __NR_clone
+	ARC_TRAP_INSN
+
+	cmp	r0, 0		; return code : 0 new process, !0 parent
+	blt	.L__sys_err2	; < 0 (signed) error
+	jnz	[blink]		; Parent returns
+
+	; ----- child starts here ---------
+
+	; Setup TP register (only recent kernels v4.19+ do that)
+	and.f	0, r12, CLONE_SETTLS
+	mov.nz	r25, r9
+
+	; child jumps off to @fn with @arg as argument, and returns here
+	jl.d	[r10]
+	mov	r0, r11
+
+	; exit() with result from @fn (already in r0)
+	mov	r8, __NR_exit
+	ARC_TRAP_INSN
+	; In case it ever came back
+	flag	1
+
+.L__sys_err:
+	mov	r0, -EINVAL
+.L__sys_err2:
+	; (1) No need to make -ve kernel error code as positive errno
+	;   __syscall_error expects the -ve error code returned by kernel
+	; (2) r0 still had orig -ve kernel error code
+	; (3) Tail call to __syscall_error so we dont have to come back
+	;     here hence instead of jmp-n-link (reg push/pop) we do jmp
+	; (4) No need to route __syscall_error via PLT, B is inherently
+	;     position independent
+	b   __syscall_error
+PSEUDO_END (__clone)
+libc_hidden_def (__clone)
+weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h b/sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h
new file mode 100644
index 000000000000..2fec69d21657
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/jmp_buf-macros.h
@@ -0,0 +1,6 @@ 
+#define JMP_BUF_SIZE		(32 + 1 + 1024/32) * 4
+#define SIGJMP_BUF_SIZE		(32 + 1 + 1024/32) * 4
+#define JMP_BUF_ALIGN		4
+#define SIGJMP_BUF_ALIGN	4
+#define MASK_WAS_SAVED_OFFSET	32 * 4
+#define SAVED_MASK_OFFSET	33 * 4
diff --git a/sysdeps/unix/sysv/linux/arc/kernel-features.h b/sysdeps/unix/sysv/linux/arc/kernel-features.h
new file mode 100644
index 000000000000..d8f667ca4759
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/kernel-features.h
@@ -0,0 +1,28 @@ 
+/* Set flags signalling availability of kernel features based on given
+   kernel version number.
+
+   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+/* The minimum supported kernel version for ARC is 3.9,
+   guaranteeing many kernel features.  */
+
+#include_next <kernel-features.h>
+
+#undef __ASSUME_CLONE_DEFAULT
+#define __ASSUME_CLONE_BACKWARDS 1
diff --git a/sysdeps/unix/sysv/linux/arc/mmap_internal.h b/sysdeps/unix/sysv/linux/arc/mmap_internal.h
new file mode 100644
index 000000000000..3c8c55d57d0e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/mmap_internal.h
@@ -0,0 +1,26 @@ 
+/* mmap - map files or devices into memory.  Linux/ARC version.
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 MMAP_ARC_INTERNAL_H
+#define MMAP_ARC_INTERNAL_H
+
+#define MMAP2_PAGE_UNIT 8192ULL	/* 8K page is default for ARC */
+
+#include_next <mmap_internal.h>
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/arc/profil-counter.h b/sysdeps/unix/sysv/linux/arc/profil-counter.h
new file mode 100644
index 000000000000..8a6a0bcf3d59
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/profil-counter.h
@@ -0,0 +1,2 @@ 
+/* We can use the ix86 version.  */
+#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
diff --git a/sysdeps/unix/sysv/linux/arc/pt-vfork.S b/sysdeps/unix/sysv/linux/arc/pt-vfork.S
new file mode 100644
index 000000000000..65cc3823ac87
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/pt-vfork.S
@@ -0,0 +1 @@ 
+#include <sysdeps/unix/sysv/linux/alpha/pt-vfork.S>
diff --git a/sysdeps/unix/sysv/linux/arc/sigaction.c b/sysdeps/unix/sysv/linux/arc/sigaction.c
new file mode 100644
index 000000000000..0a58e78f8834
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/sigaction.c
@@ -0,0 +1,69 @@ 
+/* ARC specific sigaction and signal restorer
+   Copyright (C) 1997-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 <sysdep.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/syscall.h>
+
+/*
+ * Default sigretrun stub if user doesn't specify SA_RESTORER
+ */
+static void __default_rt_sa_restorer(void)
+{
+	INTERNAL_SYSCALL_NCS(__NR_rt_sigreturn, , 0);
+}
+
+#define SA_RESTORER	0x04000000
+
+/* If @act is not NULL, change the action for @sig to @act.
+   If @oact is not NULL, put the old action for @sig in @oact.  */
+int
+__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+{
+	struct sigaction kact;
+	const struct sigaction *arg;
+
+	/*
+	 * SA_RESTORER is only relevant for act != NULL case
+	 * (!act means caller only wants to know @oact)
+	 */
+	if (act && !(act->sa_flags & SA_RESTORER)) {
+		kact.sa_restorer = __default_rt_sa_restorer;
+		kact.sa_flags = act->sa_flags | SA_RESTORER;
+
+		kact.sa_handler = act->sa_handler;
+		kact.sa_mask = act->sa_mask;
+
+		arg = &kact;
+	} else {
+		arg = act;
+	}
+
+	/*
+	 * syscall also expects sizeof(sa_mask) and asm-generic kernel syscall
+	 * ABI mandates it be 2 words (8 bytes below) although glibc defines
+	 * sigset_to be much larger (1024 / 32 == 64 bytes)
+	 */
+	return INLINE_SYSCALL(rt_sigaction, 4, sig, arg, oact, _NSIG / 8);
+}
+
+libc_hidden_def (__libc_sigaction)
+
+#include <nptl/sigaction.c>
diff --git a/sysdeps/unix/sysv/linux/arc/syscall.S b/sysdeps/unix/sysv/linux/arc/syscall.S
new file mode 100644
index 000000000000..8f76fa43e95f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/syscall.S
@@ -0,0 +1,38 @@ 
+/* syscall - indirect system call.
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 <sysdep.h>
+
+ENTRY (syscall)
+	mov_s	r8, r0
+	mov_s	r0, r1
+	mov_s	r1, r2
+	mov_s	r2, r3
+	mov_s	r3, r4
+#ifdef __ARC700__
+	mov	r4, r5
+	mov	r5, r6
+#else
+	mov_s	r4, r5
+	mov_s	r5, r6
+#endif
+
+	ARC_TRAP_INSN
+	brhi	r0, -1024, .Lcall_syscall_err
+	j	[blink]
+PSEUDO_END (syscall)
diff --git a/sysdeps/unix/sysv/linux/arc/sysdep.c b/sysdeps/unix/sysv/linux/arc/sysdep.c
new file mode 100644
index 000000000000..d9bcc305b846
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/sysdep.c
@@ -0,0 +1,33 @@ 
+/* ARC wrapper for setting errno
+   Copyright (C) 1997-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 <sysdep.h>
+#include <errno.h>
+
+/* All syscall handler come here to avoid generated code bloat due to
+ * GOT reference  to errno_location or it's equivalent
+ */
+int __syscall_error(int err_no)
+{
+	__set_errno(-err_no);
+	return -1;
+}
+
+#if IS_IN (libc)
+hidden_def (__syscall_error)
+#endif
diff --git a/sysdeps/unix/sysv/linux/arc/sysdep.h b/sysdeps/unix/sysv/linux/arc/sysdep.h
new file mode 100644
index 000000000000..39d1f03c3710
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/sysdep.h
@@ -0,0 +1,259 @@ 
+/* Assembler macros for ARC.
+   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 _LINUX_ARC_SYSDEP_H
+#define _LINUX_ARC_SYSDEP_H 1
+
+#include <asm/unistd.h>
+#include <sysdeps/arc/sysdep.h>
+#include <sysdeps/unix/sysv/linux/generic/sysdep.h>
+
+/* For RTLD_PRIVATE_ERRNO.  */
+#include <dl-sysdep.h>
+
+#include <tls.h>
+
+#undef SYS_ify
+#define SYS_ify(syscall_name)   __NR_##syscall_name
+
+#ifdef __ASSEMBLER__
+
+/* This is a "normal" system call stub: if there is an error,
+   it returns -1 and sets errno.  */
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)			\
+  PSEUDO_NOERRNO(name, syscall_name, args)	ASM_LINE_SEP	\
+    brhi   r0, -1024, .Lcall_syscall_err	ASM_LINE_SEP
+
+#define ret	j  [blink]
+
+# undef PSEUDO_END
+# define PSEUDO_END(name)					\
+  SYSCALL_ERROR_HANDLER				ASM_LINE_SEP	\
+  END (name)
+
+/* --------- helper for SYSCALL_NOERRNO ----------- */
+
+/* This kind of system call stub never returns an error.
+   We return the return value register to the caller unexamined.  */
+
+# undef PSEUDO_NOERRNO
+# define PSEUDO_NOERRNO(name, syscall_name, args)		\
+  .text						ASM_LINE_SEP	\
+  ENTRY (name)					ASM_LINE_SEP	\
+    DO_CALL (syscall_name, args)		ASM_LINE_SEP	\
+
+/* return the return value register unexamined
+ * r0 is both syscall return reg and function return reg, so no need to do
+ * anything
+ */
+# define ret_NOERRNO						\
+  j_s  [blink]		ASM_LINE_SEP
+
+# undef PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name)				\
+  END (name)
+
+/* --------- helper for SYSCALL_ERRVAL ----------- */
+
+/* This kind of system call stub returns the errno code as its return
+   value, or zero for success.  We may massage the kernel's return value
+   to meet that ABI, but we never set errno here.  */
+
+# undef PSEUDO_ERRVAL
+# define PSEUDO_ERRVAL(name, syscall_name, args)		\
+  PSEUDO_NOERRNO(name, syscall_name, args)	ASM_LINE_SEP
+
+/* don't set errno, return kernel error (in errno form) or zero */
+# define ret_ERRVAL						\
+  rsub   r0, r0, 0				ASM_LINE_SEP	\
+  ret_NOERRNO
+
+# undef PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name)				\
+  END (name)
+
+
+/* To reduce the code footprint, we confine the actual errno access
+ * to single place in __syscall_error()
+ * this takes raw kernel error value, sets errno and returns -1
+ */
+#if IS_IN (libc)
+#define CALL_ERRNO_SETTER_C	bl     PLTJMP(HIDDEN_JUMPTARGET(__syscall_error))
+#else
+#define CALL_ERRNO_SETTER_C	bl     PLTJMP(__syscall_error)
+#endif
+
+# define SYSCALL_ERROR_HANDLER					\
+.Lcall_syscall_err:				ASM_LINE_SEP	\
+    st.a   blink, [sp, -4]			ASM_LINE_SEP	\
+    cfi_adjust_cfa_offset (4)			ASM_LINE_SEP	\
+    cfi_rel_offset (blink, 0)			ASM_LINE_SEP	\
+    CALL_ERRNO_SETTER_C				ASM_LINE_SEP	\
+    ld.ab  blink, [sp, 4]			ASM_LINE_SEP	\
+    cfi_adjust_cfa_offset (-4)			ASM_LINE_SEP	\
+    cfi_restore (blink)				ASM_LINE_SEP	\
+    j      [blink]
+
+# define DO_CALL(syscall_name, args)				\
+    mov    r8, SYS_ify (syscall_name)		ASM_LINE_SEP	\
+    ARC_TRAP_INSN				ASM_LINE_SEP
+
+#define ARC_TRAP_INSN	trap_s 0
+
+#else  /* !__ASSEMBLER__ */
+
+# define SINGLE_THREAD_BY_GLOBAL		1
+
+/* In order to get __set_errno() definition in INLINE_SYSCALL.  */
+#include <errno.h>
+
+extern int __syscall_error (int);
+
+#if IS_IN (libc)
+hidden_proto (__syscall_error)
+#define CALL_ERRNO_SETTER   "bl   __syscall_error    \n\t"
+#else
+#define CALL_ERRNO_SETTER   "bl   __syscall_error@plt    \n\t"
+#endif
+
+
+/* Define a macro which expands into the inline wrapper code for a system
+   call.  */
+#undef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr_args, args...)				\
+({									\
+	register int __res __asm__("r0");				\
+	__res = INTERNAL_SYSCALL_NCS(__NR_##name, , nr_args, args);	\
+	if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P ((__res), ), 0))	\
+	{								\
+		asm volatile ("st.a blink, [sp, -4] \n\t"		\
+			      CALL_ERRNO_SETTER				\
+			      "ld.ab blink, [sp, 4] \n\t"		\
+			      :"+r" (__res)				\
+			      :						\
+			      :"r1","r2","r3","r4","r5","r6",		\
+			       "r7","r8","r9","r10","r11","r12");	\
+	}								\
+	__res;								\
+})
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+#undef INTERNAL_SYSCALL_ERRNO
+# define INTERNAL_SYSCALL_ERRNO(val, err)    (-(val))
+
+/* -1 to -1023 are valid errno values */
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err)	\
+	((unsigned int) (val) > -1024U)
+
+#define ARC_TRAP_INSN	"trap_s 0	\n\t"
+
+#undef INTERNAL_SYSCALL_RAW
+#define INTERNAL_SYSCALL_RAW(name, err, nr_args, args...)	\
+({							\
+	/* Per ABI, r0 is 1st arg and return reg */	\
+	register int __ret __asm__("r0");		\
+	register int _sys_num __asm__("r8");		\
+							\
+	LOAD_ARGS_##nr_args (name, args)		\
+							\
+        __asm__ volatile (				\
+		ARC_TRAP_INSN				\
+		: "+r" (__ret)				\
+		: "r"(_sys_num) ASM_ARGS_##nr_args	\
+		: "memory");				\
+                                                        \
+	__ret;						\
+})
+
+/* Macros for setting up inline __asm__ input regs */
+#define ASM_ARGS_0
+#define ASM_ARGS_1	ASM_ARGS_0, "r" (__ret)
+#define ASM_ARGS_2	ASM_ARGS_1, "r" (_arg2)
+#define ASM_ARGS_3	ASM_ARGS_2, "r" (_arg3)
+#define ASM_ARGS_4	ASM_ARGS_3, "r" (_arg4)
+#define ASM_ARGS_5	ASM_ARGS_4, "r" (_arg5)
+#define ASM_ARGS_6	ASM_ARGS_5, "r" (_arg6)
+#define ASM_ARGS_7	ASM_ARGS_6, "r" (_arg7)
+
+/* Macros for converting sys-call wrapper args into sys call args */
+#define LOAD_ARGS_0(nm, arg)					\
+	_sys_num = (int) (nm);
+
+#define LOAD_ARGS_1(nm, arg1) 					\
+	__ret = (int) (arg1);					\
+	LOAD_ARGS_0 (nm, arg1)
+
+/*
+ * Note that the use of _tmpX might look superflous, however it is needed
+ * to ensure that register variables are not clobbered if arg happens to be
+ * a function call itself. e.g. sched_setaffinity() calling getpid() for arg2
+ *
+ * Also this specific order of recursive calling is important to segregate
+ * the tmp args evaluation (function call case described above) and assigment
+ * of register variables
+ */
+#define LOAD_ARGS_2(nm, arg1, arg2)				\
+	int _tmp2 = (int) (arg2);				\
+	LOAD_ARGS_1 (nm, arg1)					\
+	register int _arg2 __asm__ ("r1") = _tmp2;
+
+#define LOAD_ARGS_3(nm, arg1, arg2, arg3)			\
+	int _tmp3 = (int) (arg3);				\
+	LOAD_ARGS_2 (nm, arg1, arg2)				\
+	register int _arg3 __asm__ ("r2") = _tmp3;
+
+#define LOAD_ARGS_4(nm, arg1, arg2, arg3, arg4)			\
+	int _tmp4 = (int) (arg4);				\
+	LOAD_ARGS_3 (nm, arg1, arg2, arg3)			\
+	register int _arg4 __asm__ ("r3") = _tmp4;
+
+#define LOAD_ARGS_5(nm, arg1, arg2, arg3, arg4, arg5)		\
+	int _tmp5 = (int) (arg5);				\
+	LOAD_ARGS_4 (nm, arg1, arg2, arg3, arg4)		\
+	register int _arg5 __asm__ ("r4") = _tmp5;
+
+#define LOAD_ARGS_6(nm,  arg1, arg2, arg3, arg4, arg5, arg6)	\
+	int _tmp6 = (int) (arg6);				\
+	LOAD_ARGS_5 (nm, arg1, arg2, arg3, arg4, arg5)		\
+	register int _arg6 __asm__ ("r5") = _tmp6;
+
+#define LOAD_ARGS_7(nm, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
+	int _tmp7 = (int) (arg7);				\
+	LOAD_ARGS_6 (nm, arg1, arg2, arg3, arg4, arg5, arg6)	\
+	register int _arg7 __asm__ ("r6") = _tmp7;
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+	INTERNAL_SYSCALL_RAW(SYS_ify(name), err, nr, args)
+
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
+	INTERNAL_SYSCALL_RAW(number, err, nr, args)
+
+/* Pointer mangling not yet supported  */
+# define PTR_MANGLE(var) (void) (var)
+# define PTR_DEMANGLE(var) (void) (var)
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* linux/arc/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/arc/vfork.S b/sysdeps/unix/sysv/linux/arc/vfork.S
new file mode 100644
index 000000000000..6d7f63c9900b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arc/vfork.S
@@ -0,0 +1,42 @@ 
+/* vfork for ARC Linux.
+   Copyright (C) 2005-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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 <sysdep.h>
+#include <tcb-offsets.h>
+#define _SIGNAL_H
+#include <bits/signum.h>       /* For SIGCHLD */
+
+#define CLONE_VM		0x00000100
+#define CLONE_VFORK		0x00004000
+#define CLONE_FLAGS_FOR_VFORK	(CLONE_VM|CLONE_VFORK|SIGCHLD)
+
+ENTRY(__vfork)
+	mov	r0, CLONE_FLAGS_FOR_VFORK
+	mov_s	r1, sp
+	mov	r8, __NR_clone
+	ARC_TRAP_INSN
+
+	cmp	r0, 0
+	jge	[blink]	; child continues
+
+	b   __syscall_error
+PSEUDO_END (__vfork)
+libc_hidden_def (__vfork)
+
+weak_alias (__vfork, vfork)