]>
Commit | Line | Data |
---|---|---|
18178ff8 VK |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* | |
3 | * tools/testing/selftests/kvm/include/vmx.h | |
4 | * | |
5 | * Copyright (C) 2018, Red Hat, Inc. | |
6 | * | |
7 | */ | |
8 | ||
9 | #ifndef SELFTEST_KVM_EVMCS_H | |
10 | #define SELFTEST_KVM_EVMCS_H | |
11 | ||
12 | #include <stdint.h> | |
13 | #include "vmx.h" | |
14 | ||
15 | #define u16 uint16_t | |
16 | #define u32 uint32_t | |
17 | #define u64 uint64_t | |
18 | ||
7bcf732e VK |
19 | #define EVMCS_VERSION 1 |
20 | ||
18178ff8 VK |
21 | extern bool enable_evmcs; |
22 | ||
23 | struct hv_vp_assist_page { | |
24 | __u32 apic_assist; | |
25 | __u32 reserved; | |
26 | __u64 vtl_control[2]; | |
27 | __u64 nested_enlightenments_control[2]; | |
28 | __u32 enlighten_vmentry; | |
29 | __u64 current_nested_vmcs; | |
30 | }; | |
31 | ||
32 | struct hv_enlightened_vmcs { | |
33 | u32 revision_id; | |
34 | u32 abort; | |
35 | ||
36 | u16 host_es_selector; | |
37 | u16 host_cs_selector; | |
38 | u16 host_ss_selector; | |
39 | u16 host_ds_selector; | |
40 | u16 host_fs_selector; | |
41 | u16 host_gs_selector; | |
42 | u16 host_tr_selector; | |
43 | ||
44 | u64 host_ia32_pat; | |
45 | u64 host_ia32_efer; | |
46 | ||
47 | u64 host_cr0; | |
48 | u64 host_cr3; | |
49 | u64 host_cr4; | |
50 | ||
51 | u64 host_ia32_sysenter_esp; | |
52 | u64 host_ia32_sysenter_eip; | |
53 | u64 host_rip; | |
54 | u32 host_ia32_sysenter_cs; | |
55 | ||
56 | u32 pin_based_vm_exec_control; | |
57 | u32 vm_exit_controls; | |
58 | u32 secondary_vm_exec_control; | |
59 | ||
60 | u64 io_bitmap_a; | |
61 | u64 io_bitmap_b; | |
62 | u64 msr_bitmap; | |
63 | ||
64 | u16 guest_es_selector; | |
65 | u16 guest_cs_selector; | |
66 | u16 guest_ss_selector; | |
67 | u16 guest_ds_selector; | |
68 | u16 guest_fs_selector; | |
69 | u16 guest_gs_selector; | |
70 | u16 guest_ldtr_selector; | |
71 | u16 guest_tr_selector; | |
72 | ||
73 | u32 guest_es_limit; | |
74 | u32 guest_cs_limit; | |
75 | u32 guest_ss_limit; | |
76 | u32 guest_ds_limit; | |
77 | u32 guest_fs_limit; | |
78 | u32 guest_gs_limit; | |
79 | u32 guest_ldtr_limit; | |
80 | u32 guest_tr_limit; | |
81 | u32 guest_gdtr_limit; | |
82 | u32 guest_idtr_limit; | |
83 | ||
84 | u32 guest_es_ar_bytes; | |
85 | u32 guest_cs_ar_bytes; | |
86 | u32 guest_ss_ar_bytes; | |
87 | u32 guest_ds_ar_bytes; | |
88 | u32 guest_fs_ar_bytes; | |
89 | u32 guest_gs_ar_bytes; | |
90 | u32 guest_ldtr_ar_bytes; | |
91 | u32 guest_tr_ar_bytes; | |
92 | ||
93 | u64 guest_es_base; | |
94 | u64 guest_cs_base; | |
95 | u64 guest_ss_base; | |
96 | u64 guest_ds_base; | |
97 | u64 guest_fs_base; | |
98 | u64 guest_gs_base; | |
99 | u64 guest_ldtr_base; | |
100 | u64 guest_tr_base; | |
101 | u64 guest_gdtr_base; | |
102 | u64 guest_idtr_base; | |
103 | ||
104 | u64 padding64_1[3]; | |
105 | ||
106 | u64 vm_exit_msr_store_addr; | |
107 | u64 vm_exit_msr_load_addr; | |
108 | u64 vm_entry_msr_load_addr; | |
109 | ||
110 | u64 cr3_target_value0; | |
111 | u64 cr3_target_value1; | |
112 | u64 cr3_target_value2; | |
113 | u64 cr3_target_value3; | |
114 | ||
115 | u32 page_fault_error_code_mask; | |
116 | u32 page_fault_error_code_match; | |
117 | ||
118 | u32 cr3_target_count; | |
119 | u32 vm_exit_msr_store_count; | |
120 | u32 vm_exit_msr_load_count; | |
121 | u32 vm_entry_msr_load_count; | |
122 | ||
123 | u64 tsc_offset; | |
124 | u64 virtual_apic_page_addr; | |
125 | u64 vmcs_link_pointer; | |
126 | ||
127 | u64 guest_ia32_debugctl; | |
128 | u64 guest_ia32_pat; | |
129 | u64 guest_ia32_efer; | |
130 | ||
131 | u64 guest_pdptr0; | |
132 | u64 guest_pdptr1; | |
133 | u64 guest_pdptr2; | |
134 | u64 guest_pdptr3; | |
135 | ||
136 | u64 guest_pending_dbg_exceptions; | |
137 | u64 guest_sysenter_esp; | |
138 | u64 guest_sysenter_eip; | |
139 | ||
140 | u32 guest_activity_state; | |
141 | u32 guest_sysenter_cs; | |
142 | ||
143 | u64 cr0_guest_host_mask; | |
144 | u64 cr4_guest_host_mask; | |
145 | u64 cr0_read_shadow; | |
146 | u64 cr4_read_shadow; | |
147 | u64 guest_cr0; | |
148 | u64 guest_cr3; | |
149 | u64 guest_cr4; | |
150 | u64 guest_dr7; | |
151 | ||
152 | u64 host_fs_base; | |
153 | u64 host_gs_base; | |
154 | u64 host_tr_base; | |
155 | u64 host_gdtr_base; | |
156 | u64 host_idtr_base; | |
157 | u64 host_rsp; | |
158 | ||
159 | u64 ept_pointer; | |
160 | ||
161 | u16 virtual_processor_id; | |
162 | u16 padding16[3]; | |
163 | ||
164 | u64 padding64_2[5]; | |
165 | u64 guest_physical_address; | |
166 | ||
167 | u32 vm_instruction_error; | |
168 | u32 vm_exit_reason; | |
169 | u32 vm_exit_intr_info; | |
170 | u32 vm_exit_intr_error_code; | |
171 | u32 idt_vectoring_info_field; | |
172 | u32 idt_vectoring_error_code; | |
173 | u32 vm_exit_instruction_len; | |
174 | u32 vmx_instruction_info; | |
175 | ||
176 | u64 exit_qualification; | |
177 | u64 exit_io_instruction_ecx; | |
178 | u64 exit_io_instruction_esi; | |
179 | u64 exit_io_instruction_edi; | |
180 | u64 exit_io_instruction_eip; | |
181 | ||
182 | u64 guest_linear_address; | |
183 | u64 guest_rsp; | |
184 | u64 guest_rflags; | |
185 | ||
186 | u32 guest_interruptibility_info; | |
187 | u32 cpu_based_vm_exec_control; | |
188 | u32 exception_bitmap; | |
189 | u32 vm_entry_controls; | |
190 | u32 vm_entry_intr_info_field; | |
191 | u32 vm_entry_exception_error_code; | |
192 | u32 vm_entry_instruction_len; | |
193 | u32 tpr_threshold; | |
194 | ||
195 | u64 guest_rip; | |
196 | ||
197 | u32 hv_clean_fields; | |
198 | u32 hv_padding_32; | |
199 | u32 hv_synthetic_controls; | |
200 | struct { | |
201 | u32 nested_flush_hypercall:1; | |
202 | u32 msr_bitmap:1; | |
203 | u32 reserved:30; | |
204 | } hv_enlightenments_control; | |
205 | u32 hv_vp_id; | |
206 | ||
207 | u64 hv_vm_id; | |
208 | u64 partition_assist_page; | |
209 | u64 padding64_4[4]; | |
210 | u64 guest_bndcfgs; | |
211 | u64 padding64_5[7]; | |
212 | u64 xss_exit_bitmap; | |
213 | u64 padding64_6[7]; | |
214 | }; | |
215 | ||
216 | #define HV_X64_MSR_VP_ASSIST_PAGE 0x40000073 | |
217 | #define HV_X64_MSR_VP_ASSIST_PAGE_ENABLE 0x00000001 | |
218 | #define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT 12 | |
219 | #define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_MASK \ | |
220 | (~((1ull << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT) - 1)) | |
221 | ||
8ffdaf91 PX |
222 | extern struct hv_enlightened_vmcs *current_evmcs; |
223 | extern struct hv_vp_assist_page *current_vp_assist; | |
18178ff8 | 224 | |
65efa61d PB |
225 | int vcpu_enable_evmcs(struct kvm_vm *vm, int vcpu_id); |
226 | ||
18178ff8 VK |
227 | static inline int enable_vp_assist(uint64_t vp_assist_pa, void *vp_assist) |
228 | { | |
229 | u64 val = (vp_assist_pa & HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_MASK) | | |
230 | HV_X64_MSR_VP_ASSIST_PAGE_ENABLE; | |
231 | ||
232 | wrmsr(HV_X64_MSR_VP_ASSIST_PAGE, val); | |
233 | ||
234 | current_vp_assist = vp_assist; | |
235 | ||
236 | enable_evmcs = true; | |
237 | ||
238 | return 0; | |
239 | } | |
240 | ||
241 | static inline int evmcs_vmptrld(uint64_t vmcs_pa, void *vmcs) | |
242 | { | |
243 | current_vp_assist->current_nested_vmcs = vmcs_pa; | |
244 | current_vp_assist->enlighten_vmentry = 1; | |
245 | ||
246 | current_evmcs = vmcs; | |
247 | ||
248 | return 0; | |
249 | } | |
250 | ||
251 | static inline int evmcs_vmptrst(uint64_t *value) | |
252 | { | |
253 | *value = current_vp_assist->current_nested_vmcs & | |
254 | ~HV_X64_MSR_VP_ASSIST_PAGE_ENABLE; | |
255 | ||
256 | return 0; | |
257 | } | |
258 | ||
259 | static inline int evmcs_vmread(uint64_t encoding, uint64_t *value) | |
260 | { | |
261 | switch (encoding) { | |
262 | case GUEST_RIP: | |
263 | *value = current_evmcs->guest_rip; | |
264 | break; | |
265 | case GUEST_RSP: | |
266 | *value = current_evmcs->guest_rsp; | |
267 | break; | |
268 | case GUEST_RFLAGS: | |
269 | *value = current_evmcs->guest_rflags; | |
270 | break; | |
271 | case HOST_IA32_PAT: | |
272 | *value = current_evmcs->host_ia32_pat; | |
273 | break; | |
274 | case HOST_IA32_EFER: | |
275 | *value = current_evmcs->host_ia32_efer; | |
276 | break; | |
277 | case HOST_CR0: | |
278 | *value = current_evmcs->host_cr0; | |
279 | break; | |
280 | case HOST_CR3: | |
281 | *value = current_evmcs->host_cr3; | |
282 | break; | |
283 | case HOST_CR4: | |
284 | *value = current_evmcs->host_cr4; | |
285 | break; | |
286 | case HOST_IA32_SYSENTER_ESP: | |
287 | *value = current_evmcs->host_ia32_sysenter_esp; | |
288 | break; | |
289 | case HOST_IA32_SYSENTER_EIP: | |
290 | *value = current_evmcs->host_ia32_sysenter_eip; | |
291 | break; | |
292 | case HOST_RIP: | |
293 | *value = current_evmcs->host_rip; | |
294 | break; | |
295 | case IO_BITMAP_A: | |
296 | *value = current_evmcs->io_bitmap_a; | |
297 | break; | |
298 | case IO_BITMAP_B: | |
299 | *value = current_evmcs->io_bitmap_b; | |
300 | break; | |
301 | case MSR_BITMAP: | |
302 | *value = current_evmcs->msr_bitmap; | |
303 | break; | |
304 | case GUEST_ES_BASE: | |
305 | *value = current_evmcs->guest_es_base; | |
306 | break; | |
307 | case GUEST_CS_BASE: | |
308 | *value = current_evmcs->guest_cs_base; | |
309 | break; | |
310 | case GUEST_SS_BASE: | |
311 | *value = current_evmcs->guest_ss_base; | |
312 | break; | |
313 | case GUEST_DS_BASE: | |
314 | *value = current_evmcs->guest_ds_base; | |
315 | break; | |
316 | case GUEST_FS_BASE: | |
317 | *value = current_evmcs->guest_fs_base; | |
318 | break; | |
319 | case GUEST_GS_BASE: | |
320 | *value = current_evmcs->guest_gs_base; | |
321 | break; | |
322 | case GUEST_LDTR_BASE: | |
323 | *value = current_evmcs->guest_ldtr_base; | |
324 | break; | |
325 | case GUEST_TR_BASE: | |
326 | *value = current_evmcs->guest_tr_base; | |
327 | break; | |
328 | case GUEST_GDTR_BASE: | |
329 | *value = current_evmcs->guest_gdtr_base; | |
330 | break; | |
331 | case GUEST_IDTR_BASE: | |
332 | *value = current_evmcs->guest_idtr_base; | |
333 | break; | |
334 | case TSC_OFFSET: | |
335 | *value = current_evmcs->tsc_offset; | |
336 | break; | |
337 | case VIRTUAL_APIC_PAGE_ADDR: | |
338 | *value = current_evmcs->virtual_apic_page_addr; | |
339 | break; | |
340 | case VMCS_LINK_POINTER: | |
341 | *value = current_evmcs->vmcs_link_pointer; | |
342 | break; | |
343 | case GUEST_IA32_DEBUGCTL: | |
344 | *value = current_evmcs->guest_ia32_debugctl; | |
345 | break; | |
346 | case GUEST_IA32_PAT: | |
347 | *value = current_evmcs->guest_ia32_pat; | |
348 | break; | |
349 | case GUEST_IA32_EFER: | |
350 | *value = current_evmcs->guest_ia32_efer; | |
351 | break; | |
352 | case GUEST_PDPTR0: | |
353 | *value = current_evmcs->guest_pdptr0; | |
354 | break; | |
355 | case GUEST_PDPTR1: | |
356 | *value = current_evmcs->guest_pdptr1; | |
357 | break; | |
358 | case GUEST_PDPTR2: | |
359 | *value = current_evmcs->guest_pdptr2; | |
360 | break; | |
361 | case GUEST_PDPTR3: | |
362 | *value = current_evmcs->guest_pdptr3; | |
363 | break; | |
364 | case GUEST_PENDING_DBG_EXCEPTIONS: | |
365 | *value = current_evmcs->guest_pending_dbg_exceptions; | |
366 | break; | |
367 | case GUEST_SYSENTER_ESP: | |
368 | *value = current_evmcs->guest_sysenter_esp; | |
369 | break; | |
370 | case GUEST_SYSENTER_EIP: | |
371 | *value = current_evmcs->guest_sysenter_eip; | |
372 | break; | |
373 | case CR0_GUEST_HOST_MASK: | |
374 | *value = current_evmcs->cr0_guest_host_mask; | |
375 | break; | |
376 | case CR4_GUEST_HOST_MASK: | |
377 | *value = current_evmcs->cr4_guest_host_mask; | |
378 | break; | |
379 | case CR0_READ_SHADOW: | |
380 | *value = current_evmcs->cr0_read_shadow; | |
381 | break; | |
382 | case CR4_READ_SHADOW: | |
383 | *value = current_evmcs->cr4_read_shadow; | |
384 | break; | |
385 | case GUEST_CR0: | |
386 | *value = current_evmcs->guest_cr0; | |
387 | break; | |
388 | case GUEST_CR3: | |
389 | *value = current_evmcs->guest_cr3; | |
390 | break; | |
391 | case GUEST_CR4: | |
392 | *value = current_evmcs->guest_cr4; | |
393 | break; | |
394 | case GUEST_DR7: | |
395 | *value = current_evmcs->guest_dr7; | |
396 | break; | |
397 | case HOST_FS_BASE: | |
398 | *value = current_evmcs->host_fs_base; | |
399 | break; | |
400 | case HOST_GS_BASE: | |
401 | *value = current_evmcs->host_gs_base; | |
402 | break; | |
403 | case HOST_TR_BASE: | |
404 | *value = current_evmcs->host_tr_base; | |
405 | break; | |
406 | case HOST_GDTR_BASE: | |
407 | *value = current_evmcs->host_gdtr_base; | |
408 | break; | |
409 | case HOST_IDTR_BASE: | |
410 | *value = current_evmcs->host_idtr_base; | |
411 | break; | |
412 | case HOST_RSP: | |
413 | *value = current_evmcs->host_rsp; | |
414 | break; | |
415 | case EPT_POINTER: | |
416 | *value = current_evmcs->ept_pointer; | |
417 | break; | |
418 | case GUEST_BNDCFGS: | |
419 | *value = current_evmcs->guest_bndcfgs; | |
420 | break; | |
421 | case XSS_EXIT_BITMAP: | |
422 | *value = current_evmcs->xss_exit_bitmap; | |
423 | break; | |
424 | case GUEST_PHYSICAL_ADDRESS: | |
425 | *value = current_evmcs->guest_physical_address; | |
426 | break; | |
427 | case EXIT_QUALIFICATION: | |
428 | *value = current_evmcs->exit_qualification; | |
429 | break; | |
430 | case GUEST_LINEAR_ADDRESS: | |
431 | *value = current_evmcs->guest_linear_address; | |
432 | break; | |
433 | case VM_EXIT_MSR_STORE_ADDR: | |
434 | *value = current_evmcs->vm_exit_msr_store_addr; | |
435 | break; | |
436 | case VM_EXIT_MSR_LOAD_ADDR: | |
437 | *value = current_evmcs->vm_exit_msr_load_addr; | |
438 | break; | |
439 | case VM_ENTRY_MSR_LOAD_ADDR: | |
440 | *value = current_evmcs->vm_entry_msr_load_addr; | |
441 | break; | |
442 | case CR3_TARGET_VALUE0: | |
443 | *value = current_evmcs->cr3_target_value0; | |
444 | break; | |
445 | case CR3_TARGET_VALUE1: | |
446 | *value = current_evmcs->cr3_target_value1; | |
447 | break; | |
448 | case CR3_TARGET_VALUE2: | |
449 | *value = current_evmcs->cr3_target_value2; | |
450 | break; | |
451 | case CR3_TARGET_VALUE3: | |
452 | *value = current_evmcs->cr3_target_value3; | |
453 | break; | |
454 | case TPR_THRESHOLD: | |
455 | *value = current_evmcs->tpr_threshold; | |
456 | break; | |
457 | case GUEST_INTERRUPTIBILITY_INFO: | |
458 | *value = current_evmcs->guest_interruptibility_info; | |
459 | break; | |
460 | case CPU_BASED_VM_EXEC_CONTROL: | |
461 | *value = current_evmcs->cpu_based_vm_exec_control; | |
462 | break; | |
463 | case EXCEPTION_BITMAP: | |
464 | *value = current_evmcs->exception_bitmap; | |
465 | break; | |
466 | case VM_ENTRY_CONTROLS: | |
467 | *value = current_evmcs->vm_entry_controls; | |
468 | break; | |
469 | case VM_ENTRY_INTR_INFO_FIELD: | |
470 | *value = current_evmcs->vm_entry_intr_info_field; | |
471 | break; | |
472 | case VM_ENTRY_EXCEPTION_ERROR_CODE: | |
473 | *value = current_evmcs->vm_entry_exception_error_code; | |
474 | break; | |
475 | case VM_ENTRY_INSTRUCTION_LEN: | |
476 | *value = current_evmcs->vm_entry_instruction_len; | |
477 | break; | |
478 | case HOST_IA32_SYSENTER_CS: | |
479 | *value = current_evmcs->host_ia32_sysenter_cs; | |
480 | break; | |
481 | case PIN_BASED_VM_EXEC_CONTROL: | |
482 | *value = current_evmcs->pin_based_vm_exec_control; | |
483 | break; | |
484 | case VM_EXIT_CONTROLS: | |
485 | *value = current_evmcs->vm_exit_controls; | |
486 | break; | |
487 | case SECONDARY_VM_EXEC_CONTROL: | |
488 | *value = current_evmcs->secondary_vm_exec_control; | |
489 | break; | |
490 | case GUEST_ES_LIMIT: | |
491 | *value = current_evmcs->guest_es_limit; | |
492 | break; | |
493 | case GUEST_CS_LIMIT: | |
494 | *value = current_evmcs->guest_cs_limit; | |
495 | break; | |
496 | case GUEST_SS_LIMIT: | |
497 | *value = current_evmcs->guest_ss_limit; | |
498 | break; | |
499 | case GUEST_DS_LIMIT: | |
500 | *value = current_evmcs->guest_ds_limit; | |
501 | break; | |
502 | case GUEST_FS_LIMIT: | |
503 | *value = current_evmcs->guest_fs_limit; | |
504 | break; | |
505 | case GUEST_GS_LIMIT: | |
506 | *value = current_evmcs->guest_gs_limit; | |
507 | break; | |
508 | case GUEST_LDTR_LIMIT: | |
509 | *value = current_evmcs->guest_ldtr_limit; | |
510 | break; | |
511 | case GUEST_TR_LIMIT: | |
512 | *value = current_evmcs->guest_tr_limit; | |
513 | break; | |
514 | case GUEST_GDTR_LIMIT: | |
515 | *value = current_evmcs->guest_gdtr_limit; | |
516 | break; | |
517 | case GUEST_IDTR_LIMIT: | |
518 | *value = current_evmcs->guest_idtr_limit; | |
519 | break; | |
520 | case GUEST_ES_AR_BYTES: | |
521 | *value = current_evmcs->guest_es_ar_bytes; | |
522 | break; | |
523 | case GUEST_CS_AR_BYTES: | |
524 | *value = current_evmcs->guest_cs_ar_bytes; | |
525 | break; | |
526 | case GUEST_SS_AR_BYTES: | |
527 | *value = current_evmcs->guest_ss_ar_bytes; | |
528 | break; | |
529 | case GUEST_DS_AR_BYTES: | |
530 | *value = current_evmcs->guest_ds_ar_bytes; | |
531 | break; | |
532 | case GUEST_FS_AR_BYTES: | |
533 | *value = current_evmcs->guest_fs_ar_bytes; | |
534 | break; | |
535 | case GUEST_GS_AR_BYTES: | |
536 | *value = current_evmcs->guest_gs_ar_bytes; | |
537 | break; | |
538 | case GUEST_LDTR_AR_BYTES: | |
539 | *value = current_evmcs->guest_ldtr_ar_bytes; | |
540 | break; | |
541 | case GUEST_TR_AR_BYTES: | |
542 | *value = current_evmcs->guest_tr_ar_bytes; | |
543 | break; | |
544 | case GUEST_ACTIVITY_STATE: | |
545 | *value = current_evmcs->guest_activity_state; | |
546 | break; | |
547 | case GUEST_SYSENTER_CS: | |
548 | *value = current_evmcs->guest_sysenter_cs; | |
549 | break; | |
550 | case VM_INSTRUCTION_ERROR: | |
551 | *value = current_evmcs->vm_instruction_error; | |
552 | break; | |
553 | case VM_EXIT_REASON: | |
554 | *value = current_evmcs->vm_exit_reason; | |
555 | break; | |
556 | case VM_EXIT_INTR_INFO: | |
557 | *value = current_evmcs->vm_exit_intr_info; | |
558 | break; | |
559 | case VM_EXIT_INTR_ERROR_CODE: | |
560 | *value = current_evmcs->vm_exit_intr_error_code; | |
561 | break; | |
562 | case IDT_VECTORING_INFO_FIELD: | |
563 | *value = current_evmcs->idt_vectoring_info_field; | |
564 | break; | |
565 | case IDT_VECTORING_ERROR_CODE: | |
566 | *value = current_evmcs->idt_vectoring_error_code; | |
567 | break; | |
568 | case VM_EXIT_INSTRUCTION_LEN: | |
569 | *value = current_evmcs->vm_exit_instruction_len; | |
570 | break; | |
571 | case VMX_INSTRUCTION_INFO: | |
572 | *value = current_evmcs->vmx_instruction_info; | |
573 | break; | |
574 | case PAGE_FAULT_ERROR_CODE_MASK: | |
575 | *value = current_evmcs->page_fault_error_code_mask; | |
576 | break; | |
577 | case PAGE_FAULT_ERROR_CODE_MATCH: | |
578 | *value = current_evmcs->page_fault_error_code_match; | |
579 | break; | |
580 | case CR3_TARGET_COUNT: | |
581 | *value = current_evmcs->cr3_target_count; | |
582 | break; | |
583 | case VM_EXIT_MSR_STORE_COUNT: | |
584 | *value = current_evmcs->vm_exit_msr_store_count; | |
585 | break; | |
586 | case VM_EXIT_MSR_LOAD_COUNT: | |
587 | *value = current_evmcs->vm_exit_msr_load_count; | |
588 | break; | |
589 | case VM_ENTRY_MSR_LOAD_COUNT: | |
590 | *value = current_evmcs->vm_entry_msr_load_count; | |
591 | break; | |
592 | case HOST_ES_SELECTOR: | |
593 | *value = current_evmcs->host_es_selector; | |
594 | break; | |
595 | case HOST_CS_SELECTOR: | |
596 | *value = current_evmcs->host_cs_selector; | |
597 | break; | |
598 | case HOST_SS_SELECTOR: | |
599 | *value = current_evmcs->host_ss_selector; | |
600 | break; | |
601 | case HOST_DS_SELECTOR: | |
602 | *value = current_evmcs->host_ds_selector; | |
603 | break; | |
604 | case HOST_FS_SELECTOR: | |
605 | *value = current_evmcs->host_fs_selector; | |
606 | break; | |
607 | case HOST_GS_SELECTOR: | |
608 | *value = current_evmcs->host_gs_selector; | |
609 | break; | |
610 | case HOST_TR_SELECTOR: | |
611 | *value = current_evmcs->host_tr_selector; | |
612 | break; | |
613 | case GUEST_ES_SELECTOR: | |
614 | *value = current_evmcs->guest_es_selector; | |
615 | break; | |
616 | case GUEST_CS_SELECTOR: | |
617 | *value = current_evmcs->guest_cs_selector; | |
618 | break; | |
619 | case GUEST_SS_SELECTOR: | |
620 | *value = current_evmcs->guest_ss_selector; | |
621 | break; | |
622 | case GUEST_DS_SELECTOR: | |
623 | *value = current_evmcs->guest_ds_selector; | |
624 | break; | |
625 | case GUEST_FS_SELECTOR: | |
626 | *value = current_evmcs->guest_fs_selector; | |
627 | break; | |
628 | case GUEST_GS_SELECTOR: | |
629 | *value = current_evmcs->guest_gs_selector; | |
630 | break; | |
631 | case GUEST_LDTR_SELECTOR: | |
632 | *value = current_evmcs->guest_ldtr_selector; | |
633 | break; | |
634 | case GUEST_TR_SELECTOR: | |
635 | *value = current_evmcs->guest_tr_selector; | |
636 | break; | |
637 | case VIRTUAL_PROCESSOR_ID: | |
638 | *value = current_evmcs->virtual_processor_id; | |
639 | break; | |
640 | default: return 1; | |
641 | } | |
642 | ||
643 | return 0; | |
644 | } | |
645 | ||
646 | static inline int evmcs_vmwrite(uint64_t encoding, uint64_t value) | |
647 | { | |
648 | switch (encoding) { | |
649 | case GUEST_RIP: | |
650 | current_evmcs->guest_rip = value; | |
651 | break; | |
652 | case GUEST_RSP: | |
653 | current_evmcs->guest_rsp = value; | |
654 | break; | |
655 | case GUEST_RFLAGS: | |
656 | current_evmcs->guest_rflags = value; | |
657 | break; | |
658 | case HOST_IA32_PAT: | |
659 | current_evmcs->host_ia32_pat = value; | |
660 | break; | |
661 | case HOST_IA32_EFER: | |
662 | current_evmcs->host_ia32_efer = value; | |
663 | break; | |
664 | case HOST_CR0: | |
665 | current_evmcs->host_cr0 = value; | |
666 | break; | |
667 | case HOST_CR3: | |
668 | current_evmcs->host_cr3 = value; | |
669 | break; | |
670 | case HOST_CR4: | |
671 | current_evmcs->host_cr4 = value; | |
672 | break; | |
673 | case HOST_IA32_SYSENTER_ESP: | |
674 | current_evmcs->host_ia32_sysenter_esp = value; | |
675 | break; | |
676 | case HOST_IA32_SYSENTER_EIP: | |
677 | current_evmcs->host_ia32_sysenter_eip = value; | |
678 | break; | |
679 | case HOST_RIP: | |
680 | current_evmcs->host_rip = value; | |
681 | break; | |
682 | case IO_BITMAP_A: | |
683 | current_evmcs->io_bitmap_a = value; | |
684 | break; | |
685 | case IO_BITMAP_B: | |
686 | current_evmcs->io_bitmap_b = value; | |
687 | break; | |
688 | case MSR_BITMAP: | |
689 | current_evmcs->msr_bitmap = value; | |
690 | break; | |
691 | case GUEST_ES_BASE: | |
692 | current_evmcs->guest_es_base = value; | |
693 | break; | |
694 | case GUEST_CS_BASE: | |
695 | current_evmcs->guest_cs_base = value; | |
696 | break; | |
697 | case GUEST_SS_BASE: | |
698 | current_evmcs->guest_ss_base = value; | |
699 | break; | |
700 | case GUEST_DS_BASE: | |
701 | current_evmcs->guest_ds_base = value; | |
702 | break; | |
703 | case GUEST_FS_BASE: | |
704 | current_evmcs->guest_fs_base = value; | |
705 | break; | |
706 | case GUEST_GS_BASE: | |
707 | current_evmcs->guest_gs_base = value; | |
708 | break; | |
709 | case GUEST_LDTR_BASE: | |
710 | current_evmcs->guest_ldtr_base = value; | |
711 | break; | |
712 | case GUEST_TR_BASE: | |
713 | current_evmcs->guest_tr_base = value; | |
714 | break; | |
715 | case GUEST_GDTR_BASE: | |
716 | current_evmcs->guest_gdtr_base = value; | |
717 | break; | |
718 | case GUEST_IDTR_BASE: | |
719 | current_evmcs->guest_idtr_base = value; | |
720 | break; | |
721 | case TSC_OFFSET: | |
722 | current_evmcs->tsc_offset = value; | |
723 | break; | |
724 | case VIRTUAL_APIC_PAGE_ADDR: | |
725 | current_evmcs->virtual_apic_page_addr = value; | |
726 | break; | |
727 | case VMCS_LINK_POINTER: | |
728 | current_evmcs->vmcs_link_pointer = value; | |
729 | break; | |
730 | case GUEST_IA32_DEBUGCTL: | |
731 | current_evmcs->guest_ia32_debugctl = value; | |
732 | break; | |
733 | case GUEST_IA32_PAT: | |
734 | current_evmcs->guest_ia32_pat = value; | |
735 | break; | |
736 | case GUEST_IA32_EFER: | |
737 | current_evmcs->guest_ia32_efer = value; | |
738 | break; | |
739 | case GUEST_PDPTR0: | |
740 | current_evmcs->guest_pdptr0 = value; | |
741 | break; | |
742 | case GUEST_PDPTR1: | |
743 | current_evmcs->guest_pdptr1 = value; | |
744 | break; | |
745 | case GUEST_PDPTR2: | |
746 | current_evmcs->guest_pdptr2 = value; | |
747 | break; | |
748 | case GUEST_PDPTR3: | |
749 | current_evmcs->guest_pdptr3 = value; | |
750 | break; | |
751 | case GUEST_PENDING_DBG_EXCEPTIONS: | |
752 | current_evmcs->guest_pending_dbg_exceptions = value; | |
753 | break; | |
754 | case GUEST_SYSENTER_ESP: | |
755 | current_evmcs->guest_sysenter_esp = value; | |
756 | break; | |
757 | case GUEST_SYSENTER_EIP: | |
758 | current_evmcs->guest_sysenter_eip = value; | |
759 | break; | |
760 | case CR0_GUEST_HOST_MASK: | |
761 | current_evmcs->cr0_guest_host_mask = value; | |
762 | break; | |
763 | case CR4_GUEST_HOST_MASK: | |
764 | current_evmcs->cr4_guest_host_mask = value; | |
765 | break; | |
766 | case CR0_READ_SHADOW: | |
767 | current_evmcs->cr0_read_shadow = value; | |
768 | break; | |
769 | case CR4_READ_SHADOW: | |
770 | current_evmcs->cr4_read_shadow = value; | |
771 | break; | |
772 | case GUEST_CR0: | |
773 | current_evmcs->guest_cr0 = value; | |
774 | break; | |
775 | case GUEST_CR3: | |
776 | current_evmcs->guest_cr3 = value; | |
777 | break; | |
778 | case GUEST_CR4: | |
779 | current_evmcs->guest_cr4 = value; | |
780 | break; | |
781 | case GUEST_DR7: | |
782 | current_evmcs->guest_dr7 = value; | |
783 | break; | |
784 | case HOST_FS_BASE: | |
785 | current_evmcs->host_fs_base = value; | |
786 | break; | |
787 | case HOST_GS_BASE: | |
788 | current_evmcs->host_gs_base = value; | |
789 | break; | |
790 | case HOST_TR_BASE: | |
791 | current_evmcs->host_tr_base = value; | |
792 | break; | |
793 | case HOST_GDTR_BASE: | |
794 | current_evmcs->host_gdtr_base = value; | |
795 | break; | |
796 | case HOST_IDTR_BASE: | |
797 | current_evmcs->host_idtr_base = value; | |
798 | break; | |
799 | case HOST_RSP: | |
800 | current_evmcs->host_rsp = value; | |
801 | break; | |
802 | case EPT_POINTER: | |
803 | current_evmcs->ept_pointer = value; | |
804 | break; | |
805 | case GUEST_BNDCFGS: | |
806 | current_evmcs->guest_bndcfgs = value; | |
807 | break; | |
808 | case XSS_EXIT_BITMAP: | |
809 | current_evmcs->xss_exit_bitmap = value; | |
810 | break; | |
811 | case GUEST_PHYSICAL_ADDRESS: | |
812 | current_evmcs->guest_physical_address = value; | |
813 | break; | |
814 | case EXIT_QUALIFICATION: | |
815 | current_evmcs->exit_qualification = value; | |
816 | break; | |
817 | case GUEST_LINEAR_ADDRESS: | |
818 | current_evmcs->guest_linear_address = value; | |
819 | break; | |
820 | case VM_EXIT_MSR_STORE_ADDR: | |
821 | current_evmcs->vm_exit_msr_store_addr = value; | |
822 | break; | |
823 | case VM_EXIT_MSR_LOAD_ADDR: | |
824 | current_evmcs->vm_exit_msr_load_addr = value; | |
825 | break; | |
826 | case VM_ENTRY_MSR_LOAD_ADDR: | |
827 | current_evmcs->vm_entry_msr_load_addr = value; | |
828 | break; | |
829 | case CR3_TARGET_VALUE0: | |
830 | current_evmcs->cr3_target_value0 = value; | |
831 | break; | |
832 | case CR3_TARGET_VALUE1: | |
833 | current_evmcs->cr3_target_value1 = value; | |
834 | break; | |
835 | case CR3_TARGET_VALUE2: | |
836 | current_evmcs->cr3_target_value2 = value; | |
837 | break; | |
838 | case CR3_TARGET_VALUE3: | |
839 | current_evmcs->cr3_target_value3 = value; | |
840 | break; | |
841 | case TPR_THRESHOLD: | |
842 | current_evmcs->tpr_threshold = value; | |
843 | break; | |
844 | case GUEST_INTERRUPTIBILITY_INFO: | |
845 | current_evmcs->guest_interruptibility_info = value; | |
846 | break; | |
847 | case CPU_BASED_VM_EXEC_CONTROL: | |
848 | current_evmcs->cpu_based_vm_exec_control = value; | |
849 | break; | |
850 | case EXCEPTION_BITMAP: | |
851 | current_evmcs->exception_bitmap = value; | |
852 | break; | |
853 | case VM_ENTRY_CONTROLS: | |
854 | current_evmcs->vm_entry_controls = value; | |
855 | break; | |
856 | case VM_ENTRY_INTR_INFO_FIELD: | |
857 | current_evmcs->vm_entry_intr_info_field = value; | |
858 | break; | |
859 | case VM_ENTRY_EXCEPTION_ERROR_CODE: | |
860 | current_evmcs->vm_entry_exception_error_code = value; | |
861 | break; | |
862 | case VM_ENTRY_INSTRUCTION_LEN: | |
863 | current_evmcs->vm_entry_instruction_len = value; | |
864 | break; | |
865 | case HOST_IA32_SYSENTER_CS: | |
866 | current_evmcs->host_ia32_sysenter_cs = value; | |
867 | break; | |
868 | case PIN_BASED_VM_EXEC_CONTROL: | |
869 | current_evmcs->pin_based_vm_exec_control = value; | |
870 | break; | |
871 | case VM_EXIT_CONTROLS: | |
872 | current_evmcs->vm_exit_controls = value; | |
873 | break; | |
874 | case SECONDARY_VM_EXEC_CONTROL: | |
875 | current_evmcs->secondary_vm_exec_control = value; | |
876 | break; | |
877 | case GUEST_ES_LIMIT: | |
878 | current_evmcs->guest_es_limit = value; | |
879 | break; | |
880 | case GUEST_CS_LIMIT: | |
881 | current_evmcs->guest_cs_limit = value; | |
882 | break; | |
883 | case GUEST_SS_LIMIT: | |
884 | current_evmcs->guest_ss_limit = value; | |
885 | break; | |
886 | case GUEST_DS_LIMIT: | |
887 | current_evmcs->guest_ds_limit = value; | |
888 | break; | |
889 | case GUEST_FS_LIMIT: | |
890 | current_evmcs->guest_fs_limit = value; | |
891 | break; | |
892 | case GUEST_GS_LIMIT: | |
893 | current_evmcs->guest_gs_limit = value; | |
894 | break; | |
895 | case GUEST_LDTR_LIMIT: | |
896 | current_evmcs->guest_ldtr_limit = value; | |
897 | break; | |
898 | case GUEST_TR_LIMIT: | |
899 | current_evmcs->guest_tr_limit = value; | |
900 | break; | |
901 | case GUEST_GDTR_LIMIT: | |
902 | current_evmcs->guest_gdtr_limit = value; | |
903 | break; | |
904 | case GUEST_IDTR_LIMIT: | |
905 | current_evmcs->guest_idtr_limit = value; | |
906 | break; | |
907 | case GUEST_ES_AR_BYTES: | |
908 | current_evmcs->guest_es_ar_bytes = value; | |
909 | break; | |
910 | case GUEST_CS_AR_BYTES: | |
911 | current_evmcs->guest_cs_ar_bytes = value; | |
912 | break; | |
913 | case GUEST_SS_AR_BYTES: | |
914 | current_evmcs->guest_ss_ar_bytes = value; | |
915 | break; | |
916 | case GUEST_DS_AR_BYTES: | |
917 | current_evmcs->guest_ds_ar_bytes = value; | |
918 | break; | |
919 | case GUEST_FS_AR_BYTES: | |
920 | current_evmcs->guest_fs_ar_bytes = value; | |
921 | break; | |
922 | case GUEST_GS_AR_BYTES: | |
923 | current_evmcs->guest_gs_ar_bytes = value; | |
924 | break; | |
925 | case GUEST_LDTR_AR_BYTES: | |
926 | current_evmcs->guest_ldtr_ar_bytes = value; | |
927 | break; | |
928 | case GUEST_TR_AR_BYTES: | |
929 | current_evmcs->guest_tr_ar_bytes = value; | |
930 | break; | |
931 | case GUEST_ACTIVITY_STATE: | |
932 | current_evmcs->guest_activity_state = value; | |
933 | break; | |
934 | case GUEST_SYSENTER_CS: | |
935 | current_evmcs->guest_sysenter_cs = value; | |
936 | break; | |
937 | case VM_INSTRUCTION_ERROR: | |
938 | current_evmcs->vm_instruction_error = value; | |
939 | break; | |
940 | case VM_EXIT_REASON: | |
941 | current_evmcs->vm_exit_reason = value; | |
942 | break; | |
943 | case VM_EXIT_INTR_INFO: | |
944 | current_evmcs->vm_exit_intr_info = value; | |
945 | break; | |
946 | case VM_EXIT_INTR_ERROR_CODE: | |
947 | current_evmcs->vm_exit_intr_error_code = value; | |
948 | break; | |
949 | case IDT_VECTORING_INFO_FIELD: | |
950 | current_evmcs->idt_vectoring_info_field = value; | |
951 | break; | |
952 | case IDT_VECTORING_ERROR_CODE: | |
953 | current_evmcs->idt_vectoring_error_code = value; | |
954 | break; | |
955 | case VM_EXIT_INSTRUCTION_LEN: | |
956 | current_evmcs->vm_exit_instruction_len = value; | |
957 | break; | |
958 | case VMX_INSTRUCTION_INFO: | |
959 | current_evmcs->vmx_instruction_info = value; | |
960 | break; | |
961 | case PAGE_FAULT_ERROR_CODE_MASK: | |
962 | current_evmcs->page_fault_error_code_mask = value; | |
963 | break; | |
964 | case PAGE_FAULT_ERROR_CODE_MATCH: | |
965 | current_evmcs->page_fault_error_code_match = value; | |
966 | break; | |
967 | case CR3_TARGET_COUNT: | |
968 | current_evmcs->cr3_target_count = value; | |
969 | break; | |
970 | case VM_EXIT_MSR_STORE_COUNT: | |
971 | current_evmcs->vm_exit_msr_store_count = value; | |
972 | break; | |
973 | case VM_EXIT_MSR_LOAD_COUNT: | |
974 | current_evmcs->vm_exit_msr_load_count = value; | |
975 | break; | |
976 | case VM_ENTRY_MSR_LOAD_COUNT: | |
977 | current_evmcs->vm_entry_msr_load_count = value; | |
978 | break; | |
979 | case HOST_ES_SELECTOR: | |
980 | current_evmcs->host_es_selector = value; | |
981 | break; | |
982 | case HOST_CS_SELECTOR: | |
983 | current_evmcs->host_cs_selector = value; | |
984 | break; | |
985 | case HOST_SS_SELECTOR: | |
986 | current_evmcs->host_ss_selector = value; | |
987 | break; | |
988 | case HOST_DS_SELECTOR: | |
989 | current_evmcs->host_ds_selector = value; | |
990 | break; | |
991 | case HOST_FS_SELECTOR: | |
992 | current_evmcs->host_fs_selector = value; | |
993 | break; | |
994 | case HOST_GS_SELECTOR: | |
995 | current_evmcs->host_gs_selector = value; | |
996 | break; | |
997 | case HOST_TR_SELECTOR: | |
998 | current_evmcs->host_tr_selector = value; | |
999 | break; | |
1000 | case GUEST_ES_SELECTOR: | |
1001 | current_evmcs->guest_es_selector = value; | |
1002 | break; | |
1003 | case GUEST_CS_SELECTOR: | |
1004 | current_evmcs->guest_cs_selector = value; | |
1005 | break; | |
1006 | case GUEST_SS_SELECTOR: | |
1007 | current_evmcs->guest_ss_selector = value; | |
1008 | break; | |
1009 | case GUEST_DS_SELECTOR: | |
1010 | current_evmcs->guest_ds_selector = value; | |
1011 | break; | |
1012 | case GUEST_FS_SELECTOR: | |
1013 | current_evmcs->guest_fs_selector = value; | |
1014 | break; | |
1015 | case GUEST_GS_SELECTOR: | |
1016 | current_evmcs->guest_gs_selector = value; | |
1017 | break; | |
1018 | case GUEST_LDTR_SELECTOR: | |
1019 | current_evmcs->guest_ldtr_selector = value; | |
1020 | break; | |
1021 | case GUEST_TR_SELECTOR: | |
1022 | current_evmcs->guest_tr_selector = value; | |
1023 | break; | |
1024 | case VIRTUAL_PROCESSOR_ID: | |
1025 | current_evmcs->virtual_processor_id = value; | |
1026 | break; | |
1027 | default: return 1; | |
1028 | } | |
1029 | ||
1030 | return 0; | |
1031 | } | |
1032 | ||
1033 | static inline int evmcs_vmlaunch(void) | |
1034 | { | |
1035 | int ret; | |
1036 | ||
1037 | current_evmcs->hv_clean_fields = 0; | |
1038 | ||
1039 | __asm__ __volatile__("push %%rbp;" | |
1040 | "push %%rcx;" | |
1041 | "push %%rdx;" | |
1042 | "push %%rsi;" | |
1043 | "push %%rdi;" | |
1044 | "push $0;" | |
1045 | "mov %%rsp, (%[host_rsp]);" | |
1046 | "lea 1f(%%rip), %%rax;" | |
1047 | "mov %%rax, (%[host_rip]);" | |
1048 | "vmlaunch;" | |
1049 | "incq (%%rsp);" | |
1050 | "1: pop %%rax;" | |
1051 | "pop %%rdi;" | |
1052 | "pop %%rsi;" | |
1053 | "pop %%rdx;" | |
1054 | "pop %%rcx;" | |
1055 | "pop %%rbp;" | |
1056 | : [ret]"=&a"(ret) | |
1057 | : [host_rsp]"r" | |
1058 | ((uint64_t)¤t_evmcs->host_rsp), | |
1059 | [host_rip]"r" | |
1060 | ((uint64_t)¤t_evmcs->host_rip) | |
1061 | : "memory", "cc", "rbx", "r8", "r9", "r10", | |
1062 | "r11", "r12", "r13", "r14", "r15"); | |
1063 | return ret; | |
1064 | } | |
1065 | ||
1066 | /* | |
1067 | * No guest state (e.g. GPRs) is established by this vmresume. | |
1068 | */ | |
1069 | static inline int evmcs_vmresume(void) | |
1070 | { | |
1071 | int ret; | |
1072 | ||
1073 | current_evmcs->hv_clean_fields = 0; | |
1074 | ||
1075 | __asm__ __volatile__("push %%rbp;" | |
1076 | "push %%rcx;" | |
1077 | "push %%rdx;" | |
1078 | "push %%rsi;" | |
1079 | "push %%rdi;" | |
1080 | "push $0;" | |
1081 | "mov %%rsp, (%[host_rsp]);" | |
1082 | "lea 1f(%%rip), %%rax;" | |
1083 | "mov %%rax, (%[host_rip]);" | |
1084 | "vmresume;" | |
1085 | "incq (%%rsp);" | |
1086 | "1: pop %%rax;" | |
1087 | "pop %%rdi;" | |
1088 | "pop %%rsi;" | |
1089 | "pop %%rdx;" | |
1090 | "pop %%rcx;" | |
1091 | "pop %%rbp;" | |
1092 | : [ret]"=&a"(ret) | |
1093 | : [host_rsp]"r" | |
1094 | ((uint64_t)¤t_evmcs->host_rsp), | |
1095 | [host_rip]"r" | |
1096 | ((uint64_t)¤t_evmcs->host_rip) | |
1097 | : "memory", "cc", "rbx", "r8", "r9", "r10", | |
1098 | "r11", "r12", "r13", "r14", "r15"); | |
1099 | return ret; | |
1100 | } | |
1101 | ||
1102 | #endif /* !SELFTEST_KVM_EVMCS_H */ |