Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/kvm/vmx/capabilities.h
29524 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
#ifndef __KVM_X86_VMX_CAPS_H
3
#define __KVM_X86_VMX_CAPS_H
4
5
#include <asm/vmx.h>
6
7
#include "../lapic.h"
8
#include "../x86.h"
9
#include "../pmu.h"
10
#include "../cpuid.h"
11
12
extern bool __read_mostly enable_vpid;
13
extern bool __read_mostly flexpriority_enabled;
14
extern bool __read_mostly enable_ept;
15
extern bool __read_mostly enable_unrestricted_guest;
16
extern bool __read_mostly enable_ept_ad_bits;
17
extern bool __read_mostly enable_pml;
18
extern int __read_mostly pt_mode;
19
20
#define PT_MODE_SYSTEM 0
21
#define PT_MODE_HOST_GUEST 1
22
23
struct nested_vmx_msrs {
24
/*
25
* We only store the "true" versions of the VMX capability MSRs. We
26
* generate the "non-true" versions by setting the must-be-1 bits
27
* according to the SDM.
28
*/
29
u32 procbased_ctls_low;
30
u32 procbased_ctls_high;
31
u32 secondary_ctls_low;
32
u32 secondary_ctls_high;
33
u32 pinbased_ctls_low;
34
u32 pinbased_ctls_high;
35
u32 exit_ctls_low;
36
u32 exit_ctls_high;
37
u32 entry_ctls_low;
38
u32 entry_ctls_high;
39
u32 misc_low;
40
u32 misc_high;
41
u32 ept_caps;
42
u32 vpid_caps;
43
u64 basic;
44
u64 cr0_fixed0;
45
u64 cr0_fixed1;
46
u64 cr4_fixed0;
47
u64 cr4_fixed1;
48
u64 vmcs_enum;
49
u64 vmfunc_controls;
50
};
51
52
struct vmcs_config {
53
u64 basic;
54
u32 pin_based_exec_ctrl;
55
u32 cpu_based_exec_ctrl;
56
u32 cpu_based_2nd_exec_ctrl;
57
u64 cpu_based_3rd_exec_ctrl;
58
u32 vmexit_ctrl;
59
u32 vmentry_ctrl;
60
u64 misc;
61
struct nested_vmx_msrs nested;
62
};
63
extern struct vmcs_config vmcs_config __ro_after_init;
64
65
struct vmx_capability {
66
u32 ept;
67
u32 vpid;
68
};
69
extern struct vmx_capability vmx_capability __ro_after_init;
70
71
static inline bool cpu_has_vmx_basic_inout(void)
72
{
73
return vmcs_config.basic & VMX_BASIC_INOUT;
74
}
75
76
static inline bool cpu_has_vmx_basic_no_hw_errcode_cc(void)
77
{
78
return vmcs_config.basic & VMX_BASIC_NO_HW_ERROR_CODE_CC;
79
}
80
81
static inline bool cpu_has_virtual_nmis(void)
82
{
83
return vmcs_config.pin_based_exec_ctrl & PIN_BASED_VIRTUAL_NMIS &&
84
vmcs_config.cpu_based_exec_ctrl & CPU_BASED_NMI_WINDOW_EXITING;
85
}
86
87
static inline bool cpu_has_vmx_preemption_timer(void)
88
{
89
return vmcs_config.pin_based_exec_ctrl &
90
PIN_BASED_VMX_PREEMPTION_TIMER;
91
}
92
93
static inline bool cpu_has_vmx_posted_intr(void)
94
{
95
return vmcs_config.pin_based_exec_ctrl & PIN_BASED_POSTED_INTR;
96
}
97
98
static inline bool cpu_has_load_ia32_efer(void)
99
{
100
return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_EFER;
101
}
102
103
static inline bool cpu_has_load_perf_global_ctrl(void)
104
{
105
return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
106
}
107
108
static inline bool cpu_has_load_cet_ctrl(void)
109
{
110
return (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_CET_STATE);
111
}
112
static inline bool cpu_has_vmx_mpx(void)
113
{
114
return vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_BNDCFGS;
115
}
116
117
static inline bool cpu_has_vmx_tpr_shadow(void)
118
{
119
return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_TPR_SHADOW;
120
}
121
122
static inline bool cpu_need_tpr_shadow(struct kvm_vcpu *vcpu)
123
{
124
return cpu_has_vmx_tpr_shadow() && lapic_in_kernel(vcpu);
125
}
126
127
static inline bool cpu_has_vmx_msr_bitmap(void)
128
{
129
return vmcs_config.cpu_based_exec_ctrl & CPU_BASED_USE_MSR_BITMAPS;
130
}
131
132
static inline bool cpu_has_secondary_exec_ctrls(void)
133
{
134
return vmcs_config.cpu_based_exec_ctrl &
135
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
136
}
137
138
static inline bool cpu_has_tertiary_exec_ctrls(void)
139
{
140
return vmcs_config.cpu_based_exec_ctrl &
141
CPU_BASED_ACTIVATE_TERTIARY_CONTROLS;
142
}
143
144
static inline bool cpu_has_vmx_virtualize_apic_accesses(void)
145
{
146
return vmcs_config.cpu_based_2nd_exec_ctrl &
147
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
148
}
149
150
static inline bool cpu_has_vmx_ept(void)
151
{
152
return vmcs_config.cpu_based_2nd_exec_ctrl &
153
SECONDARY_EXEC_ENABLE_EPT;
154
}
155
156
static inline bool vmx_umip_emulated(void)
157
{
158
return !boot_cpu_has(X86_FEATURE_UMIP) &&
159
(vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_DESC);
160
}
161
162
static inline bool cpu_has_vmx_rdtscp(void)
163
{
164
return vmcs_config.cpu_based_2nd_exec_ctrl &
165
SECONDARY_EXEC_ENABLE_RDTSCP;
166
}
167
168
static inline bool cpu_has_vmx_virtualize_x2apic_mode(void)
169
{
170
return vmcs_config.cpu_based_2nd_exec_ctrl &
171
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
172
}
173
174
static inline bool cpu_has_vmx_vpid(void)
175
{
176
return vmcs_config.cpu_based_2nd_exec_ctrl &
177
SECONDARY_EXEC_ENABLE_VPID;
178
}
179
180
static inline bool cpu_has_vmx_wbinvd_exit(void)
181
{
182
return vmcs_config.cpu_based_2nd_exec_ctrl &
183
SECONDARY_EXEC_WBINVD_EXITING;
184
}
185
186
static inline bool cpu_has_vmx_unrestricted_guest(void)
187
{
188
return vmcs_config.cpu_based_2nd_exec_ctrl &
189
SECONDARY_EXEC_UNRESTRICTED_GUEST;
190
}
191
192
static inline bool cpu_has_vmx_apic_register_virt(void)
193
{
194
return vmcs_config.cpu_based_2nd_exec_ctrl &
195
SECONDARY_EXEC_APIC_REGISTER_VIRT;
196
}
197
198
static inline bool cpu_has_vmx_virtual_intr_delivery(void)
199
{
200
return vmcs_config.cpu_based_2nd_exec_ctrl &
201
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY;
202
}
203
204
static inline bool cpu_has_vmx_ple(void)
205
{
206
return vmcs_config.cpu_based_2nd_exec_ctrl &
207
SECONDARY_EXEC_PAUSE_LOOP_EXITING;
208
}
209
210
static inline bool cpu_has_vmx_rdrand(void)
211
{
212
return vmcs_config.cpu_based_2nd_exec_ctrl &
213
SECONDARY_EXEC_RDRAND_EXITING;
214
}
215
216
static inline bool cpu_has_vmx_invpcid(void)
217
{
218
return vmcs_config.cpu_based_2nd_exec_ctrl &
219
SECONDARY_EXEC_ENABLE_INVPCID;
220
}
221
222
static inline bool cpu_has_vmx_vmfunc(void)
223
{
224
return vmcs_config.cpu_based_2nd_exec_ctrl &
225
SECONDARY_EXEC_ENABLE_VMFUNC;
226
}
227
228
static inline bool cpu_has_vmx_shadow_vmcs(void)
229
{
230
/* check if the cpu supports writing r/o exit information fields */
231
if (!(vmcs_config.misc & VMX_MISC_VMWRITE_SHADOW_RO_FIELDS))
232
return false;
233
234
return vmcs_config.cpu_based_2nd_exec_ctrl &
235
SECONDARY_EXEC_SHADOW_VMCS;
236
}
237
238
static inline bool cpu_has_vmx_encls_vmexit(void)
239
{
240
return vmcs_config.cpu_based_2nd_exec_ctrl &
241
SECONDARY_EXEC_ENCLS_EXITING;
242
}
243
244
static inline bool cpu_has_vmx_rdseed(void)
245
{
246
return vmcs_config.cpu_based_2nd_exec_ctrl &
247
SECONDARY_EXEC_RDSEED_EXITING;
248
}
249
250
static inline bool cpu_has_vmx_pml(void)
251
{
252
return vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_ENABLE_PML;
253
}
254
255
static inline bool cpu_has_vmx_xsaves(void)
256
{
257
return vmcs_config.cpu_based_2nd_exec_ctrl &
258
SECONDARY_EXEC_ENABLE_XSAVES;
259
}
260
261
static inline bool cpu_has_vmx_waitpkg(void)
262
{
263
return vmcs_config.cpu_based_2nd_exec_ctrl &
264
SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
265
}
266
267
static inline bool cpu_has_vmx_tsc_scaling(void)
268
{
269
return vmcs_config.cpu_based_2nd_exec_ctrl &
270
SECONDARY_EXEC_TSC_SCALING;
271
}
272
273
static inline bool cpu_has_vmx_bus_lock_detection(void)
274
{
275
return vmcs_config.cpu_based_2nd_exec_ctrl &
276
SECONDARY_EXEC_BUS_LOCK_DETECTION;
277
}
278
279
static inline bool cpu_has_vmx_apicv(void)
280
{
281
return cpu_has_vmx_apic_register_virt() &&
282
cpu_has_vmx_virtual_intr_delivery() &&
283
cpu_has_vmx_posted_intr();
284
}
285
286
static inline bool cpu_has_vmx_ipiv(void)
287
{
288
return vmcs_config.cpu_based_3rd_exec_ctrl & TERTIARY_EXEC_IPI_VIRT;
289
}
290
291
static inline bool cpu_has_vmx_flexpriority(void)
292
{
293
return cpu_has_vmx_tpr_shadow() &&
294
cpu_has_vmx_virtualize_apic_accesses();
295
}
296
297
static inline bool cpu_has_vmx_ept_execute_only(void)
298
{
299
return vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT;
300
}
301
302
static inline bool cpu_has_vmx_ept_4levels(void)
303
{
304
return vmx_capability.ept & VMX_EPT_PAGE_WALK_4_BIT;
305
}
306
307
static inline bool cpu_has_vmx_ept_5levels(void)
308
{
309
return vmx_capability.ept & VMX_EPT_PAGE_WALK_5_BIT;
310
}
311
312
static inline bool cpu_has_vmx_ept_mt_wb(void)
313
{
314
return vmx_capability.ept & VMX_EPTP_WB_BIT;
315
}
316
317
static inline bool cpu_has_vmx_ept_2m_page(void)
318
{
319
return vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT;
320
}
321
322
static inline bool cpu_has_vmx_ept_1g_page(void)
323
{
324
return vmx_capability.ept & VMX_EPT_1GB_PAGE_BIT;
325
}
326
327
static inline int ept_caps_to_lpage_level(u32 ept_caps)
328
{
329
if (ept_caps & VMX_EPT_1GB_PAGE_BIT)
330
return PG_LEVEL_1G;
331
if (ept_caps & VMX_EPT_2MB_PAGE_BIT)
332
return PG_LEVEL_2M;
333
return PG_LEVEL_4K;
334
}
335
336
static inline bool cpu_has_vmx_ept_ad_bits(void)
337
{
338
return vmx_capability.ept & VMX_EPT_AD_BIT;
339
}
340
341
static inline bool cpu_has_vmx_invept_context(void)
342
{
343
return vmx_capability.ept & VMX_EPT_EXTENT_CONTEXT_BIT;
344
}
345
346
static inline bool cpu_has_vmx_invept_global(void)
347
{
348
return vmx_capability.ept & VMX_EPT_EXTENT_GLOBAL_BIT;
349
}
350
351
static inline bool cpu_has_vmx_invvpid(void)
352
{
353
return vmx_capability.vpid & VMX_VPID_INVVPID_BIT;
354
}
355
356
static inline bool cpu_has_vmx_invvpid_individual_addr(void)
357
{
358
return vmx_capability.vpid & VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT;
359
}
360
361
static inline bool cpu_has_vmx_invvpid_single(void)
362
{
363
return vmx_capability.vpid & VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT;
364
}
365
366
static inline bool cpu_has_vmx_invvpid_global(void)
367
{
368
return vmx_capability.vpid & VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT;
369
}
370
371
static inline bool cpu_has_vmx_intel_pt(void)
372
{
373
return (vmcs_config.misc & VMX_MISC_INTEL_PT) &&
374
(vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_PT_USE_GPA) &&
375
(vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_RTIT_CTL);
376
}
377
378
/*
379
* Processor Trace can operate in one of three modes:
380
* a. system-wide: trace both host/guest and output to host buffer
381
* b. host-only: only trace host and output to host buffer
382
* c. host-guest: trace host and guest simultaneously and output to their
383
* respective buffer
384
*
385
* KVM currently only supports (a) and (c).
386
*/
387
static inline bool vmx_pt_mode_is_system(void)
388
{
389
return pt_mode == PT_MODE_SYSTEM;
390
}
391
static inline bool vmx_pt_mode_is_host_guest(void)
392
{
393
return pt_mode == PT_MODE_HOST_GUEST;
394
}
395
396
static inline bool vmx_pebs_supported(void)
397
{
398
return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept;
399
}
400
401
static inline bool cpu_has_notify_vmexit(void)
402
{
403
return vmcs_config.cpu_based_2nd_exec_ctrl &
404
SECONDARY_EXEC_NOTIFY_VM_EXITING;
405
}
406
407
#endif /* __KVM_X86_VMX_CAPS_H */
408
409