From: Sasha Levin Date: Mon, 17 Apr 2023 03:42:08 +0000 (-0400) Subject: Fixes for 6.1 X-Git-Tag: v4.14.313~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=84a0eecda51355c2d8ed2adb296047a3a6748a12;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.1 Signed-off-by: Sasha Levin --- 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 index 00000000000..cbfef2a28b0 --- /dev/null +++ b/queue-6.1/kvm-selftests-move-struct-hv_enlightenments-to-x86_6.patch @@ -0,0 +1,89 @@ +From 24089f547ed75b412c082c3dac07b48006c06d0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 15:53:40 +0100 +Subject: KVM: selftests: Move "struct hv_enlightenments" to x86_64/svm.h + +From: Sean Christopherson + +[ 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 +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: Paolo Bonzini +Message-Id: <20221101145426.251680-3-vkuznets@redhat.com> +Signed-off-by: Paolo Bonzini +Stable-dep-of: e5c972c1fada ("KVM: SVM: Flush Hyper-V TLB when required") +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..e7e482c0b65 --- /dev/null +++ b/queue-6.1/kvm-svm-add-a-proper-field-for-hyper-v-vmcb-enlighte.patch @@ -0,0 +1,192 @@ +From 2e0f436fe7c846ca3ca98281192528457276d453 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 15:53:41 +0100 +Subject: KVM: SVM: Add a proper field for Hyper-V VMCB enlightenments + +From: Sean Christopherson + +[ 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 +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: Paolo Bonzini +Message-Id: <20221101145426.251680-4-vkuznets@redhat.com> +Signed-off-by: Paolo Bonzini +Stable-dep-of: e5c972c1fada ("KVM: SVM: Flush Hyper-V TLB when required") +Signed-off-by: Sasha Levin +--- + 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 + #include + ++#include ++ + /* + * 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 index 00000000000..dabc91f89ca --- /dev/null +++ b/queue-6.1/kvm-svm-flush-hyper-v-tlb-when-required.patch @@ -0,0 +1,167 @@ +From a593b85e4647732d9ca07665131bf0248ed2e46c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Mar 2023 15:52:33 +0100 +Subject: KVM: SVM: Flush Hyper-V TLB when required + +From: Jeremi Piotrowski + +[ 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 +Signed-off-by: Jeremi Piotrowski +Reviewed-by: Vitaly Kuznetsov +Message-Id: <20230324145233.4585-1-jpiotrowski@linux.microsoft.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + 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 ++ + #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 index 00000000000..9c5832de115 --- /dev/null +++ b/queue-6.1/maple_tree-fix-write-memory-barrier-of-nodes-once-de.patch @@ -0,0 +1,194 @@ +From 076263ac1ca5bada4cd4e4426f0bc7ce5936290e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Suren Baghdasaryan +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-6.1/series b/queue-6.1/series index 18f418a265e..9f125f9987a 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -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 index 00000000000..52d716a9858 --- /dev/null +++ b/queue-6.1/tracing-add-trace_array_puts-to-write-into-instance.patch @@ -0,0 +1,115 @@ +From 9161c22f8b17c21dd855201a2bcacf28ab4eb366 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Feb 2023 12:28:52 -0500 +Subject: tracing: Add trace_array_puts() to write into instance + +From: Steven Rostedt (Google) + +[ 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 +Cc: Andrew Morton +Reviewed-by: Ross Zwisler +Signed-off-by: Steven Rostedt (Google) +Stable-dep-of: 9d52727f8043 ("tracing: Have tracing_snapshot_instance_cond() write errors to the appropriate instance") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..55264ec7d42 --- /dev/null +++ b/queue-6.1/tracing-have-tracing_snapshot_instance_cond-write-er.patch @@ -0,0 +1,66 @@ +From 7956504631f26c0095dcbcf778b2b9fff45712cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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) + +[ 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 +Cc: Mark Rutland +Cc: Andrew Morton +Cc: Ross Zwisler +Fixes: 2824f50332486 ("tracing: Make the snapshot trigger work with instances") +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..5a2c9c167c0 --- /dev/null +++ b/queue-6.1/x86-hyperv-kvm-rename-hv_enlightenments-to-hv_vmcb_e.patch @@ -0,0 +1,169 @@ +From 4a12e7119acd99a4e4355d646c47d0f02fb9bafc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 15:53:42 +0100 +Subject: x86/hyperv: KVM: Rename "hv_enlightenments" to + "hv_vmcb_enlightenments" + +From: Sean Christopherson + +[ 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 +Reviewed-by: Michael Kelley +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: Paolo Bonzini +Message-Id: <20221101145426.251680-5-vkuznets@redhat.com> +Signed-off-by: Paolo Bonzini +Stable-dep-of: e5c972c1fada ("KVM: SVM: Flush Hyper-V TLB when required") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a3881405630 --- /dev/null +++ b/queue-6.1/x86-hyperv-move-vmcb-enlightenment-definitions-to-hy.patch @@ -0,0 +1,180 @@ +From 8a7d5d16096123536e441bbfa7f3edb41f810b51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Nov 2022 15:53:39 +0100 +Subject: x86/hyperv: Move VMCB enlightenment definitions to hyperv-tlfs.h + +From: Sean Christopherson + +[ 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 +Signed-off-by: Vitaly Kuznetsov +Signed-off-by: Paolo Bonzini +Message-Id: <20221101145426.251680-2-vkuznets@redhat.com> +Signed-off-by: Paolo Bonzini +Stable-dep-of: e5c972c1fada ("KVM: SVM: Flush Hyper-V TLB when required") +Signed-off-by: Sasha Levin +--- + 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 +