All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] arm64: fix two bug about page table check
@ 2022-11-16  8:38 ` Liu Shixin
  0 siblings, 0 replies; 28+ messages in thread
From: Liu Shixin @ 2022-11-16  8:38 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel, Liu Shixin

Denys Vlasenko has reported two bug about page table check on arm64.       
On arm64, pmd_present() contains non-leaf pmd and invalid pmd too.         

When collapse hugepage, the pmd is non-leaf and should skip the check.
Use pmd_leaf() instead of pmd_present().
                                                                           
When split hugepage, the pmd will be marked as invalid and then populate.  
So we should decrease file_map_count when invalid pmd and then increase    
when populate the pmd.                                                     
                                                                           
Liu Shixin (2):
  arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
  arm64/mm: fix incorrect file_map_count for invalid pmd/pud

 arch/arm64/include/asm/pgtable.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 0/2] arm64: fix two bug about page table check
@ 2022-11-16  8:38 ` Liu Shixin
  0 siblings, 0 replies; 28+ messages in thread
From: Liu Shixin @ 2022-11-16  8:38 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel, Liu Shixin

Denys Vlasenko has reported two bug about page table check on arm64.       
On arm64, pmd_present() contains non-leaf pmd and invalid pmd too.         

When collapse hugepage, the pmd is non-leaf and should skip the check.
Use pmd_leaf() instead of pmd_present().
                                                                           
When split hugepage, the pmd will be marked as invalid and then populate.  
So we should decrease file_map_count when invalid pmd and then increase    
when populate the pmd.                                                     
                                                                           
Liu Shixin (2):
  arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
  arm64/mm: fix incorrect file_map_count for invalid pmd/pud

 arch/arm64/include/asm/pgtable.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
  2022-11-16  8:38 ` Liu Shixin
@ 2022-11-16  8:38   ` Liu Shixin
  -1 siblings, 0 replies; 28+ messages in thread
From: Liu Shixin @ 2022-11-16  8:38 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel, Liu Shixin

The page table check trigger BUG_ON() unexpectedly when collapse hugepage:

 ------------[ cut here ]------------
 kernel BUG at mm/page_table_check.c:82!
 Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
 Dumping ftrace buffer:
    (ftrace buffer empty)
 Modules linked in:
 CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
 Hardware name: linux,dummy-virt (DT)
 pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
 pc : page_table_check_clear.isra.0+0x258/0x3f0
 lr : page_table_check_clear.isra.0+0x240/0x3f0
[...]
 Call trace:
  page_table_check_clear.isra.0+0x258/0x3f0
  __page_table_check_pmd_clear+0xbc/0x108
  pmdp_collapse_flush+0xb0/0x160
  collapse_huge_page+0xa08/0x1080
  hpage_collapse_scan_pmd+0xf30/0x1590
  khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
  khugepaged+0x338/0x518
  kthread+0x278/0x2f8
  ret_from_fork+0x10/0x20
[...]

Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
and so trigger BUG_ON() unexpectedly.

Fix this problem by using pmd_leaf() insteal of pmd_present() in
pmd_user_accessible_page(). Moreover, use pud_leaf() for
pud_user_accessible_page() too.

Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
Signed-off-by: Liu Shixin <liushixin2@huawei.com>
---
 arch/arm64/include/asm/pgtable.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 71a1af42f0e8..edf6625ce965 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
 
 static inline bool pmd_user_accessible_page(pmd_t pmd)
 {
-	return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
+	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
 }
 
 static inline bool pud_user_accessible_page(pud_t pud)
 {
-	return pud_present(pud) && pud_user(pud);
+	return pud_leaf(pud) && pud_user(pud);
 }
 #endif
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
@ 2022-11-16  8:38   ` Liu Shixin
  0 siblings, 0 replies; 28+ messages in thread
From: Liu Shixin @ 2022-11-16  8:38 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel, Liu Shixin

The page table check trigger BUG_ON() unexpectedly when collapse hugepage:

 ------------[ cut here ]------------
 kernel BUG at mm/page_table_check.c:82!
 Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
 Dumping ftrace buffer:
    (ftrace buffer empty)
 Modules linked in:
 CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
 Hardware name: linux,dummy-virt (DT)
 pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
 pc : page_table_check_clear.isra.0+0x258/0x3f0
 lr : page_table_check_clear.isra.0+0x240/0x3f0
[...]
 Call trace:
  page_table_check_clear.isra.0+0x258/0x3f0
  __page_table_check_pmd_clear+0xbc/0x108
  pmdp_collapse_flush+0xb0/0x160
  collapse_huge_page+0xa08/0x1080
  hpage_collapse_scan_pmd+0xf30/0x1590
  khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
  khugepaged+0x338/0x518
  kthread+0x278/0x2f8
  ret_from_fork+0x10/0x20
[...]

Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
and so trigger BUG_ON() unexpectedly.

Fix this problem by using pmd_leaf() insteal of pmd_present() in
pmd_user_accessible_page(). Moreover, use pud_leaf() for
pud_user_accessible_page() too.

Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
Signed-off-by: Liu Shixin <liushixin2@huawei.com>
---
 arch/arm64/include/asm/pgtable.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 71a1af42f0e8..edf6625ce965 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
 
 static inline bool pmd_user_accessible_page(pmd_t pmd)
 {
-	return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
+	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
 }
 
 static inline bool pud_user_accessible_page(pud_t pud)
 {
-	return pud_present(pud) && pud_user(pud);
+	return pud_leaf(pud) && pud_user(pud);
 }
 #endif
 
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
  2022-11-16  8:38 ` Liu Shixin
@ 2022-11-16  8:38   ` Liu Shixin
  -1 siblings, 0 replies; 28+ messages in thread
From: Liu Shixin @ 2022-11-16  8:38 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel, Liu Shixin

The page table check trigger BUG_ON() unexpectedly when split hugepage:

 ------------[ cut here ]------------
 kernel BUG at mm/page_table_check.c:119!
 Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
 Dumping ftrace buffer:
    (ftrace buffer empty)
 Modules linked in:
 CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
 Hardware name: linux,dummy-virt (DT)
 pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
 pc : page_table_check_set.isra.0+0x398/0x468
 lr : page_table_check_set.isra.0+0x1c0/0x468
[...]
 Call trace:
  page_table_check_set.isra.0+0x398/0x468
  __page_table_check_pte_set+0x160/0x1c0
  __split_huge_pmd_locked+0x900/0x1648
  __split_huge_pmd+0x28c/0x3b8
  unmap_page_range+0x428/0x858
  unmap_single_vma+0xf4/0x1c8
  zap_page_range+0x2b0/0x410
  madvise_vma_behavior+0xc44/0xe78
  do_madvise+0x280/0x698
  __arm64_sys_madvise+0x90/0xe8
  invoke_syscall.constprop.0+0xdc/0x1d8
  do_el0_svc+0xf4/0x3f8
  el0_svc+0x58/0x120
  el0t_64_sync_handler+0xb8/0xc0
  el0t_64_sync+0x19c/0x1a0
[...]

On arm64, pmd_present() will return true even if the pmd is invalid. So
in pmdp_invalidate() the file_map_count will not only decrease once but
also increase once. Then in set_pte_at(), the file_map_count increase
again, and so trigger BUG_ON() unexpectedly.

Fix this problem by adding pmd_valid() in pmd_user_accessible_page().
Moreover, add pud_valid() for pud_user_accessible_page() too.

Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
Signed-off-by: Liu Shixin <liushixin2@huawei.com>
---
 arch/arm64/include/asm/pgtable.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index edf6625ce965..56e178de75e7 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
 
 static inline bool pmd_user_accessible_page(pmd_t pmd)
 {
-	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
+	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)) && pmd_valid(pmd);
 }
 
 static inline bool pud_user_accessible_page(pud_t pud)
 {
-	return pud_leaf(pud) && pud_user(pud);
+	return pud_leaf(pud) && pud_user(pud) && pud_valid(pud);
 }
 #endif
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
@ 2022-11-16  8:38   ` Liu Shixin
  0 siblings, 0 replies; 28+ messages in thread
From: Liu Shixin @ 2022-11-16  8:38 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel, Liu Shixin

The page table check trigger BUG_ON() unexpectedly when split hugepage:

 ------------[ cut here ]------------
 kernel BUG at mm/page_table_check.c:119!
 Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
 Dumping ftrace buffer:
    (ftrace buffer empty)
 Modules linked in:
 CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
 Hardware name: linux,dummy-virt (DT)
 pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
 pc : page_table_check_set.isra.0+0x398/0x468
 lr : page_table_check_set.isra.0+0x1c0/0x468
