From: Greg Kroah-Hartman Date: Mon, 4 Sep 2017 12:14:14 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v3.18.70~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d896c75426212533e50b28df630b0aec0a91a0d;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: kvm-arm-arm64-fix-race-in-resetting-stage2-pgd.patch kvm-arm-arm64-force-reading-uncached-stage2-pgd.patch --- diff --git a/queue-4.4/kvm-arm-arm64-fix-race-in-resetting-stage2-pgd.patch b/queue-4.4/kvm-arm-arm64-fix-race-in-resetting-stage2-pgd.patch new file mode 100644 index 00000000000..3b93c7fe8d1 --- /dev/null +++ b/queue-4.4/kvm-arm-arm64-fix-race-in-resetting-stage2-pgd.patch @@ -0,0 +1,113 @@ +From 6c0d706b563af732adb094c5bf807437e8963e84 Mon Sep 17 00:00:00 2001 +From: Suzuki K Poulose +Date: Wed, 3 May 2017 15:17:51 +0100 +Subject: kvm: arm/arm64: Fix race in resetting stage2 PGD +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Suzuki K Poulose + +commit 6c0d706b563af732adb094c5bf807437e8963e84 upstream. + +In kvm_free_stage2_pgd() we check the stage2 PGD before holding +the lock and proceed to take the lock if it is valid. And we unmap +the page tables, followed by releasing the lock. We reset the PGD +only after dropping this lock, which could cause a race condition +where another thread waiting on or even holding the lock, could +potentially see that the PGD is still valid and proceed to perform +a stage2 operation and later encounter a NULL PGD. + +[223090.242280] Unable to handle kernel NULL pointer dereference at +virtual address 00000040 +[223090.262330] PC is at unmap_stage2_range+0x8c/0x428 +[223090.262332] LR is at kvm_unmap_hva_handler+0x2c/0x3c +[223090.262531] Call trace: +[223090.262533] [] unmap_stage2_range+0x8c/0x428 +[223090.262535] [] kvm_unmap_hva_handler+0x2c/0x3c +[223090.262537] [] handle_hva_to_gpa+0xb0/0x104 +[223090.262539] [] kvm_unmap_hva+0x5c/0xbc +[223090.262543] [] +kvm_mmu_notifier_invalidate_page+0x50/0x8c +[223090.262547] [] +__mmu_notifier_invalidate_page+0x5c/0x84 +[223090.262551] [] try_to_unmap_one+0x1d0/0x4a0 +[223090.262553] [] rmap_walk+0x1cc/0x2e0 +[223090.262555] [] try_to_unmap+0x74/0xa4 +[223090.262557] [] migrate_pages+0x31c/0x5ac +[223090.262561] [] compact_zone+0x3fc/0x7ac +[223090.262563] [] compact_zone_order+0x94/0xb0 +[223090.262564] [] try_to_compact_pages+0x108/0x290 +[223090.262569] [] __alloc_pages_direct_compact+0x70/0x1ac +[223090.262571] [] __alloc_pages_nodemask+0x434/0x9f4 +[223090.262572] [] alloc_pages_vma+0x230/0x254 +[223090.262574] [] do_huge_pmd_anonymous_page+0x114/0x538 +[223090.262576] [] handle_mm_fault+0xd40/0x17a4 +[223090.262577] [] __get_user_pages+0x12c/0x36c +[223090.262578] [] get_user_pages_unlocked+0xa4/0x1b8 +[223090.262579] [] __gfn_to_pfn_memslot+0x280/0x31c +[223090.262580] [] gfn_to_pfn_prot+0x4c/0x5c +[223090.262582] [] kvm_handle_guest_abort+0x240/0x774 +[223090.262584] [] handle_exit+0x11c/0x1ac +[223090.262586] [] kvm_arch_vcpu_ioctl_run+0x31c/0x648 +[223090.262587] [] kvm_vcpu_ioctl+0x378/0x768 +[223090.262590] [] do_vfs_ioctl+0x324/0x5a4 +[223090.262591] [] SyS_ioctl+0x90/0xa4 +[223090.262595] [] el0_svc_naked+0x38/0x3c + +This patch moves the stage2 PGD manipulation under the lock. + +Reported-by: Alexander Graf +Cc: Mark Rutland +Cc: Marc Zyngier +Cc: Paolo Bonzini +Cc: Radim Krčmář +Reviewed-by: Christoffer Dall +Reviewed-by: Marc Zyngier +Signed-off-by: Suzuki K Poulose +Signed-off-by: Christoffer Dall +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/kvm/mmu.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +--- a/arch/arm/kvm/mmu.c ++++ b/arch/arm/kvm/mmu.c +@@ -824,24 +824,25 @@ void stage2_unmap_vm(struct kvm *kvm) + * Walks the level-1 page table pointed to by kvm->arch.pgd and frees all + * underlying level-2 and level-3 tables before freeing the actual level-1 table + * and setting the struct pointer to NULL. +- * +- * Note we don't need locking here as this is only called when the VM is +- * destroyed, which can only be done once. + */ + void kvm_free_stage2_pgd(struct kvm *kvm) + { +- if (kvm->arch.pgd == NULL) +- return; ++ void *pgd = NULL; ++ void *hwpgd = NULL; + + spin_lock(&kvm->mmu_lock); +- unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); ++ if (kvm->arch.pgd) { ++ unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); ++ pgd = kvm->arch.pgd; ++ hwpgd = kvm_get_hwpgd(kvm); ++ kvm->arch.pgd = NULL; ++ } + spin_unlock(&kvm->mmu_lock); + +- kvm_free_hwpgd(kvm_get_hwpgd(kvm)); +- if (KVM_PREALLOC_LEVEL > 0) +- kfree(kvm->arch.pgd); +- +- kvm->arch.pgd = NULL; ++ if (hwpgd) ++ kvm_free_hwpgd(hwpgd); ++ if (KVM_PREALLOC_LEVEL > 0 && pgd) ++ kfree(pgd); + } + + static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, diff --git a/queue-4.4/kvm-arm-arm64-force-reading-uncached-stage2-pgd.patch b/queue-4.4/kvm-arm-arm64-force-reading-uncached-stage2-pgd.patch new file mode 100644 index 00000000000..45b2932f78f --- /dev/null +++ b/queue-4.4/kvm-arm-arm64-force-reading-uncached-stage2-pgd.patch @@ -0,0 +1,35 @@ +From 2952a6070e07ebdd5896f1f5b861acad677caded Mon Sep 17 00:00:00 2001 +From: Suzuki K Poulose +Date: Tue, 16 May 2017 10:34:54 +0100 +Subject: kvm: arm/arm64: Force reading uncached stage2 PGD + +From: Suzuki K Poulose + +commit 2952a6070e07ebdd5896f1f5b861acad677caded upstream. + +Make sure we don't use a cached value of the KVM stage2 PGD while +resetting the PGD. + +Cc: Marc Zyngier +Signed-off-by: Suzuki K Poulose +Reviewed-by: Christoffer Dall +Signed-off-by: Christoffer Dall +Signed-off-by: Suzuki K Poulose +Signed-off-by: Greg Kroah-Hartman + + +--- + arch/arm/kvm/mmu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/kvm/mmu.c ++++ b/arch/arm/kvm/mmu.c +@@ -833,7 +833,7 @@ void kvm_free_stage2_pgd(struct kvm *kvm + spin_lock(&kvm->mmu_lock); + if (kvm->arch.pgd) { + unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); +- pgd = kvm->arch.pgd; ++ pgd = READ_ONCE(kvm->arch.pgd); + hwpgd = kvm_get_hwpgd(kvm); + kvm->arch.pgd = NULL; + } diff --git a/queue-4.4/series b/queue-4.4/series index a38444a442b..d512a9a9f3f 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -10,3 +10,5 @@ cifs-remove-endian-related-sparse-warning.patch wl1251-add-a-missing-spin_lock_init.patch xfrm-policy-check-policy-direction-value.patch drm-ttm-fix-accounting-error-when-fail-to-get-pages-for-pool.patch +kvm-arm-arm64-fix-race-in-resetting-stage2-pgd.patch +kvm-arm-arm64-force-reading-uncached-stage2-pgd.patch