]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: Pass MMU notifier range flags to kvm_unmap_hva_range()
authorWill Deacon <will@kernel.org>
Tue, 11 Aug 2020 10:27:24 +0000 (11:27 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Aug 2020 09:49:20 +0000 (11:49 +0200)
commit fdfe7cbd58806522e799e2a50a15aee7f2cbb7b6 upstream.

The 'flags' field of 'struct mmu_notifier_range' is used to indicate
whether invalidate_range_{start,end}() are permitted to block. In the
case of kvm_mmu_notifier_invalidate_range_start(), this field is not
forwarded on to the architecture-specific implementation of
kvm_unmap_hva_range() and therefore the backend cannot sensibly decide
whether or not to block.

Add an extra 'flags' parameter to kvm_unmap_hva_range() so that
architectures are aware as to whether or not they are permitted to block.

Cc: <stable@vger.kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: James Morse <james.morse@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Message-Id: <20200811102725.7121-2-will@kernel.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/mmu.c
arch/mips/include/asm/kvm_host.h
arch/mips/kvm/mmu.c
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/e500_mmu_host.c
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/mmu/mmu.c
virt/kvm/kvm_main.c

index e21d4a01372fe7413392a866c7f1df6c66354257..759d62343e1d0574139bdb96bfeac84e3259ca28 100644 (file)
@@ -443,7 +443,7 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
 
 #define KVM_ARCH_WANT_MMU_NOTIFIER
 int kvm_unmap_hva_range(struct kvm *kvm,
-                       unsigned long start, unsigned long end);
+                       unsigned long start, unsigned long end, unsigned flags);
 int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
 int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
 int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
index 31058e6e7c2a3a42445df11705c66f2b664b1da9..5f6b35c3361880d981129820568d76bd1c2e2f90 100644 (file)
@@ -2203,7 +2203,7 @@ static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *dat
 }
 
 int kvm_unmap_hva_range(struct kvm *kvm,
-                       unsigned long start, unsigned long end)
+                       unsigned long start, unsigned long end, unsigned flags)
 {
        if (!kvm->arch.pgd)
                return 0;
index 363e7a89d1738f858d41cd3cca55916077e72c2b..ef1d25d49ec8748a488e7d562be0bdc13f176d21 100644 (file)
@@ -981,7 +981,7 @@ enum kvm_mips_fault_result kvm_trap_emul_gva_fault(struct kvm_vcpu *vcpu,
 
 #define KVM_ARCH_WANT_MMU_NOTIFIER
 int kvm_unmap_hva_range(struct kvm *kvm,
-                       unsigned long start, unsigned long end);
+                       unsigned long start, unsigned long end, unsigned flags);
 int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
 int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
 int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
index 49bd160f4d85c52d6ce228618536446b63da7b89..0783ac9b324055aba3f57a59616ccddded85dd5c 100644 (file)
@@ -518,7 +518,8 @@ static int kvm_unmap_hva_handler(struct kvm *kvm, gfn_t gfn, gfn_t gfn_end,
        return 1;
 }
 
-int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
+int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end,
+                       unsigned flags)
 {
        handle_hva_to_gpa(kvm, start, end, &kvm_unmap_hva_handler, NULL);
 
index 7e2d061d04451b4ff4a76fd38a25236aba0062b1..bccf0ba2da2ef25e492e69540fc9cb7cf146721b 100644 (file)
@@ -58,7 +58,8 @@
 #define KVM_ARCH_WANT_MMU_NOTIFIER
 
 extern int kvm_unmap_hva_range(struct kvm *kvm,
-                              unsigned long start, unsigned long end);
+                              unsigned long start, unsigned long end,
+                              unsigned flags);
 extern int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
 extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
 extern int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
index 41fedec69ac350fc6c7a11a4b90722190c8f5c3a..49db50d1db04cde639622186f7d505de7bed1108 100644 (file)
@@ -834,7 +834,8 @@ void kvmppc_core_commit_memory_region(struct kvm *kvm,
        kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old, new, change);
 }
 
-int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
+int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end,
+                       unsigned flags)
 {
        return kvm->arch.kvm_ops->unmap_hva_range(kvm, start, end);
 }
index d6c1069e9954aa280b10237eccd749de5783fc54..ed0c9c43d0cf14cc8a4fd57d72cd74b36ff644ed 100644 (file)
@@ -734,7 +734,8 @@ static int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
        return 0;
 }
 
-int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
+int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end,
+                       unsigned flags)
 {
        /* kvm_unmap_hva flushes everything anyways */
        kvm_unmap_hva(kvm, start);
index be5363b2154096d384beadb70107eaa3b459cff8..c6908a3d551e1ff5da77c20c821ba281d54f2a35 100644 (file)
@@ -1641,7 +1641,8 @@ asmlinkage void kvm_spurious_fault(void);
        _ASM_EXTABLE(666b, 667b)
 
 #define KVM_ARCH_WANT_MMU_NOTIFIER
-int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end);
+int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end,
+                       unsigned flags);
 int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
 int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
 int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
index 6d6a0ae7800c60d75c5aae424cc9bc5707d88f5e..9516a958e7801acd6657c0d987a53bc71f92aa9e 100644 (file)
@@ -1971,7 +1971,8 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
        return kvm_handle_hva_range(kvm, hva, hva + 1, data, handler);
 }
 
-int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
+int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end,
+                       unsigned flags)
 {
        return kvm_handle_hva_range(kvm, start, end, 0, kvm_unmap_rmapp);
 }
index 0a68c9d3d3ab18ac56fb6883554f7a078b4134d4..9e925675a8868a4fddddd3531c63df0e29e651ed 100644 (file)
@@ -427,7 +427,8 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
         * count is also read inside the mmu_lock critical section.
         */
        kvm->mmu_notifier_count++;
-       need_tlb_flush = kvm_unmap_hva_range(kvm, range->start, range->end);
+       need_tlb_flush = kvm_unmap_hva_range(kvm, range->start, range->end,
+                                            range->flags);
        need_tlb_flush |= kvm->tlbs_dirty;
        /* we've to flush the tlb before the pages can be freed */
        if (need_tlb_flush)