root / targeti386 / svm.h @ b8b6a50b
History  View  Annotate  Download (10.1 kB)
1 
#ifndef __SVM_H


2 
#define __SVM_H

3  
4 
enum {

5 
/* We shift all the intercept bits so we can OR them with the

6 
TB flags later on */

7 
INTERCEPT_INTR = HF_HIF_SHIFT, 
8 
INTERCEPT_NMI, 
9 
INTERCEPT_SMI, 
10 
INTERCEPT_INIT, 
11 
INTERCEPT_VINTR, 
12 
INTERCEPT_SELECTIVE_CR0, 
13 
INTERCEPT_STORE_IDTR, 
14 
INTERCEPT_STORE_GDTR, 
15 
INTERCEPT_STORE_LDTR, 
16 
INTERCEPT_STORE_TR, 
17 
INTERCEPT_LOAD_IDTR, 
18 
INTERCEPT_LOAD_GDTR, 
19 
INTERCEPT_LOAD_LDTR, 
20 
INTERCEPT_LOAD_TR, 
21 
INTERCEPT_RDTSC, 
22 
INTERCEPT_RDPMC, 
23 
INTERCEPT_PUSHF, 
24 
INTERCEPT_POPF, 
25 
INTERCEPT_CPUID, 
26 
INTERCEPT_RSM, 
27 
INTERCEPT_IRET, 
28 
INTERCEPT_INTn, 
29 
INTERCEPT_INVD, 
30 
INTERCEPT_PAUSE, 
31 
INTERCEPT_HLT, 
32 
INTERCEPT_INVLPG, 
33 
INTERCEPT_INVLPGA, 
34 
INTERCEPT_IOIO_PROT, 
35 
INTERCEPT_MSR_PROT, 
36 
INTERCEPT_TASK_SWITCH, 
37 
INTERCEPT_FERR_FREEZE, 
38 
INTERCEPT_SHUTDOWN, 
39 
INTERCEPT_VMRUN, 
40 
INTERCEPT_VMMCALL, 
41 
INTERCEPT_VMLOAD, 
42 
INTERCEPT_VMSAVE, 
43 
INTERCEPT_STGI, 
44 
INTERCEPT_CLGI, 
45 
INTERCEPT_SKINIT, 
46 
INTERCEPT_RDTSCP, 
47 
INTERCEPT_ICEBP, 
48 
INTERCEPT_WBINVD, 
49 
}; 
50 
/* This is not really an intercept but rather a placeholder to

51 
show that we are in an SVM (just like a hidden flag, but keeps the

52 
TBs clean) */

