]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Mon, 17 Apr 2023 03:42:08 +0000 (23:42 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 17 Apr 2023 03:42:08 +0000 (23:42 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.1/kvm-selftests-move-struct-hv_enlightenments-to-x86_6.patch [new file with mode: 0644]
queue-6.1/kvm-svm-add-a-proper-field-for-hyper-v-vmcb-enlighte.patch [new file with mode: 0644]
queue-6.1/kvm-svm-flush-hyper-v-tlb-when-required.patch [new file with mode: 0644]
queue-6.1/maple_tree-fix-write-memory-barrier-of-nodes-once-de.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/tracing-add-trace_array_puts-to-write-into-instance.patch [new file with mode: 0644]
queue-6.1/tracing-have-tracing_snapshot_instance_cond-write-er.patch [new file with mode: 0644]
queue-6.1/x86-hyperv-kvm-rename-hv_enlightenments-to-hv_vmcb_e.patch [new file with mode: 0644]
queue-6.1/x86-hyperv-move-vmcb-enlightenment-definitions-to-hy.patch [new file with mode: 0644]

diff --git a/queue-6.1/kvm-selftests-move-struct-hv_enlightenments-to-x86_6.patch b/queue-6.1/kvm-selftests-move-struct-hv_enlightenments-to-x86_6.patch
new file mode 100644 (file)
index 0000000..cbfef2a
--- /dev/null
@@ -0,0 +1,89 @@
+From 24089f547ed75b412c082c3dac07b48006c06d0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 15:53:40 +0100
+Subject: KVM: selftests: Move "struct hv_enlightenments" to x86_64/svm.h
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 381fc63ac0754e05d3921e9d399b89dfdfd2b2e5 ]
+
+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 <seanjc@google.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Message-Id: <20221101145426.251680-3-vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Stable-dep-of: e5c972c1fada ("KVM: SVM: Flush Hyper-V TLB when required")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../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 c8343ff84f7f7..89ce2c6b57fe0 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 HV_VMCB_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 5060fcfe17601..2fd64b419928a 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 HV_VMCB_NESTED_ENLIGHTENMENTS (1U << 31)
+-
+ void l2_guest_code(void)
+ {
+       GUEST_SYNC(3);
+-- 
+2.39.2
+
diff --git a/queue-6.1/kvm-svm-add-a-proper-field-for-hyper-v-vmcb-enlighte.patch b/queue-6.1/kvm-svm-add-a-proper-field-for-hyper-v-vmcb-enlighte.patch
new file mode 100644 (file)
index 0000000..e7e482c
--- /dev/null
@@ -0,0 +1,192 @@
+From 2e0f436fe7c846ca3ca98281192528457276d453 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 15:53:41 +0100
+Subject: KVM: SVM: Add a proper field for Hyper-V VMCB enlightenments
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 68ae7c7bc56a4504ed5efde7c2f8d6024148a35e ]
+
+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 <seanjc@google.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Message-Id: <20221101145426.251680-4-vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Stable-dep-of: e5c972c1fada ("KVM: SVM: Flush Hyper-V TLB when required")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 236fda748ae96..98724e7c7a6e8 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 0be104ec79d96..eb5792367cc6b 100644
+--- a/arch/x86/kvm/svm/nested.c
++++ b/arch/x86/kvm/svm/nested.c
+@@ -179,8 +179,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;
+       /*
+@@ -369,8 +368,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 bbc061f3a2b37..e7a22e45a7d33 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 ed5e793925441..422d00fee24ab 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 35d69815d2f3a..51030df538ef5 100644
+--- a/arch/x86/kvm/svm/svm_onhyperv.h
++++ b/arch/x86/kvm/svm/svm_onhyperv.h
+@@ -17,8 +17,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)
+@@ -60,18 +62,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, HV_VMCB_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 89ce2c6b57fe0..6e1527aa34191 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 2fd64b419928a..8ef6a4c83cb1e 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.39.2
+
diff --git a/queue-6.1/kvm-svm-flush-hyper-v-tlb-when-required.patch b/queue-6.1/kvm-svm-flush-hyper-v-tlb-when-required.patch
new file mode 100644 (file)
index 0000000..dabc91f
--- /dev/null
@@ -0,0 +1,167 @@
+From a593b85e4647732d9ca07665131bf0248ed2e46c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Mar 2023 15:52:33 +0100
+Subject: KVM: SVM: Flush Hyper-V TLB when required
+
+From: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
+
+[ Upstream commit e5c972c1fadacc858b6a564d056f177275238040 ]
+
+The Hyper-V "EnlightenedNptTlb" enlightenment is always enabled when KVM
+is running on top of Hyper-V and Hyper-V exposes support for it (which
+is always). On AMD CPUs this enlightenment results in ASID invalidations
+not flushing TLB entries derived from the NPT. To force the underlying
+(L0) hypervisor to rebuild its shadow page tables, an explicit hypercall
+is needed.
+
+The original KVM implementation of Hyper-V's "EnlightenedNptTlb" on SVM
+only added remote TLB flush hooks. This worked out fine for a while, as
+sufficient remote TLB flushes where being issued in KVM to mask the
+problem. Since v5.17, changes in the TDP code reduced the number of
+flushes and the out-of-sync TLB prevents guests from booting
+successfully.
+
+Split svm_flush_tlb_current() into separate callbacks for the 3 cases
+(guest/all/current), and issue the required Hyper-V hypercall when a
+Hyper-V TLB flush is needed. The most important case where the TLB flush
+was missing is when loading a new PGD, which is followed by what is now
+svm_flush_tlb_current().
+
+Cc: stable@vger.kernel.org # v5.17+
+Fixes: 1e0c7d40758b ("KVM: SVM: hyper-v: Remote TLB flush for SVM")
+Link: https://lore.kernel.org/lkml/43980946-7bbf-dcef-7e40-af904c456250@linux.microsoft.com/
+Suggested-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>
+Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Message-Id: <20230324145233.4585-1-jpiotrowski@linux.microsoft.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/kvm_onhyperv.h     |  5 +++++
+ arch/x86/kvm/svm/svm.c          | 37 ++++++++++++++++++++++++++++++---
+ arch/x86/kvm/svm/svm_onhyperv.h | 15 +++++++++++++
+ 3 files changed, 54 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/kvm/kvm_onhyperv.h b/arch/x86/kvm/kvm_onhyperv.h
+index 287e98ef9df3d..6272dabec02da 100644
+--- a/arch/x86/kvm/kvm_onhyperv.h
++++ b/arch/x86/kvm/kvm_onhyperv.h
+@@ -12,6 +12,11 @@ int hv_remote_flush_tlb_with_range(struct kvm *kvm,
+ int hv_remote_flush_tlb(struct kvm *kvm);
+ void hv_track_root_tdp(struct kvm_vcpu *vcpu, hpa_t root_tdp);
+ #else /* !CONFIG_HYPERV */
++static inline int hv_remote_flush_tlb(struct kvm *kvm)
++{
++      return -EOPNOTSUPP;
++}
++
+ static inline void hv_track_root_tdp(struct kvm_vcpu *vcpu, hpa_t root_tdp)
+ {
+ }
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index 3629dd979667c..9599931c7d572 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -3719,7 +3719,7 @@ static void svm_enable_nmi_window(struct kvm_vcpu *vcpu)
+       svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
+ }
+-static void svm_flush_tlb_current(struct kvm_vcpu *vcpu)
++static void svm_flush_tlb_asid(struct kvm_vcpu *vcpu)
+ {
+       struct vcpu_svm *svm = to_svm(vcpu);
+@@ -3736,6 +3736,37 @@ static void svm_flush_tlb_current(struct kvm_vcpu *vcpu)
+               svm->current_vmcb->asid_generation--;
+ }
++static void svm_flush_tlb_current(struct kvm_vcpu *vcpu)
++{
++      hpa_t root_tdp = vcpu->arch.mmu->root.hpa;
++
++      /*
++       * When running on Hyper-V with EnlightenedNptTlb enabled, explicitly
++       * flush the NPT mappings via hypercall as flushing the ASID only
++       * affects virtual to physical mappings, it does not invalidate guest
++       * physical to host physical mappings.
++       */
++      if (svm_hv_is_enlightened_tlb_enabled(vcpu) && VALID_PAGE(root_tdp))
++              hyperv_flush_guest_mapping(root_tdp);
++
++      svm_flush_tlb_asid(vcpu);
++}
++
++static void svm_flush_tlb_all(struct kvm_vcpu *vcpu)
++{
++      /*
++       * When running on Hyper-V with EnlightenedNptTlb enabled, remote TLB
++       * flushes should be routed to hv_remote_flush_tlb() without requesting
++       * a "regular" remote flush.  Reaching this point means either there's
++       * a KVM bug or a prior hv_remote_flush_tlb() call failed, both of
++       * which might be fatal to the guest.  Yell, but try to recover.
++       */
++      if (WARN_ON_ONCE(svm_hv_is_enlightened_tlb_enabled(vcpu)))
++              hv_remote_flush_tlb(vcpu->kvm);
++
++      svm_flush_tlb_asid(vcpu);
++}
++
+ static void svm_flush_tlb_gva(struct kvm_vcpu *vcpu, gva_t gva)
+ {
+       struct vcpu_svm *svm = to_svm(vcpu);
+@@ -4733,10 +4764,10 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
+       .set_rflags = svm_set_rflags,
+       .get_if_flag = svm_get_if_flag,
+-      .flush_tlb_all = svm_flush_tlb_current,
++      .flush_tlb_all = svm_flush_tlb_all,
+       .flush_tlb_current = svm_flush_tlb_current,
+       .flush_tlb_gva = svm_flush_tlb_gva,
+-      .flush_tlb_guest = svm_flush_tlb_current,
++      .flush_tlb_guest = svm_flush_tlb_asid,
+       .vcpu_pre_run = svm_vcpu_pre_run,
+       .vcpu_run = svm_vcpu_run,
+diff --git a/arch/x86/kvm/svm/svm_onhyperv.h b/arch/x86/kvm/svm/svm_onhyperv.h
+index 780b6c09cfe4b..9a6a34149919c 100644
+--- a/arch/x86/kvm/svm/svm_onhyperv.h
++++ b/arch/x86/kvm/svm/svm_onhyperv.h
+@@ -6,6 +6,8 @@
+ #ifndef __ARCH_X86_KVM_SVM_ONHYPERV_H__
+ #define __ARCH_X86_KVM_SVM_ONHYPERV_H__
++#include <asm/mshyperv.h>
++
+ #if IS_ENABLED(CONFIG_HYPERV)
+ #include "kvm_onhyperv.h"
+@@ -15,6 +17,14 @@ static struct kvm_x86_ops svm_x86_ops;
+ int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu);
++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;
++}
++
+ static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
+ {
+       struct hv_vmcb_enlightenments *hve = &vmcb->control.hv_enlightenments;
+@@ -80,6 +90,11 @@ static inline void svm_hv_update_vp_id(struct vmcb *vmcb, struct kvm_vcpu *vcpu)
+ }
+ #else
++static inline bool svm_hv_is_enlightened_tlb_enabled(struct kvm_vcpu *vcpu)
++{
++      return false;
++}
++
+ static inline void svm_hv_init_vmcb(struct vmcb *vmcb)
+ {
+ }
+-- 
+2.39.2
+
diff --git a/queue-6.1/maple_tree-fix-write-memory-barrier-of-nodes-once-de.patch b/queue-6.1/maple_tree-fix-write-memory-barrier-of-nodes-once-de.patch
new file mode 100644 (file)
index 0000000..9c5832d
--- /dev/null
@@ -0,0 +1,194 @@
+From 076263ac1ca5bada4cd4e4426f0bc7ce5936290e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 27 Feb 2023 09:36:04 -0800
+Subject: maple_tree: fix write memory barrier of nodes once dead for RCU mode
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+[ Upstream commit c13af03de46ba27674dd9fb31a17c0d480081139 ]
+
+During the development of the maple tree, the strategy of freeing multiple
+nodes changed and, in the process, the pivots were reused to store
+pointers to dead nodes.  To ensure the readers see accurate pivots, the
+writers need to mark the nodes as dead and call smp_wmb() to ensure any
+readers can identify the node as dead before using the pivot values.
+
+There were two places where the old method of marking the node as dead
+without smp_wmb() were being used, which resulted in RCU readers seeing
+the wrong pivot value before seeing the node was dead.  Fix this race
+condition by using mte_set_node_dead() which has the smp_wmb() call to
+ensure the race is closed.
+
+Add a WARN_ON() to the ma_free_rcu() call to ensure all nodes being freed
+are marked as dead to ensure there are no other call paths besides the two
+updated paths.
+
+This is necessary for the RCU mode of the maple tree.
+
+Link: https://lkml.kernel.org/r/20230227173632.3292573-6-surenb@google.com
+Fixes: 54a611b60590 ("Maple Tree: add new data structure")
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Signed-off-by: Suren Baghdasaryan <surenb@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/maple_tree.c                 |  7 +++++--
+ tools/testing/radix-tree/maple.c | 16 ++++++++++++++++
+ 2 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/lib/maple_tree.c b/lib/maple_tree.c
+index 84530fb73bd9e..39f34ea7a9be5 100644
+--- a/lib/maple_tree.c
++++ b/lib/maple_tree.c
+@@ -178,7 +178,7 @@ static void mt_free_rcu(struct rcu_head *head)
+  */
+ static void ma_free_rcu(struct maple_node *node)
+ {
+-      node->parent = ma_parent_ptr(node);
++      WARN_ON(node->parent != ma_parent_ptr(node));
+       call_rcu(&node->rcu, mt_free_rcu);
+ }
+@@ -1780,8 +1780,10 @@ static inline void mas_replace(struct ma_state *mas, bool advanced)
+               rcu_assign_pointer(slots[offset], mas->node);
+       }
+-      if (!advanced)
++      if (!advanced) {
++              mte_set_node_dead(old_enode);
+               mas_free(mas, old_enode);
++      }
+ }
+ /*
+@@ -4216,6 +4218,7 @@ static inline bool mas_wr_node_store(struct ma_wr_state *wr_mas)
+ done:
+       mas_leaf_set_meta(mas, newnode, dst_pivots, maple_leaf_64, new_end);
+       if (in_rcu) {
++              mte_set_node_dead(mas->node);
+               mas->node = mt_mk_node(newnode, wr_mas->type);
+               mas_replace(mas, false);
+       } else {
+diff --git a/tools/testing/radix-tree/maple.c b/tools/testing/radix-tree/maple.c
+index aceb6011315c2..18e319e6ce335 100644
+--- a/tools/testing/radix-tree/maple.c
++++ b/tools/testing/radix-tree/maple.c
+@@ -107,6 +107,7 @@ static noinline void check_new_node(struct maple_tree *mt)
+       MT_BUG_ON(mt, mn->slot[1] != NULL);
+       MT_BUG_ON(mt, mas_allocated(&mas) != 0);
++      mn->parent = ma_parent_ptr(mn);
+       ma_free_rcu(mn);
+       mas.node = MAS_START;
+       mas_nomem(&mas, GFP_KERNEL);
+@@ -159,6 +160,7 @@ static noinline void check_new_node(struct maple_tree *mt)
+               MT_BUG_ON(mt, mas_allocated(&mas) != i);
+               MT_BUG_ON(mt, !mn);
+               MT_BUG_ON(mt, not_empty(mn));
++              mn->parent = ma_parent_ptr(mn);
+               ma_free_rcu(mn);
+       }
+@@ -191,6 +193,7 @@ static noinline void check_new_node(struct maple_tree *mt)
+               MT_BUG_ON(mt, not_empty(mn));
+               MT_BUG_ON(mt, mas_allocated(&mas) != i - 1);
+               MT_BUG_ON(mt, !mn);
++              mn->parent = ma_parent_ptr(mn);
+               ma_free_rcu(mn);
+       }
+@@ -209,6 +212,7 @@ static noinline void check_new_node(struct maple_tree *mt)
+                       mn = mas_pop_node(&mas);
+                       MT_BUG_ON(mt, not_empty(mn));
+                       MT_BUG_ON(mt, mas_allocated(&mas) != j - 1);
++                      mn->parent = ma_parent_ptr(mn);
+                       ma_free_rcu(mn);
+               }
+               MT_BUG_ON(mt, mas_allocated(&mas) != 0);
+@@ -232,6 +236,7 @@ static noinline void check_new_node(struct maple_tree *mt)
+                       MT_BUG_ON(mt, mas_allocated(&mas) != i - j);
+                       mn = mas_pop_node(&mas);
+                       MT_BUG_ON(mt, not_empty(mn));
++                      mn->parent = ma_parent_ptr(mn);
+                       ma_free_rcu(mn);
+                       MT_BUG_ON(mt, mas_allocated(&mas) != i - j - 1);
+               }
+@@ -268,6 +273,7 @@ static noinline void check_new_node(struct maple_tree *mt)
+                       mn = mas_pop_node(&mas); /* get the next node. */
+                       MT_BUG_ON(mt, mn == NULL);
+                       MT_BUG_ON(mt, not_empty(mn));
++                      mn->parent = ma_parent_ptr(mn);
+                       ma_free_rcu(mn);
+               }
+               MT_BUG_ON(mt, mas_allocated(&mas) != 0);
+@@ -293,6 +299,7 @@ static noinline void check_new_node(struct maple_tree *mt)
+                       mn = mas_pop_node(&mas2); /* get the next node. */
+                       MT_BUG_ON(mt, mn == NULL);
+                       MT_BUG_ON(mt, not_empty(mn));
++                      mn->parent = ma_parent_ptr(mn);
+                       ma_free_rcu(mn);
+               }
+               MT_BUG_ON(mt, mas_allocated(&mas2) != 0);
+@@ -333,10 +340,12 @@ static noinline void check_new_node(struct maple_tree *mt)
+       MT_BUG_ON(mt, mas_allocated(&mas) != MAPLE_ALLOC_SLOTS + 2);
+       mn = mas_pop_node(&mas);
+       MT_BUG_ON(mt, not_empty(mn));
++      mn->parent = ma_parent_ptr(mn);
+       ma_free_rcu(mn);
+       for (i = 1; i <= MAPLE_ALLOC_SLOTS + 1; i++) {
+               mn = mas_pop_node(&mas);
+               MT_BUG_ON(mt, not_empty(mn));
++              mn->parent = ma_parent_ptr(mn);
+               ma_free_rcu(mn);
+       }
+       MT_BUG_ON(mt, mas_allocated(&mas) != 0);
+@@ -374,6 +383,7 @@ static noinline void check_new_node(struct maple_tree *mt)
+               mas_node_count(&mas, i); /* Request */
+               mas_nomem(&mas, GFP_KERNEL); /* Fill request */
+               mn = mas_pop_node(&mas); /* get the next node. */
++              mn->parent = ma_parent_ptr(mn);
+               ma_free_rcu(mn);
+               mas_destroy(&mas);
+@@ -381,10 +391,13 @@ static noinline void check_new_node(struct maple_tree *mt)
+               mas_node_count(&mas, i); /* Request */
+               mas_nomem(&mas, GFP_KERNEL); /* Fill request */
+               mn = mas_pop_node(&mas); /* get the next node. */
++              mn->parent = ma_parent_ptr(mn);
+               ma_free_rcu(mn);
+               mn = mas_pop_node(&mas); /* get the next node. */
++              mn->parent = ma_parent_ptr(mn);
+               ma_free_rcu(mn);
+               mn = mas_pop_node(&mas); /* get the next node. */
++              mn->parent = ma_parent_ptr(mn);
+               ma_free_rcu(mn);
+               mas_destroy(&mas);
+       }
+@@ -35368,6 +35381,7 @@ static noinline void check_prealloc(struct maple_tree *mt)
+       MT_BUG_ON(mt, allocated != 1 + height * 3);
+       mn = mas_pop_node(&mas);
+       MT_BUG_ON(mt, mas_allocated(&mas) != allocated - 1);
++      mn->parent = ma_parent_ptr(mn);
+       ma_free_rcu(mn);
+       MT_BUG_ON(mt, mas_preallocate(&mas, ptr, GFP_KERNEL) != 0);
+       mas_destroy(&mas);
+@@ -35385,6 +35399,7 @@ static noinline void check_prealloc(struct maple_tree *mt)
+       mas_destroy(&mas);
+       allocated = mas_allocated(&mas);
+       MT_BUG_ON(mt, allocated != 0);
++      mn->parent = ma_parent_ptr(mn);
+       ma_free_rcu(mn);
+       MT_BUG_ON(mt, mas_preallocate(&mas, ptr, GFP_KERNEL) != 0);
+@@ -35755,6 +35770,7 @@ void farmer_tests(void)
+       tree.ma_root = mt_mk_node(node, maple_leaf_64);
+       mt_dump(&tree);
++      node->parent = ma_parent_ptr(node);
+       ma_free_rcu(node);
+       /* Check things that will make lockdep angry */
+-- 
+2.39.2
+
index 18f418a265ed9e4998f73f552b9ddc0fab915233..9f125f9987ada705cacc99b354225f475f38df6b 100644 (file)
@@ -91,3 +91,11 @@ drm-amdgpu-add-mes-resume-when-do-gfx-post-soft-rese.patch
 drm-amdgpu-force-signal-hw_fences-that-are-embedded-.patch
 drm-amdgpu-gfx-set-cg-flags-to-enter-exit-safe-mode.patch
 acpi-resource-add-medion-s17413-to-irq-override-quir.patch
