xref: /OK3568_Linux_fs/kernel/arch/x86/include/asm/xen/interface_64.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef _ASM_X86_XEN_INTERFACE_64_H
3*4882a593Smuzhiyun #define _ASM_X86_XEN_INTERFACE_64_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun /*
6*4882a593Smuzhiyun  * 64-bit segment selectors
7*4882a593Smuzhiyun  * These flat segments are in the Xen-private section of every GDT. Since these
8*4882a593Smuzhiyun  * are also present in the initial GDT, many OSes will be able to avoid
9*4882a593Smuzhiyun  * installing their own GDT.
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #define FLAT_RING3_CS32 0xe023  /* GDT index 260 */
13*4882a593Smuzhiyun #define FLAT_RING3_CS64 0xe033  /* GDT index 261 */
14*4882a593Smuzhiyun #define FLAT_RING3_DS32 0xe02b  /* GDT index 262 */
15*4882a593Smuzhiyun #define FLAT_RING3_DS64 0x0000  /* NULL selector */
16*4882a593Smuzhiyun #define FLAT_RING3_SS32 0xe02b  /* GDT index 262 */
17*4882a593Smuzhiyun #define FLAT_RING3_SS64 0xe02b  /* GDT index 262 */
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define FLAT_KERNEL_DS64 FLAT_RING3_DS64
20*4882a593Smuzhiyun #define FLAT_KERNEL_DS32 FLAT_RING3_DS32
21*4882a593Smuzhiyun #define FLAT_KERNEL_DS   FLAT_KERNEL_DS64
22*4882a593Smuzhiyun #define FLAT_KERNEL_CS64 FLAT_RING3_CS64
23*4882a593Smuzhiyun #define FLAT_KERNEL_CS32 FLAT_RING3_CS32
24*4882a593Smuzhiyun #define FLAT_KERNEL_CS   FLAT_KERNEL_CS64
25*4882a593Smuzhiyun #define FLAT_KERNEL_SS64 FLAT_RING3_SS64
26*4882a593Smuzhiyun #define FLAT_KERNEL_SS32 FLAT_RING3_SS32
27*4882a593Smuzhiyun #define FLAT_KERNEL_SS   FLAT_KERNEL_SS64
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #define FLAT_USER_DS64 FLAT_RING3_DS64
30*4882a593Smuzhiyun #define FLAT_USER_DS32 FLAT_RING3_DS32
31*4882a593Smuzhiyun #define FLAT_USER_DS   FLAT_USER_DS64
32*4882a593Smuzhiyun #define FLAT_USER_CS64 FLAT_RING3_CS64
33*4882a593Smuzhiyun #define FLAT_USER_CS32 FLAT_RING3_CS32
34*4882a593Smuzhiyun #define FLAT_USER_CS   FLAT_USER_CS64
35*4882a593Smuzhiyun #define FLAT_USER_SS64 FLAT_RING3_SS64
36*4882a593Smuzhiyun #define FLAT_USER_SS32 FLAT_RING3_SS32
37*4882a593Smuzhiyun #define FLAT_USER_SS   FLAT_USER_SS64
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define __HYPERVISOR_VIRT_START 0xFFFF800000000000
40*4882a593Smuzhiyun #define __HYPERVISOR_VIRT_END   0xFFFF880000000000
41*4882a593Smuzhiyun #define __MACH2PHYS_VIRT_START  0xFFFF800000000000
42*4882a593Smuzhiyun #define __MACH2PHYS_VIRT_END    0xFFFF804000000000
43*4882a593Smuzhiyun #define __MACH2PHYS_SHIFT       3
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /*
46*4882a593Smuzhiyun  * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
47*4882a593Smuzhiyun  *  @which == SEGBASE_*  ;  @base == 64-bit base address
48*4882a593Smuzhiyun  * Returns 0 on success.
49*4882a593Smuzhiyun  */
50*4882a593Smuzhiyun #define SEGBASE_FS          0
51*4882a593Smuzhiyun #define SEGBASE_GS_USER     1
52*4882a593Smuzhiyun #define SEGBASE_GS_KERNEL   2
53*4882a593Smuzhiyun #define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun /*
56*4882a593Smuzhiyun  * int HYPERVISOR_iret(void)
57*4882a593Smuzhiyun  * All arguments are on the kernel stack, in the following format.
58*4882a593Smuzhiyun  * Never returns if successful. Current kernel context is lost.
59*4882a593Smuzhiyun  * The saved CS is mapped as follows:
60*4882a593Smuzhiyun  *   RING0 -> RING3 kernel mode.
61*4882a593Smuzhiyun  *   RING1 -> RING3 kernel mode.
62*4882a593Smuzhiyun  *   RING2 -> RING3 kernel mode.
63*4882a593Smuzhiyun  *   RING3 -> RING3 user mode.
64*4882a593Smuzhiyun  * However RING0 indicates that the guest kernel should return to iteself
65*4882a593Smuzhiyun  * directly with
66*4882a593Smuzhiyun  *      orb   $3,1*8(%rsp)
67*4882a593Smuzhiyun  *      iretq
68*4882a593Smuzhiyun  * If flags contains VGCF_in_syscall:
69*4882a593Smuzhiyun  *   Restore RAX, RIP, RFLAGS, RSP.
70*4882a593Smuzhiyun  *   Discard R11, RCX, CS, SS.
71*4882a593Smuzhiyun  * Otherwise:
72*4882a593Smuzhiyun  *   Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
73*4882a593Smuzhiyun  * All other registers are saved on hypercall entry and restored to user.
74*4882a593Smuzhiyun  */
75*4882a593Smuzhiyun /* Guest exited in SYSCALL context? Return to guest with SYSRET? */
76*4882a593Smuzhiyun #define _VGCF_in_syscall 8
77*4882a593Smuzhiyun #define VGCF_in_syscall  (1<<_VGCF_in_syscall)
78*4882a593Smuzhiyun #define VGCF_IN_SYSCALL  VGCF_in_syscall
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun #ifndef __ASSEMBLY__
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun struct iret_context {
83*4882a593Smuzhiyun     /* Top of stack (%rsp at point of hypercall). */
84*4882a593Smuzhiyun     uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
85*4882a593Smuzhiyun     /* Bottom of iret stack frame. */
86*4882a593Smuzhiyun };
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
89*4882a593Smuzhiyun /* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */
90*4882a593Smuzhiyun #define __DECL_REG(name) union { \
91*4882a593Smuzhiyun     uint64_t r ## name, e ## name; \
92*4882a593Smuzhiyun     uint32_t _e ## name; \
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun #else
95*4882a593Smuzhiyun /* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */
96*4882a593Smuzhiyun #define __DECL_REG(name) uint64_t r ## name
97*4882a593Smuzhiyun #endif
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun struct cpu_user_regs {
100*4882a593Smuzhiyun     uint64_t r15;
101*4882a593Smuzhiyun     uint64_t r14;
102*4882a593Smuzhiyun     uint64_t r13;
103*4882a593Smuzhiyun     uint64_t r12;
104*4882a593Smuzhiyun     __DECL_REG(bp);
105*4882a593Smuzhiyun     __DECL_REG(bx);
106*4882a593Smuzhiyun     uint64_t r11;
107*4882a593Smuzhiyun     uint64_t r10;
108*4882a593Smuzhiyun     uint64_t r9;
109*4882a593Smuzhiyun     uint64_t r8;
110*4882a593Smuzhiyun     __DECL_REG(ax);
111*4882a593Smuzhiyun     __DECL_REG(cx);
112*4882a593Smuzhiyun     __DECL_REG(dx);
113*4882a593Smuzhiyun     __DECL_REG(si);
114*4882a593Smuzhiyun     __DECL_REG(di);
115*4882a593Smuzhiyun     uint32_t error_code;    /* private */
116*4882a593Smuzhiyun     uint32_t entry_vector;  /* private */
117*4882a593Smuzhiyun     __DECL_REG(ip);
118*4882a593Smuzhiyun     uint16_t cs, _pad0[1];
119*4882a593Smuzhiyun     uint8_t  saved_upcall_mask;
120*4882a593Smuzhiyun     uint8_t  _pad1[3];
121*4882a593Smuzhiyun     __DECL_REG(flags);      /* rflags.IF == !saved_upcall_mask */
122*4882a593Smuzhiyun     __DECL_REG(sp);
123*4882a593Smuzhiyun     uint16_t ss, _pad2[3];
124*4882a593Smuzhiyun     uint16_t es, _pad3[3];
125*4882a593Smuzhiyun     uint16_t ds, _pad4[3];
126*4882a593Smuzhiyun     uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base.     */
127*4882a593Smuzhiyun     uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs);
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun #undef __DECL_REG
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun #define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12)
134*4882a593Smuzhiyun #define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12)
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun struct arch_vcpu_info {
137*4882a593Smuzhiyun     unsigned long cr2;
138*4882a593Smuzhiyun     unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
139*4882a593Smuzhiyun };
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun typedef unsigned long xen_callback_t;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun #define XEN_CALLBACK(__cs, __rip)				\
144*4882a593Smuzhiyun 	((unsigned long)(__rip))
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun #endif /* !__ASSEMBLY__ */
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun #endif /* _ASM_X86_XEN_INTERFACE_64_H */
150