53 
#define INTERCEPT_SVM 63 
54 
#define INTERCEPT_SVM_MASK (1ULL << INTERCEPT_SVM) 
55  
56 
struct __attribute__ ((__packed__)) vmcb_control_area {

57 
uint16_t intercept_cr_read; 
58 
uint16_t intercept_cr_write; 
59 
uint16_t intercept_dr_read; 
60 
uint16_t intercept_dr_write; 
61 
uint32_t intercept_exceptions; 
62 
uint64_t intercept; 
63 
uint8_t reserved_1[44];

64 
uint64_t iopm_base_pa; 
65 
uint64_t msrpm_base_pa; 
66 
uint64_t tsc_offset; 
67 
uint32_t asid; 
68 
uint8_t tlb_ctl; 
69 
uint8_t reserved_2[3];

70 
uint32_t int_ctl; 
71 
uint32_t int_vector; 
72 
uint32_t int_state; 
73 
uint8_t reserved_3[4];

74 
uint64_t exit_code; 
75 
uint64_t exit_info_1; 
76 
uint64_t exit_info_2; 
77 
uint32_t exit_int_info; 
78 
uint32_t exit_int_info_err; 
79 
uint64_t nested_ctl; 
80 
uint8_t reserved_4[16];

81 
uint32_t event_inj; 
82 
uint32_t event_inj_err; 
83 
uint64_t nested_cr3; 
84 
uint64_t lbr_ctl; 
85 
uint8_t reserved_5[832];

86 
}; 
87  
88  
89 
#define TLB_CONTROL_DO_NOTHING 0 
90 
#define TLB_CONTROL_FLUSH_ALL_ASID 1 
91  
92 
#define V_TPR_MASK 0x0f 
93  
94 
#define V_IRQ_SHIFT 8 
95 
#define V_IRQ_MASK (1 << V_IRQ_SHIFT) 
96  
97 
#define V_INTR_PRIO_SHIFT 16 
98 
#define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT) 
99  
100 
#define V_IGN_TPR_SHIFT 20 
101 
#define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT) 
102  
103 
#define V_INTR_MASKING_SHIFT 24 
104 
#define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) 
105  
106 
#define SVM_INTERRUPT_SHADOW_MASK 1 
107  
108 
#define SVM_IOIO_STR_SHIFT 2 
109 
#define SVM_IOIO_REP_SHIFT 3 
110 
#define SVM_IOIO_SIZE_SHIFT 4 
111 
#define SVM_IOIO_ASIZE_SHIFT 7 
112  
113 
#define SVM_IOIO_TYPE_MASK 1 
114 
#define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT) 
115 
#define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT) 
116 
#define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT) 
117 
#define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT) 
118  
119 
struct __attribute__ ((__packed__)) vmcb_seg {

120 
uint16_t selector; 
121 
uint16_t attrib; 
122 
uint32_t limit; 
123 
uint64_t base; 
124 
}; 
125  
126 
struct __attribute__ ((__packed__)) vmcb_save_area {

127 
struct vmcb_seg es;

128 
struct vmcb_seg cs;

129 
struct vmcb_seg ss;

130 
struct vmcb_seg ds;

131 
struct vmcb_seg fs;

132 
struct vmcb_seg gs;

133 
struct vmcb_seg gdtr;

134 
struct vmcb_seg ldtr;

135 
struct vmcb_seg idtr;

136 
struct vmcb_seg tr;

137 
uint8_t reserved_1[43];

138 
uint8_t cpl; 
139 
uint8_t reserved_2[4];

140 
uint64_t efer; 
141 
uint8_t reserved_3[112];

142 
uint64_t cr4; 
143 
uint64_t cr3; 
144 
uint64_t cr0; 
145 
uint64_t dr7; 
146 
uint64_t dr6; 
147 
uint64_t rflags; 
148 
uint64_t rip; 
149 
uint8_t reserved_4[88];

150 
uint64_t rsp; 
151 
uint8_t reserved_5[24];

152 
uint64_t rax; 
153 
uint64_t star; 
154 
uint64_t lstar; 
155 
uint64_t cstar; 
156 
uint64_t sfmask; 
157 
uint64_t kernel_gs_base; 
158 
uint64_t sysenter_cs; 
159 
uint64_t sysenter_esp; 
160 
uint64_t sysenter_eip; 
161 
uint64_t cr2; 
162 
/* qemu: cr8 added to reuse this as hsave */

163 
uint64_t cr8; 
164 
uint8_t reserved_6[32  8]; /* originally 32 */ 
165 
uint64_t g_pat; 
166 
uint64_t dbgctl; 
167 
uint64_t br_from; 
168 
uint64_t br_to; 
169 
uint64_t last_excp_from; 
170 
uint64_t last_excp_to; 
171 
}; 
172  
173 
struct __attribute__ ((__packed__)) vmcb {

174 
struct vmcb_control_area control;

175 
struct vmcb_save_area save;

176 
}; 
177  
178 
#define SVM_CPUID_FEATURE_SHIFT 2 
179 
#define SVM_CPUID_FUNC 0x8000000a 
180  
181 
#define MSR_EFER_SVME_MASK (1ULL << 12) 
182  
183 
#define SVM_SELECTOR_S_SHIFT 4 
184 
#define SVM_SELECTOR_DPL_SHIFT 5 
185 
#define SVM_SELECTOR_P_SHIFT 7 
186 
#define SVM_SELECTOR_AVL_SHIFT 8 
187 
#define SVM_SELECTOR_L_SHIFT 9 
188 
#define SVM_SELECTOR_DB_SHIFT 10 
189 
#define SVM_SELECTOR_G_SHIFT 11 
190  
191 
#define SVM_SELECTOR_TYPE_MASK (0xf) 
192 
#define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT) 
193 
#define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT) 
194 
#define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT) 
195 
#define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT) 
196 
#define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT) 
197 
#define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT) 
198 
#define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT) 
199  
200 
#define SVM_SELECTOR_WRITE_MASK (1 << 1) 
201 
#define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK

202 
#define SVM_SELECTOR_CODE_MASK (1 << 3) 
203  
204 
#define INTERCEPT_CR0_MASK 1 
205 
#define INTERCEPT_CR3_MASK (1 << 3) 
206 
#define INTERCEPT_CR4_MASK (1 << 4) 
207  
208 
#define INTERCEPT_DR0_MASK 1 
209 
#define INTERCEPT_DR1_MASK (1 << 1) 
210 
#define INTERCEPT_DR2_MASK (1 << 2) 
211 
#define INTERCEPT_DR3_MASK (1 << 3) 
212 
#define INTERCEPT_DR4_MASK (1 << 4) 
213 
#define INTERCEPT_DR5_MASK (1 << 5) 
214 
#define INTERCEPT_DR6_MASK (1 << 6) 
215 
#define INTERCEPT_DR7_MASK (1 << 7) 
216  
217 
#define SVM_EVTINJ_VEC_MASK 0xff 
218  
219 
#define SVM_EVTINJ_TYPE_SHIFT 8 
220 
#define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT) 
221  
222 
#define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT) 
223 
#define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT) 
224 
#define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT) 
225 
#define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT) 
226  
227 
#define SVM_EVTINJ_VALID (1 << 31) 
228 
#define SVM_EVTINJ_VALID_ERR (1 << 11) 
229  
230 
#define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK

231  
232 
#define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR

233 
#define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI

234 
#define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT

235 
#define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT

236  
237 
#define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID

238 
#define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR

239  
240 
#define SVM_EXIT_READ_CR0 0x000 
241 
#define SVM_EXIT_READ_CR3 0x003 
242 
#define SVM_EXIT_READ_CR4 0x004 
243 
#define SVM_EXIT_READ_CR8 0x008 
244 
#define SVM_EXIT_WRITE_CR0 0x010 
245 
#define SVM_EXIT_WRITE_CR3 0x013 
246 
#define SVM_EXIT_WRITE_CR4 0x014 
247 
#define SVM_EXIT_WRITE_CR8 0x018 
248 
#define SVM_EXIT_READ_DR0 0x020 
249 
#define SVM_EXIT_READ_DR1 0x021 
250 
#define SVM_EXIT_READ_DR2 0x022 
251 
#define SVM_EXIT_READ_DR3 0x023 
252 
#define SVM_EXIT_READ_DR4 0x024 
253 
#define SVM_EXIT_READ_DR5 0x025 
254 
#define SVM_EXIT_READ_DR6 0x026 
255 
#define SVM_EXIT_READ_DR7 0x027 
256 
#define SVM_EXIT_WRITE_DR0 0x030 
257 
#define SVM_EXIT_WRITE_DR1 0x031 
258 
#define SVM_EXIT_WRITE_DR2 0x032 
259 
#define SVM_EXIT_WRITE_DR3 0x033 
260 
#define SVM_EXIT_WRITE_DR4 0x034 
261 
#define SVM_EXIT_WRITE_DR5 0x035 
262 
#define SVM_EXIT_WRITE_DR6 0x036 
263 
#define SVM_EXIT_WRITE_DR7 0x037 
264 
#define SVM_EXIT_EXCP_BASE 0x040 
265 
#define SVM_EXIT_INTR 0x060 
266 
#define SVM_EXIT_NMI 0x061 
267 
#define SVM_EXIT_SMI 0x062 
268 
#define SVM_EXIT_INIT 0x063 
269 
#define SVM_EXIT_VINTR 0x064 
270 
#define SVM_EXIT_CR0_SEL_WRITE 0x065 
271 
#define SVM_EXIT_IDTR_READ 0x066 
272 
#define SVM_EXIT_GDTR_READ 0x067 
273 
#define SVM_EXIT_LDTR_READ 0x068 
274 
#define SVM_EXIT_TR_READ 0x069 
275 
#define SVM_EXIT_IDTR_WRITE 0x06a 
276 
#define SVM_EXIT_GDTR_WRITE 0x06b 
277 
#define SVM_EXIT_LDTR_WRITE 0x06c 
278 
#define SVM_EXIT_TR_WRITE 0x06d 
279 
#define SVM_EXIT_RDTSC 0x06e 
280 
#define SVM_EXIT_RDPMC 0x06f 
281 
#define SVM_EXIT_PUSHF 0x070 
282 
#define SVM_EXIT_POPF 0x071 
283 
#define SVM_EXIT_CPUID 0x072 
284 
#define SVM_EXIT_RSM 0x073 
285 
#define SVM_EXIT_IRET 0x074 
286 
#define SVM_EXIT_SWINT 0x075 
287 
#define SVM_EXIT_INVD 0x076 
288 
#define SVM_EXIT_PAUSE 0x077 
289 
#define SVM_EXIT_HLT 0x078 
290 
#define SVM_EXIT_INVLPG 0x079 
291 
#define SVM_EXIT_INVLPGA 0x07a 
292 
#define SVM_EXIT_IOIO 0x07b 
293 
#define SVM_EXIT_MSR 0x07c 
294 
#define SVM_EXIT_TASK_SWITCH 0x07d 
295 
#define SVM_EXIT_FERR_FREEZE 0x07e 
296 
#define SVM_EXIT_SHUTDOWN 0x07f 
297 
#define SVM_EXIT_VMRUN 0x080 
298 
#define SVM_EXIT_VMMCALL 0x081 
299 
#define SVM_EXIT_VMLOAD 0x082 
300 
#define SVM_EXIT_VMSAVE 0x083 
301 
#define SVM_EXIT_STGI 0x084 
302 
#define SVM_EXIT_CLGI 0x085 
303 
#define SVM_EXIT_SKINIT 0x086 
304 
#define SVM_EXIT_RDTSCP 0x087 
305 
#define SVM_EXIT_ICEBP 0x088 
306 
#define SVM_EXIT_WBINVD 0x089 
307 
/* only included in documentation, maybe wrong */

