xref: /openbmc/linux/arch/x86/kvm/svm/svm_onhyperv.h (revision b83237ad)
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 
16*b83237adSVitaly Kuznetsov int svm_hv_enable_l2_tlb_flush(struct kvm_vcpu *vcpu);
171183646aSVineeth Pillai 
181e0c7d40SVineeth Pillai static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
191e0c7d40SVineeth Pillai {
2026b516bbSSean Christopherson 	struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
2168ae7c7bSSean Christopherson 
2268ae7c7bSSean Christopherson 	BUILD_BUG_ON(sizeof(vmcb->control.hv_enlightenments) !=
2368ae7c7bSSean 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 		}
56*b83237adSVitaly Kuznetsov 		svm_x86_ops.enable_l2_tlb_flush =
57*b83237adSVitaly Kuznetsov 				svm_hv_enable_l2_tlb_flush;
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;
6526b516bbSSean Christopherson 	struct hv_vmcb_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 
7168ae7c7bSSean Christopherson static inline void svm_hv_update_vp_id(struct vmcb *vmcb, struct kvm_vcpu *vcpu)
721183646aSVineeth Pillai {
7326b516bbSSean Christopherson 	struct hv_vmcb_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