Skip to content

Commit 7974c47

Browse files
chleroympe
authored andcommitted
powerpc/32s: Implement dedicated kasan_init_region()
Implement a kasan_init_region() dedicated to book3s/32 that allocates KASAN regions using BATs. Signed-off-by: Christophe Leroy <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/709e821602b48a1d7c211a9b156da26db98c3e9d.1589866984.git.christophe.leroy@csgroup.eu
1 parent 2b279c0 commit 7974c47

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

arch/powerpc/include/asm/kasan.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ static inline void kasan_init(void) { }
3434
static inline void kasan_late_init(void) { }
3535
#endif
3636

37+
void kasan_update_early_region(unsigned long k_start, unsigned long k_end, pte_t pte);
3738
int kasan_init_shadow_page_tables(unsigned long k_start, unsigned long k_end);
3839
int kasan_init_region(void *start, size_t size);
3940

arch/powerpc/mm/kasan/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ KASAN_SANITIZE := n
44

55
obj-$(CONFIG_PPC32) += kasan_init_32.o
66
obj-$(CONFIG_PPC_8xx) += 8xx.o
7+
obj-$(CONFIG_PPC_BOOK3S_32) += book3s_32.o

arch/powerpc/mm/kasan/book3s_32.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#define DISABLE_BRANCH_PROFILING
4+
5+
#include <linux/kasan.h>
6+
#include <linux/memblock.h>
7+
#include <asm/pgalloc.h>
8+
#include <mm/mmu_decl.h>
9+
10+
int __init kasan_init_region(void *start, size_t size)
11+
{
12+
unsigned long k_start = (unsigned long)kasan_mem_to_shadow(start);
13+
unsigned long k_end = (unsigned long)kasan_mem_to_shadow(start + size);
14+
unsigned long k_cur = k_start;
15+
int k_size = k_end - k_start;
16+
int k_size_base = 1 << (ffs(k_size) - 1);
17+
int ret;
18+
void *block;
19+
20+
block = memblock_alloc(k_size, k_size_base);
21+
22+
if (block && k_size_base >= SZ_128K && k_start == ALIGN(k_start, k_size_base)) {
23+
int k_size_more = 1 << (ffs(k_size - k_size_base) - 1);
24+
25+
setbat(-1, k_start, __pa(block), k_size_base, PAGE_KERNEL);
26+
if (k_size_more >= SZ_128K)
27+
setbat(-1, k_start + k_size_base, __pa(block) + k_size_base,
28+
k_size_more, PAGE_KERNEL);
29+
if (v_block_mapped(k_start))
30+
k_cur = k_start + k_size_base;
31+
if (v_block_mapped(k_start + k_size_base))
32+
k_cur = k_start + k_size_base + k_size_more;
33+
34+
update_bats();
35+
}
36+
37+
if (!block)
38+
block = memblock_alloc(k_size, PAGE_SIZE);
39+
if (!block)
40+
return -ENOMEM;
41+
42+
ret = kasan_init_shadow_page_tables(k_start, k_end);
43+
if (ret)
44+
return ret;
45+
46+
kasan_update_early_region(k_start, k_cur, __pte(0));
47+
48+
for (; k_cur < k_end; k_cur += PAGE_SIZE) {
49+
pmd_t *pmd = pmd_ptr_k(k_cur);
50+
void *va = block + k_cur - k_start;
51+
pte_t pte = pfn_pte(PHYS_PFN(__pa(va)), PAGE_KERNEL);
52+
53+
__set_pte_at(&init_mm, k_cur, pte_offset_kernel(pmd, k_cur), pte, 0);
54+
}
55+
flush_tlb_kernel_range(k_start, k_end);
56+
return 0;
57+
}

arch/powerpc/mm/kasan/kasan_init_32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ int __init __weak kasan_init_region(void *start, size_t size)
7979
return 0;
8080
}
8181

82-
static void __init
82+
void __init
8383
kasan_update_early_region(unsigned long k_start, unsigned long k_end, pte_t pte)
8484
{
8585
unsigned long k_cur;

0 commit comments

Comments
 (0)