From: Greg Kroah-Hartman Date: Fri, 31 Aug 2018 20:17:01 +0000 (-0700) Subject: 3.18-stable patches X-Git-Tag: v3.18.121~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=46b11ad28bc7140ecf0bfeffdc3e0bf5f05847e7;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch --- diff --git a/queue-3.18/kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch b/queue-3.18/kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch new file mode 100644 index 00000000000..b6424571cac --- /dev/null +++ b/queue-3.18/kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch @@ -0,0 +1,87 @@ +From 86658b819cd0a9aa584cd84453ed268a6f013770 Mon Sep 17 00:00:00 2001 +From: Punit Agrawal +Date: Mon, 13 Aug 2018 11:43:50 +0100 +Subject: KVM: arm/arm64: Skip updating PMD entry if no change + +From: Punit Agrawal + +commit 86658b819cd0a9aa584cd84453ed268a6f013770 upstream. + +Contention on updating a PMD entry by a large number of vcpus can lead +to duplicate work when handling stage 2 page faults. As the page table +update follows the break-before-make requirement of the architecture, +it can lead to repeated refaults due to clearing the entry and +flushing the tlbs. + +This problem is more likely when - + +* there are large number of vcpus +* the mapping is large block mapping + +such as when using PMD hugepages (512MB) with 64k pages. + +Fix this by skipping the page table update if there is no change in +the entry being updated. + +Cc: stable@vger.kernel.org +Fixes: ad361f093c1e ("KVM: ARM: Support hugetlbfs backed huge pages") +Reviewed-by: Suzuki Poulose +Acked-by: Christoffer Dall +Signed-off-by: Punit Agrawal +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman + + +--- + arch/arm/kvm/mmu.c | 38 +++++++++++++++++++++++++++----------- + 1 file changed, 27 insertions(+), 11 deletions(-) + +--- a/arch/arm/kvm/mmu.c ++++ b/arch/arm/kvm/mmu.c +@@ -841,19 +841,35 @@ static int stage2_set_pmd_huge(struct kv + pmd = stage2_get_pmd(kvm, cache, addr); + VM_BUG_ON(!pmd); + +- /* +- * Mapping in huge pages should only happen through a fault. If a +- * page is merged into a transparent huge page, the individual +- * subpages of that huge page should be unmapped through MMU +- * notifiers before we get here. +- * +- * Merging of CompoundPages is not supported; they should become +- * splitting first, unmapped, merged, and mapped back in on-demand. +- */ +- VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd)); +- + old_pmd = *pmd; + if (pmd_present(old_pmd)) { ++ /* ++ * Multiple vcpus faulting on the same PMD entry, can ++ * lead to them sequentially updating the PMD with the ++ * same value. Following the break-before-make ++ * (pmd_clear() followed by tlb_flush()) process can ++ * hinder forward progress due to refaults generated ++ * on missing translations. ++ * ++ * Skip updating the page table if the entry is ++ * unchanged. ++ */ ++ if (pmd_val(old_pmd) == pmd_val(*new_pmd)) ++ return 0; ++ ++ /* ++ * Mapping in huge pages should only happen through a ++ * fault. If a page is merged into a transparent huge ++ * page, the individual subpages of that huge page ++ * should be unmapped through MMU notifiers before we ++ * get here. ++ * ++ * Merging of CompoundPages is not supported; they ++ * should become splitting first, unmapped, merged, ++ * and mapped back in on-demand. ++ */ ++ VM_BUG_ON(pmd_pfn(old_pmd) != pmd_pfn(*new_pmd)); ++ + pmd_clear(pmd); + kvm_tlb_flush_vmid_ipa(kvm, addr); + } else { diff --git a/queue-3.18/kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch b/queue-3.18/kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch new file mode 100644 index 00000000000..811e9e7bd07 --- /dev/null +++ b/queue-3.18/kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch @@ -0,0 +1,41 @@ +From 976d34e2dab10ece5ea8fe7090b7692913f89084 Mon Sep 17 00:00:00 2001 +From: Punit Agrawal +Date: Mon, 13 Aug 2018 11:43:51 +0100 +Subject: KVM: arm/arm64: Skip updating PTE entry if no change + +From: Punit Agrawal + +commit 976d34e2dab10ece5ea8fe7090b7692913f89084 upstream. + +When there is contention on faulting in a particular page table entry +at stage 2, the break-before-make requirement of the architecture can +lead to additional refaulting due to TLB invalidation. + +Avoid this by skipping a page table update if the new value of the PTE +matches the previous value. + +Cc: stable@vger.kernel.org +Fixes: d5d8184d35c9 ("KVM: ARM: Memory virtualization setup") +Reviewed-by: Suzuki Poulose +Acked-by: Christoffer Dall +Signed-off-by: Punit Agrawal +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/kvm/mmu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/arm/kvm/mmu.c ++++ b/arch/arm/kvm/mmu.c +@@ -898,6 +898,10 @@ static int stage2_set_pte(struct kvm *kv + /* Create 2nd stage page table mapping - Level 3 */ + old_pte = *pte; + if (pte_present(old_pte)) { ++ /* Skip page table update if there is no change */ ++ if (pte_val(old_pte) == pte_val(*new_pte)) ++ return 0; ++ + kvm_set_pte(pte, __pte(0)); + kvm_tlb_flush_vmid_ipa(kvm, addr); + } else { diff --git a/queue-3.18/series b/queue-3.18/series index 2a503485ced..ae2a57dc2f3 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -37,3 +37,5 @@ btrfs-don-t-leak-ret-from-do_chunk_alloc.patch s390-kvm-fix-deadlock-when-killed-by-oom.patch ext4-reset-error-code-in-ext4_find_entry-in-fallback.patch arm64-mm-check-for-upper-page_shift-bits-in-pfn_valid.patch +kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch +kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch