This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / include / xen / interface / arch-x86_64.h
1 /******************************************************************************
2  * arch-x86_64.h
3  * 
4  * Guest OS interface to x86 64-bit Xen.
5  * 
6  * Copyright (c) 2004, K A Fraser
7  */
8
9 #ifndef __XEN_PUBLIC_ARCH_X86_64_H__
10 #define __XEN_PUBLIC_ARCH_X86_64_H__
11
12 #define __DEFINE_XEN_GUEST_HANDLE(name, type) \
13     typedef struct { type *p; } __guest_handle_ ## name
14
15 #define DEFINE_XEN_GUEST_HANDLE(name)   __DEFINE_XEN_GUEST_HANDLE(name, name)
16 #define XEN_GUEST_HANDLE(name)          __guest_handle_ ## name
17 #define set_xen_guest_handle(hnd, val)  do { (hnd).p = val; } while (0)
18 #ifdef __XEN_TOOLS__
19 #define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
20 #endif
21
22 #ifndef __ASSEMBLY__
23 /* Guest handles for primitive C types. */
24 __DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
25 __DEFINE_XEN_GUEST_HANDLE(uint,  unsigned int);
26 __DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
27 DEFINE_XEN_GUEST_HANDLE(char);
28 DEFINE_XEN_GUEST_HANDLE(int);
29 DEFINE_XEN_GUEST_HANDLE(long);
30 DEFINE_XEN_GUEST_HANDLE(void);
31
32 typedef unsigned long xen_pfn_t;
33 DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
34 #endif
35
36 /*
37  * SEGMENT DESCRIPTOR TABLES
38  */
39 /*
40  * A number of GDT entries are reserved by Xen. These are not situated at the
41  * start of the GDT because some stupid OSes export hard-coded selector values
42  * in their ABI. These hard-coded values are always near the start of the GDT,
43  * so Xen places itself out of the way, at the far end of the GDT.
44  */
45 #define FIRST_RESERVED_GDT_PAGE  14
46 #define FIRST_RESERVED_GDT_BYTE  (FIRST_RESERVED_GDT_PAGE * 4096)
47 #define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8)
48
49 /*
50  * 64-bit segment selectors
51  * These flat segments are in the Xen-private section of every GDT. Since these
52  * are also present in the initial GDT, many OSes will be able to avoid
53  * installing their own GDT.
54  */
55
56 #define FLAT_RING3_CS32 0xe023  /* GDT index 260 */
57 #define FLAT_RING3_CS64 0xe033  /* GDT index 261 */
58 #define FLAT_RING3_DS32 0xe02b  /* GDT index 262 */
59 #define FLAT_RING3_DS64 0x0000  /* NULL selector */
60 #define FLAT_RING3_SS32 0xe02b  /* GDT index 262 */
61 #define FLAT_RING3_SS64 0xe02b  /* GDT index 262 */
62
63 #define FLAT_KERNEL_DS64 FLAT_RING3_DS64
64 #define FLAT_KERNEL_DS32 FLAT_RING3_DS32
65 #define FLAT_KERNEL_DS   FLAT_KERNEL_DS64
66 #define FLAT_KERNEL_CS64 FLAT_RING3_CS64
67 #define FLAT_KERNEL_CS32 FLAT_RING3_CS32
68 #define FLAT_KERNEL_CS   FLAT_KERNEL_CS64
69 #define FLAT_KERNEL_SS64 FLAT_RING3_SS64
70 #define FLAT_KERNEL_SS32 FLAT_RING3_SS32
71 #define FLAT_KERNEL_SS   FLAT_KERNEL_SS64
72
73 #define FLAT_USER_DS64 FLAT_RING3_DS64
74 #define FLAT_USER_DS32 FLAT_RING3_DS32
75 #define FLAT_USER_DS   FLAT_USER_DS64
76 #define FLAT_USER_CS64 FLAT_RING3_CS64
77 #define FLAT_USER_CS32 FLAT_RING3_CS32
78 #define FLAT_USER_CS   FLAT_USER_CS64
79 #define FLAT_USER_SS64 FLAT_RING3_SS64
80 #define FLAT_USER_SS32 FLAT_RING3_SS32
81 #define FLAT_USER_SS   FLAT_USER_SS64
82
83 /* And the trap vector is... */
84 #define TRAP_INSTR "syscall"
85
86 #define __HYPERVISOR_VIRT_START 0xFFFF800000000000
87 #define __HYPERVISOR_VIRT_END   0xFFFF880000000000
88 #define __MACH2PHYS_VIRT_START  0xFFFF800000000000
89 #define __MACH2PHYS_VIRT_END    0xFFFF804000000000
90
91 #ifndef HYPERVISOR_VIRT_START
92 #define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
93 #define HYPERVISOR_VIRT_END   mk_unsigned_long(__HYPERVISOR_VIRT_END)
94 #endif
95
96 #define MACH2PHYS_VIRT_START  mk_unsigned_long(__MACH2PHYS_VIRT_START)
97 #define MACH2PHYS_VIRT_END    mk_unsigned_long(__MACH2PHYS_VIRT_END)
98 #define MACH2PHYS_NR_ENTRIES  ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3)
99 #ifndef machine_to_phys_mapping
100 #define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
101 #endif
102
103 /* Maximum number of virtual CPUs in multi-processor guests. */
104 #define MAX_VIRT_CPUS 32
105
106 #ifndef __ASSEMBLY__
107
108 typedef unsigned long xen_ulong_t;
109
110 /*
111  * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
112  *  @which == SEGBASE_*  ;  @base == 64-bit base address
113  * Returns 0 on success.
114  */
115 #define SEGBASE_FS          0
116 #define SEGBASE_GS_USER     1
117 #define SEGBASE_GS_KERNEL   2
118 #define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
119
120 /*
121  * int HYPERVISOR_iret(void)
122  * All arguments are on the kernel stack, in the following format.
123  * Never returns if successful. Current kernel context is lost.
124  * The saved CS is mapped as follows:
125  *   RING0 -> RING3 kernel mode.
126  *   RING1 -> RING3 kernel mode.
127  *   RING2 -> RING3 kernel mode.
128  *   RING3 -> RING3 user mode.
129  * However RING0 indicates that the guest kernel should return to iteself
130  * directly with
131  *      orb   $3,1*8(%rsp)
132  *      iretq
133  * If flags contains VGCF_IN_SYSCALL:
134  *   Restore RAX, RIP, RFLAGS, RSP.
135  *   Discard R11, RCX, CS, SS.
136  * Otherwise:
137  *   Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
138  * All other registers are saved on hypercall entry and restored to user.
139  */
140 /* Guest exited in SYSCALL context? Return to guest with SYSRET? */
141 #define VGCF_IN_SYSCALL (1<<8)
142 struct iret_context {
143     /* Top of stack (%rsp at point of hypercall). */
144     uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
145     /* Bottom of iret stack frame. */
146 };
147
148 /*
149  * Send an array of these to HYPERVISOR_set_trap_table().
150  * N.B. As in x86/32 mode, the privilege level specifies which modes may enter
151  * a trap via a software interrupt. Since rings 1 and 2 are unavailable, we
152  * allocate privilege levels as follows:
153  *  Level == 0: Noone may enter
154  *  Level == 1: Kernel may enter
155  *  Level == 2: Kernel may enter
156  *  Level == 3: Everyone may enter
157  */
158 #define TI_GET_DPL(_ti)      ((_ti)->flags & 3)
159 #define TI_GET_IF(_ti)       ((_ti)->flags & 4)
160 #define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
161 #define TI_SET_IF(_ti,_if)   ((_ti)->flags |= ((!!(_if))<<2))
162 struct trap_info {
163     uint8_t       vector;  /* exception vector                              */
164     uint8_t       flags;   /* 0-3: privilege level; 4: clear event enable?  */
165     uint16_t      cs;      /* code selector                                 */
166     unsigned long address; /* code offset                                   */
167 };
168 typedef struct trap_info trap_info_t;
169 DEFINE_XEN_GUEST_HANDLE(trap_info_t);
170
171 #ifdef __GNUC__
172 /* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */
173 #define __DECL_REG(name) union { uint64_t r ## name, e ## name; }
174 #else
175 /* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */
176 #define __DECL_REG(name) uint64_t r ## name
177 #endif
178
179 struct cpu_user_regs {
180     uint64_t r15;
181     uint64_t r14;
182     uint64_t r13;
183     uint64_t r12;
184     __DECL_REG(bp);
185     __DECL_REG(bx);
186     uint64_t r11;
187     uint64_t r10;
188     uint64_t r9;
189     uint64_t r8;
190     __DECL_REG(ax);
191     __DECL_REG(cx);
192     __DECL_REG(dx);
193     __DECL_REG(si);
194     __DECL_REG(di);
195     uint32_t error_code;    /* private */
196     uint32_t entry_vector;  /* private */
197     __DECL_REG(ip);
198     uint16_t cs, _pad0[1];
199     uint8_t  saved_upcall_mask;
200     uint8_t  _pad1[3];
201     __DECL_REG(flags);      /* rflags.IF == !saved_upcall_mask */
202     __DECL_REG(sp);
203     uint16_t ss, _pad2[3];
204     uint16_t es, _pad3[3];
205     uint16_t ds, _pad4[3];
206     uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base.     */
207     uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */
208 };
209 typedef struct cpu_user_regs cpu_user_regs_t;
210 DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
211
212 #undef __DECL_REG
213
214 typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
215
216 /*
217  * The following is all CPU context. Note that the fpu_ctxt block is filled 
218  * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
219  */
220 struct vcpu_guest_context {
221     /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */
222     struct { char x[512]; } fpu_ctxt;       /* User-level FPU registers     */
223 #define VGCF_I387_VALID                (1<<0)
224 #define VGCF_HVM_GUEST                 (1<<1)
225 #define VGCF_IN_KERNEL                 (1<<2)
226 #define _VGCF_i387_valid               0
227 #define VGCF_i387_valid                (1<<_VGCF_i387_valid)
228 #define _VGCF_hvm_guest                1
229 #define VGCF_hvm_guest                 (1<<_VGCF_hvm_guest)
230 #define _VGCF_in_kernel                2
231 #define VGCF_in_kernel                 (1<<_VGCF_in_kernel)
232 #define _VGCF_failsafe_disables_events 3
233 #define VGCF_failsafe_disables_events  (1<<_VGCF_failsafe_disables_events)
234 #define _VGCF_syscall_disables_events  4
235 #define VGCF_syscall_disables_events   (1<<_VGCF_syscall_disables_events)
236     unsigned long flags;                    /* VGCF_* flags                 */
237     struct cpu_user_regs user_regs;         /* User-level CPU registers     */
238     struct trap_info trap_ctxt[256];        /* Virtual IDT                  */
239     unsigned long ldt_base, ldt_ents;       /* LDT (linear address, # ents) */
240     unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
241     unsigned long kernel_ss, kernel_sp;     /* Virtual TSS (only SS1/SP1)   */
242     unsigned long ctrlreg[8];               /* CR0-CR7 (control registers)  */
243     unsigned long debugreg[8];              /* DB0-DB7 (debug registers)    */
244     unsigned long event_callback_eip;
245     unsigned long failsafe_callback_eip;
246     unsigned long syscall_callback_eip;
247     unsigned long vm_assist;                /* VMASST_TYPE_* bitmap */
248     /* Segment base addresses. */
249     uint64_t      fs_base;
250     uint64_t      gs_base_kernel;
251     uint64_t      gs_base_user;
252 };
253 typedef struct vcpu_guest_context vcpu_guest_context_t;
254 DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
255
256 #define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12)
257 #define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12)
258
259 struct arch_shared_info {
260     unsigned long max_pfn;                  /* max pfn that appears in table */
261     /* Frame containing list of mfns containing list of mfns containing p2m. */
262     xen_pfn_t     pfn_to_mfn_frame_list_list;
263     unsigned long nmi_reason;
264     uint64_t pad[32];
265 };
266 typedef struct arch_shared_info arch_shared_info_t;
267
268 struct arch_vcpu_info {
269     unsigned long cr2;
270     unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
271 };
272 typedef struct arch_vcpu_info  arch_vcpu_info_t;
273
274 typedef unsigned long xen_callback_t;
275
276 #endif /* !__ASSEMBLY__ */
277
278 /*
279  * Prefix forces emulation of some non-trapping instructions.
280  * Currently only CPUID.
281  */
282 #ifdef __ASSEMBLY__
283 #define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ;
284 #define XEN_CPUID          XEN_EMULATE_PREFIX cpuid
285 #else
286 #define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; "
287 #define XEN_CPUID          XEN_EMULATE_PREFIX "cpuid"
288 #endif
289
290 #endif
291
292 /*
293  * Local variables:
294  * mode: C
295  * c-set-style: "BSD"
296  * c-basic-offset: 4
297  * tab-width: 4
298  * indent-tabs-mode: nil
299  * End:
300  */