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