FAILED: patch "[PATCH] KVM: x86/mmu: Yield in TDU MMU iter even if no SPTES changed" failed to apply to 5.11-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.11-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 1af4a96025b33587ca953c7ef12a1b20c6e70412 Mon Sep 17 00:00:00 2001
From: Ben Gardon <[email protected]>
Date: Tue, 2 Feb 2021 10:57:20 -0800
Subject: [PATCH] KVM: x86/mmu: Yield in TDU MMU iter even if no SPTES changed
Given certain conditions, some TDP MMU functions may not yield reliably / frequently enough. For example, if a paging structure was very large but had few, if any writable entries, wrprot_gfn_range could traverse many entries before finding a writable entry and yielding because the check for yielding only happens after an SPTE is modified.
Fix this issue by moving the yield to the beginning of the loop.
Message-Id: <[email protected]>
arch/x86/kvm/mmu/tdp_mmu.c +22 -10
@@ -501,6 +501,12 @@ static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,bool flush_needed = false;tdp_root_for_each_pte (iter, root, start, end) { +if (can_yield && +tdp_mmu_iter_cond_resched (kvm, &iter, flush_needed)) { + flush_needed = false; +continue ; + } +if (!is_shadow_present_pte (iter.old_spte))continue ;
@@ -515,9 +521,7 @@ static bool zap_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,continue ;tdp_mmu_set_spte (kvm, &iter,0 ); - - flush_needed = !(can_yield && -tdp_mmu_iter_cond_resched (kvm, &iter, true)); + flush_needed = true; }return flush_needed; }
@@ -880,6 +884,9 @@ static bool wrprot_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,for_each_tdp_pte_min_level (iter, root->spt, root->role.level, min_level, start, end) { +if (tdp_mmu_iter_cond_resched (kvm, &iter, false)) +continue ; +if (!is_shadow_present_pte (iter.old_spte) || !is_last_spte (iter.old_spte, iter.level))continue ;
@@ -888,8 +895,6 @@ static bool wrprot_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,tdp_mmu_set_spte_no_dirty_log (kvm, &iter, new_spte); spte_set = true; - -tdp_mmu_iter_cond_resched (kvm, &iter, false); }return spte_set; }
@@ -933,6 +938,9 @@ static bool clear_dirty_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,bool spte_set = false;tdp_root_for_each_leaf_pte (iter, root, start, end) { +if (tdp_mmu_iter_cond_resched (kvm, &iter, false)) +continue ; +if (spte_ad_need_write_protect (iter.old_spte)) {if (is_writable_pte (iter.old_spte)) new_spte = iter.old_spte & ~PT_WRITABLE_MASK ;
@@ -947,8 +955,6 @@ static bool clear_dirty_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,tdp_mmu_set_spte_no_dirty_log (kvm, &iter, new_spte); spte_set = true; - -tdp_mmu_iter_cond_resched (kvm, &iter, false); }return spte_set; }
@@ -1056,6 +1062,9 @@ static bool set_dirty_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,bool spte_set = false;tdp_root_for_each_pte (iter, root, start, end) { +if (tdp_mmu_iter_cond_resched (kvm, &iter, false)) +continue ; +if (!is_shadow_present_pte (iter.old_spte))continue ;
@@ -1063,8 +1072,6 @@ static bool set_dirty_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,tdp_mmu_set_spte (kvm, &iter, new_spte); spte_set = true; - -tdp_mmu_iter_cond_resched (kvm, &iter, false); }return spte_set;
@@ -1105,6 +1112,11 @@ static void zap_collapsible_spte_range(struct kvm *kvm,bool spte_set = false;tdp_root_for_each_pte (iter, root, start, end) { +if (tdp_mmu_iter_cond_resched (kvm, &iter, spte_set)) { + spte_set = false; +continue ; + } +if (!is_shadow_present_pte (iter.old_spte) || !is_last_spte (iter.old_spte, iter.level))continue ;
@@ -1116,7 +1128,7 @@ static void zap_collapsible_spte_range(struct kvm *kvm,tdp_mmu_set_spte (kvm, &iter,0 ); - spte_set = !tdp_mmu_iter_cond_resched (kvm, &iter, true); + spte_set = true; }if (spte_set)