11e0c7d40SVineeth Pillai /* SPDX-License-Identifier: GPL-2.0-only */ 21e0c7d40SVineeth Pillai /* 31e0c7d40SVineeth Pillai * KVM L1 hypervisor optimizations on Hyper-V for SVM. 41e0c7d40SVineeth Pillai */ 51e0c7d40SVineeth Pillai 61e0c7d40SVineeth Pillai #ifndef __ARCH_X86_KVM_SVM_ONHYPERV_H__ 71e0c7d40SVineeth Pillai #define __ARCH_X86_KVM_SVM_ONHYPERV_H__ 81e0c7d40SVineeth Pillai 91e0c7d40SVineeth Pillai #if IS_ENABLED(CONFIG_HYPERV) 101e0c7d40SVineeth Pillai 111e0c7d40SVineeth Pillai #include "kvm_onhyperv.h" 129e083ec7SVitaly Kuznetsov #include "svm/hyperv.h" 131e0c7d40SVineeth Pillai 141e0c7d40SVineeth Pillai static struct kvm_x86_ops svm_x86_ops; 151e0c7d40SVineeth Pillai 161183646aSVineeth Pillai int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu); 171183646aSVineeth Pillai 181e0c7d40SVineeth Pillai static inline void svm_hv_init_vmcb(struct vmcb *vmcb) 191e0c7d40SVineeth Pillai { 20*68ae7c7bSSean Christopherson struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments; 21*68ae7c7bSSean Christopherson 22*68ae7c7bSSean Christopherson BUILD_BUG_ON(sizeof(vmcb->control.hv_enlightenments) != 23*68ae7c7bSSean Christopherson sizeof(vmcb->control.reserved_sw)); 241e0c7d40SVineeth Pillai 251e0c7d40SVineeth Pillai if (npt_enabled && 261e0c7d40SVineeth Pillai ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB) 271e0c7d40SVineeth Pillai hve->hv_enlightenments_control.enlightened_npt_tlb = 1; 2838dfa830SVitaly Kuznetsov 2938dfa830SVitaly Kuznetsov if (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP) 3038dfa830SVitaly Kuznetsov hve->hv_enlightenments_control.msr_bitmap = 1; 311e0c7d40SVineeth Pillai } 321e0c7d40SVineeth Pillai 331e0c7d40SVineeth Pillai static inline void svm_hv_hardware_setup(void) 341e0c7d40SVineeth Pillai { 351e0c7d40SVineeth Pillai if (npt_enabled && 361e0c7d40SVineeth Pillai ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB) { 371e0c7d40SVineeth Pillai pr_info("kvm: Hyper-V enlightened NPT TLB flush enabled\n"); 381e0c7d40SVineeth Pillai svm_x86_ops.tlb_remote_flush = hv_remote_flush_tlb; 391e0c7d40SVineeth Pillai svm_x86_ops.tlb_remote_flush_with_range = 401e0c7d40SVineeth Pillai hv_remote_flush_tlb_with_range; 411e0c7d40SVineeth Pillai } 421183646aSVineeth Pillai 431183646aSVineeth Pillai if (ms_hyperv.nested_features & HV_X64_NESTED_DIRECT_FLUSH) { 441183646aSVineeth Pillai int cpu; 451183646aSVineeth Pillai 461183646aSVineeth Pillai pr_info("kvm: Hyper-V Direct TLB Flush enabled\n"); 471183646aSVineeth Pillai for_each_online_cpu(cpu) { 481183646aSVineeth Pillai struct hv_vp_assist_page *vp_ap = 491183646aSVineeth Pillai hv_get_vp_assist_page(cpu); 501183646aSVineeth Pillai 511183646aSVineeth Pillai if (!vp_ap) 521183646aSVineeth Pillai continue; 531183646aSVineeth Pillai 541183646aSVineeth Pillai vp_ap->nested_control.features.directhypercall = 1; 551183646aSVineeth Pillai } 561183646aSVineeth Pillai svm_x86_ops.enable_direct_tlbflush = 571183646aSVineeth Pillai svm_hv_enable_direct_tlbflush; 581183646aSVineeth Pillai } 591e0c7d40SVineeth Pillai } 601e0c7d40SVineeth Pillai 61c4327f15SVineeth Pillai static inline void svm_hv_vmcb_dirty_nested_enlightenments( 62c4327f15SVineeth Pillai struct kvm_vcpu *vcpu) 63c4327f15SVineeth Pillai { 64c4327f15SVineeth Pillai struct vmcb *vmcb = to_svm(vcpu)->vmcb; 65*68ae7c7bSSean Christopherson struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments; 66c4327f15SVineeth Pillai 67aa3b39f3SVitaly Kuznetsov if (hve->hv_enlightenments_control.msr_bitmap) 68089fe572SSean Christopherson vmcb_mark_dirty(vmcb, HV_VMCB_NESTED_ENLIGHTENMENTS); 69c4327f15SVineeth Pillai } 701183646aSVineeth Pillai 71*68ae7c7bSSean Christopherson static inline void svm_hv_update_vp_id(struct vmcb *vmcb, struct kvm_vcpu *vcpu) 721183646aSVineeth Pillai { 73*68ae7c7bSSean Christopherson struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments; 741183646aSVineeth Pillai u32 vp_index = kvm_hv_get_vpindex(vcpu); 751183646aSVineeth Pillai 761183646aSVineeth Pillai if (hve->hv_vp_id != vp_index) { 771183646aSVineeth Pillai hve->hv_vp_id = vp_index; 78089fe572SSean Christopherson vmcb_mark_dirty(vmcb, HV_VMCB_NESTED_ENLIGHTENMENTS); 791183646aSVineeth Pillai } 801183646aSVineeth Pillai } 811e0c7d40SVineeth Pillai #else 821e0c7d40SVineeth Pillai 831e0c7d40SVineeth Pillai static inline void svm_hv_init_vmcb(struct vmcb *vmcb) 841e0c7d40SVineeth Pillai { 851e0c7d40SVineeth Pillai } 861e0c7d40SVineeth Pillai 871e0c7d40SVineeth Pillai static inline void svm_hv_hardware_setup(void) 881e0c7d40SVineeth Pillai { 891e0c7d40SVineeth Pillai } 90c4327f15SVineeth Pillai 91c4327f15SVineeth Pillai static inline void svm_hv_vmcb_dirty_nested_enlightenments( 92c4327f15SVineeth Pillai struct kvm_vcpu *vcpu) 93c4327f15SVineeth Pillai { 94c4327f15SVineeth Pillai } 951183646aSVineeth Pillai 961183646aSVineeth Pillai static inline void svm_hv_update_vp_id(struct vmcb *vmcb, 971183646aSVineeth Pillai struct kvm_vcpu *vcpu) 981183646aSVineeth Pillai { 991183646aSVineeth Pillai } 1001e0c7d40SVineeth Pillai #endif /* CONFIG_HYPERV */ 1011e0c7d40SVineeth Pillai 1021e0c7d40SVineeth Pillai #endif /* __ARCH_X86_KVM_SVM_ONHYPERV_H__ */ 103