1*1e0c7d40SVineeth Pillai /* SPDX-License-Identifier: GPL-2.0-only */ 2*1e0c7d40SVineeth Pillai /* 3*1e0c7d40SVineeth Pillai * KVM L1 hypervisor optimizations on Hyper-V for SVM. 4*1e0c7d40SVineeth Pillai */ 5*1e0c7d40SVineeth Pillai 6*1e0c7d40SVineeth Pillai #ifndef __ARCH_X86_KVM_SVM_ONHYPERV_H__ 7*1e0c7d40SVineeth Pillai #define __ARCH_X86_KVM_SVM_ONHYPERV_H__ 8*1e0c7d40SVineeth Pillai 9*1e0c7d40SVineeth Pillai #if IS_ENABLED(CONFIG_HYPERV) 10*1e0c7d40SVineeth Pillai #include <asm/mshyperv.h> 11*1e0c7d40SVineeth Pillai 12*1e0c7d40SVineeth Pillai #include "hyperv.h" 13*1e0c7d40SVineeth Pillai #include "kvm_onhyperv.h" 14*1e0c7d40SVineeth Pillai 15*1e0c7d40SVineeth Pillai static struct kvm_x86_ops svm_x86_ops; 16*1e0c7d40SVineeth Pillai 17*1e0c7d40SVineeth Pillai /* 18*1e0c7d40SVineeth Pillai * Hyper-V uses the software reserved 32 bytes in VMCB 19*1e0c7d40SVineeth Pillai * control area to expose SVM enlightenments to guests. 20*1e0c7d40SVineeth Pillai */ 21*1e0c7d40SVineeth Pillai struct hv_enlightenments { 22*1e0c7d40SVineeth Pillai struct __packed hv_enlightenments_control { 23*1e0c7d40SVineeth Pillai u32 nested_flush_hypercall:1; 24*1e0c7d40SVineeth Pillai u32 msr_bitmap:1; 25*1e0c7d40SVineeth Pillai u32 enlightened_npt_tlb: 1; 26*1e0c7d40SVineeth Pillai u32 reserved:29; 27*1e0c7d40SVineeth Pillai } __packed hv_enlightenments_control; 28*1e0c7d40SVineeth Pillai u32 hv_vp_id; 29*1e0c7d40SVineeth Pillai u64 hv_vm_id; 30*1e0c7d40SVineeth Pillai u64 partition_assist_page; 31*1e0c7d40SVineeth Pillai u64 reserved; 32*1e0c7d40SVineeth Pillai } __packed; 33*1e0c7d40SVineeth Pillai 34*1e0c7d40SVineeth Pillai static inline void svm_hv_init_vmcb(struct vmcb *vmcb) 35*1e0c7d40SVineeth Pillai { 36*1e0c7d40SVineeth Pillai struct hv_enlightenments *hve = 37*1e0c7d40SVineeth Pillai (struct hv_enlightenments *)vmcb->control.reserved_sw; 38*1e0c7d40SVineeth Pillai 39*1e0c7d40SVineeth Pillai if (npt_enabled && 40*1e0c7d40SVineeth Pillai ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB) 41*1e0c7d40SVineeth Pillai hve->hv_enlightenments_control.enlightened_npt_tlb = 1; 42*1e0c7d40SVineeth Pillai } 43*1e0c7d40SVineeth Pillai 44*1e0c7d40SVineeth Pillai static inline void svm_hv_hardware_setup(void) 45*1e0c7d40SVineeth Pillai { 46*1e0c7d40SVineeth Pillai if (npt_enabled && 47*1e0c7d40SVineeth Pillai ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB) { 48*1e0c7d40SVineeth Pillai pr_info("kvm: Hyper-V enlightened NPT TLB flush enabled\n"); 49*1e0c7d40SVineeth Pillai svm_x86_ops.tlb_remote_flush = hv_remote_flush_tlb; 50*1e0c7d40SVineeth Pillai svm_x86_ops.tlb_remote_flush_with_range = 51*1e0c7d40SVineeth Pillai hv_remote_flush_tlb_with_range; 52*1e0c7d40SVineeth Pillai } 53*1e0c7d40SVineeth Pillai } 54*1e0c7d40SVineeth Pillai 55*1e0c7d40SVineeth Pillai #else 56*1e0c7d40SVineeth Pillai 57*1e0c7d40SVineeth Pillai static inline void svm_hv_init_vmcb(struct vmcb *vmcb) 58*1e0c7d40SVineeth Pillai { 59*1e0c7d40SVineeth Pillai } 60*1e0c7d40SVineeth Pillai 61*1e0c7d40SVineeth Pillai static inline void svm_hv_hardware_setup(void) 62*1e0c7d40SVineeth Pillai { 63*1e0c7d40SVineeth Pillai } 64*1e0c7d40SVineeth Pillai #endif /* CONFIG_HYPERV */ 65*1e0c7d40SVineeth Pillai 66*1e0c7d40SVineeth Pillai #endif /* __ARCH_X86_KVM_SVM_ONHYPERV_H__ */ 67