[...]
 Call trace:
  page_table_check_set.isra.0+0x398/0x468
  __page_table_check_pte_set+0x160/0x1c0
  __split_huge_pmd_locked+0x900/0x1648
  __split_huge_pmd+0x28c/0x3b8
  unmap_page_range+0x428/0x858
  unmap_single_vma+0xf4/0x1c8
  zap_page_range+0x2b0/0x410
  madvise_vma_behavior+0xc44/0xe78
  do_madvise+0x280/0x698
  __arm64_sys_madvise+0x90/0xe8
  invoke_syscall.constprop.0+0xdc/0x1d8
  do_el0_svc+0xf4/0x3f8
  el0_svc+0x58/0x120
  el0t_64_sync_handler+0xb8/0xc0
  el0t_64_sync+0x19c/0x1a0
[...]

On arm64, pmd_present() will return true even if the pmd is invalid. So
in pmdp_invalidate() the file_map_count will not only decrease once but
also increase once. Then in set_pte_at(), the file_map_count increase
again, and so trigger BUG_ON() unexpectedly.

Fix this problem by adding pmd_valid() in pmd_user_accessible_page().
Moreover, add pud_valid() for pud_user_accessible_page() too.

Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
Signed-off-by: Liu Shixin <liushixin2@huawei.com>
---
 arch/arm64/include/asm/pgtable.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index edf6625ce965..56e178de75e7 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
 
 static inline bool pmd_user_accessible_page(pmd_t pmd)
 {
-	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
+	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)) && pmd_valid(pmd);
 }
 
 static inline bool pud_user_accessible_page(pud_t pud)
 {
-	return pud_leaf(pud) && pud_user(pud);
+	return pud_leaf(pud) && pud_user(pud) && pud_valid(pud);
 }
 #endif
 
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
  2022-11-16  8:38   ` Liu Shixin
@ 2022-11-16  9:04     ` David Hildenbrand
  -1 siblings, 0 replies; 28+ messages in thread
From: David Hildenbrand @ 2022-11-16  9:04 UTC (permalink / raw)
  To: Liu Shixin, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel

On 16.11.22 09:38, Liu Shixin wrote:
> The page table check trigger BUG_ON() unexpectedly when collapse hugepage:
> 
>   ------------[ cut here ]------------
>   kernel BUG at mm/page_table_check.c:82!
>   Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>   Dumping ftrace buffer:
>      (ftrace buffer empty)
>   Modules linked in:
>   CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
>   Hardware name: linux,dummy-virt (DT)
>   pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>   pc : page_table_check_clear.isra.0+0x258/0x3f0
>   lr : page_table_check_clear.isra.0+0x240/0x3f0
> [...]
>   Call trace:
>    page_table_check_clear.isra.0+0x258/0x3f0
>    __page_table_check_pmd_clear+0xbc/0x108
>    pmdp_collapse_flush+0xb0/0x160
>    collapse_huge_page+0xa08/0x1080
>    hpage_collapse_scan_pmd+0xf30/0x1590
>    khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
>    khugepaged+0x338/0x518
>    kthread+0x278/0x2f8
>    ret_from_fork+0x10/0x20
> [...]
> 
> Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
> decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
> and so trigger BUG_ON() unexpectedly.
> 
> Fix this problem by using pmd_leaf() insteal of pmd_present() in
> pmd_user_accessible_page(). Moreover, use pud_leaf() for
> pud_user_accessible_page() too.
> 
> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
> ---
>   arch/arm64/include/asm/pgtable.h | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 71a1af42f0e8..edf6625ce965 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>   
>   static inline bool pmd_user_accessible_page(pmd_t pmd)
>   {
> -	return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
> +	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>   }
>   
>   static inline bool pud_user_accessible_page(pud_t pud)
>   {
> -	return pud_present(pud) && pud_user(pud);
> +	return pud_leaf(pud) && pud_user(pud);
>   }
>   #endif
>   

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 
Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
@ 2022-11-16  9:04     ` David Hildenbrand
  0 siblings, 0 replies; 28+ messages in thread
From: David Hildenbrand @ 2022-11-16  9:04 UTC (permalink / raw)
  To: Liu Shixin, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel

On 16.11.22 09:38, Liu Shixin wrote:
> The page table check trigger BUG_ON() unexpectedly when collapse hugepage:
> 
>   ------------[ cut here ]------------
>   kernel BUG at mm/page_table_check.c:82!
>   Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>   Dumping ftrace buffer:
>      (ftrace buffer empty)
>   Modules linked in:
>   CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
>   Hardware name: linux,dummy-virt (DT)
>   pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>   pc : page_table_check_clear.isra.0+0x258/0x3f0
>   lr : page_table_check_clear.isra.0+0x240/0x3f0
> [...]
>   Call trace:
>    page_table_check_clear.isra.0+0x258/0x3f0
>    __page_table_check_pmd_clear+0xbc/0x108
>    pmdp_collapse_flush+0xb0/0x160
>    collapse_huge_page+0xa08/0x1080
>    hpage_collapse_scan_pmd+0xf30/0x1590
>    khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
>    khugepaged+0x338/0x518
>    kthread+0x278/0x2f8
>    ret_from_fork+0x10/0x20
> [...]
> 
> Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
> decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
> and so trigger BUG_ON() unexpectedly.
> 
> Fix this problem by using pmd_leaf() insteal of pmd_present() in
> pmd_user_accessible_page(). Moreover, use pud_leaf() for
> pud_user_accessible_page() too.
> 
> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
> ---
>   arch/arm64/include/asm/pgtable.h | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 71a1af42f0e8..edf6625ce965 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>   
>   static inline bool pmd_user_accessible_page(pmd_t pmd)
>   {
> -	return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
> +	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>   }
>   
>   static inline bool pud_user_accessible_page(pud_t pud)
>   {
> -	return pud_present(pud) && pud_user(pud);
> +	return pud_leaf(pud) && pud_user(pud);
>   }
>   #endif
>   

Reviewed-by: David Hildenbrand <david@redhat.com>

-- 
Thanks,

David / dhildenb


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
  2022-11-16  8:38   ` Liu Shixin
@ 2022-11-16  9:08     ` David Hildenbrand
  -1 siblings, 0 replies; 28+ messages in thread
From: David Hildenbrand @ 2022-11-16  9:08 UTC (permalink / raw)
  To: Liu Shixin, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel

On 16.11.22 09:38, Liu Shixin wrote:
> The page table check trigger BUG_ON() unexpectedly when split hugepage:
> 
>   ------------[ cut here ]------------
>   kernel BUG at mm/page_table_check.c:119!
>   Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>   Dumping ftrace buffer:
>      (ftrace buffer empty)
>   Modules linked in:
>   CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
>   Hardware name: linux,dummy-virt (DT)
>   pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>   pc : page_table_check_set.isra.0+0x398/0x468
>   lr : page_table_check_set.isra.0+0x1c0/0x468
> [...]
>   Call trace:
>    page_table_check_set.isra.0+0x398/0x468
>    __page_table_check_pte_set+0x160/0x1c0
>    __split_huge_pmd_locked+0x900/0x1648
>    __split_huge_pmd+0x28c/0x3b8
>    unmap_page_range+0x428/0x858
>    unmap_single_vma+0xf4/0x1c8
>    zap_page_range+0x2b0/0x410
>    madvise_vma_behavior+0xc44/0xe78
>    do_madvise+0x280/0x698
>    __arm64_sys_madvise+0x90/0xe8
>    invoke_syscall.constprop.0+0xdc/0x1d8
>    do_el0_svc+0xf4/0x3f8
>    el0_svc+0x58/0x120
>    el0t_64_sync_handler+0xb8/0xc0
>    el0t_64_sync+0x19c/0x1a0
> [...]
> 
> On arm64, pmd_present() will return true even if the pmd is invalid.

I assume that's because of the pmd_present_invalid() check.

... I wonder why that behavior was chosen. Sounds error-prone to me.

Fix LGHTM, but I am not an arm64 pgtable expert.

-- 
Thanks,

David / dhildenb


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
@ 2022-11-16  9:08     ` David Hildenbrand
  0 siblings, 0 replies; 28+ messages in thread
From: David Hildenbrand @ 2022-11-16  9:08 UTC (permalink / raw)
  To: Liu Shixin, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel

On 16.11.22 09:38, Liu Shixin wrote:
> The page table check trigger BUG_ON() unexpectedly when split hugepage:
> 
>   ------------[ cut here ]------------
>   kernel BUG at mm/page_table_check.c:119!
>   Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>   Dumping ftrace buffer:
>      (ftrace buffer empty)
>   Modules linked in:
>   CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
>   Hardware name: linux,dummy-virt (DT)
>   pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>   pc : page_table_check_set.isra.0+0x398/0x468
>   lr : page_table_check_set.isra.0+0x1c0/0x468
> [...]
>   Call trace:
>    page_table_check_set.isra.0+0x398/0x468
>    __page_table_check_pte_set+0x160/0x1c0
>    __split_huge_pmd_locked+0x900/0x1648
>    __split_huge_pmd+0x28c/0x3b8
>    unmap_page_range+0x428/0x858
>    unmap_single_vma+0xf4/0x1c8
>    zap_page_range+0x2b0/0x410
>    madvise_vma_behavior+0xc44/0xe78
>    do_madvise+0x280/0x698
>    __arm64_sys_madvise+0x90/0xe8
>    invoke_syscall.constprop.0+0xdc/0x1d8
>    do_el0_svc+0xf4/0x3f8
>    el0_svc+0x58/0x120
>    el0t_64_sync_handler+0xb8/0xc0
>    el0t_64_sync+0x19c/0x1a0
> [...]
> 
> On arm64, pmd_present() will return true even if the pmd is invalid.

