|
14 | 14 | #include "vmcs.h" |
15 | 15 | #include "vmcs12.h" |
16 | 16 |
|
17 | | -struct vmcs_config; |
18 | | - |
19 | | -#define current_evmcs ((struct hv_enlightened_vmcs *)this_cpu_read(current_vmcs)) |
20 | | - |
21 | 17 | #define KVM_EVMCS_VERSION 1 |
22 | 18 |
|
| 19 | +/* |
| 20 | + * Enlightened VMCSv1 doesn't support these: |
| 21 | + * |
| 22 | + * POSTED_INTR_NV = 0x00000002, |
| 23 | + * GUEST_INTR_STATUS = 0x00000810, |
| 24 | + * APIC_ACCESS_ADDR = 0x00002014, |
| 25 | + * POSTED_INTR_DESC_ADDR = 0x00002016, |
| 26 | + * EOI_EXIT_BITMAP0 = 0x0000201c, |
| 27 | + * EOI_EXIT_BITMAP1 = 0x0000201e, |
| 28 | + * EOI_EXIT_BITMAP2 = 0x00002020, |
| 29 | + * EOI_EXIT_BITMAP3 = 0x00002022, |
| 30 | + * GUEST_PML_INDEX = 0x00000812, |
| 31 | + * PML_ADDRESS = 0x0000200e, |
| 32 | + * VM_FUNCTION_CONTROL = 0x00002018, |
| 33 | + * EPTP_LIST_ADDRESS = 0x00002024, |
| 34 | + * VMREAD_BITMAP = 0x00002026, |
| 35 | + * VMWRITE_BITMAP = 0x00002028, |
| 36 | + * |
| 37 | + * TSC_MULTIPLIER = 0x00002032, |
| 38 | + * PLE_GAP = 0x00004020, |
| 39 | + * PLE_WINDOW = 0x00004022, |
| 40 | + * VMX_PREEMPTION_TIMER_VALUE = 0x0000482E, |
| 41 | + * |
| 42 | + * Currently unsupported in KVM: |
| 43 | + * GUEST_IA32_RTIT_CTL = 0x00002814, |
| 44 | + */ |
| 45 | +#define EVMCS1_SUPPORTED_PINCTRL \ |
| 46 | + (PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR | \ |
| 47 | + PIN_BASED_EXT_INTR_MASK | \ |
| 48 | + PIN_BASED_NMI_EXITING | \ |
| 49 | + PIN_BASED_VIRTUAL_NMIS) |
| 50 | + |
| 51 | +#define EVMCS1_SUPPORTED_EXEC_CTRL \ |
| 52 | + (CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR | \ |
| 53 | + CPU_BASED_HLT_EXITING | \ |
| 54 | + CPU_BASED_CR3_LOAD_EXITING | \ |
| 55 | + CPU_BASED_CR3_STORE_EXITING | \ |
| 56 | + CPU_BASED_UNCOND_IO_EXITING | \ |
| 57 | + CPU_BASED_MOV_DR_EXITING | \ |
| 58 | + CPU_BASED_USE_TSC_OFFSETTING | \ |
| 59 | + CPU_BASED_MWAIT_EXITING | \ |
| 60 | + CPU_BASED_MONITOR_EXITING | \ |
| 61 | + CPU_BASED_INVLPG_EXITING | \ |
| 62 | + CPU_BASED_RDPMC_EXITING | \ |
| 63 | + CPU_BASED_INTR_WINDOW_EXITING | \ |
| 64 | + CPU_BASED_CR8_LOAD_EXITING | \ |
| 65 | + CPU_BASED_CR8_STORE_EXITING | \ |
| 66 | + CPU_BASED_RDTSC_EXITING | \ |
| 67 | + CPU_BASED_TPR_SHADOW | \ |
| 68 | + CPU_BASED_USE_IO_BITMAPS | \ |
| 69 | + CPU_BASED_MONITOR_TRAP_FLAG | \ |
| 70 | + CPU_BASED_USE_MSR_BITMAPS | \ |
| 71 | + CPU_BASED_NMI_WINDOW_EXITING | \ |
| 72 | + CPU_BASED_PAUSE_EXITING | \ |
| 73 | + CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) |
| 74 | + |
| 75 | +#define EVMCS1_SUPPORTED_2NDEXEC \ |
| 76 | + (SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | \ |
| 77 | + SECONDARY_EXEC_WBINVD_EXITING | \ |
| 78 | + SECONDARY_EXEC_ENABLE_VPID | \ |
| 79 | + SECONDARY_EXEC_ENABLE_EPT | \ |
| 80 | + SECONDARY_EXEC_UNRESTRICTED_GUEST | \ |
| 81 | + SECONDARY_EXEC_DESC | \ |
| 82 | + SECONDARY_EXEC_ENABLE_RDTSCP | \ |
| 83 | + SECONDARY_EXEC_ENABLE_INVPCID | \ |
| 84 | + SECONDARY_EXEC_ENABLE_XSAVES | \ |
| 85 | + SECONDARY_EXEC_RDSEED_EXITING | \ |
| 86 | + SECONDARY_EXEC_RDRAND_EXITING | \ |
| 87 | + SECONDARY_EXEC_TSC_SCALING | \ |
| 88 | + SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | \ |
| 89 | + SECONDARY_EXEC_PT_USE_GPA | \ |
| 90 | + SECONDARY_EXEC_PT_CONCEAL_VMX | \ |
| 91 | + SECONDARY_EXEC_BUS_LOCK_DETECTION | \ |
| 92 | + SECONDARY_EXEC_NOTIFY_VM_EXITING | \ |
| 93 | + SECONDARY_EXEC_ENCLS_EXITING) |
| 94 | + |
| 95 | +#define EVMCS1_SUPPORTED_3RDEXEC (0ULL) |
| 96 | + |
| 97 | +#define EVMCS1_SUPPORTED_VMEXIT_CTRL \ |
| 98 | + (VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | \ |
| 99 | + VM_EXIT_SAVE_DEBUG_CONTROLS | \ |
| 100 | + VM_EXIT_ACK_INTR_ON_EXIT | \ |
| 101 | + VM_EXIT_HOST_ADDR_SPACE_SIZE | \ |
| 102 | + VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | \ |
| 103 | + VM_EXIT_SAVE_IA32_PAT | \ |
| 104 | + VM_EXIT_LOAD_IA32_PAT | \ |
| 105 | + VM_EXIT_SAVE_IA32_EFER | \ |
| 106 | + VM_EXIT_LOAD_IA32_EFER | \ |
| 107 | + VM_EXIT_CLEAR_BNDCFGS | \ |
| 108 | + VM_EXIT_PT_CONCEAL_PIP | \ |
| 109 | + VM_EXIT_CLEAR_IA32_RTIT_CTL) |
| 110 | + |
| 111 | +#define EVMCS1_SUPPORTED_VMENTRY_CTRL \ |
| 112 | + (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | \ |
| 113 | + VM_ENTRY_LOAD_DEBUG_CONTROLS | \ |
| 114 | + VM_ENTRY_IA32E_MODE | \ |
| 115 | + VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | \ |
| 116 | + VM_ENTRY_LOAD_IA32_PAT | \ |
| 117 | + VM_ENTRY_LOAD_IA32_EFER | \ |
| 118 | + VM_ENTRY_LOAD_BNDCFGS | \ |
| 119 | + VM_ENTRY_PT_CONCEAL_PIP | \ |
| 120 | + VM_ENTRY_LOAD_IA32_RTIT_CTL) |
| 121 | + |
| 122 | +#define EVMCS1_SUPPORTED_VMFUNC (0) |
| 123 | + |
23 | 124 | struct evmcs_field { |
24 | 125 | u16 offset; |
25 | 126 | u16 clean_field; |
@@ -65,114 +166,6 @@ static inline u64 evmcs_read_any(struct hv_enlightened_vmcs *evmcs, |
65 | 166 | return vmcs12_read_any((void *)evmcs, field, offset); |
66 | 167 | } |
67 | 168 |
|
68 | | -#if IS_ENABLED(CONFIG_HYPERV) |
69 | | - |
70 | | -DECLARE_STATIC_KEY_FALSE(__kvm_is_using_evmcs); |
71 | | - |
72 | | -static __always_inline bool kvm_is_using_evmcs(void) |
73 | | -{ |
74 | | - return static_branch_unlikely(&__kvm_is_using_evmcs); |
75 | | -} |
76 | | - |
77 | | -static __always_inline int get_evmcs_offset(unsigned long field, |
78 | | - u16 *clean_field) |
79 | | -{ |
80 | | - int offset = evmcs_field_offset(field, clean_field); |
81 | | - |
82 | | - WARN_ONCE(offset < 0, "accessing unsupported EVMCS field %lx\n", field); |
83 | | - return offset; |
84 | | -} |
85 | | - |
86 | | -static __always_inline void evmcs_write64(unsigned long field, u64 value) |
87 | | -{ |
88 | | - u16 clean_field; |
89 | | - int offset = get_evmcs_offset(field, &clean_field); |
90 | | - |
91 | | - if (offset < 0) |
92 | | - return; |
93 | | - |
94 | | - *(u64 *)((char *)current_evmcs + offset) = value; |
95 | | - |
96 | | - current_evmcs->hv_clean_fields &= ~clean_field; |
97 | | -} |
98 | | - |
99 | | -static __always_inline void evmcs_write32(unsigned long field, u32 value) |
100 | | -{ |
101 | | - u16 clean_field; |
102 | | - int offset = get_evmcs_offset(field, &clean_field); |
103 | | - |
104 | | - if (offset < 0) |
105 | | - return; |
106 | | - |
107 | | - *(u32 *)((char *)current_evmcs + offset) = value; |
108 | | - current_evmcs->hv_clean_fields &= ~clean_field; |
109 | | -} |
110 | | - |
111 | | -static __always_inline void evmcs_write16(unsigned long field, u16 value) |
112 | | -{ |
113 | | - u16 clean_field; |
114 | | - int offset = get_evmcs_offset(field, &clean_field); |
115 | | - |
116 | | - if (offset < 0) |
117 | | - return; |
118 | | - |
119 | | - *(u16 *)((char *)current_evmcs + offset) = value; |
120 | | - current_evmcs->hv_clean_fields &= ~clean_field; |
121 | | -} |
122 | | - |
123 | | -static __always_inline u64 evmcs_read64(unsigned long field) |
124 | | -{ |
125 | | - int offset = get_evmcs_offset(field, NULL); |
126 | | - |
127 | | - if (offset < 0) |
128 | | - return 0; |
129 | | - |
130 | | - return *(u64 *)((char *)current_evmcs + offset); |
131 | | -} |
132 | | - |
133 | | -static __always_inline u32 evmcs_read32(unsigned long field) |
134 | | -{ |
135 | | - int offset = get_evmcs_offset(field, NULL); |
136 | | - |
137 | | - if (offset < 0) |
138 | | - return 0; |
139 | | - |
140 | | - return *(u32 *)((char *)current_evmcs + offset); |
141 | | -} |
142 | | - |
143 | | -static __always_inline u16 evmcs_read16(unsigned long field) |
144 | | -{ |
145 | | - int offset = get_evmcs_offset(field, NULL); |
146 | | - |
147 | | - if (offset < 0) |
148 | | - return 0; |
149 | | - |
150 | | - return *(u16 *)((char *)current_evmcs + offset); |
151 | | -} |
152 | | - |
153 | | -static inline void evmcs_load(u64 phys_addr) |
154 | | -{ |
155 | | - struct hv_vp_assist_page *vp_ap = |
156 | | - hv_get_vp_assist_page(smp_processor_id()); |
157 | | - |
158 | | - if (current_evmcs->hv_enlightenments_control.nested_flush_hypercall) |
159 | | - vp_ap->nested_control.features.directhypercall = 1; |
160 | | - vp_ap->current_nested_vmcs = phys_addr; |
161 | | - vp_ap->enlighten_vmentry = 1; |
162 | | -} |
163 | | - |
164 | | -void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf); |
165 | | -#else /* !IS_ENABLED(CONFIG_HYPERV) */ |
166 | | -static __always_inline bool kvm_is_using_evmcs(void) { return false; } |
167 | | -static __always_inline void evmcs_write64(unsigned long field, u64 value) {} |
168 | | -static __always_inline void evmcs_write32(unsigned long field, u32 value) {} |
169 | | -static __always_inline void evmcs_write16(unsigned long field, u16 value) {} |
170 | | -static __always_inline u64 evmcs_read64(unsigned long field) { return 0; } |
171 | | -static __always_inline u32 evmcs_read32(unsigned long field) { return 0; } |
172 | | -static __always_inline u16 evmcs_read16(unsigned long field) { return 0; } |
173 | | -static inline void evmcs_load(u64 phys_addr) {} |
174 | | -#endif /* IS_ENABLED(CONFIG_HYPERV) */ |
175 | | - |
176 | 169 | #define EVMPTR_INVALID (-1ULL) |
177 | 170 | #define EVMPTR_MAP_PENDING (-2ULL) |
178 | 171 |
|
|
0 commit comments