]> git.itanic.dy.fi Git - linux-stable/commitdiff
Revert "arm64: kasan: Revert "arm64: mte: reset the page tag in page->flags""
authorSasha Levin <sashal@kernel.org>
Mon, 12 Sep 2022 11:07:56 +0000 (07:07 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Sep 2022 08:47:19 +0000 (10:47 +0200)
This reverts commit add4bc9281e8704e5ab15616b429576c84f453a2.

On Mon, Sep 12, 2022 at 10:52:45AM +0100, Catalin Marinas wrote:
>I missed this (holidays) and it looks like it's in stable already. On
>its own it will likely break kasan_hw if used together with user-space
>MTE as this change relies on two previous commits:
>
>70c248aca9e7 ("mm: kasan: Skip unpoisoning of user pages")
>6d05141a3930 ("mm: kasan: Skip page unpoisoning only if __GFP_SKIP_KASAN_UNPOISON")
>
>The reason I did not cc stable is that there are other dependencies in
>this area. The potential issues without the above commits were rather
>theoretical, so take these patches rather as clean-ups/refactoring than
>fixes.

Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/arm64/kernel/hibernate.c
arch/arm64/kernel/mte.c
arch/arm64/mm/copypage.c
arch/arm64/mm/mteswap.c

index af5df48ba915b9274211f66c33f4e61fcbe89a1e..2e248342476eaff93a95160aa80abfb3d1c6f63e 100644 (file)
@@ -300,6 +300,11 @@ static void swsusp_mte_restore_tags(void)
                unsigned long pfn = xa_state.xa_index;
                struct page *page = pfn_to_online_page(pfn);
 
+               /*
+                * It is not required to invoke page_kasan_tag_reset(page)
+                * at this point since the tags stored in page->flags are
+                * already restored.
+                */
                mte_restore_page_tags(page_address(page), tags);
 
                mte_free_tag_storage(tags);
index b2b730233274b72f4e1c619d39a0e68d22835f13..f6b00743c3994a19f78be4b81b52a6c570800ec3 100644 (file)
@@ -48,6 +48,15 @@ static void mte_sync_page_tags(struct page *page, pte_t old_pte,
        if (!pte_is_tagged)
                return;
 
+       page_kasan_tag_reset(page);
+       /*
+        * We need smp_wmb() in between setting the flags and clearing the
+        * tags because if another thread reads page->flags and builds a
+        * tagged address out of it, there is an actual dependency to the
+        * memory access, but on the current thread we do not guarantee that
+        * the new page->flags are visible before the tags were updated.
+        */
+       smp_wmb();
        mte_clear_page_tags(page_address(page));
 }
 
index 24913271e898c121a9083610144ec640804f02c0..0dea80bf6de469e6ab3d5b584d451cf100e77e94 100644 (file)
@@ -23,6 +23,15 @@ void copy_highpage(struct page *to, struct page *from)
 
        if (system_supports_mte() && test_bit(PG_mte_tagged, &from->flags)) {
                set_bit(PG_mte_tagged, &to->flags);
+               page_kasan_tag_reset(to);
+               /*
+                * We need smp_wmb() in between setting the flags and clearing the
+                * tags because if another thread reads page->flags and builds a
+                * tagged address out of it, there is an actual dependency to the
+                * memory access, but on the current thread we do not guarantee that
+                * the new page->flags are visible before the tags were updated.
+                */
+               smp_wmb();
                mte_copy_page_tags(kto, kfrom);
        }
 }
index 4334dec93bd441eb285d27b97d2b86cfdf1d00c0..a9e50e930484aa3ce7e09f3d9344f7a72b08de6a 100644 (file)
@@ -53,6 +53,15 @@ bool mte_restore_tags(swp_entry_t entry, struct page *page)
        if (!tags)
                return false;
 
+       page_kasan_tag_reset(page);
+       /*
+        * We need smp_wmb() in between setting the flags and clearing the
+        * tags because if another thread reads page->flags and builds a
+        * tagged address out of it, there is an actual dependency to the
+        * memory access, but on the current thread we do not guarantee that
+        * the new page->flags are visible before the tags were updated.
+        */
+       smp_wmb();
        mte_restore_page_tags(page_address(page), tags);
 
        return true;