mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 12:44:11 +08:00
KVM: x86: Move Hyper-V partition assist page out of Hyper-V emulation context
Hyper-V partition assist page is used when KVM runs on top of Hyper-V and is not used for Windows/Hyper-V guests on KVM, this means that 'hv_pa_pg' placement in 'struct kvm_hv' is unfortunate. As a preparation to making Hyper-V emulation optional, move 'hv_pa_pg' to 'struct kvm_arch' and put it under CONFIG_HYPERV. While on it, introduce hv_get_partition_assist_page() helper to allocate partition assist page. Move the comment explaining why we use a single page for all vCPUs from VMX and expand it a bit. No functional change intended. Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com> Tested-by: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Link: https://lore.kernel.org/r/20231205103630.1391318-3-vkuznets@redhat.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
parent
87562052c9
commit
cfef5af3cb
@ -1125,7 +1125,6 @@ struct kvm_hv {
|
||||
*/
|
||||
unsigned int synic_auto_eoi_used;
|
||||
|
||||
struct hv_partition_assist_pg *hv_pa_pg;
|
||||
struct kvm_hv_syndbg hv_syndbg;
|
||||
};
|
||||
|
||||
@ -1447,6 +1446,7 @@ struct kvm_arch {
|
||||
#if IS_ENABLED(CONFIG_HYPERV)
|
||||
hpa_t hv_root_tdp;
|
||||
spinlock_t hv_root_tdp_lock;
|
||||
struct hv_partition_assist_pg *hv_pa_pg;
|
||||
#endif
|
||||
/*
|
||||
* VM-scope maximum vCPU ID. Used to determine the size of structures
|
||||
|
@ -10,6 +10,26 @@
|
||||
int hv_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn, gfn_t nr_pages);
|
||||
int hv_flush_remote_tlbs(struct kvm *kvm);
|
||||
void hv_track_root_tdp(struct kvm_vcpu *vcpu, hpa_t root_tdp);
|
||||
static inline hpa_t hv_get_partition_assist_page(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
/*
|
||||
* Partition assist page is something which Hyper-V running in L0
|
||||
* requires from KVM running in L1 before direct TLB flush for L2
|
||||
* guests can be enabled. KVM doesn't currently use the page but to
|
||||
* comply with TLFS it still needs to be allocated. For now, this
|
||||
* is a single page shared among all vCPUs.
|
||||
*/
|
||||
struct hv_partition_assist_pg **p_hv_pa_pg =
|
||||
&vcpu->kvm->arch.hv_pa_pg;
|
||||
|
||||
if (!*p_hv_pa_pg)
|
||||
*p_hv_pa_pg = kzalloc(PAGE_SIZE, GFP_KERNEL_ACCOUNT);
|
||||
|
||||
if (!*p_hv_pa_pg)
|
||||
return INVALID_PAGE;
|
||||
|
||||
return __pa(*p_hv_pa_pg);
|
||||
}
|
||||
#else /* !CONFIG_HYPERV */
|
||||
static inline int hv_flush_remote_tlbs(struct kvm *kvm)
|
||||
{
|
||||
|
@ -18,18 +18,14 @@
|
||||
int svm_hv_enable_l2_tlb_flush(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct hv_vmcb_enlightenments *hve;
|
||||
struct hv_partition_assist_pg **p_hv_pa_pg =
|
||||
&to_kvm_hv(vcpu->kvm)->hv_pa_pg;
|
||||
hpa_t partition_assist_page = hv_get_partition_assist_page(vcpu);
|
||||
|
||||
if (!*p_hv_pa_pg)
|
||||
*p_hv_pa_pg = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
|
||||
if (!*p_hv_pa_pg)
|
||||
if (partition_assist_page == INVALID_PAGE)
|
||||
return -ENOMEM;
|
||||
|
||||
hve = &to_svm(vcpu)->vmcb->control.hv_enlightenments;
|
||||
|
||||
hve->partition_assist_page = __pa(*p_hv_pa_pg);
|
||||
hve->partition_assist_page = partition_assist_page;
|
||||
hve->hv_vm_id = (unsigned long)vcpu->kvm;
|
||||
if (!hve->hv_enlightenments_control.nested_flush_hypercall) {
|
||||
hve->hv_enlightenments_control.nested_flush_hypercall = 1;
|
||||
|
@ -523,22 +523,14 @@ module_param(enlightened_vmcs, bool, 0444);
|
||||
static int hv_enable_l2_tlb_flush(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct hv_enlightened_vmcs *evmcs;
|
||||
struct hv_partition_assist_pg **p_hv_pa_pg =
|
||||
&to_kvm_hv(vcpu->kvm)->hv_pa_pg;
|
||||
/*
|
||||
* Synthetic VM-Exit is not enabled in current code and so All
|
||||
* evmcs in singe VM shares same assist page.
|
||||
*/
|
||||
if (!*p_hv_pa_pg)
|
||||
*p_hv_pa_pg = kzalloc(PAGE_SIZE, GFP_KERNEL_ACCOUNT);
|
||||
hpa_t partition_assist_page = hv_get_partition_assist_page(vcpu);
|
||||
|
||||
if (!*p_hv_pa_pg)
|
||||
if (partition_assist_page == INVALID_PAGE)
|
||||
return -ENOMEM;
|
||||
|
||||
evmcs = (struct hv_enlightened_vmcs *)to_vmx(vcpu)->loaded_vmcs->vmcs;
|
||||
|
||||
evmcs->partition_assist_page =
|
||||
__pa(*p_hv_pa_pg);
|
||||
evmcs->partition_assist_page = partition_assist_page;
|
||||
evmcs->hv_vm_id = (unsigned long)vcpu->kvm;
|
||||
evmcs->hv_enlightenments_control.nested_flush_hypercall = 1;
|
||||
|
||||
|
@ -12438,7 +12438,9 @@ void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu)
|
||||
|
||||
void kvm_arch_free_vm(struct kvm *kvm)
|
||||
{
|
||||
kfree(to_kvm_hv(kvm)->hv_pa_pg);
|
||||
#if IS_ENABLED(CONFIG_HYPERV)
|
||||
kfree(kvm->arch.hv_pa_pg);
|
||||
#endif
|
||||
__kvm_arch_free_vm(kvm);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user