162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __KVM_X86_VMX_INSN_H 362306a36Sopenharmony_ci#define __KVM_X86_VMX_INSN_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/nospec.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <asm/vmx.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "hyperv.h" 1062306a36Sopenharmony_ci#include "vmcs.h" 1162306a36Sopenharmony_ci#include "../x86.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_civoid vmread_error(unsigned long field); 1462306a36Sopenharmony_civoid vmwrite_error(unsigned long field, unsigned long value); 1562306a36Sopenharmony_civoid vmclear_error(struct vmcs *vmcs, u64 phys_addr); 1662306a36Sopenharmony_civoid vmptrld_error(struct vmcs *vmcs, u64 phys_addr); 1762306a36Sopenharmony_civoid invvpid_error(unsigned long ext, u16 vpid, gva_t gva); 1862306a36Sopenharmony_civoid invept_error(unsigned long ext, u64 eptp, gpa_t gpa); 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#ifndef CONFIG_CC_HAS_ASM_GOTO_OUTPUT 2162306a36Sopenharmony_ci/* 2262306a36Sopenharmony_ci * The VMREAD error trampoline _always_ uses the stack to pass parameters, even 2362306a36Sopenharmony_ci * for 64-bit targets. Preserving all registers allows the VMREAD inline asm 2462306a36Sopenharmony_ci * blob to avoid clobbering GPRs, which in turn allows the compiler to better 2562306a36Sopenharmony_ci * optimize sequences of VMREADs. 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * Declare the trampoline as an opaque label as it's not safe to call from C 2862306a36Sopenharmony_ci * code; there is no way to tell the compiler to pass params on the stack for 2962306a36Sopenharmony_ci * 64-bit targets. 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * void vmread_error_trampoline(unsigned long field, bool fault); 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_ciextern unsigned long vmread_error_trampoline; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/* 3662306a36Sopenharmony_ci * The second VMREAD error trampoline, called from the assembly trampoline, 3762306a36Sopenharmony_ci * exists primarily to enable instrumentation for the VM-Fail path. 3862306a36Sopenharmony_ci */ 3962306a36Sopenharmony_civoid vmread_error_trampoline2(unsigned long field, bool fault); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#endif 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic __always_inline void vmcs_check16(unsigned long field) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2000, 4662306a36Sopenharmony_ci "16-bit accessor invalid for 64-bit field"); 4762306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001, 4862306a36Sopenharmony_ci "16-bit accessor invalid for 64-bit high field"); 4962306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x4000, 5062306a36Sopenharmony_ci "16-bit accessor invalid for 32-bit high field"); 5162306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x6000, 5262306a36Sopenharmony_ci "16-bit accessor invalid for natural width field"); 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic __always_inline void vmcs_check32(unsigned long field) 5662306a36Sopenharmony_ci{ 5762306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0, 5862306a36Sopenharmony_ci "32-bit accessor invalid for 16-bit field"); 5962306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2000, 6062306a36Sopenharmony_ci "32-bit accessor invalid for 64-bit field"); 6162306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001, 6262306a36Sopenharmony_ci "32-bit accessor invalid for 64-bit high field"); 6362306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x6000, 6462306a36Sopenharmony_ci "32-bit accessor invalid for natural width field"); 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_cistatic __always_inline void vmcs_check64(unsigned long field) 6862306a36Sopenharmony_ci{ 6962306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0, 7062306a36Sopenharmony_ci "64-bit accessor invalid for 16-bit field"); 7162306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001, 7262306a36Sopenharmony_ci "64-bit accessor invalid for 64-bit high field"); 7362306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x4000, 7462306a36Sopenharmony_ci "64-bit accessor invalid for 32-bit field"); 7562306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x6000, 7662306a36Sopenharmony_ci "64-bit accessor invalid for natural width field"); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic __always_inline void vmcs_checkl(unsigned long field) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0, 8262306a36Sopenharmony_ci "Natural width accessor invalid for 16-bit field"); 8362306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2000, 8462306a36Sopenharmony_ci "Natural width accessor invalid for 64-bit field"); 8562306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6001) == 0x2001, 8662306a36Sopenharmony_ci "Natural width accessor invalid for 64-bit high field"); 8762306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x4000, 8862306a36Sopenharmony_ci "Natural width accessor invalid for 32-bit field"); 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic __always_inline unsigned long __vmcs_readl(unsigned long field) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci unsigned long value; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci asm_goto_output("1: vmread %[field], %[output]\n\t" 9862306a36Sopenharmony_ci "jna %l[do_fail]\n\t" 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci _ASM_EXTABLE(1b, %l[do_exception]) 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci : [output] "=r" (value) 10362306a36Sopenharmony_ci : [field] "r" (field) 10462306a36Sopenharmony_ci : "cc" 10562306a36Sopenharmony_ci : do_fail, do_exception); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci return value; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cido_fail: 11062306a36Sopenharmony_ci instrumentation_begin(); 11162306a36Sopenharmony_ci vmread_error(field); 11262306a36Sopenharmony_ci instrumentation_end(); 11362306a36Sopenharmony_ci return 0; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cido_exception: 11662306a36Sopenharmony_ci kvm_spurious_fault(); 11762306a36Sopenharmony_ci return 0; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci#else /* !CONFIG_CC_HAS_ASM_GOTO_OUTPUT */ 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci asm volatile("1: vmread %2, %1\n\t" 12262306a36Sopenharmony_ci ".byte 0x3e\n\t" /* branch taken hint */ 12362306a36Sopenharmony_ci "ja 3f\n\t" 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci /* 12662306a36Sopenharmony_ci * VMREAD failed. Push '0' for @fault, push the failing 12762306a36Sopenharmony_ci * @field, and bounce through the trampoline to preserve 12862306a36Sopenharmony_ci * volatile registers. 12962306a36Sopenharmony_ci */ 13062306a36Sopenharmony_ci "xorl %k1, %k1\n\t" 13162306a36Sopenharmony_ci "2:\n\t" 13262306a36Sopenharmony_ci "push %1\n\t" 13362306a36Sopenharmony_ci "push %2\n\t" 13462306a36Sopenharmony_ci "call vmread_error_trampoline\n\t" 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci /* 13762306a36Sopenharmony_ci * Unwind the stack. Note, the trampoline zeros out the 13862306a36Sopenharmony_ci * memory for @fault so that the result is '0' on error. 13962306a36Sopenharmony_ci */ 14062306a36Sopenharmony_ci "pop %2\n\t" 14162306a36Sopenharmony_ci "pop %1\n\t" 14262306a36Sopenharmony_ci "3:\n\t" 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci /* VMREAD faulted. As above, except push '1' for @fault. */ 14562306a36Sopenharmony_ci _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_ONE_REG, %1) 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci : ASM_CALL_CONSTRAINT, "=&r"(value) : "r"(field) : "cc"); 14862306a36Sopenharmony_ci return value; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci#endif /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */ 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistatic __always_inline u16 vmcs_read16(unsigned long field) 15462306a36Sopenharmony_ci{ 15562306a36Sopenharmony_ci vmcs_check16(field); 15662306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 15762306a36Sopenharmony_ci return evmcs_read16(field); 15862306a36Sopenharmony_ci return __vmcs_readl(field); 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistatic __always_inline u32 vmcs_read32(unsigned long field) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci vmcs_check32(field); 16462306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 16562306a36Sopenharmony_ci return evmcs_read32(field); 16662306a36Sopenharmony_ci return __vmcs_readl(field); 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic __always_inline u64 vmcs_read64(unsigned long field) 17062306a36Sopenharmony_ci{ 17162306a36Sopenharmony_ci vmcs_check64(field); 17262306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 17362306a36Sopenharmony_ci return evmcs_read64(field); 17462306a36Sopenharmony_ci#ifdef CONFIG_X86_64 17562306a36Sopenharmony_ci return __vmcs_readl(field); 17662306a36Sopenharmony_ci#else 17762306a36Sopenharmony_ci return __vmcs_readl(field) | ((u64)__vmcs_readl(field+1) << 32); 17862306a36Sopenharmony_ci#endif 17962306a36Sopenharmony_ci} 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cistatic __always_inline unsigned long vmcs_readl(unsigned long field) 18262306a36Sopenharmony_ci{ 18362306a36Sopenharmony_ci vmcs_checkl(field); 18462306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 18562306a36Sopenharmony_ci return evmcs_read64(field); 18662306a36Sopenharmony_ci return __vmcs_readl(field); 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci#define vmx_asm1(insn, op1, error_args...) \ 19062306a36Sopenharmony_cido { \ 19162306a36Sopenharmony_ci asm goto("1: " __stringify(insn) " %0\n\t" \ 19262306a36Sopenharmony_ci ".byte 0x2e\n\t" /* branch not taken hint */ \ 19362306a36Sopenharmony_ci "jna %l[error]\n\t" \ 19462306a36Sopenharmony_ci _ASM_EXTABLE(1b, %l[fault]) \ 19562306a36Sopenharmony_ci : : op1 : "cc" : error, fault); \ 19662306a36Sopenharmony_ci return; \ 19762306a36Sopenharmony_cierror: \ 19862306a36Sopenharmony_ci instrumentation_begin(); \ 19962306a36Sopenharmony_ci insn##_error(error_args); \ 20062306a36Sopenharmony_ci instrumentation_end(); \ 20162306a36Sopenharmony_ci return; \ 20262306a36Sopenharmony_cifault: \ 20362306a36Sopenharmony_ci kvm_spurious_fault(); \ 20462306a36Sopenharmony_ci} while (0) 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci#define vmx_asm2(insn, op1, op2, error_args...) \ 20762306a36Sopenharmony_cido { \ 20862306a36Sopenharmony_ci asm goto("1: " __stringify(insn) " %1, %0\n\t" \ 20962306a36Sopenharmony_ci ".byte 0x2e\n\t" /* branch not taken hint */ \ 21062306a36Sopenharmony_ci "jna %l[error]\n\t" \ 21162306a36Sopenharmony_ci _ASM_EXTABLE(1b, %l[fault]) \ 21262306a36Sopenharmony_ci : : op1, op2 : "cc" : error, fault); \ 21362306a36Sopenharmony_ci return; \ 21462306a36Sopenharmony_cierror: \ 21562306a36Sopenharmony_ci instrumentation_begin(); \ 21662306a36Sopenharmony_ci insn##_error(error_args); \ 21762306a36Sopenharmony_ci instrumentation_end(); \ 21862306a36Sopenharmony_ci return; \ 21962306a36Sopenharmony_cifault: \ 22062306a36Sopenharmony_ci kvm_spurious_fault(); \ 22162306a36Sopenharmony_ci} while (0) 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_cistatic __always_inline void __vmcs_writel(unsigned long field, unsigned long value) 22462306a36Sopenharmony_ci{ 22562306a36Sopenharmony_ci vmx_asm2(vmwrite, "r"(field), "rm"(value), field, value); 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistatic __always_inline void vmcs_write16(unsigned long field, u16 value) 22962306a36Sopenharmony_ci{ 23062306a36Sopenharmony_ci vmcs_check16(field); 23162306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 23262306a36Sopenharmony_ci return evmcs_write16(field, value); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci __vmcs_writel(field, value); 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic __always_inline void vmcs_write32(unsigned long field, u32 value) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci vmcs_check32(field); 24062306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 24162306a36Sopenharmony_ci return evmcs_write32(field, value); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci __vmcs_writel(field, value); 24462306a36Sopenharmony_ci} 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_cistatic __always_inline void vmcs_write64(unsigned long field, u64 value) 24762306a36Sopenharmony_ci{ 24862306a36Sopenharmony_ci vmcs_check64(field); 24962306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 25062306a36Sopenharmony_ci return evmcs_write64(field, value); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci __vmcs_writel(field, value); 25362306a36Sopenharmony_ci#ifndef CONFIG_X86_64 25462306a36Sopenharmony_ci __vmcs_writel(field+1, value >> 32); 25562306a36Sopenharmony_ci#endif 25662306a36Sopenharmony_ci} 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistatic __always_inline void vmcs_writel(unsigned long field, unsigned long value) 25962306a36Sopenharmony_ci{ 26062306a36Sopenharmony_ci vmcs_checkl(field); 26162306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 26262306a36Sopenharmony_ci return evmcs_write64(field, value); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci __vmcs_writel(field, value); 26562306a36Sopenharmony_ci} 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_cistatic __always_inline void vmcs_clear_bits(unsigned long field, u32 mask) 26862306a36Sopenharmony_ci{ 26962306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x2000, 27062306a36Sopenharmony_ci "vmcs_clear_bits does not support 64-bit fields"); 27162306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 27262306a36Sopenharmony_ci return evmcs_write32(field, evmcs_read32(field) & ~mask); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci __vmcs_writel(field, __vmcs_readl(field) & ~mask); 27562306a36Sopenharmony_ci} 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic __always_inline void vmcs_set_bits(unsigned long field, u32 mask) 27862306a36Sopenharmony_ci{ 27962306a36Sopenharmony_ci BUILD_BUG_ON_MSG(__builtin_constant_p(field) && ((field) & 0x6000) == 0x2000, 28062306a36Sopenharmony_ci "vmcs_set_bits does not support 64-bit fields"); 28162306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 28262306a36Sopenharmony_ci return evmcs_write32(field, evmcs_read32(field) | mask); 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci __vmcs_writel(field, __vmcs_readl(field) | mask); 28562306a36Sopenharmony_ci} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_cistatic inline void vmcs_clear(struct vmcs *vmcs) 28862306a36Sopenharmony_ci{ 28962306a36Sopenharmony_ci u64 phys_addr = __pa(vmcs); 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci vmx_asm1(vmclear, "m"(phys_addr), vmcs, phys_addr); 29262306a36Sopenharmony_ci} 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_cistatic inline void vmcs_load(struct vmcs *vmcs) 29562306a36Sopenharmony_ci{ 29662306a36Sopenharmony_ci u64 phys_addr = __pa(vmcs); 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci if (kvm_is_using_evmcs()) 29962306a36Sopenharmony_ci return evmcs_load(phys_addr); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci vmx_asm1(vmptrld, "m"(phys_addr), vmcs, phys_addr); 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_cistatic inline void __invvpid(unsigned long ext, u16 vpid, gva_t gva) 30562306a36Sopenharmony_ci{ 30662306a36Sopenharmony_ci struct { 30762306a36Sopenharmony_ci u64 vpid : 16; 30862306a36Sopenharmony_ci u64 rsvd : 48; 30962306a36Sopenharmony_ci u64 gva; 31062306a36Sopenharmony_ci } operand = { vpid, 0, gva }; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci vmx_asm2(invvpid, "r"(ext), "m"(operand), ext, vpid, gva); 31362306a36Sopenharmony_ci} 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistatic inline void __invept(unsigned long ext, u64 eptp, gpa_t gpa) 31662306a36Sopenharmony_ci{ 31762306a36Sopenharmony_ci struct { 31862306a36Sopenharmony_ci u64 eptp, gpa; 31962306a36Sopenharmony_ci } operand = {eptp, gpa}; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci vmx_asm2(invept, "r"(ext), "m"(operand), ext, eptp, gpa); 32262306a36Sopenharmony_ci} 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_cistatic inline void vpid_sync_vcpu_single(int vpid) 32562306a36Sopenharmony_ci{ 32662306a36Sopenharmony_ci if (vpid == 0) 32762306a36Sopenharmony_ci return; 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci __invvpid(VMX_VPID_EXTENT_SINGLE_CONTEXT, vpid, 0); 33062306a36Sopenharmony_ci} 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_cistatic inline void vpid_sync_vcpu_global(void) 33362306a36Sopenharmony_ci{ 33462306a36Sopenharmony_ci __invvpid(VMX_VPID_EXTENT_ALL_CONTEXT, 0, 0); 33562306a36Sopenharmony_ci} 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_cistatic inline void vpid_sync_context(int vpid) 33862306a36Sopenharmony_ci{ 33962306a36Sopenharmony_ci if (cpu_has_vmx_invvpid_single()) 34062306a36Sopenharmony_ci vpid_sync_vcpu_single(vpid); 34162306a36Sopenharmony_ci else if (vpid != 0) 34262306a36Sopenharmony_ci vpid_sync_vcpu_global(); 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistatic inline void vpid_sync_vcpu_addr(int vpid, gva_t addr) 34662306a36Sopenharmony_ci{ 34762306a36Sopenharmony_ci if (vpid == 0) 34862306a36Sopenharmony_ci return; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci if (cpu_has_vmx_invvpid_individual_addr()) 35162306a36Sopenharmony_ci __invvpid(VMX_VPID_EXTENT_INDIVIDUAL_ADDR, vpid, addr); 35262306a36Sopenharmony_ci else 35362306a36Sopenharmony_ci vpid_sync_context(vpid); 35462306a36Sopenharmony_ci} 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_cistatic inline void ept_sync_global(void) 35762306a36Sopenharmony_ci{ 35862306a36Sopenharmony_ci __invept(VMX_EPT_EXTENT_GLOBAL, 0, 0); 35962306a36Sopenharmony_ci} 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cistatic inline void ept_sync_context(u64 eptp) 36262306a36Sopenharmony_ci{ 36362306a36Sopenharmony_ci if (cpu_has_vmx_invept_context()) 36462306a36Sopenharmony_ci __invept(VMX_EPT_EXTENT_CONTEXT, eptp, 0); 36562306a36Sopenharmony_ci else 36662306a36Sopenharmony_ci ept_sync_global(); 36762306a36Sopenharmony_ci} 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci#endif /* __KVM_X86_VMX_INSN_H */ 370