308 
#define SVM_EXIT_MONITOR 0x08a 
309 
#define SVM_EXIT_MWAIT 0x08b 
310 
#define SVM_EXIT_NPF 0x400 
311  
312 
#define SVM_EXIT_ERR 1 
313  
314 
#define SVM_CR0_SELECTIVE_MASK (1 << 3  1) /* TS and MP */ 
315  
316 
#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda" 
317 
#define SVM_VMRUN ".byte 0x0f, 0x01, 0xd8" 
318 
#define SVM_VMSAVE ".byte 0x0f, 0x01, 0xdb" 
319 
#define SVM_CLGI ".byte 0x0f, 0x01, 0xdd" 
320 
#define SVM_STGI ".byte 0x0f, 0x01, 0xdc" 
321 
#define SVM_INVLPGA ".byte 0x0f, 0x01, 0xdf" 
322  
323 
/* function references */

324  
325 
#define INTERCEPTED(mask) (env>intercept & mask)

326 
#define INTERCEPTEDw(var, mask) (env>intercept ## var & mask) 
327 
#define INTERCEPTEDl(var, mask) (env>intercept ## var & mask) 
328  
329 
#define SVM_LOAD_SEG(addr, seg_index, seg) \

330 
cpu_x86_load_seg_cache(env, \ 
331 
R_##seg_index, \ 
332 
lduw_phys(addr + offsetof(struct vmcb, save.seg.selector)),\

333 
ldq_phys(addr + offsetof(struct vmcb, save.seg.base)),\

334 
ldl_phys(addr + offsetof(struct vmcb, save.seg.limit)),\

335 
vmcb2cpu_attrib(lduw_phys(addr + offsetof(struct vmcb, save.seg.attrib)), ldq_phys(addr + offsetof(struct vmcb, save.seg.base)), ldl_phys(addr + offsetof(struct vmcb, save.seg.limit)))) 
336  
337 
#define SVM_LOAD_SEG2(addr, seg_qemu, seg_vmcb) \

338 
env>seg_qemu.selector = lduw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.selector)); \

339 
env>seg_qemu.base = ldq_phys(addr + offsetof(struct vmcb, save.seg_vmcb.base)); \

340 
env>seg_qemu.limit = ldl_phys(addr + offsetof(struct vmcb, save.seg_vmcb.limit)); \

341 
env>seg_qemu.flags = vmcb2cpu_attrib(lduw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.attrib)), env>seg_qemu.base, env>seg_qemu.limit)

342  
343 
#define SVM_SAVE_SEG(addr, seg_qemu, seg_vmcb) \

344 
stw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.selector), env>seg_qemu.selector); \

345 
stq_phys(addr + offsetof(struct vmcb, save.seg_vmcb.base), env>seg_qemu.base); \

346 
stl_phys(addr + offsetof(struct vmcb, save.seg_vmcb.limit), env>seg_qemu.limit); \

347 
stw_phys(addr + offsetof(struct vmcb, save.seg_vmcb.attrib), cpu2vmcb_attrib(env>seg_qemu.flags))

348  
349 
#endif