I assume that's because of the pmd_present_invalid() check.

... I wonder why that behavior was chosen. Sounds error-prone to me.

Fix LGHTM, but I am not an arm64 pgtable expert.

-- 
Thanks,

David / dhildenb


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
  2022-11-16  8:38   ` Liu Shixin
@ 2022-11-16 14:59     ` Pasha Tatashin
  -1 siblings, 0 replies; 28+ messages in thread
From: Pasha Tatashin @ 2022-11-16 14:59 UTC (permalink / raw)
  To: Liu Shixin
  Cc: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	linux-arm-kernel, linux-kernel

On Wed, Nov 16, 2022 at 2:51 AM Liu Shixin <liushixin2@huawei.com> wrote:
>
> The page table check trigger BUG_ON() unexpectedly when collapse hugepage:
>
>  ------------[ cut here ]------------
>  kernel BUG at mm/page_table_check.c:82!
>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>  Dumping ftrace buffer:
>     (ftrace buffer empty)
>  Modules linked in:
>  CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
>  Hardware name: linux,dummy-virt (DT)
>  pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : page_table_check_clear.isra.0+0x258/0x3f0
>  lr : page_table_check_clear.isra.0+0x240/0x3f0
> [...]
>  Call trace:
>   page_table_check_clear.isra.0+0x258/0x3f0
>   __page_table_check_pmd_clear+0xbc/0x108
>   pmdp_collapse_flush+0xb0/0x160
>   collapse_huge_page+0xa08/0x1080
>   hpage_collapse_scan_pmd+0xf30/0x1590
>   khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
>   khugepaged+0x338/0x518
>   kthread+0x278/0x2f8
>   ret_from_fork+0x10/0x20
> [...]
>
> Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
> decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
> and so trigger BUG_ON() unexpectedly.
>
> Fix this problem by using pmd_leaf() insteal of pmd_present() in

s/insteal/instead

