github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/vdso/syscalls.h (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // System call support for the VDSO.
    16  //
    17  // Provides fallback system call interfaces for getcpu()
    18  // and clock_gettime().
    19  
    20  #ifndef VDSO_SYSCALLS_H_
    21  #define VDSO_SYSCALLS_H_
    22  
    23  #include <asm/unistd.h>
    24  #include <errno.h>
    25  #include <fcntl.h>
    26  #include <stddef.h>
    27  #include <sys/types.h>
    28  
    29  #define __stringify_1(x...) #x
    30  #define __stringify(x...) __stringify_1(x)
    31  
    32  namespace vdso {
    33  
    34  #if __x86_64__
    35  
    36  struct getcpu_cache;
    37  
    38  static inline int sys_clock_gettime(clockid_t clock, struct timespec* ts) {
    39    int num = __NR_clock_gettime;
    40    asm volatile("syscall\n"
    41                 : "+a"(num)
    42                 : "D"(clock), "S"(ts)
    43                 : "rcx", "r11", "memory");
    44    return num;
    45  }
    46  
    47  static inline int sys_getcpu(unsigned* cpu, unsigned* node,
    48                               struct getcpu_cache* cache) {
    49    int num = __NR_getcpu;
    50    asm volatile("syscall\n"
    51                 : "+a"(num)
    52                 : "D"(cpu), "S"(node), "d"(cache)
    53                 : "rcx", "r11", "memory");
    54    return num;
    55  }
    56  
    57  static inline void sys_rt_sigreturn(void) {
    58    asm volatile("movl $" __stringify(__NR_rt_sigreturn)", %eax \n"
    59                 "syscall \n");
    60  }
    61  
    62  #elif __aarch64__
    63  
    64  static inline int sys_clock_gettime(clockid_t _clkid, struct timespec* _ts) {
    65    register struct timespec* ts asm("x1") = _ts;
    66    register clockid_t clkid asm("x0") = _clkid;
    67    register long ret asm("x0");
    68    register long nr asm("x8") = __NR_clock_gettime;
    69  
    70    asm volatile("svc #0\n"
    71                 : "=r"(ret)
    72                 : "r"(clkid), "r"(ts), "r"(nr)
    73                 : "memory");
    74    return ret;
    75  }
    76  
    77  static inline int sys_clock_getres(clockid_t _clkid, struct timespec* _ts) {
    78    register struct timespec* ts asm("x1") = _ts;
    79    register clockid_t clkid asm("x0") = _clkid;
    80    register long ret asm("x0");
    81    register long nr asm("x8") = __NR_clock_getres;
    82  
    83    asm volatile("svc #0\n"
    84                 : "=r"(ret)
    85                 : "r"(clkid), "r"(ts), "r"(nr)
    86                 : "memory");
    87    return ret;
    88  }
    89  
    90  static inline void sys_rt_sigreturn(void) {
    91    asm volatile("mov x8, #" __stringify(__NR_rt_sigreturn)" \n"
    92                 "svc #0 \n");
    93  }
    94  
    95  #else
    96  #error "unsupported architecture"
    97  #endif
    98  }  // namespace vdso
    99  
   100  #endif  // VDSO_SYSCALLS_H_