Commit | Line | Data |
---|---|---|
a42089dd JF |
1 | /****************************************************************************** |
2 | * arch-x86_32.h | |
3 | * | |
48b5db20 | 4 | * Guest OS interface to x86 Xen. |
a42089dd JF |
5 | * |
6 | * Copyright (c) 2004, K A Fraser | |
7 | */ | |
8 | ||
05e4d316 PA |
9 | #ifndef _ASM_X86_XEN_INTERFACE_H |
10 | #define _ASM_X86_XEN_INTERFACE_H | |
a42089dd JF |
11 | |
12 | #ifdef __XEN__ | |
13 | #define __DEFINE_GUEST_HANDLE(name, type) \ | |
14 | typedef struct { type *p; } __guest_handle_ ## name | |
15 | #else | |
16 | #define __DEFINE_GUEST_HANDLE(name, type) \ | |
17 | typedef type * __guest_handle_ ## name | |
18 | #endif | |
19 | ||
20 | #define DEFINE_GUEST_HANDLE_STRUCT(name) \ | |
21 | __DEFINE_GUEST_HANDLE(name, struct name) | |
22 | #define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name) | |
23 | #define GUEST_HANDLE(name) __guest_handle_ ## name | |
24 | ||
87e27cf6 IY |
25 | #ifdef __XEN__ |
26 | #if defined(__i386__) | |
27 | #define set_xen_guest_handle(hnd, val) \ | |
28 | do { \ | |
29 | if (sizeof(hnd) == 8) \ | |
30 | *(uint64_t *)&(hnd) = 0; \ | |
31 | (hnd).p = val; \ | |
32 | } while (0) | |
33 | #elif defined(__x86_64__) | |
34 | #define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) | |
35 | #endif | |
36 | #else | |
37 | #if defined(__i386__) | |
38 | #define set_xen_guest_handle(hnd, val) \ | |
39 | do { \ | |
40 | if (sizeof(hnd) == 8) \ | |
41 | *(uint64_t *)&(hnd) = 0; \ | |
42 | (hnd) = val; \ | |
43 | } while (0) | |
44 | #elif defined(__x86_64__) | |
45 | #define set_xen_guest_handle(hnd, val) do { (hnd) = val; } while (0) | |
46 | #endif | |
47 | #endif | |
48 | ||
a42089dd | 49 | #ifndef __ASSEMBLY__ |
bd3f79b7 SS |
50 | /* Explicitly size integers that represent pfns in the public interface |
51 | * with Xen so that on ARM we can have one ABI that works for 32 and 64 | |
52 | * bit guests. */ | |
53 | typedef unsigned long xen_pfn_t; | |
a42089dd JF |
54 | /* Guest handles for primitive C types. */ |
55 | __DEFINE_GUEST_HANDLE(uchar, unsigned char); | |
56 | __DEFINE_GUEST_HANDLE(uint, unsigned int); | |
57 | __DEFINE_GUEST_HANDLE(ulong, unsigned long); | |
58 | DEFINE_GUEST_HANDLE(char); | |
59 | DEFINE_GUEST_HANDLE(int); | |
60 | DEFINE_GUEST_HANDLE(long); | |
61 | DEFINE_GUEST_HANDLE(void); | |
3e099679 | 62 | DEFINE_GUEST_HANDLE(uint64_t); |
73c154c6 | 63 | DEFINE_GUEST_HANDLE(uint32_t); |
bd3f79b7 | 64 | DEFINE_GUEST_HANDLE(xen_pfn_t); |
a42089dd JF |
65 | #endif |
66 | ||
48b5db20 JF |
67 | #ifndef HYPERVISOR_VIRT_START |
68 | #define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) | |
69 | #endif | |
70 | ||
7e77506a IC |
71 | #define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) |
72 | #define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) | |
73 | #define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>__MACH2PHYS_SHIFT) | |
48b5db20 JF |
74 | |
75 | /* Maximum number of virtual CPUs in multi-processor guests. */ | |
76 | #define MAX_VIRT_CPUS 32 | |
77 | ||
a42089dd JF |
78 | /* |
79 | * SEGMENT DESCRIPTOR TABLES | |
80 | */ | |
81 | /* | |
82 | * A number of GDT entries are reserved by Xen. These are not situated at the | |
83 | * start of the GDT because some stupid OSes export hard-coded selector values | |
84 | * in their ABI. These hard-coded values are always near the start of the GDT, | |
85 | * so Xen places itself out of the way, at the far end of the GDT. | |
86 | */ | |
87 | #define FIRST_RESERVED_GDT_PAGE 14 | |
88 | #define FIRST_RESERVED_GDT_BYTE (FIRST_RESERVED_GDT_PAGE * 4096) | |
89 | #define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8) | |
90 | ||
a42089dd JF |
91 | /* |
92 | * Send an array of these to HYPERVISOR_set_trap_table() | |
48b5db20 JF |
93 | * The privilege level specifies which modes may enter a trap via a software |
94 | * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate | |
95 | * privilege levels as follows: | |
0d2eb44f | 96 | * Level == 0: No one may enter |
48b5db20 JF |
97 | * Level == 1: Kernel may enter |
98 | * Level == 2: Kernel may enter | |
99 | * Level == 3: Everyone may enter | |
a42089dd JF |
100 | */ |
101 | #define TI_GET_DPL(_ti) ((_ti)->flags & 3) | |
102 | #define TI_GET_IF(_ti) ((_ti)->flags & 4) | |
103 | #define TI_SET_DPL(_ti, _dpl) ((_ti)->flags |= (_dpl)) | |
104 | #define TI_SET_IF(_ti, _if) ((_ti)->flags |= ((!!(_if))<<2)) | |
105 | ||
48b5db20 | 106 | #ifndef __ASSEMBLY__ |
a42089dd JF |
107 | struct trap_info { |
108 | uint8_t vector; /* exception vector */ | |
109 | uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */ | |
110 | uint16_t cs; /* code selector */ | |
111 | unsigned long address; /* code offset */ | |
112 | }; | |
113 | DEFINE_GUEST_HANDLE_STRUCT(trap_info); | |
114 | ||
48b5db20 JF |
115 | struct arch_shared_info { |
116 | unsigned long max_pfn; /* max pfn that appears in table */ | |
117 | /* Frame containing list of mfns containing list of mfns containing p2m. */ | |
118 | unsigned long pfn_to_mfn_frame_list_list; | |
119 | unsigned long nmi_reason; | |
a42089dd | 120 | }; |
48b5db20 | 121 | #endif /* !__ASSEMBLY__ */ |
a42089dd | 122 | |
48b5db20 JF |
123 | #ifdef CONFIG_X86_32 |
124 | #include "interface_32.h" | |
125 | #else | |
126 | #include "interface_64.h" | |
127 | #endif | |
a42089dd | 128 | |
4d9310e3 SS |
129 | #include <asm/pvclock-abi.h> |
130 | ||
48b5db20 | 131 | #ifndef __ASSEMBLY__ |
a42089dd JF |
132 | /* |
133 | * The following is all CPU context. Note that the fpu_ctxt block is filled | |
134 | * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used. | |
135 | */ | |
136 | struct vcpu_guest_context { | |
137 | /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */ | |
138 | struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */ | |
139 | #define VGCF_I387_VALID (1<<0) | |
140 | #define VGCF_HVM_GUEST (1<<1) | |
141 | #define VGCF_IN_KERNEL (1<<2) | |
142 | unsigned long flags; /* VGCF_* flags */ | |
143 | struct cpu_user_regs user_regs; /* User-level CPU registers */ | |
144 | struct trap_info trap_ctxt[256]; /* Virtual IDT */ | |
145 | unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */ | |
146 | unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */ | |
147 | unsigned long kernel_ss, kernel_sp; /* Virtual TSS (only SS1/SP1) */ | |
48b5db20 | 148 | /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */ |
a42089dd JF |
149 | unsigned long ctrlreg[8]; /* CR0-CR7 (control registers) */ |
150 | unsigned long debugreg[8]; /* DB0-DB7 (debug registers) */ | |
48b5db20 | 151 | #ifdef __i386__ |
a42089dd JF |
152 | unsigned long event_callback_cs; /* CS:EIP of event callback */ |
153 | unsigned long event_callback_eip; | |
154 | unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */ | |
155 | unsigned long failsafe_callback_eip; | |
48b5db20 JF |
156 | #else |
157 | unsigned long event_callback_eip; | |
158 | unsigned long failsafe_callback_eip; | |
159 | unsigned long syscall_callback_eip; | |
160 | #endif | |
a42089dd | 161 | unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ |
48b5db20 JF |
162 | #ifdef __x86_64__ |
163 | /* Segment base addresses. */ | |
164 | uint64_t fs_base; | |
165 | uint64_t gs_base_kernel; | |
166 | uint64_t gs_base_user; | |
167 | #endif | |
a42089dd JF |
168 | }; |
169 | DEFINE_GUEST_HANDLE_STRUCT(vcpu_guest_context); | |
48b5db20 | 170 | #endif /* !__ASSEMBLY__ */ |
a42089dd JF |
171 | |
172 | /* | |
173 | * Prefix forces emulation of some non-trapping instructions. | |
174 | * Currently only CPUID. | |
175 | */ | |
176 | #ifdef __ASSEMBLY__ | |
177 | #define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ; | |
178 | #define XEN_CPUID XEN_EMULATE_PREFIX cpuid | |
179 | #else | |
180 | #define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; " | |
181 | #define XEN_CPUID XEN_EMULATE_PREFIX "cpuid" | |
182 | #endif | |
183 | ||
05e4d316 | 184 | #endif /* _ASM_X86_XEN_INTERFACE_H */ |