+x86-hyperv-move-vmcb-enlightenment-definitions-to-hy.patch
+kvm-selftests-move-struct-hv_enlightenments-to-x86_6.patch
+kvm-svm-add-a-proper-field-for-hyper-v-vmcb-enlighte.patch
+x86-hyperv-kvm-rename-hv_enlightenments-to-hv_vmcb_e.patch
+kvm-svm-flush-hyper-v-tlb-when-required.patch
+tracing-add-trace_array_puts-to-write-into-instance.patch
+tracing-have-tracing_snapshot_instance_cond-write-er.patch
+maple_tree-fix-write-memory-barrier-of-nodes-once-de.patch
diff --git a/queue-6.1/tracing-add-trace_array_puts-to-write-into-instance.patch b/queue-6.1/tracing-add-trace_array_puts-to-write-into-instance.patch
new file mode 100644 (file)
index 0000000..52d716a
--- /dev/null
@@ -0,0 +1,115 @@
+From 9161c22f8b17c21dd855201a2bcacf28ab4eb366 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Feb 2023 12:28:52 -0500
+Subject: tracing: Add trace_array_puts() to write into instance
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit d503b8f7474fe7ac616518f7fc49773cbab49f36 ]
+
+Add a generic trace_array_puts() that can be used to "trace_puts()" into
+an allocated trace_array instance. This is just another variant of
+trace_array_printk().
+
+Link: https://lkml.kernel.org/r/20230207173026.584717290@goodmis.org
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Reviewed-by: Ross Zwisler <zwisler@google.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Stable-dep-of: 9d52727f8043 ("tracing: Have tracing_snapshot_instance_cond() write errors to the appropriate instance")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/trace.h | 12 ++++++++++++
+ kernel/trace/trace.c  | 27 +++++++++++++++++----------
+ 2 files changed, 29 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/trace.h b/include/linux/trace.h
+index 80ffda8717491..2a70a447184c9 100644
+--- a/include/linux/trace.h
++++ b/include/linux/trace.h
+@@ -33,6 +33,18 @@ struct trace_array;
+ int register_ftrace_export(struct trace_export *export);
+ int unregister_ftrace_export(struct trace_export *export);
++/**
++ * trace_array_puts - write a constant string into the trace buffer.
++ * @tr:    The trace array to write to
++ * @str:   The constant string to write
++ */
++#define trace_array_puts(tr, str)                                     \
++      ({                                                              \
++              str ? __trace_array_puts(tr, _THIS_IP_, str, strlen(str)) : -1; \
++      })
++int __trace_array_puts(struct trace_array *tr, unsigned long ip,
++                     const char *str, int size);
++
+ void trace_printk_init_buffers(void);
+ __printf(3, 4)
+ int trace_array_printk(struct trace_array *tr, unsigned long ip,
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 78855e74e355f..5016ae826c463 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1002,13 +1002,8 @@ __buffer_unlock_commit(struct trace_buffer *buffer, struct ring_buffer_event *ev
+               ring_buffer_unlock_commit(buffer, event);
+ }
+-/**
+- * __trace_puts - write a constant string into the trace buffer.
+- * @ip:          The address of the caller
+- * @str:   The constant string to write
+- * @size:  The size of the string.
+- */
+-int __trace_puts(unsigned long ip, const char *str, int size)
++int __trace_array_puts(struct trace_array *tr, unsigned long ip,
++                     const char *str, int size)
+ {
+       struct ring_buffer_event *event;
+       struct trace_buffer *buffer;
+@@ -1016,7 +1011,7 @@ int __trace_puts(unsigned long ip, const char *str, int size)
+       unsigned int trace_ctx;
+       int alloc;
+-      if (!(global_trace.trace_flags & TRACE_ITER_PRINTK))
++      if (!(tr->trace_flags & TRACE_ITER_PRINTK))
+               return 0;
+       if (unlikely(tracing_selftest_running || tracing_disabled))
+@@ -1025,7 +1020,7 @@ int __trace_puts(unsigned long ip, const char *str, int size)
+       alloc = sizeof(*entry) + size + 2; /* possible \n added */
+       trace_ctx = tracing_gen_ctx();
+-      buffer = global_trace.array_buffer.buffer;
++      buffer = tr->array_buffer.buffer;
+       ring_buffer_nest_start(buffer);
+       event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc,
+                                           trace_ctx);
+@@ -1047,11 +1042,23 @@ int __trace_puts(unsigned long ip, const char *str, int size)
+               entry->buf[size] = '\0';
+       __buffer_unlock_commit(buffer, event);
+-      ftrace_trace_stack(&global_trace, buffer, trace_ctx, 4, NULL);
++      ftrace_trace_stack(tr, buffer, trace_ctx, 4, NULL);
+  out:
+       ring_buffer_nest_end(buffer);
+       return size;
+ }
++EXPORT_SYMBOL_GPL(__trace_array_puts);
++
++/**
++ * __trace_puts - write a constant string into the trace buffer.
++ * @ip:          The address of the caller
++ * @str:   The constant string to write
++ * @size:  The size of the string.
++ */
++int __trace_puts(unsigned long ip, const char *str, int size)
++{
++      return __trace_array_puts(&global_trace, ip, str, size);
++}
+ EXPORT_SYMBOL_GPL(__trace_puts);
+ /**
+-- 
+2.39.2
+
diff --git a/queue-6.1/tracing-have-tracing_snapshot_instance_cond-write-er.patch b/queue-6.1/tracing-have-tracing_snapshot_instance_cond-write-er.patch
new file mode 100644 (file)
index 0000000..55264ec
--- /dev/null
@@ -0,0 +1,66 @@
+From 7956504631f26c0095dcbcf778b2b9fff45712cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Apr 2023 22:21:14 -0400
+Subject: tracing: Have tracing_snapshot_instance_cond() write errors to the
+ appropriate instance
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit 9d52727f8043cfda241ae96896628d92fa9c50bb ]
+
+If a trace instance has a failure with its snapshot code, the error
+message is to be written to that instance's buffer. But currently, the
+message is written to the top level buffer. Worse yet, it may also disable
+the top level buffer and not the instance that had the issue.
+
+Link: https://lkml.kernel.org/r/20230405022341.688730321@goodmis.org
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ross Zwisler <zwisler@google.com>
+Fixes: 2824f50332486 ("tracing: Make the snapshot trigger work with instances")
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 5016ae826c463..3360d638071a1 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1112,22 +1112,22 @@ static void tracing_snapshot_instance_cond(struct trace_array *tr,
+       unsigned long flags;
+       if (in_nmi()) {
+-              internal_trace_puts("*** SNAPSHOT CALLED FROM NMI CONTEXT ***\n");
+-              internal_trace_puts("*** snapshot is being ignored        ***\n");
++              trace_array_puts(tr, "*** SNAPSHOT CALLED FROM NMI CONTEXT ***\n");
++              trace_array_puts(tr, "*** snapshot is being ignored        ***\n");
+               return;
+       }
+       if (!tr->allocated_snapshot) {
+-              internal_trace_puts("*** SNAPSHOT NOT ALLOCATED ***\n");
+-              internal_trace_puts("*** stopping trace here!   ***\n");
+-              tracing_off();
++              trace_array_puts(tr, "*** SNAPSHOT NOT ALLOCATED ***\n");
++              trace_array_puts(tr, "*** stopping trace here!   ***\n");
++              tracer_tracing_off(tr);
+               return;
+       }
+       /* Note, snapshot can not be used when the tracer uses it */
+       if (tracer->use_max_tr) {
+-              internal_trace_puts("*** LATENCY TRACER ACTIVE ***\n");
+-              internal_trace_puts("*** Can not use snapshot (sorry) ***\n");
++              trace_array_puts(tr, "*** LATENCY TRACER ACTIVE ***\n");
++              trace_array_puts(tr, "*** Can not use snapshot (sorry) ***\n");
+               return;
+       }
+-- 
+2.39.2
+
diff --git a/queue-6.1/x86-hyperv-kvm-rename-hv_enlightenments-to-hv_vmcb_e.patch b/queue-6.1/x86-hyperv-kvm-rename-hv_enlightenments-to-hv_vmcb_e.patch
new file mode 100644 (file)
index 0000000..5a2c9c1
--- /dev/null
@@ -0,0 +1,169 @@
+From 4a12e7119acd99a4e4355d646c47d0f02fb9bafc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 15:53:42 +0100
+Subject: x86/hyperv: KVM: Rename "hv_enlightenments" to
+ "hv_vmcb_enlightenments"
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 26b516bb39215cf60aa1fb55d0a6fd73058698fa ]
+
+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 <seanjc@google.com>
+Reviewed-by: Michael Kelley <mikelley@microsoft.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Message-Id: <20221101145426.251680-5-vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Stable-dep-of: e5c972c1fada ("KVM: SVM: Flush Hyper-V TLB when required")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 245a806a97170..c5e0e5a06c0dc 100644
+--- a/arch/x86/include/asm/hyperv-tlfs.h
++++ b/arch/x86/include/asm/hyperv-tlfs.h
+@@ -602,7 +602,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 98724e7c7a6e8..02aac78cb21d4 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 eb5792367cc6b..92268645a5fed 100644
+--- a/arch/x86/kvm/svm/nested.c
++++ b/arch/x86/kvm/svm/nested.c
+@@ -179,7 +179,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 e7a22e45a7d33..d0ed3f5952295 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 422d00fee24ab..52c73a8be72b1 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 51030df538ef5..780b6c09cfe4b 100644
+--- a/arch/x86/kvm/svm/svm_onhyperv.h
++++ b/arch/x86/kvm/svm/svm_onhyperv.h
+@@ -17,7 +17,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));
+@@ -62,7 +62,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, HV_VMCB_NESTED_ENLIGHTENMENTS);
+@@ -70,7 +70,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 6e1527aa34191..483e6ae12f69e 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 8ef6a4c83cb1e..1c3fc38b4f151 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.39.2
+
diff --git a/queue-6.1/x86-hyperv-move-vmcb-enlightenment-definitions-to-hy.patch b/queue-6.1/x86-hyperv-move-vmcb-enlightenment-definitions-to-hy.patch
new file mode 100644 (file)
index 0000000..a388140
--- /dev/null
@@ -0,0 +1,180 @@
+From 8a7d5d16096123536e441bbfa7f3edb41f810b51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Nov 2022 15:53:39 +0100
+Subject: x86/hyperv: Move VMCB enlightenment definitions to hyperv-tlfs.h
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit 089fe572a2e0a89e36a455d299d801770293d08f ]
+
+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
+
+[vitaly: rename VMCB_HV_ -> HV_VMCB_ to match the rest of
+hyperv-tlfs.h, keep svm/hyperv.h]
+
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Message-Id: <20221101145426.251680-2-vkuznets@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Stable-dep-of: e5c972c1fada ("KVM: SVM: Flush Hyper-V TLB when required")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/hyperv-tlfs.h            | 22 +++++++++++++++++++
+ arch/x86/kvm/svm/hyperv.h                     | 22 -------------------
+ arch/x86/kvm/svm/nested.c                     |  2 +-
+ arch/x86/kvm/svm/svm_onhyperv.c               |  2 +-
+ arch/x86/kvm/svm/svm_onhyperv.h               |  4 ++--
+ .../selftests/kvm/x86_64/hyperv_svm_test.c    |  6 ++---
+ 6 files changed, 29 insertions(+), 29 deletions(-)
+
+diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
+index 3089ec352743b..245a806a97170 100644
+--- a/arch/x86/include/asm/hyperv-tlfs.h
++++ b/arch/x86/include/asm/hyperv-tlfs.h
+@@ -598,6 +598,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 HV_VMCB_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
+index 7d6d97968fb98..c59544cdf03b7 100644
+--- a/arch/x86/kvm/svm/hyperv.h
++++ b/arch/x86/kvm/svm/hyperv.h
+@@ -10,26 +10,4 @@
+ #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/nested.c b/arch/x86/kvm/svm/nested.c
+index 995bc0f907591..0be104ec79d96 100644
+--- a/arch/x86/kvm/svm/nested.c
++++ b/arch/x86/kvm/svm/nested.c
+@@ -194,7 +194,7 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
+       if (!svm->nested.force_msr_bitmap_recalc &&
+           kvm_hv_hypercall_enabled(&svm->vcpu) &&
+           hve->hv_enlightenments_control.msr_bitmap &&
+-          (svm->nested.ctl.clean & BIT(VMCB_HV_NESTED_ENLIGHTENMENTS)))
++          (svm->nested.ctl.clean & BIT(HV_VMCB_NESTED_ENLIGHTENMENTS)))
+               goto set_msrpm_base_pa;
+       if (!(vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_MSR_PROT)))
+diff --git a/arch/x86/kvm/svm/svm_onhyperv.c b/arch/x86/kvm/svm/svm_onhyperv.c
+index 8cdc62c74a964..ed5e793925441 100644
+--- a/arch/x86/kvm/svm/svm_onhyperv.c
++++ b/arch/x86/kvm/svm/svm_onhyperv.c
+@@ -32,7 +32,7 @@ int svm_hv_enable_direct_tlbflush(struct kvm_vcpu *vcpu)
+       hve->hv_vm_id = (unsigned long)vcpu->kvm;
+       if (!hve->hv_enlightenments_control.nested_flush_hypercall) {
+               hve->hv_enlightenments_control.nested_flush_hypercall = 1;
+-              vmcb_mark_dirty(to_svm(vcpu)->vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS);
++              vmcb_mark_dirty(to_svm(vcpu)->vmcb, HV_VMCB_NESTED_ENLIGHTENMENTS);
+       }
+       return 0;
+diff --git a/arch/x86/kvm/svm/svm_onhyperv.h b/arch/x86/kvm/svm/svm_onhyperv.h
+index 4387173576d5e..35d69815d2f3a 100644
+--- a/arch/x86/kvm/svm/svm_onhyperv.h
++++ b/arch/x86/kvm/svm/svm_onhyperv.h
+@@ -64,7 +64,7 @@ static inline void svm_hv_vmcb_dirty_nested_enlightenments(
+               (struct hv_enlightenments *)vmcb->control.reserved_sw;
+       if (hve->hv_enlightenments_control.msr_bitmap)
+-              vmcb_mark_dirty(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS);
++              vmcb_mark_dirty(vmcb, HV_VMCB_NESTED_ENLIGHTENMENTS);
+ }
+ static inline void svm_hv_update_vp_id(struct vmcb *vmcb,
+@@ -76,7 +76,7 @@ static inline void svm_hv_update_vp_id(struct vmcb *vmcb,
+       if (hve->hv_vp_id != vp_index) {
+               hve->hv_vp_id = vp_index;
+-              vmcb_mark_dirty(vmcb, VMCB_HV_NESTED_ENLIGHTENMENTS);
++              vmcb_mark_dirty(vmcb, HV_VMCB_NESTED_ENLIGHTENMENTS);
+       }
+ }
+ #else
+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 a380ad7bb9b34..5060fcfe17601 100644
+--- a/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
++++ b/tools/testing/selftests/kvm/x86_64/hyperv_svm_test.c
+@@ -39,7 +39,7 @@ struct hv_enlightenments {
+ /*
+  * Hyper-V uses the software reserved clean bit in VMCB
+  */
+-#define VMCB_HV_NESTED_ENLIGHTENMENTS (1U << 31)
++#define HV_VMCB_NESTED_ENLIGHTENMENTS (1U << 31)
+ void l2_guest_code(void)
+ {
+@@ -98,14 +98,14 @@ static void __attribute__((__flatten__)) guest_code(struct svm_test_data *svm)
+       /* Intercept RDMSR 0xc0000101 without telling KVM about it */
+       set_bit(2 * (MSR_GS_BASE & 0x1fff), svm->msr + 0x800);
+       /* Make sure HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP is set */
+-      vmcb->control.clean |= VMCB_HV_NESTED_ENLIGHTENMENTS;
++      vmcb->control.clean |= HV_VMCB_NESTED_ENLIGHTENMENTS;
+       run_guest(vmcb, svm->vmcb_gpa);
+       /* Make sure we don't see SVM_EXIT_MSR here so eMSR bitmap works */
+       GUEST_ASSERT(vmcb->control.exit_code == SVM_EXIT_VMMCALL);
+       vmcb->save.rip += 3; /* vmcall */
+       /* Now tell KVM we've changed MSR-Bitmap */
+-      vmcb->control.clean &= ~VMCB_HV_NESTED_ENLIGHTENMENTS;
++      vmcb->control.clean &= ~HV_VMCB_NESTED_ENLIGHTENMENTS;
+       run_guest(vmcb, svm->vmcb_gpa);
+       GUEST_ASSERT(vmcb->control.exit_code == SVM_EXIT_MSR);
+       vmcb->save.rip += 2; /* rdmsr */
+-- 
+2.39.2
+