/root/src/xen/xen/include/public/arch-x86/xen.h
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * arch-x86/xen.h |
3 | | * |
4 | | * Guest OS interface to x86 Xen. |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | | * of this software and associated documentation files (the "Software"), to |
8 | | * deal in the Software without restriction, including without limitation the |
9 | | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
10 | | * sell copies of the Software, and to permit persons to whom the Software is |
11 | | * furnished to do so, subject to the following conditions: |
12 | | * |
13 | | * The above copyright notice and this permission notice shall be included in |
14 | | * all copies or substantial portions of the Software. |
15 | | * |
16 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 | | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
21 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
22 | | * DEALINGS IN THE SOFTWARE. |
23 | | * |
24 | | * Copyright (c) 2004-2006, K A Fraser |
25 | | */ |
26 | | |
27 | | #include "../xen.h" |
28 | | |
29 | | #ifndef __XEN_PUBLIC_ARCH_X86_XEN_H__ |
30 | | #define __XEN_PUBLIC_ARCH_X86_XEN_H__ |
31 | | |
32 | | /* Structural guest handles introduced in 0x00030201. */ |
33 | | #if __XEN_INTERFACE_VERSION__ >= 0x00030201 |
34 | | #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ |
35 | 0 | typedef struct { type *p; } __guest_handle_ ## name |
36 | | #else |
37 | | #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ |
38 | | typedef type * __guest_handle_ ## name |
39 | | #endif |
40 | | |
41 | | /* |
42 | | * XEN_GUEST_HANDLE represents a guest pointer, when passed as a field |
43 | | * in a struct in memory. |
44 | | * XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an |
45 | | * hypercall argument. |
46 | | * XEN_GUEST_HANDLE_PARAM and XEN_GUEST_HANDLE are the same on X86 but |
47 | | * they might not be on other architectures. |
48 | | */ |
49 | | #define __DEFINE_XEN_GUEST_HANDLE(name, type) \ |
50 | 0 | ___DEFINE_XEN_GUEST_HANDLE(name, type); \ |
51 | 0 | ___DEFINE_XEN_GUEST_HANDLE(const_##name, const type) |
52 | 0 | #define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name) |
53 | 1.41k | #define __XEN_GUEST_HANDLE(name) __guest_handle_ ## name |
54 | 1.41k | #define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name) |
55 | 1 | #define XEN_GUEST_HANDLE_PARAM(name) XEN_GUEST_HANDLE(name) |
56 | 0 | #define set_xen_guest_handle_raw(hnd, val) do { (hnd).p = val; } while (0) |
57 | 0 | #define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val) |
58 | | |
59 | | #if defined(__i386__) |
60 | | # ifdef __XEN__ |
61 | | __DeFiNe__ __DECL_REG_LO8(which) uint32_t e ## which ## x |
62 | | __DeFiNe__ __DECL_REG_LO16(name) union { uint32_t e ## name; } |
63 | | # endif |
64 | | #include "xen-x86_32.h" |
65 | | # ifdef __XEN__ |
66 | | __UnDeF__ __DECL_REG_LO8 |
67 | | __UnDeF__ __DECL_REG_LO16 |
68 | | __DeFiNe__ __DECL_REG_LO8(which) e ## which ## x |
69 | | __DeFiNe__ __DECL_REG_LO16(name) e ## name |
70 | | # endif |
71 | | #elif defined(__x86_64__) |
72 | | #include "xen-x86_64.h" |
73 | | #endif |
74 | | |
75 | | #ifndef __ASSEMBLY__ |
76 | | typedef unsigned long xen_pfn_t; |
77 | | #define PRI_xen_pfn "lx" |
78 | | #endif |
79 | | |
80 | | #define XEN_HAVE_PV_GUEST_ENTRY 1 |
81 | | |
82 | | #define XEN_HAVE_PV_UPCALL_MASK 1 |
83 | | |
84 | | /* |
85 | | * `incontents 200 segdesc Segment Descriptor Tables |
86 | | */ |
87 | | /* |
88 | | * ` enum neg_errnoval |
89 | | * ` HYPERVISOR_set_gdt(const xen_pfn_t frames[], unsigned int entries); |
90 | | * ` |
91 | | */ |
92 | | /* |
93 | | * A number of GDT entries are reserved by Xen. These are not situated at the |
94 | | * start of the GDT because some stupid OSes export hard-coded selector values |
95 | | * in their ABI. These hard-coded values are always near the start of the GDT, |
96 | | * so Xen places itself out of the way, at the far end of the GDT. |
97 | | * |
98 | | * NB The LDT is set using the MMUEXT_SET_LDT op of HYPERVISOR_mmuext_op |
99 | | */ |
100 | 1.19k | #define FIRST_RESERVED_GDT_PAGE 14 |
101 | 1.19k | #define FIRST_RESERVED_GDT_BYTE (FIRST_RESERVED_GDT_PAGE * 4096) |
102 | 1.17k | #define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8) |
103 | | |
104 | | |
105 | | /* |
106 | | * ` enum neg_errnoval |
107 | | * ` HYPERVISOR_update_descriptor(u64 pa, u64 desc); |
108 | | * ` |
109 | | * ` @pa The machine physical address of the descriptor to |
110 | | * ` update. Must be either a descriptor page or writable. |
111 | | * ` @desc The descriptor value to update, in the same format as a |
112 | | * ` native descriptor table entry. |
113 | | */ |
114 | | |
115 | | /* Maximum number of virtual CPUs in legacy multi-processor guests. */ |
116 | 12 | #define XEN_LEGACY_MAX_VCPUS 32 |
117 | | |
118 | | #ifndef __ASSEMBLY__ |
119 | | |
120 | | typedef unsigned long xen_ulong_t; |
121 | | #define PRI_xen_ulong "lx" |
122 | | |
123 | | /* |
124 | | * ` enum neg_errnoval |
125 | | * ` HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp); |
126 | | * ` |
127 | | * Sets the stack segment and pointer for the current vcpu. |
128 | | */ |
129 | | |
130 | | /* |
131 | | * ` enum neg_errnoval |
132 | | * ` HYPERVISOR_set_trap_table(const struct trap_info traps[]); |
133 | | * ` |
134 | | */ |
135 | | /* |
136 | | * Send an array of these to HYPERVISOR_set_trap_table(). |
137 | | * Terminate the array with a sentinel entry, with traps[].address==0. |
138 | | * The privilege level specifies which modes may enter a trap via a software |
139 | | * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate |
140 | | * privilege levels as follows: |
141 | | * Level == 0: Noone may enter |
142 | | * Level == 1: Kernel may enter |
143 | | * Level == 2: Kernel may enter |
144 | | * Level == 3: Everyone may enter |
145 | | */ |
146 | | #define TI_GET_DPL(_ti) ((_ti)->flags & 3) |
147 | 0 | #define TI_GET_IF(_ti) ((_ti)->flags & 4) |
148 | | #define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl)) |
149 | 0 | #define TI_SET_IF(_ti,_if) ((_ti)->flags |= ((!!(_if))<<2)) |
150 | | struct trap_info { |
151 | | uint8_t vector; /* exception vector */ |
152 | | uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */ |
153 | | uint16_t cs; /* code selector */ |
154 | | unsigned long address; /* code offset */ |
155 | | }; |
156 | | typedef struct trap_info trap_info_t; |
157 | | DEFINE_XEN_GUEST_HANDLE(trap_info_t); |
158 | | |
159 | | typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ |
160 | | |
161 | | /* |
162 | | * The following is all CPU context. Note that the fpu_ctxt block is filled |
163 | | * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used. |
164 | | * |
165 | | * Also note that when calling DOMCTL_setvcpucontext for HVM guests, not all |
166 | | * information in this structure is updated, the fields read include: fpu_ctxt |
167 | | * (if VGCT_I387_VALID is set), flags, user_regs and debugreg[*]. |
168 | | * |
169 | | * Note: VCPUOP_initialise for HVM guests is non-symetric with |
170 | | * DOMCTL_setvcpucontext, and uses struct vcpu_hvm_context from hvm/hvm_vcpu.h |
171 | | */ |
172 | | struct vcpu_guest_context { |
173 | | /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */ |
174 | | struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */ |
175 | 0 | #define VGCF_I387_VALID (1<<0) |
176 | | #define VGCF_IN_KERNEL (1<<2) |
177 | | #define _VGCF_i387_valid 0 |
178 | | #define VGCF_i387_valid (1<<_VGCF_i387_valid) |
179 | 0 | #define _VGCF_in_kernel 2 |
180 | 0 | #define VGCF_in_kernel (1<<_VGCF_in_kernel) |
181 | | #define _VGCF_failsafe_disables_events 3 |
182 | 0 | #define VGCF_failsafe_disables_events (1<<_VGCF_failsafe_disables_events) |
183 | | #define _VGCF_syscall_disables_events 4 |
184 | | #define VGCF_syscall_disables_events (1<<_VGCF_syscall_disables_events) |
185 | 11 | #define _VGCF_online 5 |
186 | 11 | #define VGCF_online (1<<_VGCF_online) |
187 | | unsigned long flags; /* VGCF_* flags */ |
188 | | struct cpu_user_regs user_regs; /* User-level CPU registers */ |
189 | | struct trap_info trap_ctxt[256]; /* Virtual IDT */ |
190 | | unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */ |
191 | | unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */ |
192 | | unsigned long kernel_ss, kernel_sp; /* Virtual TSS (only SS1/SP1) */ |
193 | | /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */ |
194 | | unsigned long ctrlreg[8]; /* CR0-CR7 (control registers) */ |
195 | | unsigned long debugreg[8]; /* DB0-DB7 (debug registers) */ |
196 | | #ifdef __i386__ |
197 | | unsigned long event_callback_cs; /* CS:EIP of event callback */ |
198 | | unsigned long event_callback_eip; |
199 | | unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */ |
200 | | unsigned long failsafe_callback_eip; |
201 | | #else |
202 | | unsigned long event_callback_eip; |
203 | | unsigned long failsafe_callback_eip; |
204 | | #ifdef __XEN__ |
205 | | union { |
206 | | unsigned long syscall_callback_eip; |
207 | | struct { |
208 | | unsigned int event_callback_cs; /* compat CS of event cb */ |
209 | | unsigned int failsafe_callback_cs; /* compat CS of failsafe cb */ |
210 | | }; |
211 | | }; |
212 | | #else |
213 | | unsigned long syscall_callback_eip; |
214 | | #endif |
215 | | #endif |
216 | | unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ |
217 | | #ifdef __x86_64__ |
218 | | /* Segment base addresses. */ |
219 | | uint64_t fs_base; |
220 | | uint64_t gs_base_kernel; |
221 | | uint64_t gs_base_user; |
222 | | #endif |
223 | | }; |
224 | | typedef struct vcpu_guest_context vcpu_guest_context_t; |
225 | | DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); |
226 | | |
227 | | struct arch_shared_info { |
228 | | /* |
229 | | * Number of valid entries in the p2m table(s) anchored at |
230 | | * pfn_to_mfn_frame_list_list and/or p2m_vaddr. |
231 | | */ |
232 | | unsigned long max_pfn; |
233 | | /* |
234 | | * Frame containing list of mfns containing list of mfns containing p2m. |
235 | | * A value of 0 indicates it has not yet been set up, ~0 indicates it has |
236 | | * been set to invalid e.g. due to the p2m being too large for the 3-level |
237 | | * p2m tree. In this case the linear mapper p2m list anchored at p2m_vaddr |
238 | | * is to be used. |
239 | | */ |
240 | | xen_pfn_t pfn_to_mfn_frame_list_list; |
241 | | unsigned long nmi_reason; |
242 | | /* |
243 | | * Following three fields are valid if p2m_cr3 contains a value different |
244 | | * from 0. |
245 | | * p2m_cr3 is the root of the address space where p2m_vaddr is valid. |
246 | | * p2m_cr3 is in the same format as a cr3 value in the vcpu register state |
247 | | * and holds the folded machine frame number (via xen_pfn_to_cr3) of a |
248 | | * L3 or L4 page table. |
249 | | * p2m_vaddr holds the virtual address of the linear p2m list. All entries |
250 | | * in the range [0...max_pfn[ are accessible via this pointer. |
251 | | * p2m_generation will be incremented by the guest before and after each |
252 | | * change of the mappings of the p2m list. p2m_generation starts at 0 and |
253 | | * a value with the least significant bit set indicates that a mapping |
254 | | * update is in progress. This allows guest external software (e.g. in Dom0) |
255 | | * to verify that read mappings are consistent and whether they have changed |
256 | | * since the last check. |
257 | | * Modifying a p2m element in the linear p2m list is allowed via an atomic |
258 | | * write only. |
259 | | */ |
260 | | unsigned long p2m_cr3; /* cr3 value of the p2m address space */ |
261 | | unsigned long p2m_vaddr; /* virtual address of the p2m list */ |
262 | | unsigned long p2m_generation; /* generation count of p2m mapping */ |
263 | | #ifdef __i386__ |
264 | | /* There's no room for this field in the generic structure. */ |
265 | | uint32_t wc_sec_hi; |
266 | | #endif |
267 | | }; |
268 | | typedef struct arch_shared_info arch_shared_info_t; |
269 | | |
270 | | #if defined(__XEN__) || defined(__XEN_TOOLS__) |
271 | | /* |
272 | | * struct xen_arch_domainconfig's ABI is covered by |
273 | | * XEN_DOMCTL_INTERFACE_VERSION. |
274 | | */ |
275 | | struct xen_arch_domainconfig { |
276 | 73 | #define _XEN_X86_EMU_LAPIC 0 |
277 | 73 | #define XEN_X86_EMU_LAPIC (1U<<_XEN_X86_EMU_LAPIC) |
278 | 2 | #define _XEN_X86_EMU_HPET 1 |
279 | 2 | #define XEN_X86_EMU_HPET (1U<<_XEN_X86_EMU_HPET) |
280 | 2 | #define _XEN_X86_EMU_PM 2 |
281 | 2 | #define XEN_X86_EMU_PM (1U<<_XEN_X86_EMU_PM) |
282 | 550 | #define _XEN_X86_EMU_RTC 3 |
283 | 550 | #define XEN_X86_EMU_RTC (1U<<_XEN_X86_EMU_RTC) |
284 | 5 | #define _XEN_X86_EMU_IOAPIC 4 |
285 | 5 | #define XEN_X86_EMU_IOAPIC (1U<<_XEN_X86_EMU_IOAPIC) |
286 | 7.85M | #define _XEN_X86_EMU_PIC 5 |
287 | 7.85M | #define XEN_X86_EMU_PIC (1U<<_XEN_X86_EMU_PIC) |
288 | 2 | #define _XEN_X86_EMU_VGA 6 |
289 | 2 | #define XEN_X86_EMU_VGA (1U<<_XEN_X86_EMU_VGA) |
290 | 1 | #define _XEN_X86_EMU_IOMMU 7 |
291 | 1 | #define XEN_X86_EMU_IOMMU (1U<<_XEN_X86_EMU_IOMMU) |
292 | 3 | #define _XEN_X86_EMU_PIT 8 |
293 | 3 | #define XEN_X86_EMU_PIT (1U<<_XEN_X86_EMU_PIT) |
294 | 71 | #define _XEN_X86_EMU_USE_PIRQ 9 |
295 | 71 | #define XEN_X86_EMU_USE_PIRQ (1U<<_XEN_X86_EMU_USE_PIRQ) |
296 | 9.75M | #define _XEN_X86_EMU_VPCI 10 |
297 | 9.75M | #define XEN_X86_EMU_VPCI (1U<<_XEN_X86_EMU_VPCI) |
298 | | |
299 | 1 | #define XEN_X86_EMU_ALL (XEN_X86_EMU_LAPIC | XEN_X86_EMU_HPET | \ |
300 | 1 | XEN_X86_EMU_PM | XEN_X86_EMU_RTC | \ |
301 | 1 | XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC | \ |
302 | 1 | XEN_X86_EMU_VGA | XEN_X86_EMU_IOMMU | \ |
303 | 1 | XEN_X86_EMU_PIT | XEN_X86_EMU_USE_PIRQ |\ |
304 | 1 | XEN_X86_EMU_VPCI) |
305 | | uint32_t emulation_flags; |
306 | | }; |
307 | | |
308 | | /* Location of online VCPU bitmap. */ |
309 | | #define XEN_ACPI_CPU_MAP 0xaf00 |
310 | | #define XEN_ACPI_CPU_MAP_LEN ((HVM_MAX_VCPUS + 7) / 8) |
311 | | |
312 | | /* GPE0 bit set during CPU hotplug */ |
313 | | #define XEN_ACPI_GPE0_CPUHP_BIT 2 |
314 | | #endif |
315 | | |
316 | | #endif /* !__ASSEMBLY__ */ |
317 | | |
318 | | /* |
319 | | * ` enum neg_errnoval |
320 | | * ` HYPERVISOR_fpu_taskswitch(int set); |
321 | | * ` |
322 | | * Sets (if set!=0) or clears (if set==0) CR0.TS. |
323 | | */ |
324 | | |
325 | | /* |
326 | | * ` enum neg_errnoval |
327 | | * ` HYPERVISOR_set_debugreg(int regno, unsigned long value); |
328 | | * |
329 | | * ` unsigned long |
330 | | * ` HYPERVISOR_get_debugreg(int regno); |
331 | | * For 0<=reg<=7, returns the debug register value. |
332 | | * For other values of reg, returns ((unsigned long)-EINVAL). |
333 | | * (Unfortunately, this interface is defective.) |
334 | | */ |
335 | | |
336 | | /* |
337 | | * Prefix forces emulation of some non-trapping instructions. |
338 | | * Currently only CPUID. |
339 | | */ |
340 | | #ifdef __ASSEMBLY__ |
341 | | #define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ; |
342 | | #define XEN_CPUID XEN_EMULATE_PREFIX cpuid |
343 | | #else |
344 | | #define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; " |
345 | | #define XEN_CPUID XEN_EMULATE_PREFIX "cpuid" |
346 | | #endif |
347 | | |
348 | | #endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */ |
349 | | |
350 | | /* |
351 | | * Local variables: |
352 | | * mode: C |
353 | | * c-file-style: "BSD" |
354 | | * c-basic-offset: 4 |
355 | | * tab-width: 4 |
356 | | * indent-tabs-mode: nil |
357 | | * End: |
358 | | */ |