This patch series enables the nested virtualization enlightenments for
SVM. This is very similar to the enlightenments for VMX except for the
fact that there is no enlightened VMCS. For SVM, VMCB is already an
architectural in-memory data structure.
The supported enlightenments are:
Enlightened TLB Flush: If this is enabled, ASID invalidations invalidate
only gva -> hpa entries. To flush entries derived from NPT, hyper-v
provided hypercalls (HvFlushGuestPhysicalAddressSpace or
HvFlushGuestPhysicalAddressList) should be used.
Enlightened MSR bitmap(TLFS 16.5.3): "When enabled, L0 hypervisor does
not monitor the MSR bitmaps for changes. Instead, the L1 hypervisor must
invalidate the corresponding clean field after making changes to one of
the MSR bitmaps."
Direct Virtual Flush(TLFS 16.8): The hypervisor exposes hypercalls
(HvFlushVirtualAddressSpace, HvFlushVirtualAddressSpaceEx,
HvFlushVirtualAddressList, and HvFlushVirtualAddressListEx) that allow
operating systems to more efficiently manage the virtual TLB. The L1
hypervisor can choose to allow its guest to use those hypercalls and
delegate the responsibility to handle them to the L0 hypervisor. This
requires the use of a partition assist page."
L2 Windows boot time was measured with and without the patch. Time was
measured from power on to the login screen and was averaged over a
consecutive 5 trials:
Without the patch: 42 seconds
With the patch: 29 seconds
--
Changes from v1:
- Move the remote TLB flush related fields from kvm_vcpu_hv and kvm_hv
to kvm_vcpu_arch and kvm_arch.
- Modify the VMCB clean mask runtime based on whether L1 hypervisor
is running on Hyper-V or not.
- Detect Hyper-V nested enlightenments based on
HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS.
- Address other minor review comments.
---
Vineeth Pillai (7):
hyperv: Detect Nested virtualization support for SVM
hyperv: SVM enlightened TLB flush support flag
KVM: x86: hyper-v: Move the remote TLB flush logic out of vmx
KVM: SVM: hyper-v: Nested enlightenments in VMCB
KVM: SVM: hyper-v: Remote TLB flush for SVM
KVM: SVM: hyper-v: Enlightened MSR-Bitmap support
KVM: SVM: hyper-v: Direct Virtual Flush support
arch/x86/include/asm/hyperv-tlfs.h | 9 +++
arch/x86/include/asm/kvm_host.h | 14 ++++
arch/x86/include/asm/svm.h | 24 +++++-
arch/x86/kernel/cpu/mshyperv.c | 10 ++-
arch/x86/kvm/hyperv.c | 87 +++++++++++++++++++++
arch/x86/kvm/hyperv.h | 20 +++++
arch/x86/kvm/svm/svm.c | 120 +++++++++++++++++++++++++++++
arch/x86/kvm/svm/svm.h | 30 +++++++-
arch/x86/kvm/vmx/vmx.c | 97 ++---------------------
arch/x86/kvm/vmx/vmx.h | 10 ---
arch/x86/kvm/x86.c | 9 ++-
11 files changed, 323 insertions(+), 107 deletions(-)
--
2.25.1
Bit 22 of HYPERV_CPUID_FEATURES.EDX is specific to SVM and specifies
support for enlightened TLB flush. With this enlightenment enabled,
ASID invalidations flushes only gva->hpa entries. To flush TLB entries
derived from NPT, hypercalls should be used
(HvFlushGuestPhysicalAddressSpace or HvFlushGuestPhysicalAddressList)
Signed-off-by: Vineeth Pillai <redacted>
---
arch/x86/include/asm/hyperv-tlfs.h | 9 +++++++++
1 file changed, 9 insertions(+)
Currently the remote TLB flush logic is specific to VMX.
Move it to a common place so that SVM can use it as well.
Signed-off-by: Vineeth Pillai <redacted>
---
arch/x86/include/asm/kvm_host.h | 14 +++++
arch/x86/kvm/hyperv.c | 87 +++++++++++++++++++++++++++++
arch/x86/kvm/hyperv.h | 20 +++++++
arch/x86/kvm/vmx/vmx.c | 97 +++------------------------------
arch/x86/kvm/vmx/vmx.h | 10 ----
arch/x86/kvm/x86.c | 9 ++-
6 files changed, 136 insertions(+), 101 deletions(-)
@@ -2180,3 +2181,89 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,return0;}++#if IS_ENABLED(CONFIG_HYPERV)+/* check_tdp_pointer() should be under protection of tdp_pointer_lock. */+staticvoidcheck_tdp_pointer_match(structkvm*kvm)+{+u64tdp_pointer=INVALID_PAGE;+boolvalid_tdp=false;+structkvm_vcpu*vcpu;+inti;++kvm_for_each_vcpu(i,vcpu,kvm){+if(!valid_tdp){+tdp_pointer=vcpu->arch.tdp_pointer;+valid_tdp=true;+continue;+}++if(tdp_pointer!=vcpu->arch.tdp_pointer){+kvm->arch.tdp_pointers_match=TDP_POINTERS_MISMATCH;+return;+}+}++kvm->arch.tdp_pointers_match=TDP_POINTERS_MATCH;+}++staticintkvm_fill_hv_flush_list_func(structhv_guest_mapping_flush_list*flush,+void*data)+{+structkvm_tlb_range*range=data;++returnhyperv_fill_flush_guest_mapping_list(flush,range->start_gfn,+range->pages);+}++staticinlineint__hv_remote_flush_tlb_with_range(structkvm*kvm,+structkvm_vcpu*vcpu,structkvm_tlb_range*range)+{+u64tdp_pointer=vcpu->arch.tdp_pointer;++/*+*FLUSH_GUEST_PHYSICAL_ADDRESS_SPACEhypercallneedsaddress+*ofthebaseofEPTPML4table,stripoffEPTconfiguration+*information.+*/+if(range)+returnhyperv_flush_guest_mapping_range(tdp_pointer&PAGE_MASK,+kvm_fill_hv_flush_list_func,(void*)range);+else+returnhyperv_flush_guest_mapping(tdp_pointer&PAGE_MASK);+}++intkvm_hv_remote_flush_tlb_with_range(structkvm*kvm,+structkvm_tlb_range*range)+{+structkvm_vcpu*vcpu;+intret=0,i;++spin_lock(&kvm->arch.tdp_pointer_lock);++if(kvm->arch.tdp_pointers_match==TDP_POINTERS_CHECK)+check_tdp_pointer_match(kvm);++if(kvm->arch.tdp_pointers_match!=TDP_POINTERS_MATCH){+kvm_for_each_vcpu(i,vcpu,kvm){+/* If tdp_pointer is invalid pointer, bypass flush request. */+if(VALID_PAGE(vcpu->arch.tdp_pointer))+ret|=__hv_remote_flush_tlb_with_range(+kvm,vcpu,range);+}+}else{+ret=__hv_remote_flush_tlb_with_range(kvm,+kvm_get_vcpu(kvm,0),range);+}++spin_unlock(&kvm->arch.tdp_pointer_lock);+returnret;+}+EXPORT_SYMBOL_GPL(kvm_hv_remote_flush_tlb_with_range);++intkvm_hv_remote_flush_tlb(structkvm*kvm)+{+returnkvm_hv_remote_flush_tlb_with_range(kvm,NULL);+}+EXPORT_SYMBOL_GPL(kvm_hv_remote_flush_tlb);+#endif
@@ -472,83 +473,6 @@ static const u32 vmx_uret_msrs_list[] = {staticbool__read_mostlyenlightened_vmcs=true;module_param(enlightened_vmcs,bool,0444);-/* check_ept_pointer() should be under protection of ept_pointer_lock. */-staticvoidcheck_ept_pointer_match(structkvm*kvm)-{-structkvm_vcpu*vcpu;-u64tmp_eptp=INVALID_PAGE;-inti;--kvm_for_each_vcpu(i,vcpu,kvm){-if(!VALID_PAGE(tmp_eptp)){-tmp_eptp=to_vmx(vcpu)->ept_pointer;-}elseif(tmp_eptp!=to_vmx(vcpu)->ept_pointer){-to_kvm_vmx(kvm)->ept_pointers_match-=EPT_POINTERS_MISMATCH;-return;-}-}--to_kvm_vmx(kvm)->ept_pointers_match=EPT_POINTERS_MATCH;-}--staticintkvm_fill_hv_flush_list_func(structhv_guest_mapping_flush_list*flush,-void*data)-{-structkvm_tlb_range*range=data;--returnhyperv_fill_flush_guest_mapping_list(flush,range->start_gfn,-range->pages);-}--staticinlineint__hv_remote_flush_tlb_with_range(structkvm*kvm,-structkvm_vcpu*vcpu,structkvm_tlb_range*range)-{-u64ept_pointer=to_vmx(vcpu)->ept_pointer;--/*-*FLUSH_GUEST_PHYSICAL_ADDRESS_SPACEhypercallneedsaddress-*ofthebaseofEPTPML4table,stripoffEPTconfiguration-*information.-*/-if(range)-returnhyperv_flush_guest_mapping_range(ept_pointer&PAGE_MASK,-kvm_fill_hv_flush_list_func,(void*)range);-else-returnhyperv_flush_guest_mapping(ept_pointer&PAGE_MASK);-}--staticinthv_remote_flush_tlb_with_range(structkvm*kvm,-structkvm_tlb_range*range)-{-structkvm_vcpu*vcpu;-intret=0,i;--spin_lock(&to_kvm_vmx(kvm)->ept_pointer_lock);--if(to_kvm_vmx(kvm)->ept_pointers_match==EPT_POINTERS_CHECK)-check_ept_pointer_match(kvm);--if(to_kvm_vmx(kvm)->ept_pointers_match!=EPT_POINTERS_MATCH){-kvm_for_each_vcpu(i,vcpu,kvm){-/* If ept_pointer is invalid pointer, bypass flush request. */-if(VALID_PAGE(to_vmx(vcpu)->ept_pointer))-ret|=__hv_remote_flush_tlb_with_range(-kvm,vcpu,range);-}-}else{-ret=__hv_remote_flush_tlb_with_range(kvm,-kvm_get_vcpu(kvm,0),range);-}--spin_unlock(&to_kvm_vmx(kvm)->ept_pointer_lock);-returnret;-}-staticinthv_remote_flush_tlb(structkvm*kvm)-{-returnhv_remote_flush_tlb_with_range(kvm,NULL);-}-staticinthv_enable_direct_tlbflush(structkvm_vcpu*vcpu){structhv_enlightened_vmcs*evmcs;
Add Hyper-V specific fields in VMCB to support SVM enlightenments.
Also a small refactoring of VMCB clean bits handling.
Signed-off-by: Vineeth Pillai <redacted>
---
arch/x86/include/asm/svm.h | 24 +++++++++++++++++++++++-
arch/x86/kvm/svm/svm.c | 8 ++++++++
arch/x86/kvm/svm/svm.h | 30 ++++++++++++++++++++++++++++--
3 files changed, 59 insertions(+), 3 deletions(-)
Enlightened MSR-Bitmap as per TLFS:
"The L1 hypervisor may collaborate with the L0 hypervisor to make MSR
accesses more efficient. It can enable enlightened MSR bitmaps by setting
the corresponding field in the enlightened VMCS to 1. When enabled, L0
hypervisor does not monitor the MSR bitmaps for changes. Instead, the L1
hypervisor must invalidate the corresponding clean field after making
changes to one of the MSR bitmaps."
Enable this for SVM.
Related VMX changes:
commit ceef7d10dfb6 ("KVM: x86: VMX: hyper-v: Enlightened MSR-Bitmap support")
Signed-off-by: Vineeth Pillai <redacted>
---
arch/x86/kvm/svm/svm.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
From Hyper-V TLFS:
"The hypervisor exposes hypercalls (HvFlushVirtualAddressSpace,
HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressList, and
HvFlushVirtualAddressListEx) that allow operating systems to more
efficiently manage the virtual TLB. The L1 hypervisor can choose to
allow its guest to use those hypercalls and delegate the responsibility
to handle them to the L0 hypervisor. This requires the use of a
partition assist page."
Add the Direct Virtual Flush support for SVM.
Related VMX changes:
commit 6f6a657c9998 ("KVM/Hyper-V/VMX: Add direct tlb flush support")
Signed-off-by: Vineeth Pillai <redacted>
---
arch/x86/kvm/svm/svm.c | 48 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
Detect nested features exposed by Hyper-V if SVM is enabled.
It may make sense to expand this a bit as it is probably unclear how the
change is related to SVM.
Something like:
HYPERV_CPUID_NESTED_FEATURES CPUID leaf can be present on both Intel and
AMD Hyper-V guests. Previously, the code was using
HV_X64_ENLIGHTENED_VMCS_RECOMMENDED feature bit to determine the
availability of nested features leaf and this complies to TLFS:
"Recommend a nested hypervisor using the enlightened VMCS interface.
Also indicates that additional nested enlightenments may be available
(see leaf 0x4000000A)". Enlightened VMCS, however, is an Intel only
feature so the detection method doesn't work for AMD. Use
HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS.EAX CPUID information ("The
maximum input value for hypervisor CPUID information.") instead, this
works for both AMD and Intel.
Currently the remote TLB flush logic is specific to VMX.
Move it to a common place so that SVM can use it as well.
Signed-off-by: Vineeth Pillai <redacted>
---
arch/x86/include/asm/kvm_host.h | 14 +++++
arch/x86/kvm/hyperv.c | 87 +++++++++++++++++++++++++++++
arch/x86/kvm/hyperv.h | 20 +++++++
arch/x86/kvm/vmx/vmx.c | 97 +++------------------------------
arch/x86/kvm/vmx/vmx.h | 10 ----
arch/x86/kvm/x86.c | 9 ++-
6 files changed, 136 insertions(+), 101 deletions(-)
I still think that using arch/x86/kvm/hyperv.[ch] for KVM-on-Hyper-V is
misleading. Currently, these are dedicated to emulating Hyper-V
interface to KVM guests and this is orthogonal to nesting KVM on
Hyper-V. As a solution, I'd suggest you either:
- Put the stuff in x86.c
- Create a dedicated set of files, e.g. 'kvmonhyperv.[ch]' (I also
thought about 'hyperv_host.[ch]' but then I realized it's equally
misleading as one can read this as 'KVM is acting as Hyper-V host').
Personally, I'd vote for the later. Besides eliminating confusion, the
benefit of having dedicated files is that we can avoid compiling them
completely when !IS_ENABLED(CONFIG_HYPERV) (#ifdefs in C are ugly).
@@ -472,83 +473,6 @@ static const u32 vmx_uret_msrs_list[] = {staticbool__read_mostlyenlightened_vmcs=true;module_param(enlightened_vmcs,bool,0444);-/* check_ept_pointer() should be under protection of ept_pointer_lock. */-staticvoidcheck_ept_pointer_match(structkvm*kvm)-{-structkvm_vcpu*vcpu;-u64tmp_eptp=INVALID_PAGE;-inti;--kvm_for_each_vcpu(i,vcpu,kvm){-if(!VALID_PAGE(tmp_eptp)){-tmp_eptp=to_vmx(vcpu)->ept_pointer;-}elseif(tmp_eptp!=to_vmx(vcpu)->ept_pointer){-to_kvm_vmx(kvm)->ept_pointers_match-=EPT_POINTERS_MISMATCH;-return;-}-}--to_kvm_vmx(kvm)->ept_pointers_match=EPT_POINTERS_MATCH;-}--staticintkvm_fill_hv_flush_list_func(structhv_guest_mapping_flush_list*flush,-void*data)-{-structkvm_tlb_range*range=data;--returnhyperv_fill_flush_guest_mapping_list(flush,range->start_gfn,-range->pages);-}--staticinlineint__hv_remote_flush_tlb_with_range(structkvm*kvm,-structkvm_vcpu*vcpu,structkvm_tlb_range*range)-{-u64ept_pointer=to_vmx(vcpu)->ept_pointer;--/*-*FLUSH_GUEST_PHYSICAL_ADDRESS_SPACEhypercallneedsaddress-*ofthebaseofEPTPML4table,stripoffEPTconfiguration-*information.-*/-if(range)-returnhyperv_flush_guest_mapping_range(ept_pointer&PAGE_MASK,-kvm_fill_hv_flush_list_func,(void*)range);-else-returnhyperv_flush_guest_mapping(ept_pointer&PAGE_MASK);-}--staticinthv_remote_flush_tlb_with_range(structkvm*kvm,-structkvm_tlb_range*range)-{-structkvm_vcpu*vcpu;-intret=0,i;--spin_lock(&to_kvm_vmx(kvm)->ept_pointer_lock);--if(to_kvm_vmx(kvm)->ept_pointers_match==EPT_POINTERS_CHECK)-check_ept_pointer_match(kvm);--if(to_kvm_vmx(kvm)->ept_pointers_match!=EPT_POINTERS_MATCH){-kvm_for_each_vcpu(i,vcpu,kvm){-/* If ept_pointer is invalid pointer, bypass flush request. */-if(VALID_PAGE(to_vmx(vcpu)->ept_pointer))-ret|=__hv_remote_flush_tlb_with_range(-kvm,vcpu,range);-}-}else{-ret=__hv_remote_flush_tlb_with_range(kvm,-kvm_get_vcpu(kvm,0),range);-}--spin_unlock(&to_kvm_vmx(kvm)->ept_pointer_lock);-returnret;-}-staticinthv_remote_flush_tlb(structkvm*kvm)-{-returnhv_remote_flush_tlb_with_range(kvm,NULL);-}-staticinthv_enable_direct_tlbflush(structkvm_vcpu*vcpu){structhv_enlightened_vmcs*evmcs;
From: Paolo Bonzini <pbonzini@redhat.com> Date: 2021-04-16 08:40:19
On 16/04/21 10:36, Vitaly Kuznetsov wrote:
- Create a dedicated set of files, e.g. 'kvmonhyperv.[ch]' (I also
thought about 'hyperv_host.[ch]' but then I realized it's equally
misleading as one can read this as 'KVM is acting as Hyper-V host').
Personally, I'd vote for the later. Besides eliminating confusion, the
benefit of having dedicated files is that we can avoid compiling them
completely when !IS_ENABLED(CONFIG_HYPERV) (#ifdefs in C are ugly).
Indeed. For the file, kvm-on-hv.[ch] can do.
Paolo
Add Hyper-V specific fields in VMCB to support SVM enlightenments.
Also a small refactoring of VMCB clean bits handling.
Signed-off-by: Vineeth Pillai <redacted>
---
arch/x86/include/asm/svm.h | 24 +++++++++++++++++++++++-
arch/x86/kvm/svm/svm.c | 8 ++++++++
arch/x86/kvm/svm/svm.h | 30 ++++++++++++++++++++++++++++--
3 files changed, 59 insertions(+), 3 deletions(-)
Enlightened VMCS seems to have the same part:
struct {
u32 nested_flush_hypercall:1;
u32 msr_bitmap:1;
u32 reserved:30;
} __packed hv_enlightenments_control;
u32 hv_vp_id;
u64 hv_vm_id;
u64 partition_assist_page;
Would it maybe make sense to unify these two (in case they are the same
thing in Hyper-V, of course)?
What if we preserve VMCB_DIRTY_MAX and drop this newly introduced
VMCB_ALL_CLEAN_MASK (which basically lists all the members of the enum
above)? '1 << VMCB_DIRTY_MAX' can still work. (If the 'VMCB_DIRTY_MAX'
name becomes misleading we can e.g. rename it to VMCB_NATIVE_DIRTY_MAX
or something but I'm not sure it's worth it)
Nitpick: we can probably have a 'static inline' for
"npt_enabled && ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB"
e.g. 'hv_svm_enlightened_tlbflush()'
It may make sense to expand this a bit as it is probably unclear how the
change is related to SVM.
Something like:
HYPERV_CPUID_NESTED_FEATURES CPUID leaf can be present on both Intel and
AMD Hyper-V guests. Previously, the code was using
HV_X64_ENLIGHTENED_VMCS_RECOMMENDED feature bit to determine the
availability of nested features leaf and this complies to TLFS:
"Recommend a nested hypervisor using the enlightened VMCS interface.
Also indicates that additional nested enlightenments may be available
(see leaf 0x4000000A)". Enlightened VMCS, however, is an Intel only
feature so the detection method doesn't work for AMD. Use
HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS.EAX CPUID information ("The
maximum input value for hypervisor CPUID information.") instead, this
works for both AMD and Intel.
Thanks for the input. Will update the commit message in next revision.
Thanks,
Vineeth
I still think that using arch/x86/kvm/hyperv.[ch] for KVM-on-Hyper-V is
misleading. Currently, these are dedicated to emulating Hyper-V
interface to KVM guests and this is orthogonal to nesting KVM on
Hyper-V. As a solution, I'd suggest you either:
- Put the stuff in x86.c
- Create a dedicated set of files, e.g. 'kvmonhyperv.[ch]' (I also
thought about 'hyperv_host.[ch]' but then I realized it's equally
misleading as one can read this as 'KVM is acting as Hyper-V host').
Personally, I'd vote for the later. Besides eliminating confusion, the
benefit of having dedicated files is that we can avoid compiling them
completely when !IS_ENABLED(CONFIG_HYPERV) (#ifdefs in C are ugly).
Makes sense, creating new set of files looks good to me. The default
hyperv.c
for hyperv emulation also seems misleading - probably we should rename it
to hyperv_host_emul.[ch] or similar. That way, probably I can use
hyperv.[ch]
for kvm on hyperv code. If you feel, thats too big of a churn, I shall use
kvm_on_hyperv.[ch] (to avoid reading the file differently). What do you
think?
Enlightened VMCS seems to have the same part:
struct {
u32 nested_flush_hypercall:1;
u32 msr_bitmap:1;
u32 reserved:30;
} __packed hv_enlightenments_control;
u32 hv_vp_id;
u64 hv_vm_id;
u64 partition_assist_page;
Would it maybe make sense to unify these two (in case they are the same
thing in Hyper-V, of course)?
They are very similar but, the individual bits are a bit different. SVM
struct has an
additional bit 'enlightened_npt_tlb'. There might be future changes as
well if new
enlightenments are designed for performance optimization. So I feel, we
can have
it as separate structs.
What if we preserve VMCB_DIRTY_MAX and drop this newly introduced
VMCB_ALL_CLEAN_MASK (which basically lists all the members of the enum
above)? '1 << VMCB_DIRTY_MAX' can still work. (If the 'VMCB_DIRTY_MAX'
name becomes misleading we can e.g. rename it to VMCB_NATIVE_DIRTY_MAX
or something but I'm not sure it's worth it)
I thought of keeping this code because, if we have non-contiguous bits
in future, we
would need this kinda logic anyways. But I get your point. Will revert this.
I still think that using arch/x86/kvm/hyperv.[ch] for KVM-on-Hyper-V is
misleading. Currently, these are dedicated to emulating Hyper-V
interface to KVM guests and this is orthogonal to nesting KVM on
Hyper-V. As a solution, I'd suggest you either:
- Put the stuff in x86.c
- Create a dedicated set of files, e.g. 'kvmonhyperv.[ch]' (I also
thought about 'hyperv_host.[ch]' but then I realized it's equally
misleading as one can read this as 'KVM is acting as Hyper-V host').
Personally, I'd vote for the later. Besides eliminating confusion, the
benefit of having dedicated files is that we can avoid compiling them
completely when !IS_ENABLED(CONFIG_HYPERV) (#ifdefs in C are ugly).
Makes sense, creating new set of files looks good to me. The default
hyperv.c
for hyperv emulation also seems misleading - probably we should rename it
to hyperv_host_emul.[ch] or similar. That way, probably I can use
hyperv.[ch]
for kvm on hyperv code. If you feel, thats too big of a churn, I shall use
kvm_on_hyperv.[ch] (to avoid reading the file differently). What do you
think?
I agree that 'hyperv.[ch]' is not ideal but I'm on the fence whether
renaming it is worth it. If we were to rename it, I'd suggest just
'hyperv_emul.[ch]' to indicate that here we're emulating Hyper-V.
I don't think reusing 'hyperv.[ch]' for KVM-on-Hyper-V is a good idea,
it would be doubly misleading and not friendly to backporters. Let's not
do that.
It was kinda leftover, but I thought I'd keep it as it removes and
unnecessary line.
The idea is to have meaninful patches as concise as possible splitting
off cleanup / preparatory patches which don't actually change anything;
this way big series are much easier to review.
From: Wei Liu <wei.liu@kernel.org> Date: 2021-04-21 10:00:36
On Thu, Apr 15, 2021 at 01:43:37PM +0000, Vineeth Pillai wrote:
quoted hunk
Bit 22 of HYPERV_CPUID_FEATURES.EDX is specific to SVM and specifies
support for enlightened TLB flush. With this enlightenment enabled,
ASID invalidations flushes only gva->hpa entries. To flush TLB entries
derived from NPT, hypercalls should be used
(HvFlushGuestPhysicalAddressSpace or HvFlushGuestPhysicalAddressList)
Signed-off-by: Vineeth Pillai <redacted>
---
arch/x86/include/asm/hyperv-tlfs.h | 9 +++++++++
1 file changed, 9 insertions(+)
This is not yet documented in TLFS, right? I can't find this bit in the
latest edition (6.0b).
My first thought is the comment says this is AMD specific but the name
is rather generic. That looks a bit odd to begin with.
Wei.
On Thu, Apr 15, 2021 at 01:43:37PM +0000, Vineeth Pillai wrote:
quoted
+/*
+ * This is specific to AMD and specifies that enlightened TLB flush is
+ * supported. If guest opts in to this feature, ASID invalidations only
+ * flushes gva -> hpa mapping entries. To flush the TLB entries derived
+ * from NPT, hypercalls should be used (HvFlushGuestPhysicalAddressSpace
+ * or HvFlushGuestPhysicalAddressList).
+ */
+#define HV_X64_NESTED_ENLIGHTENED_TLB BIT(22)
+
c
This is not yet documented in TLFS, right? I can't find this bit in the
latest edition (6.0b).
This would be documented in the TLFS update which is soon to be
released.
My first thought is the comment says this is AMD specific but the name
is rather generic. That looks a bit odd to begin with.
I thought of of keeping the name generic to avoid renaming Intel
specific ones also. If I understand correctly, the TLFS would also
be having generic name for this and just translated the generic
name here in this header.
Thanks,
Vineeth
From: Wei Liu <wei.liu@kernel.org> Date: 2021-04-21 13:21:51
On Wed, Apr 21, 2021 at 07:15:54AM -0400, Vineeth Pillai wrote:
On 4/21/21 6:00 AM, Wei Liu wrote:
quoted
On Thu, Apr 15, 2021 at 01:43:37PM +0000, Vineeth Pillai wrote:
quoted
+/*
+ * This is specific to AMD and specifies that enlightened TLB flush is
+ * supported. If guest opts in to this feature, ASID invalidations only
+ * flushes gva -> hpa mapping entries. To flush the TLB entries derived
+ * from NPT, hypercalls should be used (HvFlushGuestPhysicalAddressSpace
+ * or HvFlushGuestPhysicalAddressList).
+ */
+#define HV_X64_NESTED_ENLIGHTENED_TLB BIT(22)
+
c
This is not yet documented in TLFS, right? I can't find this bit in the
latest edition (6.0b).
This would be documented in the TLFS update which is soon to be
released.
Okay.
quoted
My first thought is the comment says this is AMD specific but the name
is rather generic. That looks a bit odd to begin with.
I thought of of keeping the name generic to avoid renaming Intel
specific ones also. If I understand correctly, the TLFS would also
be having generic name for this and just translated the generic
name here in this header.
+#if IS_ENABLED(CONFIG_HYPERV)
+static void hv_init_vmcb(struct vmcb *vmcb)
+{
+ struct hv_enlightenments *hve = &vmcb->hv_enlightenments;
+
+ if (npt_enabled &&
+ ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB)
Nitpick: we can probably have a 'static inline' for
"npt_enabled && ms_hyperv.nested_features &
HV_X64_NESTED_ENLIGHTENED_TLB"
e.g. 'hv_svm_enlightened_tlbflush()'
Makes sense, will do.
On a second thought, this function itself is small and just does this
one check.
So, might not make sense to add one more function. I shall rather change
this
function to be an inline.
Thanks,
Vineeth