xref: /openbmc/linux/arch/x86/kvm/vmx/hyperv.h (revision 0db00e5d86dc793aab9722ad3728d99166eb7d96)
1a789aebaSVitaly Kuznetsov /* SPDX-License-Identifier: GPL-2.0 */
2a789aebaSVitaly Kuznetsov #ifndef __KVM_X86_VMX_HYPERV_H
3a789aebaSVitaly Kuznetsov #define __KVM_X86_VMX_HYPERV_H
4a789aebaSVitaly Kuznetsov 
5a789aebaSVitaly Kuznetsov #include <linux/jump_label.h>
6a789aebaSVitaly Kuznetsov 
7a789aebaSVitaly Kuznetsov #include <asm/hyperv-tlfs.h>
8a789aebaSVitaly Kuznetsov #include <asm/mshyperv.h>
9a789aebaSVitaly Kuznetsov #include <asm/vmx.h>
10a789aebaSVitaly Kuznetsov 
11a789aebaSVitaly Kuznetsov #include "../hyperv.h"
12a789aebaSVitaly Kuznetsov 
13a789aebaSVitaly Kuznetsov #include "capabilities.h"
14a789aebaSVitaly Kuznetsov #include "vmcs.h"
15a789aebaSVitaly Kuznetsov #include "vmcs12.h"
16a789aebaSVitaly Kuznetsov 
17a789aebaSVitaly Kuznetsov #define KVM_EVMCS_VERSION 1
18a789aebaSVitaly Kuznetsov 
19*ebfed7beSVitaly Kuznetsov /*
20*ebfed7beSVitaly Kuznetsov  * Enlightened VMCSv1 doesn't support these:
21*ebfed7beSVitaly Kuznetsov  *
22*ebfed7beSVitaly Kuznetsov  *	POSTED_INTR_NV                  = 0x00000002,
23*ebfed7beSVitaly Kuznetsov  *	GUEST_INTR_STATUS               = 0x00000810,
24*ebfed7beSVitaly Kuznetsov  *	APIC_ACCESS_ADDR		= 0x00002014,
25*ebfed7beSVitaly Kuznetsov  *	POSTED_INTR_DESC_ADDR           = 0x00002016,
26*ebfed7beSVitaly Kuznetsov  *	EOI_EXIT_BITMAP0                = 0x0000201c,
27*ebfed7beSVitaly Kuznetsov  *	EOI_EXIT_BITMAP1                = 0x0000201e,
28*ebfed7beSVitaly Kuznetsov  *	EOI_EXIT_BITMAP2                = 0x00002020,
29*ebfed7beSVitaly Kuznetsov  *	EOI_EXIT_BITMAP3                = 0x00002022,
30*ebfed7beSVitaly Kuznetsov  *	GUEST_PML_INDEX			= 0x00000812,
31*ebfed7beSVitaly Kuznetsov  *	PML_ADDRESS			= 0x0000200e,
32*ebfed7beSVitaly Kuznetsov  *	VM_FUNCTION_CONTROL             = 0x00002018,
33*ebfed7beSVitaly Kuznetsov  *	EPTP_LIST_ADDRESS               = 0x00002024,
34*ebfed7beSVitaly Kuznetsov  *	VMREAD_BITMAP                   = 0x00002026,
35*ebfed7beSVitaly Kuznetsov  *	VMWRITE_BITMAP                  = 0x00002028,
36*ebfed7beSVitaly Kuznetsov  *
37*ebfed7beSVitaly Kuznetsov  *	TSC_MULTIPLIER                  = 0x00002032,
38*ebfed7beSVitaly Kuznetsov  *	PLE_GAP                         = 0x00004020,
39*ebfed7beSVitaly Kuznetsov  *	PLE_WINDOW                      = 0x00004022,
40*ebfed7beSVitaly Kuznetsov  *	VMX_PREEMPTION_TIMER_VALUE      = 0x0000482E,
41*ebfed7beSVitaly Kuznetsov  *
42*ebfed7beSVitaly Kuznetsov  * Currently unsupported in KVM:
43*ebfed7beSVitaly Kuznetsov  *	GUEST_IA32_RTIT_CTL		= 0x00002814,
44*ebfed7beSVitaly Kuznetsov  */
45*ebfed7beSVitaly Kuznetsov #define EVMCS1_SUPPORTED_PINCTRL					\
46*ebfed7beSVitaly Kuznetsov 	(PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |				\
47*ebfed7beSVitaly Kuznetsov 	 PIN_BASED_EXT_INTR_MASK |					\
48*ebfed7beSVitaly Kuznetsov 	 PIN_BASED_NMI_EXITING |					\
49*ebfed7beSVitaly Kuznetsov 	 PIN_BASED_VIRTUAL_NMIS)
50*ebfed7beSVitaly Kuznetsov 
51*ebfed7beSVitaly Kuznetsov #define EVMCS1_SUPPORTED_EXEC_CTRL					\
52*ebfed7beSVitaly Kuznetsov 	(CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR |				\
53*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_HLT_EXITING |					\
54*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_CR3_LOAD_EXITING |					\
55*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_CR3_STORE_EXITING |					\
56*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_UNCOND_IO_EXITING |					\
57*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_MOV_DR_EXITING |					\
58*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_USE_TSC_OFFSETTING |					\
59*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_MWAIT_EXITING |					\
60*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_MONITOR_EXITING |					\
61*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_INVLPG_EXITING |					\
62*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_RDPMC_EXITING |					\
63*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_INTR_WINDOW_EXITING |				\
64*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_CR8_LOAD_EXITING |					\
65*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_CR8_STORE_EXITING |					\
66*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_RDTSC_EXITING |					\
67*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_TPR_SHADOW |						\
68*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_USE_IO_BITMAPS |					\
69*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_MONITOR_TRAP_FLAG |					\
70*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_USE_MSR_BITMAPS |					\
71*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_NMI_WINDOW_EXITING |					\
72*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_PAUSE_EXITING |					\
73*ebfed7beSVitaly Kuznetsov 	 CPU_BASED_ACTIVATE_SECONDARY_CONTROLS)
74*ebfed7beSVitaly Kuznetsov 
75*ebfed7beSVitaly Kuznetsov #define EVMCS1_SUPPORTED_2NDEXEC					\
76*ebfed7beSVitaly Kuznetsov 	(SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |			\
77*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_WBINVD_EXITING |				\
78*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_ENABLE_VPID |					\
79*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_ENABLE_EPT |					\
80*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_UNRESTRICTED_GUEST |				\
81*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_DESC |						\
82*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_ENABLE_RDTSCP |					\
83*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_ENABLE_INVPCID |				\
84*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_ENABLE_XSAVES |					\
85*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_RDSEED_EXITING |				\
86*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_RDRAND_EXITING |				\
87*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_TSC_SCALING |					\
88*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE |				\
89*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_PT_USE_GPA |					\
90*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_PT_CONCEAL_VMX |				\
91*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_BUS_LOCK_DETECTION |				\
92*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_NOTIFY_VM_EXITING |				\
93*ebfed7beSVitaly Kuznetsov 	 SECONDARY_EXEC_ENCLS_EXITING)
94*ebfed7beSVitaly Kuznetsov 
95*ebfed7beSVitaly Kuznetsov #define EVMCS1_SUPPORTED_3RDEXEC (0ULL)
96*ebfed7beSVitaly Kuznetsov 
97*ebfed7beSVitaly Kuznetsov #define EVMCS1_SUPPORTED_VMEXIT_CTRL					\
98*ebfed7beSVitaly Kuznetsov 	(VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR |				\
99*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_SAVE_DEBUG_CONTROLS |					\
100*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_ACK_INTR_ON_EXIT |					\
101*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_HOST_ADDR_SPACE_SIZE |					\
102*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |				\
103*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_SAVE_IA32_PAT |					\
104*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_LOAD_IA32_PAT |					\
105*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_SAVE_IA32_EFER |					\
106*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_LOAD_IA32_EFER |					\
107*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_CLEAR_BNDCFGS |					\
108*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_PT_CONCEAL_PIP |					\
109*ebfed7beSVitaly Kuznetsov 	 VM_EXIT_CLEAR_IA32_RTIT_CTL)
110*ebfed7beSVitaly Kuznetsov 
111*ebfed7beSVitaly Kuznetsov #define EVMCS1_SUPPORTED_VMENTRY_CTRL					\
112*ebfed7beSVitaly Kuznetsov 	(VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR |				\
113*ebfed7beSVitaly Kuznetsov 	 VM_ENTRY_LOAD_DEBUG_CONTROLS |					\
114*ebfed7beSVitaly Kuznetsov 	 VM_ENTRY_IA32E_MODE |						\
115*ebfed7beSVitaly Kuznetsov 	 VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL |				\
116*ebfed7beSVitaly Kuznetsov 	 VM_ENTRY_LOAD_IA32_PAT |					\
117*ebfed7beSVitaly Kuznetsov 	 VM_ENTRY_LOAD_IA32_EFER |					\
118*ebfed7beSVitaly Kuznetsov 	 VM_ENTRY_LOAD_BNDCFGS |					\
119*ebfed7beSVitaly Kuznetsov 	 VM_ENTRY_PT_CONCEAL_PIP |					\
120*ebfed7beSVitaly Kuznetsov 	 VM_ENTRY_LOAD_IA32_RTIT_CTL)
121*ebfed7beSVitaly Kuznetsov 
122*ebfed7beSVitaly Kuznetsov #define EVMCS1_SUPPORTED_VMFUNC (0)
123*ebfed7beSVitaly Kuznetsov 
124a789aebaSVitaly Kuznetsov struct evmcs_field {
125a789aebaSVitaly Kuznetsov 	u16 offset;
126a789aebaSVitaly Kuznetsov 	u16 clean_field;
127a789aebaSVitaly Kuznetsov };
128a789aebaSVitaly Kuznetsov 
129a789aebaSVitaly Kuznetsov extern const struct evmcs_field vmcs_field_to_evmcs_1[];
130a789aebaSVitaly Kuznetsov extern const unsigned int nr_evmcs_1_fields;
131a789aebaSVitaly Kuznetsov 
evmcs_field_offset(unsigned long field,u16 * clean_field)132a789aebaSVitaly Kuznetsov static __always_inline int evmcs_field_offset(unsigned long field,
133a789aebaSVitaly Kuznetsov 					      u16 *clean_field)
134a789aebaSVitaly Kuznetsov {
135a789aebaSVitaly Kuznetsov 	unsigned int index = ROL16(field, 6);
136a789aebaSVitaly Kuznetsov 	const struct evmcs_field *evmcs_field;
137a789aebaSVitaly Kuznetsov 
138a789aebaSVitaly Kuznetsov 	if (unlikely(index >= nr_evmcs_1_fields))
139a789aebaSVitaly Kuznetsov 		return -ENOENT;
140a789aebaSVitaly Kuznetsov 
141a789aebaSVitaly Kuznetsov 	evmcs_field = &vmcs_field_to_evmcs_1[index];
142a789aebaSVitaly Kuznetsov 
143a789aebaSVitaly Kuznetsov 	/*
144a789aebaSVitaly Kuznetsov 	 * Use offset=0 to detect holes in eVMCS. This offset belongs to
145a789aebaSVitaly Kuznetsov 	 * 'revision_id' but this field has no encoding and is supposed to
146a789aebaSVitaly Kuznetsov 	 * be accessed directly.
147a789aebaSVitaly Kuznetsov 	 */
148a789aebaSVitaly Kuznetsov 	if (unlikely(!evmcs_field->offset))
149a789aebaSVitaly Kuznetsov 		return -ENOENT;
150a789aebaSVitaly Kuznetsov 
151a789aebaSVitaly Kuznetsov 	if (clean_field)
152a789aebaSVitaly Kuznetsov 		*clean_field = evmcs_field->clean_field;
153a789aebaSVitaly Kuznetsov 
154a789aebaSVitaly Kuznetsov 	return evmcs_field->offset;
155a789aebaSVitaly Kuznetsov }
156a789aebaSVitaly Kuznetsov 
evmcs_read_any(struct hv_enlightened_vmcs * evmcs,unsigned long field,u16 offset)157a789aebaSVitaly Kuznetsov static inline u64 evmcs_read_any(struct hv_enlightened_vmcs *evmcs,
158a789aebaSVitaly Kuznetsov 				 unsigned long field, u16 offset)
159a789aebaSVitaly Kuznetsov {
160a789aebaSVitaly Kuznetsov 	/*
161a789aebaSVitaly Kuznetsov 	 * vmcs12_read_any() doesn't care whether the supplied structure
162a789aebaSVitaly Kuznetsov 	 * is 'struct vmcs12' or 'struct hv_enlightened_vmcs' as it takes
163a789aebaSVitaly Kuznetsov 	 * the exact offset of the required field, use it for convenience
164a789aebaSVitaly Kuznetsov 	 * here.
165a789aebaSVitaly Kuznetsov 	 */
166a789aebaSVitaly Kuznetsov 	return vmcs12_read_any((void *)evmcs, field, offset);
167a789aebaSVitaly Kuznetsov }
168a789aebaSVitaly Kuznetsov 
169a789aebaSVitaly Kuznetsov #define EVMPTR_INVALID (-1ULL)
170a789aebaSVitaly Kuznetsov #define EVMPTR_MAP_PENDING (-2ULL)
171a789aebaSVitaly Kuznetsov 
evmptr_is_valid(u64 evmptr)172a789aebaSVitaly Kuznetsov static inline bool evmptr_is_valid(u64 evmptr)
173a789aebaSVitaly Kuznetsov {
174a789aebaSVitaly Kuznetsov 	return evmptr != EVMPTR_INVALID && evmptr != EVMPTR_MAP_PENDING;
175a789aebaSVitaly Kuznetsov }
176a789aebaSVitaly Kuznetsov 
177a789aebaSVitaly Kuznetsov enum nested_evmptrld_status {
178a789aebaSVitaly Kuznetsov 	EVMPTRLD_DISABLED,
179a789aebaSVitaly Kuznetsov 	EVMPTRLD_SUCCEEDED,
180a789aebaSVitaly Kuznetsov 	EVMPTRLD_VMFAIL,
181a789aebaSVitaly Kuznetsov 	EVMPTRLD_ERROR,
182a789aebaSVitaly Kuznetsov };
183a789aebaSVitaly Kuznetsov 
184046f5756SVitaly Kuznetsov u64 nested_get_evmptr(struct kvm_vcpu *vcpu);
185a789aebaSVitaly Kuznetsov uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu);
186a789aebaSVitaly Kuznetsov int nested_enable_evmcs(struct kvm_vcpu *vcpu,
187a789aebaSVitaly Kuznetsov 			uint16_t *vmcs_version);
188a789aebaSVitaly Kuznetsov void nested_evmcs_filter_control_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
189a789aebaSVitaly Kuznetsov int nested_evmcs_check_controls(struct vmcs12 *vmcs12);
190c30e9bc8SVitaly Kuznetsov bool nested_evmcs_l2_tlb_flush_enabled(struct kvm_vcpu *vcpu);
191b0c9c25eSVitaly Kuznetsov void vmx_hv_inject_synthetic_vmexit_post_tlb_flush(struct kvm_vcpu *vcpu);
192a789aebaSVitaly Kuznetsov 
193a789aebaSVitaly Kuznetsov #endif /* __KVM_X86_VMX_HYPERV_H */
194