Hyper-V folks, if the changes look ok I'd like to take this through the
KVM tree as Vitaly has an in-progress KVM series[*] that conflicts mightily
with these changes.
The main goal of this series it to clean up KVM's ugly casting of the
VMCB's software reserved field to the Hyper-V enlightenments struct,
e.g. replace a bunch of code that does:
(struct hv_enlightenments *)vmcb->control.reserved_sw;
with:
&vmcb->control.hv_enlightenments;
That cleanup is complicated slightly due the Hyper-V enlightenments
being "KVM private", versus the VMCB struct being "public", but that
itself is also a "bug". The enlightenments come directly from the TLFS,
i.e. aren't KVM internal. Moving the definition to hyperv-tlfs.h where
it belongs has the happy side effect of making the struct visible to
asm/svm.h.
Compile tested only, but the resulting kvm-amd.ko binary is identical
before and after the series.
[*] https://lore.kernel.org/all/[email protected]
Sean Christopherson (4):
x86/hyperv: Move VMCB enlightenment definitions to hyperv-tlfs.h
KVM: selftests: Move "struct hv_enlightenments" to x86_64/svm.h
KVM: SVM: Add a proper field for Hyper-V VMCB enlightenments
x86/hyperv: KVM: Rename "hv_enlightenments" to
"hv_vmcb_enlightenments"
arch/x86/include/asm/hyperv-tlfs.h | 22 ++++++++++++
arch/x86/include/asm/svm.h | 7 +++-
arch/x86/kvm/svm/hyperv.h | 35 -------------------
arch/x86/kvm/svm/nested.c | 9 +++--
arch/x86/kvm/svm/svm.h | 5 ++-
arch/x86/kvm/svm/svm_onhyperv.c | 4 +--
arch/x86/kvm/svm/svm_onhyperv.h | 18 +++++-----
.../selftests/kvm/include/x86_64/svm.h | 22 +++++++++++-
.../selftests/kvm/x86_64/hyperv_svm_test.c | 21 +----------
9 files changed, 69 insertions(+), 74 deletions(-)
delete mode 100644 arch/x86/kvm/svm/hyperv.h
base-commit: 372d07084593dc7a399bf9bee815711b1fb1bcf2
--
2.37.3.968.ga6b4b080e4-goog
Move Hyper-V's VMCB "struct hv_enlightenments" to the svm.h header so
that the struct can be referenced in "struct vmcb_control_area".
Alternatively, a dedicated header for SVM+Hyper-V could be added, a la
x86_64/evmcs.h, but it doesn't appear that Hyper-V will end up needing
a wholesale replacement for the VMCB.
No functional change intended.
Signed-off-by: Sean Christopherson <[email protected]>
---
.../testing/selftests/kvm/include/x86_64/svm.h | 17 +++++++++++++++++
.../selftests/kvm/x86_64/hyperv_svm_test.c | 18 ------------------
2 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/x86_64/svm.h b/tools/testing/selftests/kvm/include/x86_64/svm.h
index c8343ff84f7f..10b9d0d4e0ec 100644
--- a/tools/testing/selftests/kvm/include/x86_64/svm.h
+++ b/tools/testing/selftests/kvm/include/x86_64/svm.h
@@ -58,6 +58,23 @@ enum {
INTERCEPT_RDPRU,
};
+struct hv_enlightenments {
+ struct __packed hv_enlightenments_control {
+ u32 nested_flush_hypercall:1;
+ u32 msr_bitmap:1;
+ u32 enlightened_npt_tlb: 1;
+ u32 reserved:29;
+ } __packed hv_enlightenments_control;
+ u32 hv_vp_id;
+ u64 hv_vm_id;
+ u64 partition_assist_page;
+ u64 reserved;
+} __packed;
+
+/*
+ * Hyper-V uses the software reserved clean bit in VMCB
+ */
+#define VMCB_HV_NESTED_ENLIGHTENMENTS (1U << 31)
struct __attribute__ ((__packed__)) vmcb_control_area {
u32 intercept_cr;
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c b/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
index a380ad7bb9b3..b366b197759f 100644
--- a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
+++ b/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
@@ -23,24 +23,6 @@
#define L2_GUEST_STACK_SIZE 256
-struct hv_enlightenments {
- struct __packed hv_enlightenments_control {
- u32 nested_flush_hypercall:1;
- u32 msr_bitmap:1;
- u32 enlightened_npt_tlb: 1;
- u32 reserved:29;
- } __packed hv_enlightenments_control;
- u32 hv_vp_id;
- u64 hv_vm_id;
- u64 partition_assist_page;
- u64 reserved;
-} __packed;
-
-/*
- * Hyper-V uses the software reserved clean bit in VMCB
- */
-#define VMCB_HV_NESTED_ENLIGHTENMENTS (1U << 31)
-
void l2_guest_code(void)
{
GUEST_SYNC(3);
--
2.37.3.968.ga6b4b080e4-goog
Now that KVM isn't littered with "struct hv_enlightenments" casts, rename
the struct to "hv_vmcb_enlightenments" to highlight the fact that the
struct is specifically for SVM's VMCB.
No functional change intended.
Signed-off-by: Sean Christopherson <[email protected]>
---
arch/x86/include/asm/hyperv-tlfs.h | 2 +-
arch/x86/include/asm/svm.h | 2 +-
arch/x86/kvm/svm/nested.c | 2 +-
arch/x86/kvm/svm/svm.h | 2 +-
arch/x86/kvm/svm/svm_onhyperv.c | 2 +-
arch/x86/kvm/svm/svm_onhyperv.h | 6 +++---
tools/testing/selftests/kvm/include/x86_64/svm.h | 4 ++--
tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c | 2 +-
8 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 4c4f81daf5a2..f7a431bcb2c3 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -588,7 +588,7 @@ struct hv_enlightened_vmcs {
* Hyper-V uses the software reserved 32 bytes in VMCB control area to expose
* SVM enlightenments to guests.
*/
-struct hv_enlightenments {
+struct hv_vmcb_enlightenments {
struct __packed hv_enlightenments_control {
u32 nested_flush_hypercall:1;
u32 msr_bitmap:1;
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 6befed2b30a6..621f064bb7cc 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -164,7 +164,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
* for use by hypervisor/software.
*/
union {
- struct hv_enlightenments hv_enlightenments;
+ struct hv_vmcb_enlightenments hv_enlightenments;
u8 reserved_sw[32];
};
};
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index a6a87d9743ce..bc9fb4dbf0ae 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -201,7 +201,7 @@ void recalc_intercepts(struct vcpu_svm *svm)
*/
static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
{
- struct hv_enlightenments *hve = &svm->nested.ctl.hv_enlightenments;
+ struct hv_vmcb_enlightenments *hve = &svm->nested.ctl.hv_enlightenments;
int i;
/*
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 9eb2fc76732f..5e1178bc9a64 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -152,7 +152,7 @@ struct vmcb_ctrl_area_cached {
u64 virt_ext;
u32 clean;
union {
- struct hv_enlightenments hv_enlightenments;
+ struct hv_vmcb_enlightenments hv_enlightenments;
u8 reserved_sw[32];
};
};
diff --git a/arch/x86/kvm/svm/svm_onhyperv.c b/arch/x86/kvm/svm/svm_onhyperv.c
index 5d4036611a37..0b657c7cd21b 100644
--- a/arch/x86/kvm/svm/svm_onhyperv.c
+++ b/arch/x86/kvm/svm/svm_onhyperv.c
@@ -16,7 +16,7 @@
int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu)
{
- struct hv_enlightenments *hve;
+ struct hv_vmcb_enlightenments *hve;
struct hv_partition_assist_pg **p_hv_pa_pg =
&to_kvm_hv(vcpu->kvm)->hv_pa_pg;
diff --git a/arch/x86/kvm/svm/svm_onhyperv.h b/arch/x86/kvm/svm/svm_onhyperv.h
index c8f8045305be..e08cd7192559 100644
--- a/arch/x86/kvm/svm/svm_onhyperv.h
+++ b/arch/x86/kvm/svm/svm_onhyperv.h
@@ -18,7 +18,7 @@ int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu);
static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
{
- struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
+ struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
BUILD_BUG_ON(sizeof(vmcb->control.hv_enlightenments) !=
sizeof(vmcb->control.reserved_sw));
@@ -63,7 +63,7 @@ static inline void svm_hv_vmcb_dirty_nested_enlightenments(
struct kvm_vcpu *vcpu)
{
struct vmcb *vmcb = to_svm(vcpu)->vmcb;
- struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
+ struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
if (hve->hv_enlightenments_control.msr_bitmap)
vmcb_mark_dirty(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS);
@@ -71,7 +71,7 @@ static inline void svm_hv_vmcb_dirty_nested_enlightenments(
static inline void svm_hv_update_vp_id(struct vmcb *vmcb, struct kvm_vcpu *vcpu)
{
- struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
+ struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
u32 vp_index = kvm_hv_get_vpindex(vcpu);
if (hve->hv_vp_id != vp_index) {
diff --git a/tools/testing/selftests/kvm/include/x86_64/svm.h b/tools/testing/selftests/kvm/include/x86_64/svm.h
index 0c32549c6b64..49292190c219 100644
--- a/tools/testing/selftests/kvm/include/x86_64/svm.h
+++ b/tools/testing/selftests/kvm/include/x86_64/svm.h
@@ -58,7 +58,7 @@ enum {
INTERCEPT_RDPRU,
};
-struct hv_enlightenments {
+struct hv_vmcb_enlightenments {
struct __packed hv_enlightenments_control {
u32 nested_flush_hypercall:1;
u32 msr_bitmap:1;
@@ -124,7 +124,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
* for use by hypervisor/software.
*/
union {
- struct hv_enlightenments hv_enlightenments;
+ struct hv_vmcb_enlightenments hv_enlightenments;
u8 reserved_sw[32];
};
};
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c b/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
index 81b204ee509a..f8e43c798c86 100644
--- a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
+++ b/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
@@ -46,7 +46,7 @@ static void __attribute__((__flatten__)) guest_code(struct svm_test_data *svm)
{
unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
struct vmcb *vmcb = svm->vmcb;
- struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
+ struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
GUEST_SYNC(1);
--
2.37.3.968.ga6b4b080e4-goog
Move Hyper-V's VMCB enlightenment definitions to the TLFS header; the
definitions come directly from the TLFS[*], not from KVM.
No functional change intended.
[*] https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/datatypes/hv_svm_enlightened_vmcb_fields
Signed-off-by: Sean Christopherson <[email protected]>
---
arch/x86/include/asm/hyperv-tlfs.h | 22 +++++++++++++++++++
arch/x86/kvm/svm/hyperv.h | 35 ------------------------------
arch/x86/kvm/svm/svm_onhyperv.h | 3 ++-
3 files changed, 24 insertions(+), 36 deletions(-)
delete mode 100644 arch/x86/kvm/svm/hyperv.h
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 0a9407dc0859..4c4f81daf5a2 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -584,6 +584,28 @@ struct hv_enlightened_vmcs {
#define HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL 0xFFFF
+/*
+ * Hyper-V uses the software reserved 32 bytes in VMCB control area to expose
+ * SVM enlightenments to guests.
+ */
+struct hv_enlightenments {
+ struct __packed hv_enlightenments_control {
+ u32 nested_flush_hypercall:1;
+ u32 msr_bitmap:1;
+ u32 enlightened_npt_tlb: 1;
+ u32 reserved:29;
+ } __packed hv_enlightenments_control;
+ u32 hv_vp_id;
+ u64 hv_vm_id;
+ u64 partition_assist_page;
+ u64 reserved;
+} __packed;
+
+/*
+ * Hyper-V uses the software reserved clean bit in VMCB.
+ */
+#define VMCB_HV_NESTED_ENLIGHTENMENTS 31
+
struct hv_partition_assist_pg {
u32 tlb_lock_count;
};
diff --git a/arch/x86/kvm/svm/hyperv.h b/arch/x86/kvm/svm/hyperv.h
deleted file mode 100644
index 7d6d97968fb9..000000000000
--- a/arch/x86/kvm/svm/hyperv.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Common Hyper-V on KVM and KVM on Hyper-V definitions (SVM).
- */
-
-#ifndef __ARCH_X86_KVM_SVM_HYPERV_H__
-#define __ARCH_X86_KVM_SVM_HYPERV_H__
-
-#include <asm/mshyperv.h>
-
-#include "../hyperv.h"
-
-/*
- * Hyper-V uses the software reserved 32 bytes in VMCB
- * control area to expose SVM enlightenments to guests.
- */
-struct hv_enlightenments {
- struct __packed hv_enlightenments_control {
- u32 nested_flush_hypercall:1;
- u32 msr_bitmap:1;
- u32 enlightened_npt_tlb: 1;
- u32 reserved:29;
- } __packed hv_enlightenments_control;
- u32 hv_vp_id;
- u64 hv_vm_id;
- u64 partition_assist_page;
- u64 reserved;
-} __packed;
-
-/*
- * Hyper-V uses the software reserved clean bit in VMCB
- */
-#define VMCB_HV_NESTED_ENLIGHTENMENTS VMCB_SW
-
-#endif /* __ARCH_X86_KVM_SVM_HYPERV_H__ */
diff --git a/arch/x86/kvm/svm/svm_onhyperv.h b/arch/x86/kvm/svm/svm_onhyperv.h
index e2fc59380465..8d02654ad6f8 100644
--- a/arch/x86/kvm/svm/svm_onhyperv.h
+++ b/arch/x86/kvm/svm/svm_onhyperv.h
@@ -8,8 +8,9 @@
#if IS_ENABLED(CONFIG_HYPERV)
+#include <asm/mshyperv.h>
+
#include "kvm_onhyperv.h"
-#include "svm/hyperv.h"
static struct kvm_x86_ops svm_x86_ops;
--
2.37.3.968.ga6b4b080e4-goog
Add a union to provide hv_enlightenments side-by-side with the sw_reserved
bytes that Hyper-V's enlightenments overlay. Casting sw_reserved
everywhere is messy, confusing, and unnecessarily unsafe.
No functional change intended.
Signed-off-by: Sean Christopherson <[email protected]>
---
arch/x86/include/asm/svm.h | 7 ++++++-
arch/x86/kvm/svm/nested.c | 9 ++++-----
arch/x86/kvm/svm/svm.h | 5 ++++-
arch/x86/kvm/svm/svm_onhyperv.c | 2 +-
arch/x86/kvm/svm/svm_onhyperv.h | 15 +++++++--------
tools/testing/selftests/kvm/include/x86_64/svm.h | 5 ++++-
.../selftests/kvm/x86_64/hyperv_svm_test.c | 3 +--
7 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 0361626841bc..6befed2b30a6 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -5,6 +5,8 @@
#include <uapi/asm/svm.h>
#include <uapi/asm/kvm.h>
+#include <asm/hyperv-tlfs.h>
+
/*
* 32-bit intercept words in the VMCB Control Area, starting
* at Byte offset 000h.
@@ -161,7 +163,10 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
* Offset 0x3e0, 32 bytes reserved
* for use by hypervisor/software.
*/
- u8 reserved_sw[32];
+ union {
+ struct hv_enlightenments hv_enlightenments;
+ u8 reserved_sw[32];
+ };
};
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index 76dcc8a3e849..a6a87d9743ce 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -201,8 +201,7 @@ void recalc_intercepts(struct vcpu_svm *svm)
*/
static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
{
- struct hv_enlightenments *hve =
- (struct hv_enlightenments *)svm->nested.ctl.reserved_sw;
+ struct hv_enlightenments *hve = &svm->nested.ctl.hv_enlightenments;
int i;
/*
@@ -391,8 +390,8 @@ void __nested_copy_vmcb_control_to_cache(struct kvm_vcpu *vcpu,
/* Hyper-V extensions (Enlightened VMCB) */
if (kvm_hv_hypercall_enabled(vcpu)) {
to->clean = from->clean;
- memcpy(to->reserved_sw, from->reserved_sw,
- sizeof(struct hv_enlightenments));
+ memcpy(&to->hv_enlightenments, &from->hv_enlightenments,
+ sizeof(to->hv_enlightenments));
}
}
@@ -1485,7 +1484,7 @@ static void nested_copy_vmcb_cache_to_control(struct vmcb_control_area *dst,
dst->virt_ext = from->virt_ext;
dst->pause_filter_count = from->pause_filter_count;
dst->pause_filter_thresh = from->pause_filter_thresh;
- /* 'clean' and 'reserved_sw' are not changed by KVM */
+ /* 'clean' and 'hv_enlightenments' are not changed by KVM */
}
static int svm_get_nested_state(struct kvm_vcpu *vcpu,
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 6a7686bf6900..9eb2fc76732f 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -151,7 +151,10 @@ struct vmcb_ctrl_area_cached {
u64 nested_cr3;
u64 virt_ext;
u32 clean;
- u8 reserved_sw[32];
+ union {
+ struct hv_enlightenments hv_enlightenments;
+ u8 reserved_sw[32];
+ };
};
struct svm_nested_state {
diff --git a/arch/x86/kvm/svm/svm_onhyperv.c b/arch/x86/kvm/svm/svm_onhyperv.c
index 8cdc62c74a96..5d4036611a37 100644
--- a/arch/x86/kvm/svm/svm_onhyperv.c
+++ b/arch/x86/kvm/svm/svm_onhyperv.c
@@ -26,7 +26,7 @@ int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu)
if (!*p_hv_pa_pg)
return -ENOMEM;
- hve = (struct hv_enlightenments *)to_svm(vcpu)->vmcb->control.reserved_sw;
+ hve = &to_svm(vcpu)->vmcb->control.hv_enlightenments;
hve->partition_assist_page = __pa(*p_hv_pa_pg);
hve->hv_vm_id = (unsigned long)vcpu->kvm;
diff --git a/arch/x86/kvm/svm/svm_onhyperv.h b/arch/x86/kvm/svm/svm_onhyperv.h
index 8d02654ad6f8..c8f8045305be 100644
--- a/arch/x86/kvm/svm/svm_onhyperv.h
+++ b/arch/x86/kvm/svm/svm_onhyperv.h
@@ -18,8 +18,10 @@ int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu);
static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
{
- struct hv_enlightenments *hve =
- (struct hv_enlightenments *)vmcb->control.reserved_sw;
+ struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
+
+ BUILD_BUG_ON(sizeof(vmcb->control.hv_enlightenments) !=
+ sizeof(vmcb->control.reserved_sw));
if (npt_enabled &&
ms_hyperv.nested_features & HV_X64_NESTED_ENLIGHTENED_TLB)
@@ -61,18 +63,15 @@ static inline void svm_hv_vmcb_dirty_nested_enlightenments(
struct kvm_vcpu *vcpu)
{
struct vmcb *vmcb = to_svm(vcpu)->vmcb;
- struct hv_enlightenments *hve =
- (struct hv_enlightenments *)vmcb->control.reserved_sw;
+ struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
if (hve->hv_enlightenments_control.msr_bitmap)
vmcb_mark_dirty(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS);
}
-static inline void svm_hv_update_vp_id(struct vmcb *vmcb,
- struct kvm_vcpu *vcpu)
+static inline void svm_hv_update_vp_id(struct vmcb *vmcb, struct kvm_vcpu *vcpu)
{
- struct hv_enlightenments *hve =
- (struct hv_enlightenments *)vmcb->control.reserved_sw;
+ struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
u32 vp_index = kvm_hv_get_vpindex(vcpu);
if (hve->hv_vp_id != vp_index) {
diff --git a/tools/testing/selftests/kvm/include/x86_64/svm.h b/tools/testing/selftests/kvm/include/x86_64/svm.h
index 10b9d0d4e0ec..0c32549c6b64 100644
--- a/tools/testing/selftests/kvm/include/x86_64/svm.h
+++ b/tools/testing/selftests/kvm/include/x86_64/svm.h
@@ -123,7 +123,10 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
* Offset 0x3e0, 32 bytes reserved
* for use by hypervisor/software.
*/
- u8 reserved_sw[32];
+ union {
+ struct hv_enlightenments hv_enlightenments;
+ u8 reserved_sw[32];
+ };
};
diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c b/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
index b366b197759f..81b204ee509a 100644
--- a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
+++ b/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
@@ -46,8 +46,7 @@ static void __attribute__((__flatten__)) guest_code(struct svm_test_data *svm)
{
unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
struct vmcb *vmcb = svm->vmcb;
- struct hv_enlightenments *hve =
- (struct hv_enlightenments *)vmcb->control.reserved_sw;
+ struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
GUEST_SYNC(1);
--
2.37.3.968.ga6b4b080e4-goog
From: Sean Christopherson <[email protected]> Sent: Wednesday, September 21, 2022 1:16 PM
>
> Move Hyper-V's VMCB enlightenment definitions to the TLFS header; the
> definitions come directly from the TLFS[*], not from KVM.
>
> No functional change intended.
>
> [*] https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/datatypes/hv_svm_enlightened_vmcb_fields>
> Signed-off-by: Sean Christopherson <[email protected]>
> ---
> arch/x86/include/asm/hyperv-tlfs.h | 22 +++++++++++++++++++
> arch/x86/kvm/svm/hyperv.h | 35 ------------------------------
> arch/x86/kvm/svm/svm_onhyperv.h | 3 ++-
> 3 files changed, 24 insertions(+), 36 deletions(-)
> delete mode 100644 arch/x86/kvm/svm/hyperv.h
>
> diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
> index 0a9407dc0859..4c4f81daf5a2 100644
> --- a/arch/x86/include/asm/hyperv-tlfs.h
> +++ b/arch/x86/include/asm/hyperv-tlfs.h
> @@ -584,6 +584,28 @@ struct hv_enlightened_vmcs {
>
> #define HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL 0xFFFF
>
> +/*
> + * Hyper-V uses the software reserved 32 bytes in VMCB control area to expose
> + * SVM enlightenments to guests.
> + */
> +struct hv_enlightenments {
> + struct __packed hv_enlightenments_control {
> + u32 nested_flush_hypercall:1;
> + u32 msr_bitmap:1;
> + u32 enlightened_npt_tlb: 1;
> + u32 reserved:29;
> + } __packed hv_enlightenments_control;
> + u32 hv_vp_id;
> + u64 hv_vm_id;
> + u64 partition_assist_page;
> + u64 reserved;
> +} __packed;
> +
> +/*
> + * Hyper-V uses the software reserved clean bit in VMCB.
> + */
> +#define VMCB_HV_NESTED_ENLIGHTENMENTS 31
Is it feasible to change this identifier so it starts with HV_ like
everything else in this source code file, such as
HV_VMCB_NESTED_ENLIGHTENMENTS? It doesn't look like it is
used in very many places.
> +
> struct hv_partition_assist_pg {
> u32 tlb_lock_count;
> };
> diff --git a/arch/x86/kvm/svm/hyperv.h b/arch/x86/kvm/svm/hyperv.h
> deleted file mode 100644
> index 7d6d97968fb9..000000000000
> --- a/arch/x86/kvm/svm/hyperv.h
> +++ /dev/null
> @@ -1,35 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Common Hyper-V on KVM and KVM on Hyper-V definitions (SVM).
> - */
> -
> -#ifndef __ARCH_X86_KVM_SVM_HYPERV_H__
> -#define __ARCH_X86_KVM_SVM_HYPERV_H__
> -
> -#include <asm/mshyperv.h>
> -
> -#include "../hyperv.h"
> -
> -/*
> - * Hyper-V uses the software reserved 32 bytes in VMCB
> - * control area to expose SVM enlightenments to guests.
> - */
> -struct hv_enlightenments {
> - struct __packed hv_enlightenments_control {
> - u32 nested_flush_hypercall:1;
> - u32 msr_bitmap:1;
> - u32 enlightened_npt_tlb: 1;
> - u32 reserved:29;
> - } __packed hv_enlightenments_control;
> - u32 hv_vp_id;
> - u64 hv_vm_id;
> - u64 partition_assist_page;
> - u64 reserved;
> -} __packed;
> -
> -/*
> - * Hyper-V uses the software reserved clean bit in VMCB
> - */
> -#define VMCB_HV_NESTED_ENLIGHTENMENTS VMCB_SW
> -
> -#endif /* __ARCH_X86_KVM_SVM_HYPERV_H__ */
> diff --git a/arch/x86/kvm/svm/svm_onhyperv.h
> b/arch/x86/kvm/svm/svm_onhyperv.h
> index e2fc59380465..8d02654ad6f8 100644
> --- a/arch/x86/kvm/svm/svm_onhyperv.h
> +++ b/arch/x86/kvm/svm/svm_onhyperv.h
> @@ -8,8 +8,9 @@
>
> #if IS_ENABLED(CONFIG_HYPERV)
>
> +#include <asm/mshyperv.h>
> +
> #include "kvm_onhyperv.h"
> -#include "svm/hyperv.h"
>
> static struct kvm_x86_ops svm_x86_ops;
>
> --
> 2.37.3.968.ga6b4b080e4-goog
On Thu, Sep 22, 2022, Michael Kelley (LINUX) wrote:
> From: Sean Christopherson <[email protected]> Sent: Wednesday, September 21, 2022 1:16 PM
> >
> > Move Hyper-V's VMCB enlightenment definitions to the TLFS header; the
> > definitions come directly from the TLFS[*], not from KVM.
> >
> > No functional change intended.
> >
> > [*] https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/datatypes/hv_svm_enlightened_vmcb_fields>
> > Signed-off-by: Sean Christopherson <[email protected]>
> > ---
> > arch/x86/include/asm/hyperv-tlfs.h | 22 +++++++++++++++++++
> > arch/x86/kvm/svm/hyperv.h | 35 ------------------------------
> > arch/x86/kvm/svm/svm_onhyperv.h | 3 ++-
> > 3 files changed, 24 insertions(+), 36 deletions(-)
> > delete mode 100644 arch/x86/kvm/svm/hyperv.h
> >
> > diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
> > index 0a9407dc0859..4c4f81daf5a2 100644
> > --- a/arch/x86/include/asm/hyperv-tlfs.h
> > +++ b/arch/x86/include/asm/hyperv-tlfs.h
> > @@ -584,6 +584,28 @@ struct hv_enlightened_vmcs {
> >
> > #define HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL 0xFFFF
> >
> > +/*
> > + * Hyper-V uses the software reserved 32 bytes in VMCB control area to expose
> > + * SVM enlightenments to guests.
> > + */
> > +struct hv_enlightenments {
> > + struct __packed hv_enlightenments_control {
> > + u32 nested_flush_hypercall:1;
> > + u32 msr_bitmap:1;
> > + u32 enlightened_npt_tlb: 1;
> > + u32 reserved:29;
> > + } __packed hv_enlightenments_control;
> > + u32 hv_vp_id;
> > + u64 hv_vm_id;
> > + u64 partition_assist_page;
> > + u64 reserved;
> > +} __packed;
> > +
> > +/*
> > + * Hyper-V uses the software reserved clean bit in VMCB.
> > + */
> > +#define VMCB_HV_NESTED_ENLIGHTENMENTS 31
>
> Is it feasible to change this identifier so it starts with HV_ like
> everything else in this source code file, such as
> HV_VMCB_NESTED_ENLIGHTENMENTS? It doesn't look like it is
> used in very many places.
Most definitely, IIRC it's used in only one spot.
From: Sean Christopherson <[email protected]> Sent: Wednesday, September 21, 2022 1:16 PM
>
> Now that KVM isn't littered with "struct hv_enlightenments" casts, rename
> the struct to "hv_vmcb_enlightenments" to highlight the fact that the
> struct is specifically for SVM's VMCB.
>
> No functional change intended.
>
> Signed-off-by: Sean Christopherson <[email protected]>
> ---
> arch/x86/include/asm/hyperv-tlfs.h | 2 +-
> arch/x86/include/asm/svm.h | 2 +-
> arch/x86/kvm/svm/nested.c | 2 +-
> arch/x86/kvm/svm/svm.h | 2 +-
> arch/x86/kvm/svm/svm_onhyperv.c | 2 +-
> arch/x86/kvm/svm/svm_onhyperv.h | 6 +++---
> tools/testing/selftests/kvm/include/x86_64/svm.h | 4 ++--
> tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c | 2 +-
> 8 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
> index 4c4f81daf5a2..f7a431bcb2c3 100644
> --- a/arch/x86/include/asm/hyperv-tlfs.h
> +++ b/arch/x86/include/asm/hyperv-tlfs.h
> @@ -588,7 +588,7 @@ struct hv_enlightened_vmcs {
> * Hyper-V uses the software reserved 32 bytes in VMCB control area to expose
> * SVM enlightenments to guests.
> */
> -struct hv_enlightenments {
> +struct hv_vmcb_enlightenments {
> struct __packed hv_enlightenments_control {
> u32 nested_flush_hypercall:1;
> u32 msr_bitmap:1;
> diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
> index 6befed2b30a6..621f064bb7cc 100644
> --- a/arch/x86/include/asm/svm.h
> +++ b/arch/x86/include/asm/svm.h
> @@ -164,7 +164,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
> * for use by hypervisor/software.
> */
> union {
> - struct hv_enlightenments hv_enlightenments;
> + struct hv_vmcb_enlightenments hv_enlightenments;
> u8 reserved_sw[32];
> };
> };
> diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
> index a6a87d9743ce..bc9fb4dbf0ae 100644
> --- a/arch/x86/kvm/svm/nested.c
> +++ b/arch/x86/kvm/svm/nested.c
> @@ -201,7 +201,7 @@ void recalc_intercepts(struct vcpu_svm *svm)
> */
> static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
> {
> - struct hv_enlightenments *hve = &svm->nested.ctl.hv_enlightenments;
> + struct hv_vmcb_enlightenments *hve = &svm->nested.ctl.hv_enlightenments;
> int i;
>
> /*
> diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
> index 9eb2fc76732f..5e1178bc9a64 100644
> --- a/arch/x86/kvm/svm/svm.h
> +++ b/arch/x86/kvm/svm/svm.h
> @@ -152,7 +152,7 @@ struct vmcb_ctrl_area_cached {
> u64 virt_ext;
> u32 clean;
> union {
> - struct hv_enlightenments hv_enlightenments;
> + struct hv_vmcb_enlightenments hv_enlightenments;
> u8 reserved_sw[32];
> };
> };
> diff --git a/arch/x86/kvm/svm/svm_onhyperv.c b/arch/x86/kvm/svm/svm_onhyperv.c
> index 5d4036611a37..0b657c7cd21b 100644
> --- a/arch/x86/kvm/svm/svm_onhyperv.c
> +++ b/arch/x86/kvm/svm/svm_onhyperv.c
> @@ -16,7 +16,7 @@
>
> int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu)
> {
> - struct hv_enlightenments *hve;
> + struct hv_vmcb_enlightenments *hve;
> struct hv_partition_assist_pg **p_hv_pa_pg =
> &to_kvm_hv(vcpu->kvm)->hv_pa_pg;
>
> diff --git a/arch/x86/kvm/svm/svm_onhyperv.h
> b/arch/x86/kvm/svm/svm_onhyperv.h
> index c8f8045305be..e08cd7192559 100644
> --- a/arch/x86/kvm/svm/svm_onhyperv.h
> +++ b/arch/x86/kvm/svm/svm_onhyperv.h
> @@ -18,7 +18,7 @@ int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu);
>
> static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
> {
> - struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
> + struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
>
> BUILD_BUG_ON(sizeof(vmcb->control.hv_enlightenments) !=
> sizeof(vmcb->control.reserved_sw));
> @@ -63,7 +63,7 @@ static inline void svm_hv_vmcb_dirty_nested_enlightenments(
> struct kvm_vcpu *vcpu)
> {
> struct vmcb *vmcb = to_svm(vcpu)->vmcb;
> - struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
> + struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
>
> if (hve->hv_enlightenments_control.msr_bitmap)
> vmcb_mark_dirty(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS);
> @@ -71,7 +71,7 @@ static inline void svm_hv_vmcb_dirty_nested_enlightenments(
>
> static inline void svm_hv_update_vp_id(struct vmcb *vmcb, struct kvm_vcpu *vcpu)
> {
> - struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
> + struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
> u32 vp_index = kvm_hv_get_vpindex(vcpu);
>
> if (hve->hv_vp_id != vp_index) {
> diff --git a/tools/testing/selftests/kvm/include/x86_64/svm.h
> b/tools/testing/selftests/kvm/include/x86_64/svm.h
> index 0c32549c6b64..49292190c219 100644
> --- a/tools/testing/selftests/kvm/include/x86_64/svm.h
> +++ b/tools/testing/selftests/kvm/include/x86_64/svm.h
> @@ -58,7 +58,7 @@ enum {
> INTERCEPT_RDPRU,
> };
>
> -struct hv_enlightenments {
> +struct hv_vmcb_enlightenments {
> struct __packed hv_enlightenments_control {
> u32 nested_flush_hypercall:1;
> u32 msr_bitmap:1;
> @@ -124,7 +124,7 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
> * for use by hypervisor/software.
> */
> union {
> - struct hv_enlightenments hv_enlightenments;
> + struct hv_vmcb_enlightenments hv_enlightenments;
> u8 reserved_sw[32];
> };
> };
> diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
> b/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
> index 81b204ee509a..f8e43c798c86 100644
> --- a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
> +++ b/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
> @@ -46,7 +46,7 @@ static void __attribute__((__flatten__)) guest_code(struct
> svm_test_data *svm)
> {
> unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
> struct vmcb *vmcb = svm->vmcb;
> - struct hv_enlightenments *hve = &vmcb->control.hv_enlightenments;
> + struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
>
> GUEST_SYNC(1);
>
> --
> 2.37.3.968.ga6b4b080e4-goog
Reviewed-by: Michael Kelley <[email protected]>
Sean Christopherson <[email protected]> writes:
> On Thu, Sep 22, 2022, Michael Kelley (LINUX) wrote:
>> From: Sean Christopherson <[email protected]> Sent: Wednesday, September 21, 2022 1:16 PM
>> >
>> > Move Hyper-V's VMCB enlightenment definitions to the TLFS header; the
>> > definitions come directly from the TLFS[*], not from KVM.
>> >
>> > No functional change intended.
>> >
>> > [*] https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/datatypes/hv_svm_enlightened_vmcb_fields>
>> > Signed-off-by: Sean Christopherson <[email protected]>
>> > ---
>> > arch/x86/include/asm/hyperv-tlfs.h | 22 +++++++++++++++++++
>> > arch/x86/kvm/svm/hyperv.h | 35 ------------------------------
>> > arch/x86/kvm/svm/svm_onhyperv.h | 3 ++-
>> > 3 files changed, 24 insertions(+), 36 deletions(-)
>> > delete mode 100644 arch/x86/kvm/svm/hyperv.h
>> >
>> > diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
>> > index 0a9407dc0859..4c4f81daf5a2 100644
>> > --- a/arch/x86/include/asm/hyperv-tlfs.h
>> > +++ b/arch/x86/include/asm/hyperv-tlfs.h
>> > @@ -584,6 +584,28 @@ struct hv_enlightened_vmcs {
>> >
>> > #define HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL 0xFFFF
>> >
>> > +/*
>> > + * Hyper-V uses the software reserved 32 bytes in VMCB control area to expose
>> > + * SVM enlightenments to guests.
>> > + */
>> > +struct hv_enlightenments {
>> > + struct __packed hv_enlightenments_control {
>> > + u32 nested_flush_hypercall:1;
>> > + u32 msr_bitmap:1;
>> > + u32 enlightened_npt_tlb: 1;
>> > + u32 reserved:29;
>> > + } __packed hv_enlightenments_control;
>> > + u32 hv_vp_id;
>> > + u64 hv_vm_id;
>> > + u64 partition_assist_page;
>> > + u64 reserved;
>> > +} __packed;
>> > +
>> > +/*
>> > + * Hyper-V uses the software reserved clean bit in VMCB.
>> > + */
>> > +#define VMCB_HV_NESTED_ENLIGHTENMENTS 31
>>
>> Is it feasible to change this identifier so it starts with HV_ like
>> everything else in this source code file, such as
>> HV_VMCB_NESTED_ENLIGHTENMENTS? It doesn't look like it is
>> used in very many places.
>
> Most definitely, IIRC it's used in only one spot.
>
I'll take these 4 patches to the next iteration of my "KVM: x86:
hyper-v: Fine-grained TLB flush + L2 TLB flush features" series and I'll
change VMCB_HV_NESTED_ENLIGHTENMENTS to HV_VMCB_NESTED_ENLIGHTENMENTS.
--
Vitaly