> pmd_user_accessible_page(). Moreover, use pud_leaf() for
> pud_user_accessible_page() too.
>
> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
> ---
>  arch/arm64/include/asm/pgtable.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 71a1af42f0e8..edf6625ce965 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>
>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>  {
> -       return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
> +       return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>  }
>
>  static inline bool pud_user_accessible_page(pud_t pud)
>  {
> -       return pud_present(pud) && pud_user(pud);
> +       return pud_leaf(pud) && pud_user(pud);

Thanks a lot. The x86 variants are already using p*d_leaf() in these functions.

Acked-by: Pasha Tatashin <pasha.tatashin@soleen.com>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
@ 2022-11-16 14:59     ` Pasha Tatashin
  0 siblings, 0 replies; 28+ messages in thread
From: Pasha Tatashin @ 2022-11-16 14:59 UTC (permalink / raw)
  To: Liu Shixin
  Cc: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	linux-arm-kernel, linux-kernel

On Wed, Nov 16, 2022 at 2:51 AM Liu Shixin <liushixin2@huawei.com> wrote:
>
> The page table check trigger BUG_ON() unexpectedly when collapse hugepage:
>
>  ------------[ cut here ]------------
>  kernel BUG at mm/page_table_check.c:82!
>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>  Dumping ftrace buffer:
>     (ftrace buffer empty)
>  Modules linked in:
>  CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
>  Hardware name: linux,dummy-virt (DT)
>  pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : page_table_check_clear.isra.0+0x258/0x3f0
>  lr : page_table_check_clear.isra.0+0x240/0x3f0
> [...]
>  Call trace:
>   page_table_check_clear.isra.0+0x258/0x3f0
>   __page_table_check_pmd_clear+0xbc/0x108
>   pmdp_collapse_flush+0xb0/0x160
>   collapse_huge_page+0xa08/0x1080
>   hpage_collapse_scan_pmd+0xf30/0x1590
>   khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
>   khugepaged+0x338/0x518
>   kthread+0x278/0x2f8
>   ret_from_fork+0x10/0x20
> [...]
>
> Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
> decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
> and so trigger BUG_ON() unexpectedly.
>
> Fix this problem by using pmd_leaf() insteal of pmd_present() in

s/insteal/instead

> pmd_user_accessible_page(). Moreover, use pud_leaf() for
> pud_user_accessible_page() too.
>
> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
> ---
>  arch/arm64/include/asm/pgtable.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 71a1af42f0e8..edf6625ce965 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>
>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>  {
> -       return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
> +       return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>  }
>
>  static inline bool pud_user_accessible_page(pud_t pud)
>  {
> -       return pud_present(pud) && pud_user(pud);
> +       return pud_leaf(pud) && pud_user(pud);

Thanks a lot. The x86 variants are already using p*d_leaf() in these functions.

Acked-by: Pasha Tatashin <pasha.tatashin@soleen.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
  2022-11-16  8:38   ` Liu Shixin
@ 2022-11-16 15:18     ` Pasha Tatashin
  -1 siblings, 0 replies; 28+ messages in thread
From: Pasha Tatashin @ 2022-11-16 15:18 UTC (permalink / raw)
  To: Liu Shixin
  Cc: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	linux-arm-kernel, linux-kernel

On Wed, Nov 16, 2022 at 2:51 AM Liu Shixin <liushixin2@huawei.com> wrote:
>
> The page table check trigger BUG_ON() unexpectedly when split hugepage:
>
>  ------------[ cut here ]------------
>  kernel BUG at mm/page_table_check.c:119!
>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>  Dumping ftrace buffer:
>     (ftrace buffer empty)
>  Modules linked in:
>  CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
>  Hardware name: linux,dummy-virt (DT)
>  pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : page_table_check_set.isra.0+0x398/0x468
>  lr : page_table_check_set.isra.0+0x1c0/0x468
> [...]
>  Call trace:
>   page_table_check_set.isra.0+0x398/0x468
>   __page_table_check_pte_set+0x160/0x1c0
>   __split_huge_pmd_locked+0x900/0x1648
>   __split_huge_pmd+0x28c/0x3b8
>   unmap_page_range+0x428/0x858
>   unmap_single_vma+0xf4/0x1c8
>   zap_page_range+0x2b0/0x410
>   madvise_vma_behavior+0xc44/0xe78
>   do_madvise+0x280/0x698
>   __arm64_sys_madvise+0x90/0xe8
>   invoke_syscall.constprop.0+0xdc/0x1d8
>   do_el0_svc+0xf4/0x3f8
>   el0_svc+0x58/0x120
>   el0t_64_sync_handler+0xb8/0xc0
>   el0t_64_sync+0x19c/0x1a0
> [...]
>
> On arm64, pmd_present() will return true even if the pmd is invalid.
> in pmdp_invalidate() the file_map_count will not only decrease once but
> also increase once. Then in set_pte_at(), the file_map_count increase
> again, and so trigger BUG_ON() unexpectedly.

>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>  {
> -       return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
> +       return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)) && pmd_valid(pmd);
>  }
>
>  static inline bool pud_user_accessible_page(pud_t pud)
>  {
> -       return pud_leaf(pud) && pud_user(pud);
> +       return pud_leaf(pud) && pud_user(pud) && pud_valid(pud);

This looks closer to x86 where the check is directly: pmd_val(pmd) &
_PAGE_PRESENT, without PTE_PROT_NONE that is part of pmd_present()

Acked-by: Pasha Tatashin <pasha.tatashin@soleen.com>

Thanks,
Pasha

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
@ 2022-11-16 15:18     ` Pasha Tatashin
  0 siblings, 0 replies; 28+ messages in thread
From: Pasha Tatashin @ 2022-11-16 15:18 UTC (permalink / raw)
  To: Liu Shixin
  Cc: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	linux-arm-kernel, linux-kernel

On Wed, Nov 16, 2022 at 2:51 AM Liu Shixin <liushixin2@huawei.com> wrote:
>
> The page table check trigger BUG_ON() unexpectedly when split hugepage:
>
>  ------------[ cut here ]------------
>  kernel BUG at mm/page_table_check.c:119!
>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>  Dumping ftrace buffer:
>     (ftrace buffer empty)
>  Modules linked in:
>  CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
>  Hardware name: linux,dummy-virt (DT)
>  pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : page_table_check_set.isra.0+0x398/0x468
>  lr : page_table_check_set.isra.0+0x1c0/0x468
> [...]
>  Call trace:
>   page_table_check_set.isra.0+0x398/0x468
>   __page_table_check_pte_set+0x160/0x1c0
>   __split_huge_pmd_locked+0x900/0x1648
>   __split_huge_pmd+0x28c/0x3b8
>   unmap_page_range+0x428/0x858
>   unmap_single_vma+0xf4/0x1c8
>   zap_page_range+0x2b0/0x410
>   madvise_vma_behavior+0xc44/0xe78
>   do_madvise+0x280/0x698
>   __arm64_sys_madvise+0x90/0xe8
>   invoke_syscall.constprop.0+0xdc/0x1d8
>   do_el0_svc+0xf4/0x3f8
>   el0_svc+0x58/0x120
>   el0t_64_sync_handler+0xb8/0xc0
>   el0t_64_sync+0x19c/0x1a0
> [...]
>
> On arm64, pmd_present() will return true even if the pmd is invalid.
> in pmdp_invalidate() the file_map_count will not only decrease once but
> also increase once. Then in set_pte_at(), the file_map_count increase
> again, and so trigger BUG_ON() unexpectedly.

>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>  {
> -       return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
> +       return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)) && pmd_valid(pmd);
>  }
>
>  static inline bool pud_user_accessible_page(pud_t pud)
>  {
> -       return pud_leaf(pud) && pud_user(pud);
> +       return pud_leaf(pud) && pud_user(pud) && pud_valid(pud);

This looks closer to x86 where the check is directly: pmd_val(pmd) &
_PAGE_PRESENT, without PTE_PROT_NONE that is part of pmd_present()

Acked-by: Pasha Tatashin <pasha.tatashin@soleen.com>

Thanks,
Pasha

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
  2022-11-16  9:08     ` David Hildenbrand
@ 2022-11-16 15:46       ` Mark Rutland
  -1 siblings, 0 replies; 28+ messages in thread
From: Mark Rutland @ 2022-11-16 15:46 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Liu Shixin, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin, linux-arm-kernel, linux-kernel

On Wed, Nov 16, 2022 at 10:08:27AM +0100, David Hildenbrand wrote:
> On 16.11.22 09:38, Liu Shixin wrote:
> > The page table check trigger BUG_ON() unexpectedly when split hugepage:
> > 
> >   ------------[ cut here ]------------
> >   kernel BUG at mm/page_table_check.c:119!
> >   Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
> >   Dumping ftrace buffer:
> >      (ftrace buffer empty)
> >   Modules linked in:
> >   CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
> >   Hardware name: linux,dummy-virt (DT)
> >   pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> >   pc : page_table_check_set.isra.0+0x398/0x468
> >   lr : page_table_check_set.isra.0+0x1c0/0x468
> > [...]
> >   Call trace:
> >    page_table_check_set.isra.0+0x398/0x468
> >    __page_table_check_pte_set+0x160/0x1c0
> >    __split_huge_pmd_locked+0x900/0x1648
> >    __split_huge_pmd+0x28c/0x3b8
> >    unmap_page_range+0x428/0x858
> >    unmap_single_vma+0xf4/0x1c8
> >    zap_page_range+0x2b0/0x410
> >    madvise_vma_behavior+0xc44/0xe78
> >    do_madvise+0x280/0x698
> >    __arm64_sys_madvise+0x90/0xe8
> >    invoke_syscall.constprop.0+0xdc/0x1d8
> >    do_el0_svc+0xf4/0x3f8
> >    el0_svc+0x58/0x120
> >    el0t_64_sync_handler+0xb8/0xc0
> >    el0t_64_sync+0x19c/0x1a0
> > [...]
> > 
> > On arm64, pmd_present() will return true even if the pmd is invalid.
> 
> I assume that's because of the pmd_present_invalid() check.
> 
> ... I wonder why that behavior was chosen. Sounds error-prone to me.

That seems to be down to commit:

  b65399f6111b03df ("arm64/mm: Change THP helpers to comply with generic MM semantics")

... apparently because Andrea Arcangelli said this was necessary in:

  https://lore.kernel.org/lkml/20181017020930.GN30832@redhat.com/

... but that does see to contradict what's said in:

  Documentation/mm/arch_pgtable_helpers.rst

... which just says:

  pmd_present  Tests a valid mapped PMD 

... and it's not clear to me why this *only* applies to the PMD level.

Anshuman?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
@ 2022-11-16 15:46       ` Mark Rutland
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Rutland @ 2022-11-16 15:46 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Liu Shixin, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin, linux-arm-kernel, linux-kernel

On Wed, Nov 16, 2022 at 10:08:27AM +0100, David Hildenbrand wrote:
> On 16.11.22 09:38, Liu Shixin wrote:
> > The page table check trigger BUG_ON() unexpectedly when split hugepage:
> > 
> >   ------------[ cut here ]------------
> >   kernel BUG at mm/page_table_check.c:119!
> >   Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
> >   Dumping ftrace buffer:
> >      (ftrace buffer empty)
> >   Modules linked in:
> >   CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
> >   Hardware name: linux,dummy-virt (DT)
> >   pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> >   pc : page_table_check_set.isra.0+0x398/0x468
> >   lr : page_table_check_set.isra.0+0x1c0/0x468
> > [...]
> >   Call trace:
> >    page_table_check_set.isra.0+0x398/0x468
> >    __page_table_check_pte_set+0x160/0x1c0
> >    __split_huge_pmd_locked+0x900/0x1648
> >    __split_huge_pmd+0x28c/0x3b8
> >    unmap_page_range+0x428/0x858
> >    unmap_single_vma+0xf4/0x1c8
> >    zap_page_range+0x2b0/0x410
> >    madvise_vma_behavior+0xc44/0xe78
> >    do_madvise+0x280/0x698
> >    __arm64_sys_madvise+0x90/0xe8
> >    invoke_syscall.constprop.0+0xdc/0x1d8
> >    do_el0_svc+0xf4/0x3f8
> >    el0_svc+0x58/0x120
> >    el0t_64_sync_handler+0xb8/0xc0
> >    el0t_64_sync+0x19c/0x1a0
> > [...]
> > 
> > On arm64, pmd_present() will return true even if the pmd is invalid.
> 
> I assume that's because of the pmd_present_invalid() check.
> 
> ... I wonder why that behavior was chosen. Sounds error-prone to me.

That seems to be down to commit:

  b65399f6111b03df ("arm64/mm: Change THP helpers to comply with generic MM semantics")

... apparently because Andrea Arcangelli said this was necessary in:

  https://lore.kernel.org/lkml/20181017020930.GN30832@redhat.com/

... but that does see to contradict what's said in:

  Documentation/mm/arch_pgtable_helpers.rst

... which just says:

  pmd_present  Tests a valid mapped PMD 

... and it's not clear to me why this *only* applies to the PMD level.

Anshuman?

Thanks,
Mark.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
  2022-11-16  8:38   ` Liu Shixin
@ 2022-11-16 15:52     ` Mark Rutland
  -1 siblings, 0 replies; 28+ messages in thread
From: Mark Rutland @ 2022-11-16 15:52 UTC (permalink / raw)
  To: Liu Shixin
  Cc: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin, linux-arm-kernel, linux-kernel

On Wed, Nov 16, 2022 at 04:38:11PM +0800, Liu Shixin wrote:
> The page table check trigger BUG_ON() unexpectedly when split hugepage:
> 
>  ------------[ cut here ]------------
>  kernel BUG at mm/page_table_check.c:119!
>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>  Dumping ftrace buffer:
>     (ftrace buffer empty)
>  Modules linked in:
>  CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
>  Hardware name: linux,dummy-virt (DT)
>  pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : page_table_check_set.isra.0+0x398/0x468
>  lr : page_table_check_set.isra.0+0x1c0/0x468
> [...]
>  Call trace:
>   page_table_check_set.isra.0+0x398/0x468
>   __page_table_check_pte_set+0x160/0x1c0
>   __split_huge_pmd_locked+0x900/0x1648
>   __split_huge_pmd+0x28c/0x3b8
>   unmap_page_range+0x428/0x858
>   unmap_single_vma+0xf4/0x1c8
>   zap_page_range+0x2b0/0x410
>   madvise_vma_behavior+0xc44/0xe78
>   do_madvise+0x280/0x698
>   __arm64_sys_madvise+0x90/0xe8
>   invoke_syscall.constprop.0+0xdc/0x1d8
>   do_el0_svc+0xf4/0x3f8
>   el0_svc+0x58/0x120
>   el0t_64_sync_handler+0xb8/0xc0
>   el0t_64_sync+0x19c/0x1a0
> [...]
> 
> On arm64, pmd_present() will return true even if the pmd is invalid. So
> in pmdp_invalidate() the file_map_count will not only decrease once but
> also increase once. Then in set_pte_at(), the file_map_count increase
> again, and so trigger BUG_ON() unexpectedly.

It's not clear to me how pmd_present() relates to p?d_user_accessible_page()
below. How are they related? (or is this a copy-paste error)?

> Fix this problem by adding pmd_valid() in pmd_user_accessible_page().
> Moreover, add pud_valid() for pud_user_accessible_page() too.
> 
> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
> ---
>  arch/arm64/include/asm/pgtable.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index edf6625ce965..56e178de75e7 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>  
>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>  {
> -	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
> +	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)) && pmd_valid(pmd);
>  }
>  
>  static inline bool pud_user_accessible_page(pud_t pud)
>  {
> -	return pud_leaf(pud) && pud_user(pud);
> +	return pud_leaf(pud) && pud_user(pud) && pud_valid(pud);

I think these p?d_valid() checks should be first for clarity, since the other
bits aren't necessarily meaningful for !valid entries.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
@ 2022-11-16 15:52     ` Mark Rutland
  0 siblings, 0 replies; 28+ messages in thread
From: Mark Rutland @ 2022-11-16 15:52 UTC (permalink / raw)
  To: Liu Shixin
  Cc: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin, linux-arm-kernel, linux-kernel

On Wed, Nov 16, 2022 at 04:38:11PM +0800, Liu Shixin wrote:
> The page table check trigger BUG_ON() unexpectedly when split hugepage:
> 
>  ------------[ cut here ]------------
>  kernel BUG at mm/page_table_check.c:119!
>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>  Dumping ftrace buffer:
>     (ftrace buffer empty)
>  Modules linked in:
>  CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
>  Hardware name: linux,dummy-virt (DT)
>  pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : page_table_check_set.isra.0+0x398/0x468
>  lr : page_table_check_set.isra.0+0x1c0/0x468
> [...]
>  Call trace:
>   page_table_check_set.isra.0+0x398/0x468
>   __page_table_check_pte_set+0x160/0x1c0
>   __split_huge_pmd_locked+0x900/0x1648
>   __split_huge_pmd+0x28c/0x3b8
>   unmap_page_range+0x428/0x858
>   unmap_single_vma+0xf4/0x1c8
>   zap_page_range+0x2b0/0x410
>   madvise_vma_behavior+0xc44/0xe78
>   do_madvise+0x280/0x698
>   __arm64_sys_madvise+0x90/0xe8
>   invoke_syscall.constprop.0+0xdc/0x1d8
>   do_el0_svc+0xf4/0x3f8
>   el0_svc+0x58/0x120
>   el0t_64_sync_handler+0xb8/0xc0
>   el0t_64_sync+0x19c/0x1a0
> [...]
> 
> On arm64, pmd_present() will return true even if the pmd is invalid. So
> in pmdp_invalidate() the file_map_count will not only decrease once but
> also increase once. Then in set_pte_at(), the file_map_count increase
> again, and so trigger BUG_ON() unexpectedly.

It's not clear to me how pmd_present() relates to p?d_user_accessible_page()
below. How are they related? (or is this a copy-paste error)?

> Fix this problem by adding pmd_valid() in pmd_user_accessible_page().
> Moreover, add pud_valid() for pud_user_accessible_page() too.
> 
> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
> ---
>  arch/arm64/include/asm/pgtable.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index edf6625ce965..56e178de75e7 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>  
>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>  {
> -	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
> +	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)) && pmd_valid(pmd);
>  }
>  
>  static inline bool pud_user_accessible_page(pud_t pud)
>  {
> -	return pud_leaf(pud) && pud_user(pud);
> +	return pud_leaf(pud) && pud_user(pud) && pud_valid(pud);

I think these p?d_valid() checks should be first for clarity, since the other
bits aren't necessarily meaningful for !valid entries.

Thanks,
Mark.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
  2022-11-16 15:52     ` Mark Rutland
@ 2022-11-17  3:15       ` Liu Shixin
  -1 siblings, 0 replies; 28+ messages in thread
From: Liu Shixin @ 2022-11-17  3:15 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin, linux-arm-kernel, linux-kernel



On 2022/11/16 23:52, Mark Rutland wrote:
> On Wed, Nov 16, 2022 at 04:38:11PM +0800, Liu Shixin wrote:
>> The page table check trigger BUG_ON() unexpectedly when split hugepage:
>>
>>  ------------[ cut here ]------------
>>  kernel BUG at mm/page_table_check.c:119!
>>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>>  Dumping ftrace buffer:
>>     (ftrace buffer empty)
>>  Modules linked in:
>>  CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
>>  Hardware name: linux,dummy-virt (DT)
>>  pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>>  pc : page_table_check_set.isra.0+0x398/0x468
>>  lr : page_table_check_set.isra.0+0x1c0/0x468
>> [...]
>>  Call trace:
>>   page_table_check_set.isra.0+0x398/0x468
>>   __page_table_check_pte_set+0x160/0x1c0
>>   __split_huge_pmd_locked+0x900/0x1648
>>   __split_huge_pmd+0x28c/0x3b8
>>   unmap_page_range+0x428/0x858
>>   unmap_single_vma+0xf4/0x1c8
>>   zap_page_range+0x2b0/0x410
>>   madvise_vma_behavior+0xc44/0xe78
>>   do_madvise+0x280/0x698
>>   __arm64_sys_madvise+0x90/0xe8
>>   invoke_syscall.constprop.0+0xdc/0x1d8
>>   do_el0_svc+0xf4/0x3f8
>>   el0_svc+0x58/0x120
>>   el0t_64_sync_handler+0xb8/0xc0
>>   el0t_64_sync+0x19c/0x1a0
>> [...]
>>
>> On arm64, pmd_present() will return true even if the pmd is invalid. So
>> in pmdp_invalidate() the file_map_count will not only decrease once but
>> also increase once. Then in set_pte_at(), the file_map_count increase
>> again, and so trigger BUG_ON() unexpectedly.
> It's not clear to me how pmd_present() relates to p?d_user_accessible_page()
> below. How are they related? (or is this a copy-paste error)?
Yes, should be pmd_leaf(). In the previous patch, pmd_present() has already replaced with pmd_leaf().
Thanks for your careful discovery. Will fix in next version.
>> Fix this problem by adding pmd_valid() in pmd_user_accessible_page().
>> Moreover, add pud_valid() for pud_user_accessible_page() too.
>>
>> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
>> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
>> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
>> ---
>>  arch/arm64/include/asm/pgtable.h | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index edf6625ce965..56e178de75e7 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>>  
>>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>>  {
>> -	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>> +	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)) && pmd_valid(pmd);
>>  }
>>  
>>  static inline bool pud_user_accessible_page(pud_t pud)
>>  {
>> -	return pud_leaf(pud) && pud_user(pud);
>> +	return pud_leaf(pud) && pud_user(pud) && pud_valid(pud);
> I think these p?d_valid() checks should be first for clarity, since the other
> bits aren't necessarily meaningful for !valid entries.
Thanks for your advice.
>
> Thanks,
> Mark.
>
> .
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
@ 2022-11-17  3:15       ` Liu Shixin
  0 siblings, 0 replies; 28+ messages in thread
From: Liu Shixin @ 2022-11-17  3:15 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Catalin Marinas, Will Deacon, Denys Vlasenko, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin, linux-arm-kernel, linux-kernel



On 2022/11/16 23:52, Mark Rutland wrote:
> On Wed, Nov 16, 2022 at 04:38:11PM +0800, Liu Shixin wrote:
>> The page table check trigger BUG_ON() unexpectedly when split hugepage:
>>
>>  ------------[ cut here ]------------
>>  kernel BUG at mm/page_table_check.c:119!
>>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>>  Dumping ftrace buffer:
>>     (ftrace buffer empty)
>>  Modules linked in:
>>  CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
>>  Hardware name: linux,dummy-virt (DT)
>>  pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>>  pc : page_table_check_set.isra.0+0x398/0x468
>>  lr : page_table_check_set.isra.0+0x1c0/0x468
>> [...]
>>  Call trace:
>>   page_table_check_set.isra.0+0x398/0x468
>>   __page_table_check_pte_set+0x160/0x1c0
>>   __split_huge_pmd_locked+0x900/0x1648
>>   __split_huge_pmd+0x28c/0x3b8
>>   unmap_page_range+0x428/0x858
>>   unmap_single_vma+0xf4/0x1c8
>>   zap_page_range+0x2b0/0x410
>>   madvise_vma_behavior+0xc44/0xe78
>>   do_madvise+0x280/0x698
>>   __arm64_sys_madvise+0x90/0xe8
>>   invoke_syscall.constprop.0+0xdc/0x1d8
>>   do_el0_svc+0xf4/0x3f8
>>   el0_svc+0x58/0x120
>>   el0t_64_sync_handler+0xb8/0xc0
>>   el0t_64_sync+0x19c/0x1a0
>> [...]
>>
>> On arm64, pmd_present() will return true even if the pmd is invalid. So
>> in pmdp_invalidate() the file_map_count will not only decrease once but
>> also increase once. Then in set_pte_at(), the file_map_count increase
>> again, and so trigger BUG_ON() unexpectedly.
> It's not clear to me how pmd_present() relates to p?d_user_accessible_page()
> below. How are they related? (or is this a copy-paste error)?
Yes, should be pmd_leaf(). In the previous patch, pmd_present() has already replaced with pmd_leaf().
Thanks for your careful discovery. Will fix in next version.
>> Fix this problem by adding pmd_valid() in pmd_user_accessible_page().
>> Moreover, add pud_valid() for pud_user_accessible_page() too.
>>
>> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
>> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
>> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
>> ---
>>  arch/arm64/include/asm/pgtable.h | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index edf6625ce965..56e178de75e7 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>>  
>>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>>  {
>> -	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>> +	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)) && pmd_valid(pmd);
>>  }
>>  
>>  static inline bool pud_user_accessible_page(pud_t pud)
>>  {
>> -	return pud_leaf(pud) && pud_user(pud);
>> +	return pud_leaf(pud) && pud_user(pud) && pud_valid(pud);
> I think these p?d_valid() checks should be first for clarity, since the other
> bits aren't necessarily meaningful for !valid entries.
Thanks for your advice.
>
> Thanks,
> Mark.
>
> .
>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
  2022-11-16  8:38   ` Liu Shixin
@ 2022-11-17  4:09     ` Anshuman Khandual
  -1 siblings, 0 replies; 28+ messages in thread
From: Anshuman Khandual @ 2022-11-17  4:09 UTC (permalink / raw)
  To: Liu Shixin, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, David Hildenbrand, Rafael Aquini, Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel



On 11/16/22 14:08, Liu Shixin wrote:
> The page table check trigger BUG_ON() unexpectedly when collapse hugepage:
> 
>  ------------[ cut here ]------------
>  kernel BUG at mm/page_table_check.c:82!
>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>  Dumping ftrace buffer:
>     (ftrace buffer empty)
>  Modules linked in:
>  CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
>  Hardware name: linux,dummy-virt (DT)
>  pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : page_table_check_clear.isra.0+0x258/0x3f0
>  lr : page_table_check_clear.isra.0+0x240/0x3f0
> [...]
>  Call trace:
>   page_table_check_clear.isra.0+0x258/0x3f0
>   __page_table_check_pmd_clear+0xbc/0x108
>   pmdp_collapse_flush+0xb0/0x160
>   collapse_huge_page+0xa08/0x1080
>   hpage_collapse_scan_pmd+0xf30/0x1590
>   khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
>   khugepaged+0x338/0x518
>   kthread+0x278/0x2f8
>   ret_from_fork+0x10/0x20
> [...]
> 
> Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
> decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
> and so trigger BUG_ON() unexpectedly.

Could you please provide the pmd_val() on the pmd entry, that triggers this
BUG_ON() here ? Only additional thing pmd_leaf() ensures, is that the entry
is not a table one.

#define pmd_leaf(pmd)           (pmd_present(pmd) && !pmd_table(pmd))

collapse_huge_page() pmd is non-leaf because it has table bit on ?

> 
> Fix this problem by using pmd_leaf() insteal of pmd_present() in
> pmd_user_accessible_page(). Moreover, use pud_leaf() for
> pud_user_accessible_page() too.
> 
> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
> ---
>  arch/arm64/include/asm/pgtable.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 71a1af42f0e8..edf6625ce965 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>  
>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>  {
> -	return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
> +	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>  }
>  
>  static inline bool pud_user_accessible_page(pud_t pud)
>  {
> -	return pud_present(pud) && pud_user(pud);
> +	return pud_leaf(pud) && pud_user(pud);
>  }
>  #endif
>  

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
@ 2022-11-17  4:09     ` Anshuman Khandual
  0 siblings, 0 replies; 28+ messages in thread
From: Anshuman Khandual @ 2022-11-17  4:09 UTC (permalink / raw)
  To: Liu Shixin, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, David Hildenbrand, Rafael Aquini, Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel



On 11/16/22 14:08, Liu Shixin wrote:
> The page table check trigger BUG_ON() unexpectedly when collapse hugepage:
> 
>  ------------[ cut here ]------------
>  kernel BUG at mm/page_table_check.c:82!
>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>  Dumping ftrace buffer:
>     (ftrace buffer empty)
>  Modules linked in:
>  CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
>  Hardware name: linux,dummy-virt (DT)
>  pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : page_table_check_clear.isra.0+0x258/0x3f0
>  lr : page_table_check_clear.isra.0+0x240/0x3f0
> [...]
>  Call trace:
>   page_table_check_clear.isra.0+0x258/0x3f0
>   __page_table_check_pmd_clear+0xbc/0x108
>   pmdp_collapse_flush+0xb0/0x160
>   collapse_huge_page+0xa08/0x1080
>   hpage_collapse_scan_pmd+0xf30/0x1590
>   khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
>   khugepaged+0x338/0x518
>   kthread+0x278/0x2f8
>   ret_from_fork+0x10/0x20
> [...]
> 
> Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
> decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
> and so trigger BUG_ON() unexpectedly.

Could you please provide the pmd_val() on the pmd entry, that triggers this
BUG_ON() here ? Only additional thing pmd_leaf() ensures, is that the entry
is not a table one.

#define pmd_leaf(pmd)           (pmd_present(pmd) && !pmd_table(pmd))

collapse_huge_page() pmd is non-leaf because it has table bit on ?

> 
> Fix this problem by using pmd_leaf() insteal of pmd_present() in
> pmd_user_accessible_page(). Moreover, use pud_leaf() for
> pud_user_accessible_page() too.
> 
> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
> ---
>  arch/arm64/include/asm/pgtable.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 71a1af42f0e8..edf6625ce965 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>  
>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>  {
> -	return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
> +	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>  }
>  
>  static inline bool pud_user_accessible_page(pud_t pud)
>  {
> -	return pud_present(pud) && pud_user(pud);
> +	return pud_leaf(pud) && pud_user(pud);
>  }
>  #endif
>  

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
  2022-11-16 15:46       ` Mark Rutland
@ 2022-11-17  4:24         ` Anshuman Khandual
  -1 siblings, 0 replies; 28+ messages in thread
From: Anshuman Khandual @ 2022-11-17  4:24 UTC (permalink / raw)
  To: Mark Rutland, David Hildenbrand
  Cc: Liu Shixin, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, David Hildenbrand, Rafael Aquini, Pasha Tatashin,
	linux-arm-kernel, linux-kernel



On 11/16/22 21:16, Mark Rutland wrote:
> On Wed, Nov 16, 2022 at 10:08:27AM +0100, David Hildenbrand wrote:
>> On 16.11.22 09:38, Liu Shixin wrote:
>>> The page table check trigger BUG_ON() unexpectedly when split hugepage:
>>>
>>>   ------------[ cut here ]------------
>>>   kernel BUG at mm/page_table_check.c:119!
>>>   Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>>>   Dumping ftrace buffer:
>>>      (ftrace buffer empty)
>>>   Modules linked in:
>>>   CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
>>>   Hardware name: linux,dummy-virt (DT)
>>>   pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>>>   pc : page_table_check_set.isra.0+0x398/0x468
>>>   lr : page_table_check_set.isra.0+0x1c0/0x468
>>> [...]
>>>   Call trace:
>>>    page_table_check_set.isra.0+0x398/0x468
>>>    __page_table_check_pte_set+0x160/0x1c0
>>>    __split_huge_pmd_locked+0x900/0x1648
>>>    __split_huge_pmd+0x28c/0x3b8
>>>    unmap_page_range+0x428/0x858
>>>    unmap_single_vma+0xf4/0x1c8
>>>    zap_page_range+0x2b0/0x410
>>>    madvise_vma_behavior+0xc44/0xe78
>>>    do_madvise+0x280/0x698
>>>    __arm64_sys_madvise+0x90/0xe8
>>>    invoke_syscall.constprop.0+0xdc/0x1d8
>>>    do_el0_svc+0xf4/0x3f8
>>>    el0_svc+0x58/0x120
>>>    el0t_64_sync_handler+0xb8/0xc0
>>>    el0t_64_sync+0x19c/0x1a0
>>> [...]
>>>
>>> On arm64, pmd_present() will return true even if the pmd is invalid.
>>
>> I assume that's because of the pmd_present_invalid() check.
>>
>> ... I wonder why that behavior was chosen. Sounds error-prone to me.
> 
> That seems to be down to commit:
> 
>   b65399f6111b03df ("arm64/mm: Change THP helpers to comply with generic MM semantics")
> 
> ... apparently because Andrea Arcangelli said this was necessary in:
> 
>   https://lore.kernel.org/lkml/20181017020930.GN30832@redhat.com/
> 
> ... but that does see to contradict what's said in:
> 
>   Documentation/mm/arch_pgtable_helpers.rst
> 
> ... which just says:
> 
>   pmd_present  Tests a valid mapped PMD

It should be as follows instead, will update. Not sure about PUD level though,
where anon THP is not supported (AFAIK).

+---------------------------+--------------------------------------------------+
| pmd_present               | Tests if pmd_page() points to valid memory page  |
+---------------------------+--------------------------------------------------+

> 
> ... and it's not clear to me why this *only* applies to the PMD level.
> 
> Anshuman?

Because THP is supported at PMD level. As Andrea had explained earlier, pmd_present()
should return positive if pmd_page() on the entry points to valid memory irrespective
of whether the entry is valid/mapped or not. That is the semantics expected in generic
THP during PMD split, collapse, migration etc and other memory code walking past such
PMD entries. That was my understanding.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud
@ 2022-11-17  4:24         ` Anshuman Khandual
  0 siblings, 0 replies; 28+ messages in thread
From: Anshuman Khandual @ 2022-11-17  4:24 UTC (permalink / raw)
  To: Mark Rutland, David Hildenbrand
  Cc: Liu Shixin, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, David Hildenbrand, Rafael Aquini, Pasha Tatashin,
	linux-arm-kernel, linux-kernel



On 11/16/22 21:16, Mark Rutland wrote:
> On Wed, Nov 16, 2022 at 10:08:27AM +0100, David Hildenbrand wrote:
>> On 16.11.22 09:38, Liu Shixin wrote:
>>> The page table check trigger BUG_ON() unexpectedly when split hugepage:
>>>
>>>   ------------[ cut here ]------------
>>>   kernel BUG at mm/page_table_check.c:119!
>>>   Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>>>   Dumping ftrace buffer:
>>>      (ftrace buffer empty)
>>>   Modules linked in:
>>>   CPU: 7 PID: 210 Comm: transhuge-stres Not tainted 6.1.0-rc3+ #748
>>>   Hardware name: linux,dummy-virt (DT)
>>>   pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>>>   pc : page_table_check_set.isra.0+0x398/0x468
>>>   lr : page_table_check_set.isra.0+0x1c0/0x468
>>> [...]
>>>   Call trace:
>>>    page_table_check_set.isra.0+0x398/0x468
>>>    __page_table_check_pte_set+0x160/0x1c0
>>>    __split_huge_pmd_locked+0x900/0x1648
>>>    __split_huge_pmd+0x28c/0x3b8
>>>    unmap_page_range+0x428/0x858
>>>    unmap_single_vma+0xf4/0x1c8
>>>    zap_page_range+0x2b0/0x410
>>>    madvise_vma_behavior+0xc44/0xe78
>>>    do_madvise+0x280/0x698
>>>    __arm64_sys_madvise+0x90/0xe8
>>>    invoke_syscall.constprop.0+0xdc/0x1d8
>>>    do_el0_svc+0xf4/0x3f8
>>>    el0_svc+0x58/0x120
>>>    el0t_64_sync_handler+0xb8/0xc0
>>>    el0t_64_sync+0x19c/0x1a0
>>> [...]
>>>
>>> On arm64, pmd_present() will return true even if the pmd is invalid.
>>
>> I assume that's because of the pmd_present_invalid() check.
>>
>> ... I wonder why that behavior was chosen. Sounds error-prone to me.
> 
> That seems to be down to commit:
> 
>   b65399f6111b03df ("arm64/mm: Change THP helpers to comply with generic MM semantics")
> 
> ... apparently because Andrea Arcangelli said this was necessary in:
> 
>   https://lore.kernel.org/lkml/20181017020930.GN30832@redhat.com/
> 
> ... but that does see to contradict what's said in:
> 
>   Documentation/mm/arch_pgtable_helpers.rst
> 
> ... which just says:
> 
>   pmd_present  Tests a valid mapped PMD

It should be as follows instead, will update. Not sure about PUD level though,
where anon THP is not supported (AFAIK).

+---------------------------+--------------------------------------------------+
| pmd_present               | Tests if pmd_page() points to valid memory page  |
+---------------------------+--------------------------------------------------+

> 
> ... and it's not clear to me why this *only* applies to the PMD level.
> 
> Anshuman?

Because THP is supported at PMD level. As Andrea had explained earlier, pmd_present()
should return positive if pmd_page() on the entry points to valid memory irrespective
of whether the entry is valid/mapped or not. That is the semantics expected in generic
THP during PMD split, collapse, migration etc and other memory code walking past such
PMD entries. That was my understanding.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
  2022-11-17  4:09     ` Anshuman Khandual
@ 2022-11-17  6:59       ` Liu Shixin
  -1 siblings, 0 replies; 28+ messages in thread
From: Liu Shixin @ 2022-11-17  6:59 UTC (permalink / raw)
  To: Anshuman Khandual, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, David Hildenbrand, Rafael Aquini, Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel



On 2022/11/17 12:09, Anshuman Khandual wrote:
>
> On 11/16/22 14:08, Liu Shixin wrote:
>> The page table check trigger BUG_ON() unexpectedly when collapse hugepage:
>>
>>  ------------[ cut here ]------------
>>  kernel BUG at mm/page_table_check.c:82!
>>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>>  Dumping ftrace buffer:
>>     (ftrace buffer empty)
>>  Modules linked in:
>>  CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
>>  Hardware name: linux,dummy-virt (DT)
>>  pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>>  pc : page_table_check_clear.isra.0+0x258/0x3f0
>>  lr : page_table_check_clear.isra.0+0x240/0x3f0
>> [...]
>>  Call trace:
>>   page_table_check_clear.isra.0+0x258/0x3f0
>>   __page_table_check_pmd_clear+0xbc/0x108
>>   pmdp_collapse_flush+0xb0/0x160
>>   collapse_huge_page+0xa08/0x1080
>>   hpage_collapse_scan_pmd+0xf30/0x1590
>>   khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
>>   khugepaged+0x338/0x518
>>   kthread+0x278/0x2f8
>>   ret_from_fork+0x10/0x20
>> [...]
>>
>> Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
>> decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
>> and so trigger BUG_ON() unexpectedly.
> Could you please provide the pmd_val() on the pmd entry, that triggers this
> BUG_ON() here ? Only additional thing pmd_leaf() ensures, is that the entry
> is not a table one.
>
> #define pmd_leaf(pmd)           (pmd_present(pmd) && !pmd_table(pmd))
>
> collapse_huge_page() pmd is non-leaf because it has table bit on ?
The pmd_val is 0x80000004c367003. It is indeed a table entry. collapse_huge_page()
will replace page table of page granularity with block granularity. Before this replace,
it will call pmdp_collapse_flush() to clear the table pmd. In this function, the table pmd
do the check unexpectdly and trigger the BUG_ON().

diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
index 90ab721a12a8..a5c2380bac4d 100644
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -221,6 +221,7 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long address,
 
        VM_BUG_ON(address & ~HPAGE_PMD_MASK);
        VM_BUG_ON(pmd_trans_huge(*pmdp));
+       pr_err("pmd_val is 0x%lx\n", pmd_val(*pmdp));
        pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
 
        /* collapse entails shooting down ptes not pmd */

Thanks,
Liu Shixin
.

>
>> Fix this problem by using pmd_leaf() insteal of pmd_present() in
>> pmd_user_accessible_page(). Moreover, use pud_leaf() for
>> pud_user_accessible_page() too.
>>
>> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
>> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
>> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
>> ---
>>  arch/arm64/include/asm/pgtable.h | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index 71a1af42f0e8..edf6625ce965 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>>  
>>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>>  {
>> -	return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>> +	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>>  }
>>  
>>  static inline bool pud_user_accessible_page(pud_t pud)
>>  {
>> -	return pud_present(pud) && pud_user(pud);
>> +	return pud_leaf(pud) && pud_user(pud);
>>  }
>>  #endif
>>  
> .
>


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
@ 2022-11-17  6:59       ` Liu Shixin
  0 siblings, 0 replies; 28+ messages in thread
From: Liu Shixin @ 2022-11-17  6:59 UTC (permalink / raw)
  To: Anshuman Khandual, Catalin Marinas, Will Deacon, Denys Vlasenko,
	Kefeng Wang, David Hildenbrand, Rafael Aquini, Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel



On 2022/11/17 12:09, Anshuman Khandual wrote:
>
> On 11/16/22 14:08, Liu Shixin wrote:
>> The page table check trigger BUG_ON() unexpectedly when collapse hugepage:
>>
>>  ------------[ cut here ]------------
>>  kernel BUG at mm/page_table_check.c:82!
>>  Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>>  Dumping ftrace buffer:
>>     (ftrace buffer empty)
>>  Modules linked in:
>>  CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
>>  Hardware name: linux,dummy-virt (DT)
>>  pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>>  pc : page_table_check_clear.isra.0+0x258/0x3f0
>>  lr : page_table_check_clear.isra.0+0x240/0x3f0
>> [...]
>>  Call trace:
>>   page_table_check_clear.isra.0+0x258/0x3f0
>>   __page_table_check_pmd_clear+0xbc/0x108
>>   pmdp_collapse_flush+0xb0/0x160
>>   collapse_huge_page+0xa08/0x1080
>>   hpage_collapse_scan_pmd+0xf30/0x1590
>>   khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
>>   khugepaged+0x338/0x518
>>   kthread+0x278/0x2f8
>>   ret_from_fork+0x10/0x20
>> [...]
>>
>> Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
>> decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
>> and so trigger BUG_ON() unexpectedly.
> Could you please provide the pmd_val() on the pmd entry, that triggers this
> BUG_ON() here ? Only additional thing pmd_leaf() ensures, is that the entry
> is not a table one.
>
> #define pmd_leaf(pmd)           (pmd_present(pmd) && !pmd_table(pmd))
>
> collapse_huge_page() pmd is non-leaf because it has table bit on ?
The pmd_val is 0x80000004c367003. It is indeed a table entry. collapse_huge_page()
will replace page table of page granularity with block granularity. Before this replace,
it will call pmdp_collapse_flush() to clear the table pmd. In this function, the table pmd
do the check unexpectdly and trigger the BUG_ON().

diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
index 90ab721a12a8..a5c2380bac4d 100644
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -221,6 +221,7 @@ pmd_t pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long address,
 
        VM_BUG_ON(address & ~HPAGE_PMD_MASK);
        VM_BUG_ON(pmd_trans_huge(*pmdp));
+       pr_err("pmd_val is 0x%lx\n", pmd_val(*pmdp));
        pmd = pmdp_huge_get_and_clear(vma->vm_mm, address, pmdp);
 
        /* collapse entails shooting down ptes not pmd */

Thanks,
Liu Shixin
.

>
>> Fix this problem by using pmd_leaf() insteal of pmd_present() in
>> pmd_user_accessible_page(). Moreover, use pud_leaf() for
>> pud_user_accessible_page() too.
>>
>> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
>> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
>> Signed-off-by: Liu Shixin <liushixin2@huawei.com>
>> ---
>>  arch/arm64/include/asm/pgtable.h | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index 71a1af42f0e8..edf6625ce965 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
>>  
>>  static inline bool pmd_user_accessible_page(pmd_t pmd)
>>  {
>> -	return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>> +	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
>>  }
>>  
>>  static inline bool pud_user_accessible_page(pud_t pud)
>>  {
>> -	return pud_present(pud) && pud_user(pud);
>> +	return pud_leaf(pud) && pud_user(pud);
>>  }
>>  #endif
>>  
> .
>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
  2022-11-16  8:38   ` Liu Shixin
@ 2022-11-21 15:57     ` Denys Vlasenko
  -1 siblings, 0 replies; 28+ messages in thread
From: Denys Vlasenko @ 2022-11-21 15:57 UTC (permalink / raw)
  To: Liu Shixin, Catalin Marinas, Will Deacon, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel

On 11/16/22 09:38, Liu Shixin wrote:
> The page table check trigger BUG_ON() unexpectedly when collapse hugepage:
> 
>   ------------[ cut here ]------------
>   kernel BUG at mm/page_table_check.c:82!
>   Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>   Dumping ftrace buffer:
>      (ftrace buffer empty)
>   Modules linked in:
>   CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
>   Hardware name: linux,dummy-virt (DT)
>   pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>   pc : page_table_check_clear.isra.0+0x258/0x3f0
>   lr : page_table_check_clear.isra.0+0x240/0x3f0
> [...]
>   Call trace:
>    page_table_check_clear.isra.0+0x258/0x3f0
>    __page_table_check_pmd_clear+0xbc/0x108
>    pmdp_collapse_flush+0xb0/0x160
>    collapse_huge_page+0xa08/0x1080
>    hpage_collapse_scan_pmd+0xf30/0x1590
>    khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
>    khugepaged+0x338/0x518
>    kthread+0x278/0x2f8
>    ret_from_fork+0x10/0x20
> [...]
> 
> Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
> decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
> and so trigger BUG_ON() unexpectedly.
> 
> Fix this problem by using pmd_leaf() insteal of pmd_present() in
> pmd_user_accessible_page(). Moreover, use pud_leaf() for
> pud_user_accessible_page() too.
> 
> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Liu Shixin <liushixin2@huawei.com>


Tested on 6.0.6 kernel, no oopses anymore.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud
@ 2022-11-21 15:57     ` Denys Vlasenko
  0 siblings, 0 replies; 28+ messages in thread
From: Denys Vlasenko @ 2022-11-21 15:57 UTC (permalink / raw)
  To: Liu Shixin, Catalin Marinas, Will Deacon, Kefeng Wang,
	Anshuman Khandual, David Hildenbrand, Rafael Aquini,
	Pasha Tatashin
  Cc: linux-arm-kernel, linux-kernel

On 11/16/22 09:38, Liu Shixin wrote:
> The page table check trigger BUG_ON() unexpectedly when collapse hugepage:
> 
>   ------------[ cut here ]------------
>   kernel BUG at mm/page_table_check.c:82!
>   Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
>   Dumping ftrace buffer:
>      (ftrace buffer empty)
>   Modules linked in:
>   CPU: 6 PID: 68 Comm: khugepaged Not tainted 6.1.0-rc3+ #750
>   Hardware name: linux,dummy-virt (DT)
>   pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>   pc : page_table_check_clear.isra.0+0x258/0x3f0
>   lr : page_table_check_clear.isra.0+0x240/0x3f0
> [...]
>   Call trace:
>    page_table_check_clear.isra.0+0x258/0x3f0
>    __page_table_check_pmd_clear+0xbc/0x108
>    pmdp_collapse_flush+0xb0/0x160
>    collapse_huge_page+0xa08/0x1080
>    hpage_collapse_scan_pmd+0xf30/0x1590
>    khugepaged_scan_mm_slot.constprop.0+0x52c/0xac8
>    khugepaged+0x338/0x518
>    kthread+0x278/0x2f8
>    ret_from_fork+0x10/0x20
> [...]
> 
> Since pmd_user_accessible_page() doesn't check if a pmd is leaf, it
> decrease file_map_count for a non-leaf pmd comes from collapse_huge_page().
> and so trigger BUG_ON() unexpectedly.
> 
> Fix this problem by using pmd_leaf() insteal of pmd_present() in
> pmd_user_accessible_page(). Moreover, use pud_leaf() for
> pud_user_accessible_page() too.
> 
> Fixes: 42b2547137f5 ("arm64/mm: enable ARCH_SUPPORTS_PAGE_TABLE_CHECK")
> Reported-by: Denys Vlasenko <dvlasenk@redhat.com>
> Signed-off-by: Liu Shixin <liushixin2@huawei.com>


Tested on 6.0.6 kernel, no oopses anymore.


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2022-11-21 16:01 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-16  8:38 [PATCH 0/2] arm64: fix two bug about page table check Liu Shixin
2022-11-16  8:38 ` Liu Shixin
2022-11-16  8:38 ` [PATCH 1/2] arm64/mm: fix incorrect file_map_count for non-leaf pmd/pud Liu Shixin
2022-11-16  8:38   ` Liu Shixin
2022-11-16  9:04   ` David Hildenbrand
2022-11-16  9:04     ` David Hildenbrand
2022-11-16 14:59   ` Pasha Tatashin
2022-11-16 14:59     ` Pasha Tatashin
2022-11-17  4:09   ` Anshuman Khandual
2022-11-17  4:09     ` Anshuman Khandual
2022-11-17  6:59     ` Liu Shixin
2022-11-17  6:59       ` Liu Shixin
2022-11-21 15:57   ` Denys Vlasenko
2022-11-21 15:57     ` Denys Vlasenko
2022-11-16  8:38 ` [PATCH 2/2] arm64/mm: fix incorrect file_map_count for invalid pmd/pud Liu Shixin
2022-11-16  8:38   ` Liu Shixin
2022-11-16  9:08   ` David Hildenbrand
2022-11-16  9:08     ` David Hildenbrand
2022-11-16 15:46     ` Mark Rutland
2022-11-16 15:46       ` Mark Rutland
2022-11-17  4:24       ` Anshuman Khandual
2022-11-17  4:24         ` Anshuman Khandual
2022-11-16 15:18   ` Pasha Tatashin
2022-11-16 15:18     ` Pasha Tatashin
2022-11-16 15:52   ` Mark Rutland
2022-11-16 15:52     ` Mark Rutland
2022-11-17  3:15     ` Liu Shixin
2022-11-17  3:15       ` Liu Shixin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.