Added whitelisting to MSR read/write code
[akaros.git] / kern / arch / x86 / ros / syscall64.h
1 #pragma once
2
3 #ifndef ROS_INC_ARCH_SYSCALL_H
4 #error "Do not include include ros/arch/syscall64.h directly"
5 #endif
6
7 #ifndef ROS_KERNEL
8
9 #include <sys/types.h>
10 #include <stdint.h>
11 #include <ros/common.h>
12 #include <ros/arch/mmu.h>
13 #include <assert.h>
14
15 static inline intreg_t __syscall_sysenter(uintreg_t a0, uintreg_t a1)
16 {
17         intreg_t ret = 0;
18         long dummy;
19         /* we're calling using the amd function call abi.  this asm and the kernel
20          * will save the callee-saved state.  We'll use the clobber list to force
21          * the compiler to save caller-saved state.  As with uthread code, you need
22          * to make sure you have one ABI-compliant, non-inlined function call
23          * between any floating point ops and this.
24          *
25          * Note that syscall doesn't save the stack pointer - using rdx for that.
26          * The kernel will restore it for us. */
27         asm volatile ("movq %%rsp, %%rdx;       "
28                       "syscall;                 "
29                       : "=a"(ret), "=D"(dummy), "=S"(dummy) /* force D, S clobber */
30                       : "D"(a0), "S"(a1)
31                       : "cc", "memory", "rcx", "rdx", "r8", "r9", "r10", "r11");
32         return ret;
33 }
34
35 static inline intreg_t __syscall_trap(uintreg_t a0, uintreg_t a1)
36 {
37         intreg_t ret;
38         /* If you change this, change pop_user_ctx() */
39         asm volatile("int %1"
40                      : "=a" (ret)
41                      : "i" (T_SYSCALL),
42                        "D" (a0),
43                        "S" (a1)
44                      : "cc", "memory");
45         return ret;
46 }
47
48 /* The kernel has a fast path for setting the fs base, used for TLS changes on
49  * machines that can't do it from user space.  The magic value for rdi (D) is a
50  * non-canonical address, which should never be a legitamate syscall. */
51 static inline void __fastcall_setfsbase(uintptr_t fsbase)
52 {
53         long dummy;
54         asm volatile ("syscall" : "=D"(dummy), "=S"(dummy) /* force D, S clobber */
55                                 : "D"(FASTCALL_SETFSBASE), "S"(fsbase)
56                                 : "rax", "r11", "rcx", "rdx", "memory");
57 }
58
59 #endif