.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
---|
1 | 2 | /* |
---|
2 | 3 | * vmx.h: VMX Architecture related definitions |
---|
3 | 4 | * Copyright (c) 2004, Intel Corporation. |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify it |
---|
6 | | - * under the terms and conditions of the GNU General Public License, |
---|
7 | | - * version 2, as published by the Free Software Foundation. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
12 | | - * more details. |
---|
13 | | - * |
---|
14 | | - * You should have received a copy of the GNU General Public License along with |
---|
15 | | - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
---|
16 | | - * Place - Suite 330, Boston, MA 02111-1307 USA. |
---|
17 | 5 | * |
---|
18 | 6 | * A few random additions are: |
---|
19 | 7 | * Copyright (C) 2006 Qumranet |
---|
20 | 8 | * Avi Kivity <avi@qumranet.com> |
---|
21 | 9 | * Yaniv Kamay <yaniv@qumranet.com> |
---|
22 | | - * |
---|
23 | 10 | */ |
---|
24 | 11 | #ifndef VMX_H |
---|
25 | 12 | #define VMX_H |
---|
.. | .. |
---|
28 | 15 | #include <linux/bitops.h> |
---|
29 | 16 | #include <linux/types.h> |
---|
30 | 17 | #include <uapi/asm/vmx.h> |
---|
| 18 | +#include <asm/vmxfeatures.h> |
---|
| 19 | + |
---|
| 20 | +#define VMCS_CONTROL_BIT(x) BIT(VMX_FEATURE_##x & 0x1f) |
---|
31 | 21 | |
---|
32 | 22 | /* |
---|
33 | 23 | * Definitions of Primary Processor-Based VM-Execution Controls. |
---|
34 | 24 | */ |
---|
35 | | -#define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004 |
---|
36 | | -#define CPU_BASED_USE_TSC_OFFSETING 0x00000008 |
---|
37 | | -#define CPU_BASED_HLT_EXITING 0x00000080 |
---|
38 | | -#define CPU_BASED_INVLPG_EXITING 0x00000200 |
---|
39 | | -#define CPU_BASED_MWAIT_EXITING 0x00000400 |
---|
40 | | -#define CPU_BASED_RDPMC_EXITING 0x00000800 |
---|
41 | | -#define CPU_BASED_RDTSC_EXITING 0x00001000 |
---|
42 | | -#define CPU_BASED_CR3_LOAD_EXITING 0x00008000 |
---|
43 | | -#define CPU_BASED_CR3_STORE_EXITING 0x00010000 |
---|
44 | | -#define CPU_BASED_CR8_LOAD_EXITING 0x00080000 |
---|
45 | | -#define CPU_BASED_CR8_STORE_EXITING 0x00100000 |
---|
46 | | -#define CPU_BASED_TPR_SHADOW 0x00200000 |
---|
47 | | -#define CPU_BASED_VIRTUAL_NMI_PENDING 0x00400000 |
---|
48 | | -#define CPU_BASED_MOV_DR_EXITING 0x00800000 |
---|
49 | | -#define CPU_BASED_UNCOND_IO_EXITING 0x01000000 |
---|
50 | | -#define CPU_BASED_USE_IO_BITMAPS 0x02000000 |
---|
51 | | -#define CPU_BASED_MONITOR_TRAP_FLAG 0x08000000 |
---|
52 | | -#define CPU_BASED_USE_MSR_BITMAPS 0x10000000 |
---|
53 | | -#define CPU_BASED_MONITOR_EXITING 0x20000000 |
---|
54 | | -#define CPU_BASED_PAUSE_EXITING 0x40000000 |
---|
55 | | -#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000 |
---|
| 25 | +#define CPU_BASED_INTR_WINDOW_EXITING VMCS_CONTROL_BIT(INTR_WINDOW_EXITING) |
---|
| 26 | +#define CPU_BASED_USE_TSC_OFFSETTING VMCS_CONTROL_BIT(USE_TSC_OFFSETTING) |
---|
| 27 | +#define CPU_BASED_HLT_EXITING VMCS_CONTROL_BIT(HLT_EXITING) |
---|
| 28 | +#define CPU_BASED_INVLPG_EXITING VMCS_CONTROL_BIT(INVLPG_EXITING) |
---|
| 29 | +#define CPU_BASED_MWAIT_EXITING VMCS_CONTROL_BIT(MWAIT_EXITING) |
---|
| 30 | +#define CPU_BASED_RDPMC_EXITING VMCS_CONTROL_BIT(RDPMC_EXITING) |
---|
| 31 | +#define CPU_BASED_RDTSC_EXITING VMCS_CONTROL_BIT(RDTSC_EXITING) |
---|
| 32 | +#define CPU_BASED_CR3_LOAD_EXITING VMCS_CONTROL_BIT(CR3_LOAD_EXITING) |
---|
| 33 | +#define CPU_BASED_CR3_STORE_EXITING VMCS_CONTROL_BIT(CR3_STORE_EXITING) |
---|
| 34 | +#define CPU_BASED_CR8_LOAD_EXITING VMCS_CONTROL_BIT(CR8_LOAD_EXITING) |
---|
| 35 | +#define CPU_BASED_CR8_STORE_EXITING VMCS_CONTROL_BIT(CR8_STORE_EXITING) |
---|
| 36 | +#define CPU_BASED_TPR_SHADOW VMCS_CONTROL_BIT(VIRTUAL_TPR) |
---|
| 37 | +#define CPU_BASED_NMI_WINDOW_EXITING VMCS_CONTROL_BIT(NMI_WINDOW_EXITING) |
---|
| 38 | +#define CPU_BASED_MOV_DR_EXITING VMCS_CONTROL_BIT(MOV_DR_EXITING) |
---|
| 39 | +#define CPU_BASED_UNCOND_IO_EXITING VMCS_CONTROL_BIT(UNCOND_IO_EXITING) |
---|
| 40 | +#define CPU_BASED_USE_IO_BITMAPS VMCS_CONTROL_BIT(USE_IO_BITMAPS) |
---|
| 41 | +#define CPU_BASED_MONITOR_TRAP_FLAG VMCS_CONTROL_BIT(MONITOR_TRAP_FLAG) |
---|
| 42 | +#define CPU_BASED_USE_MSR_BITMAPS VMCS_CONTROL_BIT(USE_MSR_BITMAPS) |
---|
| 43 | +#define CPU_BASED_MONITOR_EXITING VMCS_CONTROL_BIT(MONITOR_EXITING) |
---|
| 44 | +#define CPU_BASED_PAUSE_EXITING VMCS_CONTROL_BIT(PAUSE_EXITING) |
---|
| 45 | +#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS VMCS_CONTROL_BIT(SEC_CONTROLS) |
---|
56 | 46 | |
---|
57 | 47 | #define CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR 0x0401e172 |
---|
58 | 48 | |
---|
59 | 49 | /* |
---|
60 | 50 | * Definitions of Secondary Processor-Based VM-Execution Controls. |
---|
61 | 51 | */ |
---|
62 | | -#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 |
---|
63 | | -#define SECONDARY_EXEC_ENABLE_EPT 0x00000002 |
---|
64 | | -#define SECONDARY_EXEC_DESC 0x00000004 |
---|
65 | | -#define SECONDARY_EXEC_RDTSCP 0x00000008 |
---|
66 | | -#define SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE 0x00000010 |
---|
67 | | -#define SECONDARY_EXEC_ENABLE_VPID 0x00000020 |
---|
68 | | -#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 |
---|
69 | | -#define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080 |
---|
70 | | -#define SECONDARY_EXEC_APIC_REGISTER_VIRT 0x00000100 |
---|
71 | | -#define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY 0x00000200 |
---|
72 | | -#define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 |
---|
73 | | -#define SECONDARY_EXEC_RDRAND_EXITING 0x00000800 |
---|
74 | | -#define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 |
---|
75 | | -#define SECONDARY_EXEC_ENABLE_VMFUNC 0x00002000 |
---|
76 | | -#define SECONDARY_EXEC_SHADOW_VMCS 0x00004000 |
---|
77 | | -#define SECONDARY_EXEC_ENCLS_EXITING 0x00008000 |
---|
78 | | -#define SECONDARY_EXEC_RDSEED_EXITING 0x00010000 |
---|
79 | | -#define SECONDARY_EXEC_ENABLE_PML 0x00020000 |
---|
80 | | -#define SECONDARY_EXEC_XSAVES 0x00100000 |
---|
81 | | -#define SECONDARY_EXEC_TSC_SCALING 0x02000000 |
---|
| 52 | +#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES VMCS_CONTROL_BIT(VIRT_APIC_ACCESSES) |
---|
| 53 | +#define SECONDARY_EXEC_ENABLE_EPT VMCS_CONTROL_BIT(EPT) |
---|
| 54 | +#define SECONDARY_EXEC_DESC VMCS_CONTROL_BIT(DESC_EXITING) |
---|
| 55 | +#define SECONDARY_EXEC_ENABLE_RDTSCP VMCS_CONTROL_BIT(RDTSCP) |
---|
| 56 | +#define SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE VMCS_CONTROL_BIT(VIRTUAL_X2APIC) |
---|
| 57 | +#define SECONDARY_EXEC_ENABLE_VPID VMCS_CONTROL_BIT(VPID) |
---|
| 58 | +#define SECONDARY_EXEC_WBINVD_EXITING VMCS_CONTROL_BIT(WBINVD_EXITING) |
---|
| 59 | +#define SECONDARY_EXEC_UNRESTRICTED_GUEST VMCS_CONTROL_BIT(UNRESTRICTED_GUEST) |
---|
| 60 | +#define SECONDARY_EXEC_APIC_REGISTER_VIRT VMCS_CONTROL_BIT(APIC_REGISTER_VIRT) |
---|
| 61 | +#define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY VMCS_CONTROL_BIT(VIRT_INTR_DELIVERY) |
---|
| 62 | +#define SECONDARY_EXEC_PAUSE_LOOP_EXITING VMCS_CONTROL_BIT(PAUSE_LOOP_EXITING) |
---|
| 63 | +#define SECONDARY_EXEC_RDRAND_EXITING VMCS_CONTROL_BIT(RDRAND_EXITING) |
---|
| 64 | +#define SECONDARY_EXEC_ENABLE_INVPCID VMCS_CONTROL_BIT(INVPCID) |
---|
| 65 | +#define SECONDARY_EXEC_ENABLE_VMFUNC VMCS_CONTROL_BIT(VMFUNC) |
---|
| 66 | +#define SECONDARY_EXEC_SHADOW_VMCS VMCS_CONTROL_BIT(SHADOW_VMCS) |
---|
| 67 | +#define SECONDARY_EXEC_ENCLS_EXITING VMCS_CONTROL_BIT(ENCLS_EXITING) |
---|
| 68 | +#define SECONDARY_EXEC_RDSEED_EXITING VMCS_CONTROL_BIT(RDSEED_EXITING) |
---|
| 69 | +#define SECONDARY_EXEC_ENABLE_PML VMCS_CONTROL_BIT(PAGE_MOD_LOGGING) |
---|
| 70 | +#define SECONDARY_EXEC_PT_CONCEAL_VMX VMCS_CONTROL_BIT(PT_CONCEAL_VMX) |
---|
| 71 | +#define SECONDARY_EXEC_XSAVES VMCS_CONTROL_BIT(XSAVES) |
---|
| 72 | +#define SECONDARY_EXEC_MODE_BASED_EPT_EXEC VMCS_CONTROL_BIT(MODE_BASED_EPT_EXEC) |
---|
| 73 | +#define SECONDARY_EXEC_PT_USE_GPA VMCS_CONTROL_BIT(PT_USE_GPA) |
---|
| 74 | +#define SECONDARY_EXEC_TSC_SCALING VMCS_CONTROL_BIT(TSC_SCALING) |
---|
| 75 | +#define SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE VMCS_CONTROL_BIT(USR_WAIT_PAUSE) |
---|
82 | 76 | |
---|
83 | | -#define PIN_BASED_EXT_INTR_MASK 0x00000001 |
---|
84 | | -#define PIN_BASED_NMI_EXITING 0x00000008 |
---|
85 | | -#define PIN_BASED_VIRTUAL_NMIS 0x00000020 |
---|
86 | | -#define PIN_BASED_VMX_PREEMPTION_TIMER 0x00000040 |
---|
87 | | -#define PIN_BASED_POSTED_INTR 0x00000080 |
---|
| 77 | +#define PIN_BASED_EXT_INTR_MASK VMCS_CONTROL_BIT(INTR_EXITING) |
---|
| 78 | +#define PIN_BASED_NMI_EXITING VMCS_CONTROL_BIT(NMI_EXITING) |
---|
| 79 | +#define PIN_BASED_VIRTUAL_NMIS VMCS_CONTROL_BIT(VIRTUAL_NMIS) |
---|
| 80 | +#define PIN_BASED_VMX_PREEMPTION_TIMER VMCS_CONTROL_BIT(PREEMPTION_TIMER) |
---|
| 81 | +#define PIN_BASED_POSTED_INTR VMCS_CONTROL_BIT(POSTED_INTR) |
---|
88 | 82 | |
---|
89 | 83 | #define PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR 0x00000016 |
---|
90 | 84 | |
---|
.. | .. |
---|
98 | 92 | #define VM_EXIT_LOAD_IA32_EFER 0x00200000 |
---|
99 | 93 | #define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER 0x00400000 |
---|
100 | 94 | #define VM_EXIT_CLEAR_BNDCFGS 0x00800000 |
---|
| 95 | +#define VM_EXIT_PT_CONCEAL_PIP 0x01000000 |
---|
| 96 | +#define VM_EXIT_CLEAR_IA32_RTIT_CTL 0x02000000 |
---|
101 | 97 | |
---|
102 | 98 | #define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR 0x00036dff |
---|
103 | 99 | |
---|
.. | .. |
---|
109 | 105 | #define VM_ENTRY_LOAD_IA32_PAT 0x00004000 |
---|
110 | 106 | #define VM_ENTRY_LOAD_IA32_EFER 0x00008000 |
---|
111 | 107 | #define VM_ENTRY_LOAD_BNDCFGS 0x00010000 |
---|
| 108 | +#define VM_ENTRY_PT_CONCEAL_PIP 0x00020000 |
---|
| 109 | +#define VM_ENTRY_LOAD_IA32_RTIT_CTL 0x00040000 |
---|
112 | 110 | |
---|
113 | 111 | #define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR 0x000011ff |
---|
114 | 112 | |
---|
.. | .. |
---|
116 | 114 | #define VMX_MISC_SAVE_EFER_LMA 0x00000020 |
---|
117 | 115 | #define VMX_MISC_ACTIVITY_HLT 0x00000040 |
---|
118 | 116 | #define VMX_MISC_ZERO_LEN_INS 0x40000000 |
---|
| 117 | +#define VMX_MISC_MSR_LIST_MULTIPLIER 512 |
---|
119 | 118 | |
---|
120 | 119 | /* VMFUNC functions */ |
---|
121 | | -#define VMX_VMFUNC_EPTP_SWITCHING 0x00000001 |
---|
| 120 | +#define VMFUNC_CONTROL_BIT(x) BIT((VMX_FEATURE_##x & 0x1f) - 28) |
---|
| 121 | + |
---|
| 122 | +#define VMX_VMFUNC_EPTP_SWITCHING VMFUNC_CONTROL_BIT(EPTP_SWITCHING) |
---|
122 | 123 | #define VMFUNC_EPTP_ENTRIES 512 |
---|
123 | 124 | |
---|
124 | 125 | static inline u32 vmx_basic_vmcs_revision_id(u64 vmx_basic) |
---|
.. | .. |
---|
240 | 241 | GUEST_PDPTR3_HIGH = 0x00002811, |
---|
241 | 242 | GUEST_BNDCFGS = 0x00002812, |
---|
242 | 243 | GUEST_BNDCFGS_HIGH = 0x00002813, |
---|
| 244 | + GUEST_IA32_RTIT_CTL = 0x00002814, |
---|
| 245 | + GUEST_IA32_RTIT_CTL_HIGH = 0x00002815, |
---|
243 | 246 | HOST_IA32_PAT = 0x00002c00, |
---|
244 | 247 | HOST_IA32_PAT_HIGH = 0x00002c01, |
---|
245 | 248 | HOST_IA32_EFER = 0x00002c02, |
---|
.. | .. |
---|
497 | 500 | VMX_EPT_EXECUTABLE_MASK) |
---|
498 | 501 | #define VMX_EPT_MT_MASK (7ull << VMX_EPT_MT_EPTE_SHIFT) |
---|
499 | 502 | |
---|
| 503 | +static inline u8 vmx_eptp_page_walk_level(u64 eptp) |
---|
| 504 | +{ |
---|
| 505 | + u64 encoded_level = eptp & VMX_EPTP_PWL_MASK; |
---|
| 506 | + |
---|
| 507 | + if (encoded_level == VMX_EPTP_PWL_5) |
---|
| 508 | + return 5; |
---|
| 509 | + |
---|
| 510 | + /* @eptp must be pre-validated by the caller. */ |
---|
| 511 | + WARN_ON_ONCE(encoded_level != VMX_EPTP_PWL_4); |
---|
| 512 | + return 4; |
---|
| 513 | +} |
---|
| 514 | + |
---|
500 | 515 | /* The mask to use to trigger an EPT Misconfiguration in order to track MMIO */ |
---|
501 | 516 | #define VMX_EPT_MISCONFIG_WX_VALUE (VMX_EPT_WRITABLE_MASK | \ |
---|
502 | 517 | VMX_EPT_EXECUTABLE_MASK) |
---|
503 | 518 | |
---|
504 | 519 | #define VMX_EPT_IDENTITY_PAGETABLE_ADDR 0xfffbc000ul |
---|
505 | | - |
---|
506 | | - |
---|
507 | | -#define ASM_VMX_VMCLEAR_RAX ".byte 0x66, 0x0f, 0xc7, 0x30" |
---|
508 | | -#define ASM_VMX_VMLAUNCH ".byte 0x0f, 0x01, 0xc2" |
---|
509 | | -#define ASM_VMX_VMRESUME ".byte 0x0f, 0x01, 0xc3" |
---|
510 | | -#define ASM_VMX_VMPTRLD_RAX ".byte 0x0f, 0xc7, 0x30" |
---|
511 | | -#define ASM_VMX_VMREAD_RDX_RAX ".byte 0x0f, 0x78, 0xd0" |
---|
512 | | -#define ASM_VMX_VMWRITE_RAX_RDX ".byte 0x0f, 0x79, 0xd0" |
---|
513 | | -#define ASM_VMX_VMWRITE_RSP_RDX ".byte 0x0f, 0x79, 0xd4" |
---|
514 | | -#define ASM_VMX_VMXOFF ".byte 0x0f, 0x01, 0xc4" |
---|
515 | | -#define ASM_VMX_VMXON_RAX ".byte 0xf3, 0x0f, 0xc7, 0x30" |
---|
516 | | -#define ASM_VMX_INVEPT ".byte 0x66, 0x0f, 0x38, 0x80, 0x08" |
---|
517 | | -#define ASM_VMX_INVVPID ".byte 0x66, 0x0f, 0x38, 0x81, 0x08" |
---|
518 | 520 | |
---|
519 | 521 | struct vmx_msr_entry { |
---|
520 | 522 | u32 index; |
---|
.. | .. |
---|
525 | 527 | /* |
---|
526 | 528 | * Exit Qualifications for entry failure during or after loading guest state |
---|
527 | 529 | */ |
---|
528 | | -#define ENTRY_FAIL_DEFAULT 0 |
---|
529 | | -#define ENTRY_FAIL_PDPTE 2 |
---|
530 | | -#define ENTRY_FAIL_NMI 3 |
---|
531 | | -#define ENTRY_FAIL_VMCS_LINK_PTR 4 |
---|
| 530 | +enum vm_entry_failure_code { |
---|
| 531 | + ENTRY_FAIL_DEFAULT = 0, |
---|
| 532 | + ENTRY_FAIL_PDPTE = 2, |
---|
| 533 | + ENTRY_FAIL_NMI = 3, |
---|
| 534 | + ENTRY_FAIL_VMCS_LINK_PTR = 4, |
---|
| 535 | +}; |
---|
532 | 536 | |
---|
533 | 537 | /* |
---|
534 | 538 | * Exit Qualifications for EPT Violations |
---|
.. | .. |
---|
579 | 583 | VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID = 28, |
---|
580 | 584 | }; |
---|
581 | 585 | |
---|
| 586 | +/* |
---|
| 587 | + * VM-instruction errors that can be encountered on VM-Enter, used to trace |
---|
| 588 | + * nested VM-Enter failures reported by hardware. Errors unique to VM-Enter |
---|
| 589 | + * from a SMI Transfer Monitor are not included as things have gone seriously |
---|
| 590 | + * sideways if we get one of those... |
---|
| 591 | + */ |
---|
| 592 | +#define VMX_VMENTER_INSTRUCTION_ERRORS \ |
---|
| 593 | + { VMXERR_VMLAUNCH_NONCLEAR_VMCS, "VMLAUNCH_NONCLEAR_VMCS" }, \ |
---|
| 594 | + { VMXERR_VMRESUME_NONLAUNCHED_VMCS, "VMRESUME_NONLAUNCHED_VMCS" }, \ |
---|
| 595 | + { VMXERR_VMRESUME_AFTER_VMXOFF, "VMRESUME_AFTER_VMXOFF" }, \ |
---|
| 596 | + { VMXERR_ENTRY_INVALID_CONTROL_FIELD, "VMENTRY_INVALID_CONTROL_FIELD" }, \ |
---|
| 597 | + { VMXERR_ENTRY_INVALID_HOST_STATE_FIELD, "VMENTRY_INVALID_HOST_STATE_FIELD" }, \ |
---|
| 598 | + { VMXERR_ENTRY_EVENTS_BLOCKED_BY_MOV_SS, "VMENTRY_EVENTS_BLOCKED_BY_MOV_SS" } |
---|
| 599 | + |
---|
582 | 600 | enum vmx_l1d_flush_state { |
---|
583 | 601 | VMENTER_L1D_FLUSH_AUTO, |
---|
584 | 602 | VMENTER_L1D_FLUSH_NEVER, |
---|