diff mbox series

arm64: mte: Fix copy_highpage() warning on hugetlb folios

Message ID 20241204175004.906754-1-catalin.marinas@arm.com (mailing list archive)
State New, archived
Headers show
Series arm64: mte: Fix copy_highpage() warning on hugetlb folios | expand

Commit Message

Catalin Marinas Dec. 4, 2024, 5:50 p.m. UTC
Commit 25c17c4b55de ("hugetlb: arm64: add mte support") improved the
copy_highpage() function to update the tags in the destination hugetlb
folio. However, when the source folio isn't tagged, the code takes the
non-hugetlb path where try_page_mte_tagging() warns as the destination
is a hugetlb folio:

  WARNING: CPU: 0 PID: 363 at arch/arm64/include/asm/mte.h:58 copy_highpage+0x1d4/0x2d8
  [...]
  pc : copy_highpage+0x1d4/0x2d8
  lr : copy_highpage+0x78/0x2d8
  [...]
  Call trace:
   copy_highpage+0x1d4/0x2d8 (P)
   copy_highpage+0x78/0x2d8 (L)
   copy_user_highpage+0x20/0x48
   copy_user_large_folio+0x1bc/0x268
   hugetlb_wp+0x190/0x860
   hugetlb_fault+0xa28/0xc10
   handle_mm_fault+0x2a0/0x2c0
   do_page_fault+0x12c/0x578
   do_mem_abort+0x4c/0xa8
   el0_da+0x44/0xb0
   el0t_64_sync_handler+0xc4/0x138
   el0t_64_sync+0x198/0x1a0

Change the check for the tagged status of the source folio so that it
does not fall through the non-hugetlb case. In addition, only perform
the copy (for the full folio) if the source page is the folio head and
warn if the destination folio is already tagged, for symmetry with the
non-hugetlb case.

Fixes: 25c17c4b55de ("hugetlb: arm64: add mte support")
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Sasha Levin <sashal@kernel.org>
Cc: Yang Shi <yang@os.amperecomputing.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/Z0STR6VLt2MCalnY@sashalap
---
 arch/arm64/mm/copypage.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

Comments

Yang Shi Dec. 4, 2024, 6:53 p.m. UTC | #1
On 12/4/24 9:50 AM, Catalin Marinas wrote:
> Commit 25c17c4b55de ("hugetlb: arm64: add mte support") improved the
> copy_highpage() function to update the tags in the destination hugetlb
> folio. However, when the source folio isn't tagged, the code takes the
> non-hugetlb path where try_page_mte_tagging() warns as the destination
> is a hugetlb folio:
>
>    WARNING: CPU: 0 PID: 363 at arch/arm64/include/asm/mte.h:58 copy_highpage+0x1d4/0x2d8
>    [...]
>    pc : copy_highpage+0x1d4/0x2d8
>    lr : copy_highpage+0x78/0x2d8
>    [...]
>    Call trace:
>     copy_highpage+0x1d4/0x2d8 (P)
>     copy_highpage+0x78/0x2d8 (L)
>     copy_user_highpage+0x20/0x48
>     copy_user_large_folio+0x1bc/0x268
>     hugetlb_wp+0x190/0x860
>     hugetlb_fault+0xa28/0xc10
>     handle_mm_fault+0x2a0/0x2c0
>     do_page_fault+0x12c/0x578
>     do_mem_abort+0x4c/0xa8
>     el0_da+0x44/0xb0
>     el0t_64_sync_handler+0xc4/0x138
>     el0t_64_sync+0x198/0x1a0
>
> Change the check for the tagged status of the source folio so that it
> does not fall through the non-hugetlb case. In addition, only perform
> the copy (for the full folio) if the source page is the folio head and
> warn if the destination folio is already tagged, for symmetry with the
> non-hugetlb case.
>
> Fixes: 25c17c4b55de ("hugetlb: arm64: add mte support")
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> Reported-by: Sasha Levin <sashal@kernel.org>
> Cc: Yang Shi <yang@os.amperecomputing.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Will Deacon <will@kernel.org>
> Link: https://lore.kernel.org/r/Z0STR6VLt2MCalnY@sashalap

Thanks for fixing this. Reviewed-by: Yang Shi <yang@os.amperecomputing.com>

> ---
>   arch/arm64/mm/copypage.c | 8 +++++---
>   1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
> index 87b3f1a25535..a86c897017df 100644
> --- a/arch/arm64/mm/copypage.c
> +++ b/arch/arm64/mm/copypage.c
> @@ -30,11 +30,13 @@ void copy_highpage(struct page *to, struct page *from)
>   	if (!system_supports_mte())
>   		return;
>   
> -	if (folio_test_hugetlb(src) &&
> -	    folio_test_hugetlb_mte_tagged(src)) {
> -		if (!folio_try_hugetlb_mte_tagging(dst))
> +	if (folio_test_hugetlb(src)) {
> +		if (!folio_test_hugetlb_mte_tagged(src) ||
> +		    from != folio_page(src, 0))
>   			return;
>   
> +		WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
> +
>   		/*
>   		 * Populate tags for all subpages.
>   		 *
Catalin Marinas Dec. 5, 2024, 6:23 p.m. UTC | #2
On Wed, 04 Dec 2024 17:50:04 +0000, Catalin Marinas wrote:
> Commit 25c17c4b55de ("hugetlb: arm64: add mte support") improved the
> copy_highpage() function to update the tags in the destination hugetlb
> folio. However, when the source folio isn't tagged, the code takes the
> non-hugetlb path where try_page_mte_tagging() warns as the destination
> is a hugetlb folio:
> 
>   WARNING: CPU: 0 PID: 363 at arch/arm64/include/asm/mte.h:58 copy_highpage+0x1d4/0x2d8
>   [...]
>   pc : copy_highpage+0x1d4/0x2d8
>   lr : copy_highpage+0x78/0x2d8
>   [...]
>   Call trace:
>    copy_highpage+0x1d4/0x2d8 (P)
>    copy_highpage+0x78/0x2d8 (L)
>    copy_user_highpage+0x20/0x48
>    copy_user_large_folio+0x1bc/0x268
>    hugetlb_wp+0x190/0x860
>    hugetlb_fault+0xa28/0xc10
>    handle_mm_fault+0x2a0/0x2c0
>    do_page_fault+0x12c/0x578
>    do_mem_abort+0x4c/0xa8
>    el0_da+0x44/0xb0
>    el0t_64_sync_handler+0xc4/0x138
>    el0t_64_sync+0x198/0x1a0
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: mte: Fix copy_highpage() warning on hugetlb folios
      https://git.kernel.org/arm64/c/cf3b16dae4ca
diff mbox series

Patch

diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c
index 87b3f1a25535..a86c897017df 100644
--- a/arch/arm64/mm/copypage.c
+++ b/arch/arm64/mm/copypage.c
@@ -30,11 +30,13 @@  void copy_highpage(struct page *to, struct page *from)
 	if (!system_supports_mte())
 		return;
 
-	if (folio_test_hugetlb(src) &&
-	    folio_test_hugetlb_mte_tagged(src)) {
-		if (!folio_try_hugetlb_mte_tagging(dst))
+	if (folio_test_hugetlb(src)) {
+		if (!folio_test_hugetlb_mte_tagged(src) ||
+		    from != folio_page(src, 0))
 			return;
 
+		WARN_ON_ONCE(!folio_try_hugetlb_mte_tagging(dst));
+
 		/*
 		 * Populate tags for all subpages.
 		 *