Skip to contentSkip to conversation

arm64: kasan: Use actual memory node when populating the kernel image shadow

PATCH New Catalin Marinas 4 participants 5 messages Mar 10, 2016 – Mar 11, 2016

Subsystems (2)
lore
Share & tools
lore

Catalin Marinas

author maintainer
#0 lore raw

PATCH 1/1 arm64: kasan: Use actual memory node when populating the kernel image shadow

With the 16KB or 64KB page configurations, the generic vmemmap_populate() implementation warns on potential offnode page_structs via vmemmap_verify() because the arm64 kasan_init() passes NUMA_NO_NODE instead of the actual node for the kernel image memory.

Fixes f9040773b7bb ("arm64: move kernel image to base of vmalloc area")
---
 arch/arm64/mm/kasan_init.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/mm/kasan_init.c +2 -1
index 56e19d150c21..a164183f3481 100644
@@ -152,7 +152,8 @@ void __init kasan_init(void)
 
 	clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
-	vmemmap_populate(kimg_shadow_start, kimg_shadow_end, NUMA_NO_NODE);
+	vmemmap_populate(kimg_shadow_start, kimg_shadow_end,
+			 pfn_to_nid(virt_to_pfn(_text)));
 
 	/*
 	 * vmemmap_populate() has populated the shadow region that covers the
#1 lore raw

PATCH 1/1 arm64: kasan: Use actual memory node when populating the kernel image shadow

Quoted 8 lines · Catalin Marinas

With the 16KB or 64KB page configurations, the generic vmemmap_populate() implementation warns on potential offnode page_structs via vmemmap_verify() because the arm64 kasan_init() passes NUMA_NO_NODE instead of the actual node for the kernel image memory.

Fixes f9040773b7bb ("arm64: move kernel image to base of vmalloc area")

I still think using vmemmap_populate() is somewhat of a hack here, and the fact that we have different versions for 4k pages and !4k pages, while perhaps justified for the actual real purpose of allocating struct page arrays, makes this code more fragile than it needs to be. How difficult would it be to simply have a kasan specific vmalloc_shadow() function that performs a memblock_alloc/create_mapping, and does the right thing wrt aligning the edges, rather than putting knowledge about how vmemmap_populate happens to align its allocations into the kasan code?

Regardless,

Quoted 18 lines
---
 arch/arm64/mm/kasan_init.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/mm/kasan_init.c +2 -1
index 56e19d150c21..a164183f3481 100644
@@ -152,7 +152,8 @@ void __init kasan_init(void)
 
        clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
-       vmemmap_populate(kimg_shadow_start, kimg_shadow_end, NUMA_NO_NODE);
+       vmemmap_populate(kimg_shadow_start, kimg_shadow_end,
+                        pfn_to_nid(virt_to_pfn(_text)));
 
        /*
         * vmemmap_populate() has populated the shadow region that covers the
reviewer
#2 lore raw

PATCH 1/1 arm64: kasan: Use actual memory node when populating the kernel image shadow

Quoted 6 lines · Ard Biesheuvel
Quoted 5 lines · Catalin Marinas

With the 16KB or 64KB page configurations, the generic vmemmap_populate() implementation warns on potential offnode page_structs via vmemmap_verify() because the arm64 kasan_init() passes NUMA_NO_NODE instead of the actual node for the kernel image memory.

Quoted 8 lines
Quoted 3 lines
Fixes f9040773b7bb ("arm64: move kernel image to base of vmalloc area")

I still think using vmemmap_populate() is somewhat of a hack here, and the fact that we have different versions for 4k pages and !4k pages, while perhaps justified for the actual real purpose of allocating struct page arrays, makes this code more fragile than it needs to be.

One of the things I had hoped to look into was having a common p?d block mapping aware vmemmap_populate that we could use in all cases, so we could minimise TLB pressure for vmemmap regardless of SWAPPER_USES_SECTION_MAPS (when we can allocate sufficiently aligned physical memory).

[...]

Quoted 3 lines

Regardless,

Likewise:

Quoted 20 lines
Quoted 19 lines
---
 arch/arm64/mm/kasan_init.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/mm/kasan_init.c +2 -1
index 56e19d150c21..a164183f3481 100644
@@ -152,7 +152,8 @@ void __init kasan_init(void)
 
        clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
-       vmemmap_populate(kimg_shadow_start, kimg_shadow_end, NUMA_NO_NODE);
+       vmemmap_populate(kimg_shadow_start, kimg_shadow_end,
+                        pfn_to_nid(virt_to_pfn(_text)));
 
        /*
         * vmemmap_populate() has populated the shadow region that covers the
author maintainer
#3 lore raw

PATCH 1/1 arm64: kasan: Use actual memory node when populating the kernel image shadow

In reply to Ard Biesheuvel
Quoted 6 lines · Ard Biesheuvel
Quoted 5 lines · Catalin Marinas

With the 16KB or 64KB page configurations, the generic vmemmap_populate() implementation warns on potential offnode page_structs via vmemmap_verify() because the arm64 kasan_init() passes NUMA_NO_NODE instead of the actual node for the kernel image memory.

Quoted 8 lines
Quoted 3 lines
Fixes f9040773b7bb ("arm64: move kernel image to base of vmalloc area")

I still think using vmemmap_populate() is somewhat of a hack here, and the fact that we have different versions for 4k pages and !4k pages, while perhaps justified for the actual real purpose of allocating struct page arrays, makes this code more fragile than it needs to be.

I agree, kasan is hijacking API meant for something else.

Quoted 5 lines

How difficult would it be to simply have a kasan specific vmalloc_shadow() function that performs a memblock_alloc/create_mapping, and does the right thing wrt aligning the edges, rather than putting knowledge about how vmemmap_populate happens to align its allocations into the kasan code?

With a long flight from Bangkok, who knows, I may see some patches on Monday ;)

Anyway, I think we also need to change the 4K pages vmemmap_populate to do a vmemmap_verify in all cases, something like below (untested):

arch/arm64/mm/mmu.c +2 -2
index d2d8b8c2e17f..c0f61235a6ec 100644
@@ -642,8 +642,8 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
 				return -ENOMEM;
 
 			set_pmd(pmd, __pmd(__pa(p) | PROT_SECT_NORMAL));
-		} else
-			vmemmap_verify((pte_t *)pmd, node, addr, next);
+		}
+		vmemmap_verify((pte_t *)pmd, node, addr, next);
 	} while (addr = next, addr != end);
 
 	return 0;
Signature · 1 line
Catalin
#4 lore raw

PATCH 1/1 arm64: kasan: Use actual memory node when populating the kernel image shadow

In reply to Ard Biesheuvel
Quoted 10 lines · Ard Biesheuvel
Quoted 8 lines · Catalin Marinas

With the 16KB or 64KB page configurations, the generic vmemmap_populate() implementation warns on potential offnode page_structs via vmemmap_verify() because the arm64 kasan_init() passes NUMA_NO_NODE instead of the actual node for the kernel image memory.

Fixes f9040773b7bb ("arm64: move kernel image to base of vmalloc area")
Quoted 9 lines

I still think using vmemmap_populate() is somewhat of a hack here, and the fact that we have different versions for 4k pages and !4k pages, while perhaps justified for the actual real purpose of allocating struct page arrays, makes this code more fragile than it needs to be. How difficult would it be to simply have a kasan specific vmalloc_shadow() function that performs a memblock_alloc/create_mapping, and does the right thing wrt aligning the edges, rather than putting knowledge about how vmemmap_populate happens to align its allocations into the kasan code?

Should be easy.