0001
0002
0003
0004
0005
0006 #ifndef __ARCH_X86_KVM_SVM_ONHYPERV_H__
0007 #define __ARCH_X86_KVM_SVM_ONHYPERV_H__
0008
0009 #if IS_ENABLED(CONFIG_HYPERV)
0010
0011 #include "kvm_onhyperv.h"
0012 #include "svm/hyperv.h"
0013
0014 static struct kvm_x86_ops svm_x86_ops;
0015
0016 int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu);
0017
0018 static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
0019 {
0020 struct hv_enlightenments *hve =
0021 (struct hv_enlightenments *)vmcb->control.reserved_sw;
0022
0023 if (npt_enabled &&
0024 ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB)
0025 hve->hv_enlightenments_control.enlightened_npt_tlb = 1;
0026
0027 if (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)
0028 hve->hv_enlightenments_control.msr_bitmap = 1;
0029 }
0030
0031 static inline void svm_hv_hardware_setup(void)
0032 {
0033 if (npt_enabled &&
0034 ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB) {
0035 pr_info("kvm: Hyper-V enlightened NPT TLB flush enabled\n");
0036 svm_x86_ops.tlb_remote_flush = hv_remote_flush_tlb;
0037 svm_x86_ops.tlb_remote_flush_with_range =
0038 hv_remote_flush_tlb_with_range;
0039 }
0040
0041 if (ms_hyperv.nested_features & HV_X64_NESTED_DIRECT_FLUSH) {
0042 int cpu;
0043
0044 pr_info("kvm: Hyper-V Direct TLB Flush enabled\n");
0045 for_each_online_cpu(cpu) {
0046 struct hv_vp_assist_page *vp_ap =
0047 hv_get_vp_assist_page(cpu);
0048
0049 if (!vp_ap)
0050 continue;
0051
0052 vp_ap->nested_control.features.directhypercall = 1;
0053 }
0054 svm_x86_ops.enable_direct_tlbflush =
0055 svm_hv_enable_direct_tlbflush;
0056 }
0057 }
0058
0059 static inline void svm_hv_vmcb_dirty_nested_enlightenments(
0060 struct kvm_vcpu *vcpu)
0061 {
0062 struct vmcb *vmcb = to_svm(vcpu)->vmcb;
0063 struct hv_enlightenments *hve =
0064 (struct hv_enlightenments *)vmcb->control.reserved_sw;
0065
0066 if (hve->hv_enlightenments_control.msr_bitmap)
0067 vmcb_mark_dirty(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS);
0068 }
0069
0070 static inline void svm_hv_update_vp_id(struct vmcb *vmcb,
0071 struct kvm_vcpu *vcpu)
0072 {
0073 struct hv_enlightenments *hve =
0074 (struct hv_enlightenments *)vmcb->control.reserved_sw;
0075 u32 vp_index = kvm_hv_get_vpindex(vcpu);
0076
0077 if (hve->hv_vp_id != vp_index) {
0078 hve->hv_vp_id = vp_index;
0079 vmcb_mark_dirty(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS);
0080 }
0081 }
0082 #else
0083
0084 static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
0085 {
0086 }
0087
0088 static inline void svm_hv_hardware_setup(void)
0089 {
0090 }
0091
0092 static inline void svm_hv_vmcb_dirty_nested_enlightenments(
0093 struct kvm_vcpu *vcpu)
0094 {
0095 }
0096
0097 static inline void svm_hv_update_vp_id(struct vmcb *vmcb,
0098 struct kvm_vcpu *vcpu)
0099 {
0100 }
0101 #endif
0102
0103 #endif