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_