KVM: arm64: Set the MTE tag bit before releasing the page
authorMarc Zyngier <maz@kernel.org>
Thu, 24 Jun 2021 13:21:05 +0000 (14:21 +0100)
committerMarc Zyngier <maz@kernel.org>
Thu, 24 Jun 2021 13:54:45 +0000 (14:54 +0100)
Setting a page flag without holding a reference to the page
is living dangerously. In the tag-writing path, we drop the
reference to the page by calling kvm_release_pfn_dirty(),
and only then set the PG_mte_tagged bit.

It would be safer to do it the other way round.

Fixes: f0376edb1ddca ("KVM: arm64: Add ioctl to fetch/store tags in a guest")
Cc: Catalin Marinas <catalin.marinas@arm.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/87k0mjidwb.wl-maz@kernel.org
arch/arm64/kvm/guest.c

index 4ddb200..60815ae 100644 (file)
@@ -1053,6 +1053,14 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
                } else {
                        num_tags = mte_copy_tags_from_user(maddr, tags,
                                                        MTE_GRANULES_PER_PAGE);
+
+                       /*
+                        * Set the flag after checking the write
+                        * completed fully
+                        */
+                       if (num_tags == MTE_GRANULES_PER_PAGE)
+                               set_bit(PG_mte_tagged, &page->flags);
+
                        kvm_release_pfn_dirty(pfn);
                }
 
@@ -1061,10 +1069,6 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
                        goto out;
                }
 
-               /* Set the flag after checking the write completed fully */
-               if (write)
-                       set_bit(PG_mte_tagged, &page->flags);
-
                gfn++;
                tags += num_tags;
                length -= PAGE_SIZE;