2021-06-03 08:14:38 -07:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
/*
|
|
|
|
* KVM L1 hypervisor optimizations on Hyper-V for SVM.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __ARCH_X86_KVM_SVM_ONHYPERV_H__
|
|
|
|
#define __ARCH_X86_KVM_SVM_ONHYPERV_H__
|
|
|
|
|
2023-03-24 07:52:33 -07:00
|
|
|
#include <asm/mshyperv.h>
|
|
|
|
|
2021-06-03 08:14:38 -07:00
|
|
|
#if IS_ENABLED(CONFIG_HYPERV)
|
|
|
|
|
|
|
|
#include "kvm_onhyperv.h"
|
2022-02-02 02:50:59 -07:00
|
|
|
#include "svm/hyperv.h"
|
2021-06-03 08:14:38 -07:00
|
|
|
|
|
|
|
static struct kvm_x86_ops svm_x86_ops;
|
|
|
|
|
2022-11-01 07:53:43 -07:00
|
|
|
int svm_hv_enable_l2_tlb_flush(struct kvm_vcpu *vcpu);
|
2021-06-03 08:14:40 -07:00
|
|
|
|
2023-03-24 07:52:33 -07:00
|
|
|
static inline bool svm_hv_is_enlightened_tlb_enabled(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct hv_vmcb_enlightenments *hve = &to_svm(vcpu)->vmcb->control.hv_enlightenments;
|
|
|
|
|
|
|
|
return ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB &&
|
|
|
|
!!hve->hv_enlightenments_control.enlightened_npt_tlb;
|
|
|
|
}
|
|
|
|
|
2021-06-03 08:14:38 -07:00
|
|
|
static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
|
|
|
|
{
|
2022-11-01 07:53:42 -07:00
|
|
|
struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
|
2022-11-01 07:53:41 -07:00
|
|
|
|
|
|
|
BUILD_BUG_ON(sizeof(vmcb->control.hv_enlightenments) !=
|
|
|
|
sizeof(vmcb->control.reserved_sw));
|
2021-06-03 08:14:38 -07:00
|
|
|
|
|
|
|
if (npt_enabled &&
|
|
|
|
ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB)
|
|
|
|
hve->hv_enlightenments_control.enlightened_npt_tlb = 1;
|
2021-12-20 08:21:36 -07:00
|
|
|
|
|
|
|
if (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)
|
|
|
|
hve->hv_enlightenments_control.msr_bitmap = 1;
|
2021-06-03 08:14:38 -07:00
|
|
|
}
|
|
|
|
|
2023-02-22 00:33:15 -07:00
|
|
|
static inline __init void svm_hv_hardware_setup(void)
|
2021-06-03 08:14:38 -07:00
|
|
|
{
|
|
|
|
if (npt_enabled &&
|
|
|
|
ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB) {
|
KVM: x86: Unify pr_fmt to use module name for all KVM modules
Define pr_fmt using KBUILD_MODNAME for all KVM x86 code so that printks
use consistent formatting across common x86, Intel, and AMD code. In
addition to providing consistent print formatting, using KBUILD_MODNAME,
e.g. kvm_amd and kvm_intel, allows referencing SVM and VMX (and SEV and
SGX and ...) as technologies without generating weird messages, and
without causing naming conflicts with other kernel code, e.g. "SEV: ",
"tdx: ", "sgx: " etc.. are all used by the kernel for non-KVM subsystems.
Opportunistically move away from printk() for prints that need to be
modified anyways, e.g. to drop a manual "kvm: " prefix.
Opportunistically convert a few SGX WARNs that are similarly modified to
WARN_ONCE; in the very unlikely event that the WARNs fire, odds are good
that they would fire repeatedly and spam the kernel log without providing
unique information in each print.
Note, defining pr_fmt yields undesirable results for code that uses KVM's
printk wrappers, e.g. vcpu_unimpl(). But, that's a pre-existing problem
as SVM/kvm_amd already defines a pr_fmt, and thankfully use of KVM's
wrappers is relatively limited in KVM x86 code.
Signed-off-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Paul Durrant <paul@xen.org>
Message-Id: <20221130230934.1014142-35-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-11-30 16:09:18 -07:00
|
|
|
pr_info(KBUILD_MODNAME ": Hyper-V enlightened NPT TLB flush enabled\n");
|
2023-04-04 17:31:32 -07:00
|
|
|
svm_x86_ops.flush_remote_tlbs = hv_flush_remote_tlbs;
|
|
|
|
svm_x86_ops.flush_remote_tlbs_range = hv_flush_remote_tlbs_range;
|
2021-06-03 08:14:38 -07:00
|
|
|
}
|
2021-06-03 08:14:40 -07:00
|
|
|
|
|
|
|
if (ms_hyperv.nested_features & HV_X64_NESTED_DIRECT_FLUSH) {
|
|
|
|
int cpu;
|
|
|
|
|
KVM: x86: Unify pr_fmt to use module name for all KVM modules
Define pr_fmt using KBUILD_MODNAME for all KVM x86 code so that printks
use consistent formatting across common x86, Intel, and AMD code. In
addition to providing consistent print formatting, using KBUILD_MODNAME,
e.g. kvm_amd and kvm_intel, allows referencing SVM and VMX (and SEV and
SGX and ...) as technologies without generating weird messages, and
without causing naming conflicts with other kernel code, e.g. "SEV: ",
"tdx: ", "sgx: " etc.. are all used by the kernel for non-KVM subsystems.
Opportunistically move away from printk() for prints that need to be
modified anyways, e.g. to drop a manual "kvm: " prefix.
Opportunistically convert a few SGX WARNs that are similarly modified to
WARN_ONCE; in the very unlikely event that the WARNs fire, odds are good
that they would fire repeatedly and spam the kernel log without providing
unique information in each print.
Note, defining pr_fmt yields undesirable results for code that uses KVM's
printk wrappers, e.g. vcpu_unimpl(). But, that's a pre-existing problem
as SVM/kvm_amd already defines a pr_fmt, and thankfully use of KVM's
wrappers is relatively limited in KVM x86 code.
Signed-off-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Paul Durrant <paul@xen.org>
Message-Id: <20221130230934.1014142-35-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-11-30 16:09:18 -07:00
|
|
|
pr_info(KBUILD_MODNAME ": Hyper-V Direct TLB Flush enabled\n");
|
2021-06-03 08:14:40 -07:00
|
|
|
for_each_online_cpu(cpu) {
|
|
|
|
struct hv_vp_assist_page *vp_ap =
|
|
|
|
hv_get_vp_assist_page(cpu);
|
|
|
|
|
|
|
|
if (!vp_ap)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
vp_ap->nested_control.features.directhypercall = 1;
|
|
|
|
}
|
2022-11-01 07:53:43 -07:00
|
|
|
svm_x86_ops.enable_l2_tlb_flush =
|
|
|
|
svm_hv_enable_l2_tlb_flush;
|
2021-06-03 08:14:40 -07:00
|
|
|
}
|
2021-06-03 08:14:38 -07:00
|
|
|
}
|
|
|
|
|
2021-06-03 08:14:39 -07:00
|
|
|
static inline void svm_hv_vmcb_dirty_nested_enlightenments(
|
|
|
|
struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
struct vmcb *vmcb = to_svm(vcpu)->vmcb;
|
2022-11-01 07:53:42 -07:00
|
|
|
struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
|
2021-06-03 08:14:39 -07:00
|
|
|
|
2021-12-20 08:21:35 -07:00
|
|
|
if (hve->hv_enlightenments_control.msr_bitmap)
|
2022-11-01 07:53:39 -07:00
|
|
|
vmcb_mark_dirty(vmcb, HV_VMCB_NESTED_ENLIGHTENMENTS);
|
2021-06-03 08:14:39 -07:00
|
|
|
}
|
2021-06-03 08:14:40 -07:00
|
|
|
|
2022-11-01 07:53:41 -07:00
|
|
|
static inline void svm_hv_update_vp_id(struct vmcb *vmcb, struct kvm_vcpu *vcpu)
|
2021-06-03 08:14:40 -07:00
|
|
|
{
|
2022-11-01 07:53:42 -07:00
|
|
|
struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
|
2021-06-03 08:14:40 -07:00
|
|
|
u32 vp_index = kvm_hv_get_vpindex(vcpu);
|
|
|
|
|
|
|
|
if (hve->hv_vp_id != vp_index) {
|
|
|
|
hve->hv_vp_id = vp_index;
|
2022-11-01 07:53:39 -07:00
|
|
|
vmcb_mark_dirty(vmcb, HV_VMCB_NESTED_ENLIGHTENMENTS);
|
2021-06-03 08:14:40 -07:00
|
|
|
}
|
|
|
|
}
|
2021-06-03 08:14:38 -07:00
|
|
|
#else
|
|
|
|
|
2023-03-24 07:52:33 -07:00
|
|
|
static inline bool svm_hv_is_enlightened_tlb_enabled(struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-06-03 08:14:38 -07:00
|
|
|
static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-02-22 00:33:15 -07:00
|
|
|
static inline __init void svm_hv_hardware_setup(void)
|
2021-06-03 08:14:38 -07:00
|
|
|
{
|
|
|
|
}
|
2021-06-03 08:14:39 -07:00
|
|
|
|
|
|
|
static inline void svm_hv_vmcb_dirty_nested_enlightenments(
|
|
|
|
struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
}
|
2021-06-03 08:14:40 -07:00
|
|
|
|
|
|
|
static inline void svm_hv_update_vp_id(struct vmcb *vmcb,
|
|
|
|
struct kvm_vcpu *vcpu)
|
|
|
|
{
|
|
|
|
}
|
2021-06-03 08:14:38 -07:00
|
|
|
#endif /* CONFIG_HYPERV */
|
|
|
|
|
|
|
|
#endif /* __ARCH_X86_KVM_SVM_ONHYPERV_H__ */
|