xref: /illumos-gate/usr/src/uts/common/xen/public/arch-x86/xen.h (revision 968633ad8faee931821fd6b656eb0d96d4b186c0)
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 /*
28  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
29  * Use is subject to license terms.
30  */
31 
32 #include "../xen.h"
33 
34 #ifndef __XEN_PUBLIC_ARCH_X86_XEN_H__
35 #define __XEN_PUBLIC_ARCH_X86_XEN_H__
36 
37 /* Structural guest handles introduced in 0x00030201. */
38 #if __XEN_INTERFACE_VERSION__ >= 0x00030201
39 #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
40     typedef struct { type *p; } __guest_handle_ ## name
41 #else
42 #define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
43     typedef type * __guest_handle_ ## name
44 #endif
45 
46 #define __DEFINE_XEN_GUEST_HANDLE(name, type) \
47     ___DEFINE_XEN_GUEST_HANDLE(name, type)
48 #define DEFINE_XEN_GUEST_HANDLE(name)   __DEFINE_XEN_GUEST_HANDLE(name, name)
49 #define __XEN_GUEST_HANDLE(name)        __guest_handle_ ## name
50 #define XEN_GUEST_HANDLE(name)          __XEN_GUEST_HANDLE(name)
51 #if !defined(__GNUC__) && defined(__i386__)
52 #define set_xen_guest_handle_u(hnd, val)  do { (hnd).u.p = val; } while (0)
53 #define get_xen_guest_handle_u(val, hnd)  do { val = (hnd).u.p; } while (0)
54 #else
55 #define set_xen_guest_handle_u(hnd, val)  do { (hnd).p = val; } while (0)
56 #define get_xen_guest_handle_u(val, hnd)  do { val = (hnd).p; } while (0)
57 #endif
58 #define set_xen_guest_handle(hnd, val)  do { (hnd).p = val; } while (0)
59 #define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
60 
61 #if defined(__i386__)
62 #include "xen-x86_32.h"
63 #elif defined(__x86_64__)
64 #include "xen-x86_64.h"
65 #endif
66 
67 #ifndef __ASSEMBLY__
68 /* Guest handles for primitive C types. */
69 __DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char);
70 __DEFINE_XEN_GUEST_HANDLE(uint,  unsigned int);
71 __DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long);
72 DEFINE_XEN_GUEST_HANDLE(char);
73 DEFINE_XEN_GUEST_HANDLE(int);
74 DEFINE_XEN_GUEST_HANDLE(long);
75 DEFINE_XEN_GUEST_HANDLE(void);
76 
77 typedef unsigned long xen_pfn_t;
78 DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
79 #define PRI_xen_pfn "lx"
80 #endif
81 
82 /*
83  * SEGMENT DESCRIPTOR TABLES
84  */
85 /*
86  * A number of GDT entries are reserved by Xen. These are not situated at the
87  * start of the GDT because some stupid OSes export hard-coded selector values
88  * in their ABI. These hard-coded values are always near the start of the GDT,
89  * so Xen places itself out of the way, at the far end of the GDT.
90  */
91 #define FIRST_RESERVED_GDT_PAGE  14
92 #define FIRST_RESERVED_GDT_BYTE  (FIRST_RESERVED_GDT_PAGE * 4096)
93 #define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8)
94 
95 /* Maximum number of virtual CPUs in multi-processor guests. */
96 #define MAX_VIRT_CPUS 32
97 
98 
99 /* Machine check support */
100 #include "xen-mca.h"
101 
102 #ifndef __ASSEMBLY__
103 
104 typedef unsigned long xen_ulong_t;
105 
106 /*
107  * Send an array of these to HYPERVISOR_set_trap_table().
108  * The privilege level specifies which modes may enter a trap via a software
109  * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate
110  * privilege levels as follows:
111  *  Level == 0: Noone may enter
112  *  Level == 1: Kernel may enter
113  *  Level == 2: Kernel may enter
114  *  Level == 3: Everyone may enter
115  */
116 #define TI_GET_DPL(_ti)      ((_ti)->flags & 3)
117 #define TI_GET_IF(_ti)       ((_ti)->flags & 4)
118 #define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
119 #define TI_SET_IF(_ti,_if)   ((_ti)->flags |= ((!!(_if))<<2))
120 struct trap_info {
121     uint8_t       vector;  /* exception vector                              */
122     uint8_t       flags;   /* 0-3: privilege level; 4: clear event enable?  */
123     uint16_t      cs;      /* code selector                                 */
124     unsigned long address; /* code offset                                   */
125 };
126 typedef struct trap_info trap_info_t;
127 DEFINE_XEN_GUEST_HANDLE(trap_info_t);
128 
129 typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
130 
131 /*
132  * The following is all CPU context. Note that the fpu_ctxt block is filled
133  * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
134  */
135 struct vcpu_guest_context {
136     /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */
137     struct { char x[512]; } fpu_ctxt;       /* User-level FPU registers     */
138 #define VGCF_I387_VALID                (1<<0)
139 #define VGCF_IN_KERNEL                 (1<<2)
140 #define _VGCF_i387_valid               0
141 #define VGCF_i387_valid                (1<<_VGCF_i387_valid)
142 #define _VGCF_in_kernel                2
143 #define VGCF_in_kernel                 (1<<_VGCF_in_kernel)
144 #define _VGCF_failsafe_disables_events 3
145 #define VGCF_failsafe_disables_events  (1<<_VGCF_failsafe_disables_events)
146 #define _VGCF_syscall_disables_events  4
147 #define VGCF_syscall_disables_events   (1<<_VGCF_syscall_disables_events)
148 #define _VGCF_online                   5
149 #define VGCF_online                    (1<<_VGCF_online)
150     unsigned long flags;                    /* VGCF_* flags                 */
151     struct cpu_user_regs user_regs;         /* User-level CPU registers     */
152     struct trap_info trap_ctxt[256];        /* Virtual IDT                  */
153     unsigned long ldt_base, ldt_ents;       /* LDT (linear address, # ents) */
154     unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
155     unsigned long kernel_ss, kernel_sp;     /* Virtual TSS (only SS1/SP1)   */
156     /* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */
157     unsigned long ctrlreg[8];               /* CR0-CR7 (control registers)  */
158     unsigned long debugreg[8];              /* DB0-DB7 (debug registers)    */
159 #ifdef __i386__
160     unsigned long event_callback_cs;        /* CS:EIP of event callback     */
161     unsigned long event_callback_eip;
162     unsigned long failsafe_callback_cs;     /* CS:EIP of failsafe callback  */
163     unsigned long failsafe_callback_eip;
164 #else
165     unsigned long event_callback_eip;
166     unsigned long failsafe_callback_eip;
167 #ifdef __XEN__
168     union {
169         unsigned long syscall_callback_eip;
170         struct {
171             unsigned int event_callback_cs;    /* compat CS of event cb     */
172             unsigned int failsafe_callback_cs; /* compat CS of failsafe cb  */
173         };
174     };
175 #else
176     unsigned long syscall_callback_eip;
177 #endif
178 #endif
179     unsigned long vm_assist;                /* VMASST_TYPE_* bitmap */
180 #ifdef __x86_64__
181     /* Segment base addresses. */
182     uint64_t      fs_base;
183     uint64_t      gs_base_kernel;
184     uint64_t      gs_base_user;
185 #endif
186 };
187 typedef struct vcpu_guest_context vcpu_guest_context_t;
188 DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
189 
190 struct arch_shared_info {
191     unsigned long max_pfn;                  /* max pfn that appears in table */
192     /* Frame containing list of mfns containing list of mfns containing p2m. */
193     xen_pfn_t     pfn_to_mfn_frame_list_list;
194     unsigned long nmi_reason;
195     uint64_t pad[32];
196 };
197 typedef struct arch_shared_info arch_shared_info_t;
198 
199 #define	MCA_PANICDATA_MAGIC	0x5044	/* "PD" */
200 #define	MCA_PANICDATA_VERS	1
201 
202 typedef struct xpv_mca_panic_data {
203 	uint16_t mpd_magic;
204 	uint16_t mpd_version;
205 	int mpd_fwdptr_offset;
206 	int mpd_revptr_offset;
207 	int mpd_dataptr_offset;
208 	void *mpd_urgent_processing;
209 	void *mpd_urgent_dangling;
210 	void *mpd_urgent_committed;
211 	void *mpd_nonurgent_processing;
212 	void *mpd_nonurgent_dangling;
213 	void *mpd_nonurgent_committed;
214 } xpv_mca_panic_data_t;
215 
216 typedef struct panic_regs panic_regs_t;
217 struct panic_info {
218 	int		pi_version;	/* panic_info format version */
219 	panic_regs_t	*pi_regs;	/* register state */
220 	void		*pi_apic;	/* local APIC address */
221 	char		*pi_panicstr;	/* panic message */
222 	void		*pi_ram_start;	/* Start of all-RAM mapping region */
223 	void		*pi_ram_end;	/* End of all-RAM mapping region */
224 	void		*pi_xen_start;	/* Start of Xen's text/heap */
225 	void		*pi_xen_end;	/* End of Xen's text/heap */
226 	void		*pi_stktop;	/* Top of current Xen stack */
227 	struct domain	*pi_domain;	/* Panicking domain */
228 	struct vcpu	*pi_vcpu;	/* Panicking vcpu */
229 	int		pi_dom0cpu;	/* cpu number - if a dom0 panic */
230 	xpv_mca_panic_data_t pi_mca;	/* Machine check error telemetry */
231 };
232 
233 struct panic_frame {
234 	unsigned long	pf_fp;
235 	unsigned long	pf_pc;
236 };
237 
238 #define PANIC_INFO_VERSION	3
239 
240 #endif /* !__ASSEMBLY__ */
241 
242 /*
243  * Prefix forces emulation of some non-trapping instructions.
244  * Currently only CPUID.
245  */
246 #ifdef __ASSEMBLY__
247 #define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ;
248 #define XEN_CPUID          XEN_EMULATE_PREFIX cpuid
249 #else
250 #define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; "
251 #define XEN_CPUID          XEN_EMULATE_PREFIX "cpuid"
252 #endif
253 
254 #endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */
255 
256 /*
257  * Local variables:
258  * mode: C
259  * c-set-style: "BSD"
260  * c-basic-offset: 4
261  * tab-width: 4
262  * indent-tabs-mode: nil
263  * End:
264  */
265