189b0c9f5SSean Christopherson /* SPDX-License-Identifier: GPL-2.0 */
289b0c9f5SSean Christopherson #ifndef __KVM_X86_VMX_INSN_H
389b0c9f5SSean Christopherson #define __KVM_X86_VMX_INSN_H
489b0c9f5SSean Christopherson
589b0c9f5SSean Christopherson #include <linux/nospec.h>
689b0c9f5SSean Christopherson
789b0c9f5SSean Christopherson #include <asm/vmx.h>
889b0c9f5SSean Christopherson
950a82b0eSVitaly Kuznetsov #include "vmx_onhyperv.h"
1089b0c9f5SSean Christopherson #include "vmcs.h"
1107853adcSJosh Poimboeuf #include "../x86.h"
1289b0c9f5SSean Christopherson
13c20d403fSSean Christopherson void vmread_error(unsigned long field);
1452a9fcbcSSean Christopherson void vmwrite_error(unsigned long field, unsigned long value);
1552a9fcbcSSean Christopherson void vmclear_error(struct vmcs *vmcs, u64 phys_addr);
1652a9fcbcSSean Christopherson void vmptrld_error(struct vmcs *vmcs, u64 phys_addr);
1752a9fcbcSSean Christopherson void invvpid_error(unsigned long ext, u16 vpid, gva_t gva);
18bc17fccbSYan Zhao void invept_error(unsigned long ext, u64 eptp);
1952a9fcbcSSean Christopherson
200b5e7a16SSean Christopherson #ifndef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
210b5e7a16SSean Christopherson /*
220b5e7a16SSean Christopherson * The VMREAD error trampoline _always_ uses the stack to pass parameters, even
230b5e7a16SSean Christopherson * for 64-bit targets. Preserving all registers allows the VMREAD inline asm
240b5e7a16SSean Christopherson * blob to avoid clobbering GPRs, which in turn allows the compiler to better
250b5e7a16SSean Christopherson * optimize sequences of VMREADs.
260b5e7a16SSean Christopherson *
270b5e7a16SSean Christopherson * Declare the trampoline as an opaque label as it's not safe to call from C
280b5e7a16SSean Christopherson * code; there is no way to tell the compiler to pass params on the stack for
290b5e7a16SSean Christopherson * 64-bit targets.
300b5e7a16SSean Christopherson *
310b5e7a16SSean Christopherson * void vmread_error_trampoline(unsigned long field, bool fault);
320b5e7a16SSean Christopherson */
330b5e7a16SSean Christopherson extern unsigned long vmread_error_trampoline;
34c20d403fSSean Christopherson
35c20d403fSSean Christopherson /*
36c20d403fSSean Christopherson * The second VMREAD error trampoline, called from the assembly trampoline,
37c20d403fSSean Christopherson * exists primarily to enable instrumentation for the VM-Fail path.
38c20d403fSSean Christopherson */
39c20d403fSSean Christopherson void vmread_error_trampoline2(unsigned long field, bool fault);
40c20d403fSSean Christopherson
410b5e7a16SSean Christopherson #endif
420b5e7a16SSean Christopherson
vmcs_check16(unsigned long field)4389b0c9f5SSean Christopherson static __always_inline void vmcs_check16(unsigned long field)
4489b0c9f5SSean Christopherson {
4589b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2000,
4689b0c9f5SSean Christopherson "16-bit accessor invalid for 64-bit field");
4789b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001,
4889b0c9f5SSean Christopherson "16-bit accessor invalid for 64-bit high field");
4989b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x4000,
50caf22c6dSQiang Liu "16-bit accessor invalid for 32-bit field");
5189b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x6000,
5289b0c9f5SSean Christopherson "16-bit accessor invalid for natural width field");
5389b0c9f5SSean Christopherson }
5489b0c9f5SSean Christopherson
vmcs_check32(unsigned long field)5589b0c9f5SSean Christopherson static __always_inline void vmcs_check32(unsigned long field)
5689b0c9f5SSean Christopherson {
5789b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0,
5889b0c9f5SSean Christopherson "32-bit accessor invalid for 16-bit field");
59870c575aSHaiwei Li BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2000,
60870c575aSHaiwei Li "32-bit accessor invalid for 64-bit field");
61870c575aSHaiwei Li BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001,
62870c575aSHaiwei Li "32-bit accessor invalid for 64-bit high field");
6389b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x6000,
6489b0c9f5SSean Christopherson "32-bit accessor invalid for natural width field");
6589b0c9f5SSean Christopherson }
6689b0c9f5SSean Christopherson
vmcs_check64(unsigned long field)6789b0c9f5SSean Christopherson static __always_inline void vmcs_check64(unsigned long field)
6889b0c9f5SSean Christopherson {
6989b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0,
7089b0c9f5SSean Christopherson "64-bit accessor invalid for 16-bit field");
7189b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001,
7289b0c9f5SSean Christopherson "64-bit accessor invalid for 64-bit high field");
7389b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x4000,
7489b0c9f5SSean Christopherson "64-bit accessor invalid for 32-bit field");
7589b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x6000,
7689b0c9f5SSean Christopherson "64-bit accessor invalid for natural width field");
7789b0c9f5SSean Christopherson }
7889b0c9f5SSean Christopherson
vmcs_checkl(unsigned long field)7989b0c9f5SSean Christopherson static __always_inline void vmcs_checkl(unsigned long field)
8089b0c9f5SSean Christopherson {
8189b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0,
8289b0c9f5SSean Christopherson "Natural width accessor invalid for 16-bit field");
8389b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2000,
8489b0c9f5SSean Christopherson "Natural width accessor invalid for 64-bit field");
8589b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001,
8689b0c9f5SSean Christopherson "Natural width accessor invalid for 64-bit high field");
8789b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x4000,
8889b0c9f5SSean Christopherson "Natural width accessor invalid for 32-bit field");
8989b0c9f5SSean Christopherson }
9089b0c9f5SSean Christopherson
__vmcs_readl(unsigned long field)9189b0c9f5SSean Christopherson static __always_inline unsigned long __vmcs_readl(unsigned long field)
9289b0c9f5SSean Christopherson {
9389b0c9f5SSean Christopherson unsigned long value;
9489b0c9f5SSean Christopherson
95907d1393SPeter Zijlstra #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
96907d1393SPeter Zijlstra
974356e9f8SLinus Torvalds asm_goto_output("1: vmread %[field], %[output]\n\t"
98907d1393SPeter Zijlstra "jna %l[do_fail]\n\t"
99907d1393SPeter Zijlstra
100907d1393SPeter Zijlstra _ASM_EXTABLE(1b, %l[do_exception])
101907d1393SPeter Zijlstra
102907d1393SPeter Zijlstra : [output] "=r" (value)
103907d1393SPeter Zijlstra : [field] "r" (field)
104907d1393SPeter Zijlstra : "cc"
105907d1393SPeter Zijlstra : do_fail, do_exception);
106907d1393SPeter Zijlstra
107907d1393SPeter Zijlstra return value;
108907d1393SPeter Zijlstra
109907d1393SPeter Zijlstra do_fail:
1108578f596SSean Christopherson instrumentation_begin();
111a062dad7SSean Christopherson vmread_error(field);
1128578f596SSean Christopherson instrumentation_end();
113907d1393SPeter Zijlstra return 0;
114907d1393SPeter Zijlstra
115907d1393SPeter Zijlstra do_exception:
116907d1393SPeter Zijlstra kvm_spurious_fault();
117907d1393SPeter Zijlstra return 0;
118907d1393SPeter Zijlstra
119907d1393SPeter Zijlstra #else /* !CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
120907d1393SPeter Zijlstra
121*e1c49eaeSJosh Poimboeuf asm volatile("1: vmread %[field], %[output]\n\t"
1226e202097SSean Christopherson ".byte 0x3e\n\t" /* branch taken hint */
1236e202097SSean Christopherson "ja 3f\n\t"
124842f4be9SSean Christopherson
125842f4be9SSean Christopherson /*
126842f4be9SSean Christopherson * VMREAD failed. Push '0' for @fault, push the failing
127842f4be9SSean Christopherson * @field, and bounce through the trampoline to preserve
128842f4be9SSean Christopherson * volatile registers.
129842f4be9SSean Christopherson */
130*e1c49eaeSJosh Poimboeuf "xorl %k[output], %k[output]\n\t"
1313e8ea780SPeter Zijlstra "2:\n\t"
132*e1c49eaeSJosh Poimboeuf "push %[output]\n\t"
133*e1c49eaeSJosh Poimboeuf "push %[field]\n\t"
1343e8ea780SPeter Zijlstra "call vmread_error_trampoline\n\t"
135842f4be9SSean Christopherson
136842f4be9SSean Christopherson /*
137842f4be9SSean Christopherson * Unwind the stack. Note, the trampoline zeros out the
138842f4be9SSean Christopherson * memory for @fault so that the result is '0' on error.
139842f4be9SSean Christopherson */
140*e1c49eaeSJosh Poimboeuf "pop %[field]\n\t"
141*e1c49eaeSJosh Poimboeuf "pop %[output]\n\t"
1426e202097SSean Christopherson "3:\n\t"
1436e202097SSean Christopherson
144842f4be9SSean Christopherson /* VMREAD faulted. As above, except push '1' for @fault. */
145*e1c49eaeSJosh Poimboeuf _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_ONE_REG, %[output])
1463e8ea780SPeter Zijlstra
147*e1c49eaeSJosh Poimboeuf : ASM_CALL_CONSTRAINT, [output] "=&r" (value)
148*e1c49eaeSJosh Poimboeuf : [field] "r" (field)
149*e1c49eaeSJosh Poimboeuf : "cc");
15089b0c9f5SSean Christopherson return value;
151907d1393SPeter Zijlstra
152907d1393SPeter Zijlstra #endif /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
15389b0c9f5SSean Christopherson }
15489b0c9f5SSean Christopherson
vmcs_read16(unsigned long field)15589b0c9f5SSean Christopherson static __always_inline u16 vmcs_read16(unsigned long field)
15689b0c9f5SSean Christopherson {
15789b0c9f5SSean Christopherson vmcs_check16(field);
15819f10315SSean Christopherson if (kvm_is_using_evmcs())
15989b0c9f5SSean Christopherson return evmcs_read16(field);
16089b0c9f5SSean Christopherson return __vmcs_readl(field);
16189b0c9f5SSean Christopherson }
16289b0c9f5SSean Christopherson
vmcs_read32(unsigned long field)16389b0c9f5SSean Christopherson static __always_inline u32 vmcs_read32(unsigned long field)
16489b0c9f5SSean Christopherson {
16589b0c9f5SSean Christopherson vmcs_check32(field);
16619f10315SSean Christopherson if (kvm_is_using_evmcs())
16789b0c9f5SSean Christopherson return evmcs_read32(field);
16889b0c9f5SSean Christopherson return __vmcs_readl(field);
16989b0c9f5SSean Christopherson }
17089b0c9f5SSean Christopherson
vmcs_read64(unsigned long field)17189b0c9f5SSean Christopherson static __always_inline u64 vmcs_read64(unsigned long field)
17289b0c9f5SSean Christopherson {
17389b0c9f5SSean Christopherson vmcs_check64(field);
17419f10315SSean Christopherson if (kvm_is_using_evmcs())
17589b0c9f5SSean Christopherson return evmcs_read64(field);
17689b0c9f5SSean Christopherson #ifdef CONFIG_X86_64
17789b0c9f5SSean Christopherson return __vmcs_readl(field);
17889b0c9f5SSean Christopherson #else
17989b0c9f5SSean Christopherson return __vmcs_readl(field) | ((u64)__vmcs_readl(field+1) << 32);
18089b0c9f5SSean Christopherson #endif
18189b0c9f5SSean Christopherson }
18289b0c9f5SSean Christopherson
vmcs_readl(unsigned long field)18389b0c9f5SSean Christopherson static __always_inline unsigned long vmcs_readl(unsigned long field)
18489b0c9f5SSean Christopherson {
18589b0c9f5SSean Christopherson vmcs_checkl(field);
18619f10315SSean Christopherson if (kvm_is_using_evmcs())
18789b0c9f5SSean Christopherson return evmcs_read64(field);
18889b0c9f5SSean Christopherson return __vmcs_readl(field);
18989b0c9f5SSean Christopherson }
19089b0c9f5SSean Christopherson
19152a9fcbcSSean Christopherson #define vmx_asm1(insn, op1, error_args...) \
19252a9fcbcSSean Christopherson do { \
1934356e9f8SLinus Torvalds asm goto("1: " __stringify(insn) " %0\n\t" \
19452a9fcbcSSean Christopherson ".byte 0x2e\n\t" /* branch not taken hint */ \
19552a9fcbcSSean Christopherson "jna %l[error]\n\t" \
19652a9fcbcSSean Christopherson _ASM_EXTABLE(1b, %l[fault]) \
19752a9fcbcSSean Christopherson : : op1 : "cc" : error, fault); \
19852a9fcbcSSean Christopherson return; \
19952a9fcbcSSean Christopherson error: \
2003ebccdf3SThomas Gleixner instrumentation_begin(); \
20152a9fcbcSSean Christopherson insn##_error(error_args); \
2023ebccdf3SThomas Gleixner instrumentation_end(); \
20352a9fcbcSSean Christopherson return; \
20452a9fcbcSSean Christopherson fault: \
20552a9fcbcSSean Christopherson kvm_spurious_fault(); \
20652a9fcbcSSean Christopherson } while (0)
20752a9fcbcSSean Christopherson
20852a9fcbcSSean Christopherson #define vmx_asm2(insn, op1, op2, error_args...) \
20952a9fcbcSSean Christopherson do { \
2104356e9f8SLinus Torvalds asm goto("1: " __stringify(insn) " %1, %0\n\t" \
21152a9fcbcSSean Christopherson ".byte 0x2e\n\t" /* branch not taken hint */ \
21252a9fcbcSSean Christopherson "jna %l[error]\n\t" \
21352a9fcbcSSean Christopherson _ASM_EXTABLE(1b, %l[fault]) \
21452a9fcbcSSean Christopherson : : op1, op2 : "cc" : error, fault); \
21552a9fcbcSSean Christopherson return; \
21652a9fcbcSSean Christopherson error: \
2173ebccdf3SThomas Gleixner instrumentation_begin(); \
21852a9fcbcSSean Christopherson insn##_error(error_args); \
2193ebccdf3SThomas Gleixner instrumentation_end(); \
22052a9fcbcSSean Christopherson return; \
22152a9fcbcSSean Christopherson fault: \
22252a9fcbcSSean Christopherson kvm_spurious_fault(); \
22352a9fcbcSSean Christopherson } while (0)
22489b0c9f5SSean Christopherson
__vmcs_writel(unsigned long field,unsigned long value)22589b0c9f5SSean Christopherson static __always_inline void __vmcs_writel(unsigned long field, unsigned long value)
22689b0c9f5SSean Christopherson {
22752a9fcbcSSean Christopherson vmx_asm2(vmwrite, "r"(field), "rm"(value), field, value);
22889b0c9f5SSean Christopherson }
22989b0c9f5SSean Christopherson
vmcs_write16(unsigned long field,u16 value)23089b0c9f5SSean Christopherson static __always_inline void vmcs_write16(unsigned long field, u16 value)
23189b0c9f5SSean Christopherson {
23289b0c9f5SSean Christopherson vmcs_check16(field);
23319f10315SSean Christopherson if (kvm_is_using_evmcs())
23489b0c9f5SSean Christopherson return evmcs_write16(field, value);
23589b0c9f5SSean Christopherson
23689b0c9f5SSean Christopherson __vmcs_writel(field, value);
23789b0c9f5SSean Christopherson }
23889b0c9f5SSean Christopherson
vmcs_write32(unsigned long field,u32 value)23989b0c9f5SSean Christopherson static __always_inline void vmcs_write32(unsigned long field, u32 value)
24089b0c9f5SSean Christopherson {
24189b0c9f5SSean Christopherson vmcs_check32(field);
24219f10315SSean Christopherson if (kvm_is_using_evmcs())
24389b0c9f5SSean Christopherson return evmcs_write32(field, value);
24489b0c9f5SSean Christopherson
24589b0c9f5SSean Christopherson __vmcs_writel(field, value);
24689b0c9f5SSean Christopherson }
24789b0c9f5SSean Christopherson
vmcs_write64(unsigned long field,u64 value)24889b0c9f5SSean Christopherson static __always_inline void vmcs_write64(unsigned long field, u64 value)
24989b0c9f5SSean Christopherson {
25089b0c9f5SSean Christopherson vmcs_check64(field);
25119f10315SSean Christopherson if (kvm_is_using_evmcs())
25289b0c9f5SSean Christopherson return evmcs_write64(field, value);
25389b0c9f5SSean Christopherson
25489b0c9f5SSean Christopherson __vmcs_writel(field, value);
25589b0c9f5SSean Christopherson #ifndef CONFIG_X86_64
25689b0c9f5SSean Christopherson __vmcs_writel(field+1, value >> 32);
25789b0c9f5SSean Christopherson #endif
25889b0c9f5SSean Christopherson }
25989b0c9f5SSean Christopherson
vmcs_writel(unsigned long field,unsigned long value)26089b0c9f5SSean Christopherson static __always_inline void vmcs_writel(unsigned long field, unsigned long value)
26189b0c9f5SSean Christopherson {
26289b0c9f5SSean Christopherson vmcs_checkl(field);
26319f10315SSean Christopherson if (kvm_is_using_evmcs())
26489b0c9f5SSean Christopherson return evmcs_write64(field, value);
26589b0c9f5SSean Christopherson
26689b0c9f5SSean Christopherson __vmcs_writel(field, value);
26789b0c9f5SSean Christopherson }
26889b0c9f5SSean Christopherson
vmcs_clear_bits(unsigned long field,u32 mask)26989b0c9f5SSean Christopherson static __always_inline void vmcs_clear_bits(unsigned long field, u32 mask)
27089b0c9f5SSean Christopherson {
27189b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x2000,
27289b0c9f5SSean Christopherson "vmcs_clear_bits does not support 64-bit fields");
27319f10315SSean Christopherson if (kvm_is_using_evmcs())
27489b0c9f5SSean Christopherson return evmcs_write32(field, evmcs_read32(field) & ~mask);
27589b0c9f5SSean Christopherson
27689b0c9f5SSean Christopherson __vmcs_writel(field, __vmcs_readl(field) & ~mask);
27789b0c9f5SSean Christopherson }
27889b0c9f5SSean Christopherson
vmcs_set_bits(unsigned long field,u32 mask)27989b0c9f5SSean Christopherson static __always_inline void vmcs_set_bits(unsigned long field, u32 mask)
28089b0c9f5SSean Christopherson {
28189b0c9f5SSean Christopherson BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x2000,
28289b0c9f5SSean Christopherson "vmcs_set_bits does not support 64-bit fields");
28319f10315SSean Christopherson if (kvm_is_using_evmcs())
28489b0c9f5SSean Christopherson return evmcs_write32(field, evmcs_read32(field) | mask);
28589b0c9f5SSean Christopherson
28689b0c9f5SSean Christopherson __vmcs_writel(field, __vmcs_readl(field) | mask);
28789b0c9f5SSean Christopherson }
28889b0c9f5SSean Christopherson
vmcs_clear(struct vmcs * vmcs)28989b0c9f5SSean Christopherson static inline void vmcs_clear(struct vmcs *vmcs)
29089b0c9f5SSean Christopherson {
29189b0c9f5SSean Christopherson u64 phys_addr = __pa(vmcs);
29289b0c9f5SSean Christopherson
29352a9fcbcSSean Christopherson vmx_asm1(vmclear, "m"(phys_addr), vmcs, phys_addr);
29489b0c9f5SSean Christopherson }
29589b0c9f5SSean Christopherson
vmcs_load(struct vmcs * vmcs)29689b0c9f5SSean Christopherson static inline void vmcs_load(struct vmcs *vmcs)
29789b0c9f5SSean Christopherson {
29889b0c9f5SSean Christopherson u64 phys_addr = __pa(vmcs);
29989b0c9f5SSean Christopherson
30019f10315SSean Christopherson if (kvm_is_using_evmcs())
30189b0c9f5SSean Christopherson return evmcs_load(phys_addr);
30289b0c9f5SSean Christopherson
30352a9fcbcSSean Christopherson vmx_asm1(vmptrld, "m"(phys_addr), vmcs, phys_addr);
30489b0c9f5SSean Christopherson }
30589b0c9f5SSean Christopherson
__invvpid(unsigned long ext,u16 vpid,gva_t gva)30689b0c9f5SSean Christopherson static inline void __invvpid(unsigned long ext, u16 vpid, gva_t gva)
30789b0c9f5SSean Christopherson {
30889b0c9f5SSean Christopherson struct {
30989b0c9f5SSean Christopherson u64 vpid : 16;
31089b0c9f5SSean Christopherson u64 rsvd : 48;
31189b0c9f5SSean Christopherson u64 gva;
31289b0c9f5SSean Christopherson } operand = { vpid, 0, gva };
31389b0c9f5SSean Christopherson
31452a9fcbcSSean Christopherson vmx_asm2(invvpid, "r"(ext), "m"(operand), ext, vpid, gva);
31589b0c9f5SSean Christopherson }
31689b0c9f5SSean Christopherson
__invept(unsigned long ext,u64 eptp)317bc17fccbSYan Zhao static inline void __invept(unsigned long ext, u64 eptp)
31889b0c9f5SSean Christopherson {
31989b0c9f5SSean Christopherson struct {
320bc17fccbSYan Zhao u64 eptp;
321bc17fccbSYan Zhao u64 reserved_0;
322bc17fccbSYan Zhao } operand = { eptp, 0 };
323bc17fccbSYan Zhao vmx_asm2(invept, "r"(ext), "m"(operand), ext, eptp);
32489b0c9f5SSean Christopherson }
32589b0c9f5SSean Christopherson
vpid_sync_vcpu_single(int vpid)32689b0c9f5SSean Christopherson static inline void vpid_sync_vcpu_single(int vpid)
32789b0c9f5SSean Christopherson {
32889b0c9f5SSean Christopherson if (vpid == 0)
32989b0c9f5SSean Christopherson return;
33089b0c9f5SSean Christopherson
33189b0c9f5SSean Christopherson __invvpid(VMX_VPID_EXTENT_SINGLE_CONTEXT, vpid, 0);
33289b0c9f5SSean Christopherson }
33389b0c9f5SSean Christopherson
vpid_sync_vcpu_global(void)33489b0c9f5SSean Christopherson static inline void vpid_sync_vcpu_global(void)
33589b0c9f5SSean Christopherson {
33689b0c9f5SSean Christopherson __invvpid(VMX_VPID_EXTENT_ALL_CONTEXT, 0, 0);
33789b0c9f5SSean Christopherson }
33889b0c9f5SSean Christopherson
vpid_sync_context(int vpid)33989b0c9f5SSean Christopherson static inline void vpid_sync_context(int vpid)
34089b0c9f5SSean Christopherson {
34189b0c9f5SSean Christopherson if (cpu_has_vmx_invvpid_single())
34289b0c9f5SSean Christopherson vpid_sync_vcpu_single(vpid);
343c746b3a4SSean Christopherson else if (vpid != 0)
34489b0c9f5SSean Christopherson vpid_sync_vcpu_global();
34589b0c9f5SSean Christopherson }
34689b0c9f5SSean Christopherson
vpid_sync_vcpu_addr(int vpid,gva_t addr)347ab4b3597SSean Christopherson static inline void vpid_sync_vcpu_addr(int vpid, gva_t addr)
3488a8b097cSSean Christopherson {
3498a8b097cSSean Christopherson if (vpid == 0)
350ab4b3597SSean Christopherson return;
3518a8b097cSSean Christopherson
352ab4b3597SSean Christopherson if (cpu_has_vmx_invvpid_individual_addr())
3538a8b097cSSean Christopherson __invvpid(VMX_VPID_EXTENT_INDIVIDUAL_ADDR, vpid, addr);
354ab4b3597SSean Christopherson else
355ab4b3597SSean Christopherson vpid_sync_context(vpid);
3568a8b097cSSean Christopherson }
3578a8b097cSSean Christopherson
ept_sync_global(void)35889b0c9f5SSean Christopherson static inline void ept_sync_global(void)
35989b0c9f5SSean Christopherson {
360bc17fccbSYan Zhao __invept(VMX_EPT_EXTENT_GLOBAL, 0);
36189b0c9f5SSean Christopherson }
36289b0c9f5SSean Christopherson
ept_sync_context(u64 eptp)36389b0c9f5SSean Christopherson static inline void ept_sync_context(u64 eptp)
36489b0c9f5SSean Christopherson {
36589b0c9f5SSean Christopherson if (cpu_has_vmx_invept_context())
366bc17fccbSYan Zhao __invept(VMX_EPT_EXTENT_CONTEXT, eptp);
36789b0c9f5SSean Christopherson else
36889b0c9f5SSean Christopherson ept_sync_global();
36989b0c9f5SSean Christopherson }
37089b0c9f5SSean Christopherson
37189b0c9f5SSean Christopherson #endif /* __KVM_X86_VMX_INSN_H */
372