xref: /qemu/include/hw/xen/interface/arch-x86/xen-x86_64.h (revision 50c88402ca599e577f025e78a4380431be2b3f6d)
1*50c88402SJoao Martins /******************************************************************************
2*50c88402SJoao Martins  * xen-x86_64.h
3*50c88402SJoao Martins  *
4*50c88402SJoao Martins  * Guest OS interface to x86 64-bit Xen.
5*50c88402SJoao Martins  *
6*50c88402SJoao Martins  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*50c88402SJoao Martins  * of this software and associated documentation files (the "Software"), to
8*50c88402SJoao Martins  * deal in the Software without restriction, including without limitation the
9*50c88402SJoao Martins  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*50c88402SJoao Martins  * sell copies of the Software, and to permit persons to whom the Software is
11*50c88402SJoao Martins  * furnished to do so, subject to the following conditions:
12*50c88402SJoao Martins  *
13*50c88402SJoao Martins  * The above copyright notice and this permission notice shall be included in
14*50c88402SJoao Martins  * all copies or substantial portions of the Software.
15*50c88402SJoao Martins  *
16*50c88402SJoao Martins  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*50c88402SJoao Martins  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*50c88402SJoao Martins  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*50c88402SJoao Martins  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*50c88402SJoao Martins  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*50c88402SJoao Martins  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22*50c88402SJoao Martins  * DEALINGS IN THE SOFTWARE.
23*50c88402SJoao Martins  *
24*50c88402SJoao Martins  * Copyright (c) 2004-2006, K A Fraser
25*50c88402SJoao Martins  */
26*50c88402SJoao Martins 
27*50c88402SJoao Martins #ifndef __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__
28*50c88402SJoao Martins #define __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__
29*50c88402SJoao Martins 
30*50c88402SJoao Martins /*
31*50c88402SJoao Martins  * Hypercall interface:
32*50c88402SJoao Martins  *  Input:  %rdi, %rsi, %rdx, %r10, %r8, %r9 (arguments 1-6)
33*50c88402SJoao Martins  *  Output: %rax
34*50c88402SJoao Martins  * Access is via hypercall page (set up by guest loader or via a Xen MSR):
35*50c88402SJoao Martins  *  call hypercall_page + hypercall-number * 32
36*50c88402SJoao Martins  * Clobbered: argument registers (e.g., 2-arg hypercall clobbers %rdi,%rsi)
37*50c88402SJoao Martins  */
38*50c88402SJoao Martins 
39*50c88402SJoao Martins /*
40*50c88402SJoao Martins  * 64-bit segment selectors
41*50c88402SJoao Martins  * These flat segments are in the Xen-private section of every GDT. Since these
42*50c88402SJoao Martins  * are also present in the initial GDT, many OSes will be able to avoid
43*50c88402SJoao Martins  * installing their own GDT.
44*50c88402SJoao Martins  */
45*50c88402SJoao Martins 
46*50c88402SJoao Martins #define FLAT_RING3_CS32 0xe023  /* GDT index 260 */
47*50c88402SJoao Martins #define FLAT_RING3_CS64 0xe033  /* GDT index 262 */
48*50c88402SJoao Martins #define FLAT_RING3_DS32 0xe02b  /* GDT index 261 */
49*50c88402SJoao Martins #define FLAT_RING3_DS64 0x0000  /* NULL selector */
50*50c88402SJoao Martins #define FLAT_RING3_SS32 0xe02b  /* GDT index 261 */
51*50c88402SJoao Martins #define FLAT_RING3_SS64 0xe02b  /* GDT index 261 */
52*50c88402SJoao Martins 
53*50c88402SJoao Martins #define FLAT_KERNEL_DS64 FLAT_RING3_DS64
54*50c88402SJoao Martins #define FLAT_KERNEL_DS32 FLAT_RING3_DS32
55*50c88402SJoao Martins #define FLAT_KERNEL_DS   FLAT_KERNEL_DS64
56*50c88402SJoao Martins #define FLAT_KERNEL_CS64 FLAT_RING3_CS64
57*50c88402SJoao Martins #define FLAT_KERNEL_CS32 FLAT_RING3_CS32
58*50c88402SJoao Martins #define FLAT_KERNEL_CS   FLAT_KERNEL_CS64
59*50c88402SJoao Martins #define FLAT_KERNEL_SS64 FLAT_RING3_SS64
60*50c88402SJoao Martins #define FLAT_KERNEL_SS32 FLAT_RING3_SS32
61*50c88402SJoao Martins #define FLAT_KERNEL_SS   FLAT_KERNEL_SS64
62*50c88402SJoao Martins 
63*50c88402SJoao Martins #define FLAT_USER_DS64 FLAT_RING3_DS64
64*50c88402SJoao Martins #define FLAT_USER_DS32 FLAT_RING3_DS32
65*50c88402SJoao Martins #define FLAT_USER_DS   FLAT_USER_DS64
66*50c88402SJoao Martins #define FLAT_USER_CS64 FLAT_RING3_CS64
67*50c88402SJoao Martins #define FLAT_USER_CS32 FLAT_RING3_CS32
68*50c88402SJoao Martins #define FLAT_USER_CS   FLAT_USER_CS64
69*50c88402SJoao Martins #define FLAT_USER_SS64 FLAT_RING3_SS64
70*50c88402SJoao Martins #define FLAT_USER_SS32 FLAT_RING3_SS32
71*50c88402SJoao Martins #define FLAT_USER_SS   FLAT_USER_SS64
72*50c88402SJoao Martins 
73*50c88402SJoao Martins #define __HYPERVISOR_VIRT_START 0xFFFF800000000000
74*50c88402SJoao Martins #define __HYPERVISOR_VIRT_END   0xFFFF880000000000
75*50c88402SJoao Martins #define __MACH2PHYS_VIRT_START  0xFFFF800000000000
76*50c88402SJoao Martins #define __MACH2PHYS_VIRT_END    0xFFFF804000000000
77*50c88402SJoao Martins 
78*50c88402SJoao Martins #ifndef HYPERVISOR_VIRT_START
79*50c88402SJoao Martins #define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START)
80*50c88402SJoao Martins #define HYPERVISOR_VIRT_END   xen_mk_ulong(__HYPERVISOR_VIRT_END)
81*50c88402SJoao Martins #endif
82*50c88402SJoao Martins 
83*50c88402SJoao Martins #define MACH2PHYS_VIRT_START  xen_mk_ulong(__MACH2PHYS_VIRT_START)
84*50c88402SJoao Martins #define MACH2PHYS_VIRT_END    xen_mk_ulong(__MACH2PHYS_VIRT_END)
85*50c88402SJoao Martins #define MACH2PHYS_NR_ENTRIES  ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3)
86*50c88402SJoao Martins #ifndef machine_to_phys_mapping
87*50c88402SJoao Martins #define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
88*50c88402SJoao Martins #endif
89*50c88402SJoao Martins 
90*50c88402SJoao Martins /*
91*50c88402SJoao Martins  * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
92*50c88402SJoao Martins  *  @which == SEGBASE_*  ;  @base == 64-bit base address
93*50c88402SJoao Martins  * Returns 0 on success.
94*50c88402SJoao Martins  */
95*50c88402SJoao Martins #define SEGBASE_FS          0
96*50c88402SJoao Martins #define SEGBASE_GS_USER     1
97*50c88402SJoao Martins #define SEGBASE_GS_KERNEL   2
98*50c88402SJoao Martins #define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
99*50c88402SJoao Martins 
100*50c88402SJoao Martins /*
101*50c88402SJoao Martins  * int HYPERVISOR_iret(void)
102*50c88402SJoao Martins  * All arguments are on the kernel stack, in the following format.
103*50c88402SJoao Martins  * Never returns if successful. Current kernel context is lost.
104*50c88402SJoao Martins  * The saved CS is mapped as follows:
105*50c88402SJoao Martins  *   RING0 -> RING3 kernel mode.
106*50c88402SJoao Martins  *   RING1 -> RING3 kernel mode.
107*50c88402SJoao Martins  *   RING2 -> RING3 kernel mode.
108*50c88402SJoao Martins  *   RING3 -> RING3 user mode.
109*50c88402SJoao Martins  * However RING0 indicates that the guest kernel should return to iteself
110*50c88402SJoao Martins  * directly with
111*50c88402SJoao Martins  *      orb   $3,1*8(%rsp)
112*50c88402SJoao Martins  *      iretq
113*50c88402SJoao Martins  * If flags contains VGCF_in_syscall:
114*50c88402SJoao Martins  *   Restore RAX, RIP, RFLAGS, RSP.
115*50c88402SJoao Martins  *   Discard R11, RCX, CS, SS.
116*50c88402SJoao Martins  * Otherwise:
117*50c88402SJoao Martins  *   Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
118*50c88402SJoao Martins  * All other registers are saved on hypercall entry and restored to user.
119*50c88402SJoao Martins  */
120*50c88402SJoao Martins /* Guest exited in SYSCALL context? Return to guest with SYSRET? */
121*50c88402SJoao Martins #define _VGCF_in_syscall 8
122*50c88402SJoao Martins #define VGCF_in_syscall  (1<<_VGCF_in_syscall)
123*50c88402SJoao Martins #define VGCF_IN_SYSCALL  VGCF_in_syscall
124*50c88402SJoao Martins 
125*50c88402SJoao Martins #ifndef __ASSEMBLY__
126*50c88402SJoao Martins 
127*50c88402SJoao Martins struct iret_context {
128*50c88402SJoao Martins     /* Top of stack (%rsp at point of hypercall). */
129*50c88402SJoao Martins     uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
130*50c88402SJoao Martins     /* Bottom of iret stack frame. */
131*50c88402SJoao Martins };
132*50c88402SJoao Martins 
133*50c88402SJoao Martins #if defined(__XEN__) || defined(__XEN_TOOLS__)
134*50c88402SJoao Martins /* Anonymous unions include all permissible names (e.g., al/ah/ax/eax/rax). */
135*50c88402SJoao Martins #define __DECL_REG_LOHI(which) union { \
136*50c88402SJoao Martins     uint64_t r ## which ## x; \
137*50c88402SJoao Martins     uint32_t e ## which ## x; \
138*50c88402SJoao Martins     uint16_t which ## x; \
139*50c88402SJoao Martins     struct { \
140*50c88402SJoao Martins         uint8_t which ## l; \
141*50c88402SJoao Martins         uint8_t which ## h; \
142*50c88402SJoao Martins     }; \
143*50c88402SJoao Martins }
144*50c88402SJoao Martins #define __DECL_REG_LO8(name) union { \
145*50c88402SJoao Martins     uint64_t r ## name; \
146*50c88402SJoao Martins     uint32_t e ## name; \
147*50c88402SJoao Martins     uint16_t name; \
148*50c88402SJoao Martins     uint8_t name ## l; \
149*50c88402SJoao Martins }
150*50c88402SJoao Martins #define __DECL_REG_LO16(name) union { \
151*50c88402SJoao Martins     uint64_t r ## name; \
152*50c88402SJoao Martins     uint32_t e ## name; \
153*50c88402SJoao Martins     uint16_t name; \
154*50c88402SJoao Martins }
155*50c88402SJoao Martins #define __DECL_REG_HI(num) union { \
156*50c88402SJoao Martins     uint64_t r ## num; \
157*50c88402SJoao Martins     uint32_t r ## num ## d; \
158*50c88402SJoao Martins     uint16_t r ## num ## w; \
159*50c88402SJoao Martins     uint8_t r ## num ## b; \
160*50c88402SJoao Martins }
161*50c88402SJoao Martins #elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
162*50c88402SJoao Martins /* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */
163*50c88402SJoao Martins #define __DECL_REG(name) union { \
164*50c88402SJoao Martins     uint64_t r ## name, e ## name; \
165*50c88402SJoao Martins     uint32_t _e ## name; \
166*50c88402SJoao Martins }
167*50c88402SJoao Martins #else
168*50c88402SJoao Martins /* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */
169*50c88402SJoao Martins #define __DECL_REG(name) uint64_t r ## name
170*50c88402SJoao Martins #endif
171*50c88402SJoao Martins 
172*50c88402SJoao Martins #ifndef __DECL_REG_LOHI
173*50c88402SJoao Martins #define __DECL_REG_LOHI(name) __DECL_REG(name ## x)
174*50c88402SJoao Martins #define __DECL_REG_LO8        __DECL_REG
175*50c88402SJoao Martins #define __DECL_REG_LO16       __DECL_REG
176*50c88402SJoao Martins #define __DECL_REG_HI(num)    uint64_t r ## num
177*50c88402SJoao Martins #endif
178*50c88402SJoao Martins 
179*50c88402SJoao Martins struct cpu_user_regs {
180*50c88402SJoao Martins     __DECL_REG_HI(15);
181*50c88402SJoao Martins     __DECL_REG_HI(14);
182*50c88402SJoao Martins     __DECL_REG_HI(13);
183*50c88402SJoao Martins     __DECL_REG_HI(12);
184*50c88402SJoao Martins     __DECL_REG_LO8(bp);
185*50c88402SJoao Martins     __DECL_REG_LOHI(b);
186*50c88402SJoao Martins     __DECL_REG_HI(11);
187*50c88402SJoao Martins     __DECL_REG_HI(10);
188*50c88402SJoao Martins     __DECL_REG_HI(9);
189*50c88402SJoao Martins     __DECL_REG_HI(8);
190*50c88402SJoao Martins     __DECL_REG_LOHI(a);
191*50c88402SJoao Martins     __DECL_REG_LOHI(c);
192*50c88402SJoao Martins     __DECL_REG_LOHI(d);
193*50c88402SJoao Martins     __DECL_REG_LO8(si);
194*50c88402SJoao Martins     __DECL_REG_LO8(di);
195*50c88402SJoao Martins     uint32_t error_code;    /* private */
196*50c88402SJoao Martins     uint32_t entry_vector;  /* private */
197*50c88402SJoao Martins     __DECL_REG_LO16(ip);
198*50c88402SJoao Martins     uint16_t cs, _pad0[1];
199*50c88402SJoao Martins     uint8_t  saved_upcall_mask;
200*50c88402SJoao Martins     uint8_t  _pad1[3];
201*50c88402SJoao Martins     __DECL_REG_LO16(flags); /* rflags.IF == !saved_upcall_mask */
202*50c88402SJoao Martins     __DECL_REG_LO8(sp);
203*50c88402SJoao Martins     uint16_t ss, _pad2[3];
204*50c88402SJoao Martins     uint16_t es, _pad3[3];
205*50c88402SJoao Martins     uint16_t ds, _pad4[3];
206*50c88402SJoao Martins     uint16_t fs, _pad5[3];
207*50c88402SJoao Martins     uint16_t gs, _pad6[3];
208*50c88402SJoao Martins };
209*50c88402SJoao Martins typedef struct cpu_user_regs cpu_user_regs_t;
210*50c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
211*50c88402SJoao Martins 
212*50c88402SJoao Martins #undef __DECL_REG
213*50c88402SJoao Martins #undef __DECL_REG_LOHI
214*50c88402SJoao Martins #undef __DECL_REG_LO8
215*50c88402SJoao Martins #undef __DECL_REG_LO16
216*50c88402SJoao Martins #undef __DECL_REG_HI
217*50c88402SJoao Martins 
218*50c88402SJoao Martins #define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12)
219*50c88402SJoao Martins #define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12)
220*50c88402SJoao Martins 
221*50c88402SJoao Martins struct arch_vcpu_info {
222*50c88402SJoao Martins     unsigned long cr2;
223*50c88402SJoao Martins     unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
224*50c88402SJoao Martins };
225*50c88402SJoao Martins typedef struct arch_vcpu_info arch_vcpu_info_t;
226*50c88402SJoao Martins 
227*50c88402SJoao Martins typedef unsigned long xen_callback_t;
228*50c88402SJoao Martins 
229*50c88402SJoao Martins #endif /* !__ASSEMBLY__ */
230*50c88402SJoao Martins 
231*50c88402SJoao Martins #endif /* __XEN_PUBLIC_ARCH_X86_XEN_X86_64_H__ */
232*50c88402SJoao Martins 
233*50c88402SJoao Martins /*
234*50c88402SJoao Martins  * Local variables:
235*50c88402SJoao Martins  * mode: C
236*50c88402SJoao Martins  * c-file-style: "BSD"
237*50c88402SJoao Martins  * c-basic-offset: 4
238*50c88402SJoao Martins  * tab-width: 4
239*50c88402SJoao Martins  * indent-tabs-mode: nil
240*50c88402SJoao Martins  * End:
241*50c88402SJoao Martins  */
242