diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2017-12-03 16:28:52 -0500 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2017-12-17 01:37:12 -0500 |
commit | c633544a6154146a210cf158157a1ae7c55473b6 (patch) | |
tree | d670a9984373622d991c382126f341b6f32154cd | |
parent | 1af1e8a39dc0fab5e50f10462c636da8c1e0cfbb (diff) |
xtensa: add support for KASAN
Cover kernel addresses above 0x90000000 by the shadow map. Enable
HAVE_ARCH_KASAN when MMU is enabled. Provide kasan_early_init that fills
shadow map with writable copies of kasan_zero_page. Call
kasan_early_init right after mmu initialization in the setup_arch.
Provide kasan_init that allocates proper shadow map pages from the
memblock and puts these pages into the shadow map for addresses from
VMALLOC area to the end of KSEG. Call kasan_init right after memblock
initialization. Don't use KASAN for the boot code, MMU and KASAN
initialization and page fault handler. Make kernel stack size 4 times
larger when KASAN is enabled to avoid stack overflows.
GCC 7.3, 8 or newer is required to build the xtensa kernel with KASAN.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
-rw-r--r-- | Documentation/features/debug/KASAN/arch-support.txt | 2 | ||||
-rw-r--r-- | Documentation/xtensa/mmu.txt | 6 | ||||
-rw-r--r-- | arch/xtensa/Kconfig | 5 | ||||
-rw-r--r-- | arch/xtensa/boot/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/xtensa/include/asm/kasan.h | 37 | ||||
-rw-r--r-- | arch/xtensa/include/asm/kmem_layout.h | 4 | ||||
-rw-r--r-- | arch/xtensa/include/asm/pgtable.h | 3 | ||||
-rw-r--r-- | arch/xtensa/include/asm/string.h | 19 | ||||
-rw-r--r-- | arch/xtensa/kernel/setup.c | 7 | ||||
-rw-r--r-- | arch/xtensa/kernel/xtensa_ksyms.c | 3 | ||||
-rw-r--r-- | arch/xtensa/lib/memcopy.S | 10 | ||||
-rw-r--r-- | arch/xtensa/lib/memset.S | 5 | ||||
-rw-r--r-- | arch/xtensa/mm/Makefile | 5 | ||||
-rw-r--r-- | arch/xtensa/mm/init.c | 7 | ||||
-rw-r--r-- | arch/xtensa/mm/kasan_init.c | 95 |
15 files changed, 201 insertions, 9 deletions
diff --git a/Documentation/features/debug/KASAN/arch-support.txt b/Documentation/features/debug/KASAN/arch-support.txt index 76bbd7fe27b3..8abb013db8d1 100644 --- a/Documentation/features/debug/KASAN/arch-support.txt +++ b/Documentation/features/debug/KASAN/arch-support.txt | |||
@@ -35,5 +35,5 @@ | |||
35 | | um: | TODO | | 35 | | um: | TODO | |
36 | | unicore32: | TODO | | 36 | | unicore32: | TODO | |
37 | | x86: | ok | | 37 | | x86: | ok | |
38 | | xtensa: | TODO | | 38 | | xtensa: | ok | |
39 | ----------------------- | 39 | ----------------------- |
diff --git a/Documentation/xtensa/mmu.txt b/Documentation/xtensa/mmu.txt index 16921393e366..318114de63f3 100644 --- a/Documentation/xtensa/mmu.txt +++ b/Documentation/xtensa/mmu.txt | |||
@@ -71,6 +71,8 @@ Default MMUv2-compatible layout. | |||
71 | +------------------+ | 71 | +------------------+ |
72 | | Page table | XCHAL_PAGE_TABLE_VADDR 0x80000000 XCHAL_PAGE_TABLE_SIZE | 72 | | Page table | XCHAL_PAGE_TABLE_VADDR 0x80000000 XCHAL_PAGE_TABLE_SIZE |
73 | +------------------+ | 73 | +------------------+ |
74 | | KASAN shadow map | KASAN_SHADOW_START 0x80400000 KASAN_SHADOW_SIZE | ||
75 | +------------------+ 0x8e400000 | ||
74 | +------------------+ | 76 | +------------------+ |
75 | | VMALLOC area | VMALLOC_START 0xc0000000 128MB - 64KB | 77 | | VMALLOC area | VMALLOC_START 0xc0000000 128MB - 64KB |
76 | +------------------+ VMALLOC_END | 78 | +------------------+ VMALLOC_END |
@@ -111,6 +113,8 @@ Default MMUv2-compatible layout. | |||
111 | +------------------+ | 113 | +------------------+ |
112 | | Page table | XCHAL_PAGE_TABLE_VADDR 0x80000000 XCHAL_PAGE_TABLE_SIZE | 114 | | Page table | XCHAL_PAGE_TABLE_VADDR 0x80000000 XCHAL_PAGE_TABLE_SIZE |
113 | +------------------+ | 115 | +------------------+ |
116 | | KASAN shadow map | KASAN_SHADOW_START 0x80400000 KASAN_SHADOW_SIZE | ||
117 | +------------------+ 0x8e400000 | ||
114 | +------------------+ | 118 | +------------------+ |
115 | | VMALLOC area | VMALLOC_START 0xa0000000 128MB - 64KB | 119 | | VMALLOC area | VMALLOC_START 0xa0000000 128MB - 64KB |
116 | +------------------+ VMALLOC_END | 120 | +------------------+ VMALLOC_END |
@@ -152,6 +156,8 @@ Default MMUv2-compatible layout. | |||
152 | +------------------+ | 156 | +------------------+ |
153 | | Page table | XCHAL_PAGE_TABLE_VADDR 0x80000000 XCHAL_PAGE_TABLE_SIZE | 157 | | Page table | XCHAL_PAGE_TABLE_VADDR 0x80000000 XCHAL_PAGE_TABLE_SIZE |
154 | +------------------+ | 158 | +------------------+ |
159 | | KASAN shadow map | KASAN_SHADOW_START 0x80400000 KASAN_SHADOW_SIZE | ||
160 | +------------------+ 0x8e400000 | ||
155 | +------------------+ | 161 | +------------------+ |
156 | | VMALLOC area | VMALLOC_START 0x90000000 128MB - 64KB | 162 | | VMALLOC area | VMALLOC_START 0x90000000 128MB - 64KB |
157 | +------------------+ VMALLOC_END | 163 | +------------------+ VMALLOC_END |
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index fffe05b698ac..f9f95d6e8da8 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -15,6 +15,7 @@ config XTENSA | |||
15 | select GENERIC_IRQ_SHOW | 15 | select GENERIC_IRQ_SHOW |
16 | select GENERIC_PCI_IOMAP | 16 | select GENERIC_PCI_IOMAP |
17 | select GENERIC_SCHED_CLOCK | 17 | select GENERIC_SCHED_CLOCK |
18 | select HAVE_ARCH_KASAN if MMU | ||
18 | select HAVE_CC_STACKPROTECTOR | 19 | select HAVE_CC_STACKPROTECTOR |
19 | select HAVE_DEBUG_KMEMLEAK | 20 | select HAVE_DEBUG_KMEMLEAK |
20 | select HAVE_DMA_API_DEBUG | 21 | select HAVE_DMA_API_DEBUG |
@@ -80,6 +81,10 @@ config VARIANT_IRQ_SWITCH | |||
80 | config HAVE_XTENSA_GPIO32 | 81 | config HAVE_XTENSA_GPIO32 |
81 | def_bool n | 82 | def_bool n |
82 | 83 | ||
84 | config KASAN_SHADOW_OFFSET | ||
85 | hex | ||
86 | default 0x6e400000 | ||
87 | |||
83 | menu "Processor type and features" | 88 | menu "Processor type and features" |
84 | 89 | ||
85 | choice | 90 | choice |
diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile index 2fe182915b63..355127faade1 100644 --- a/arch/xtensa/boot/lib/Makefile +++ b/arch/xtensa/boot/lib/Makefile | |||
@@ -15,6 +15,8 @@ CFLAGS_REMOVE_inftrees.o = -pg | |||
15 | CFLAGS_REMOVE_inffast.o = -pg | 15 | CFLAGS_REMOVE_inffast.o = -pg |
16 | endif | 16 | endif |
17 | 17 | ||
18 | KASAN_SANITIZE := n | ||
19 | |||
18 | CFLAGS_REMOVE_inflate.o += -fstack-protector -fstack-protector-strong | 20 | CFLAGS_REMOVE_inflate.o += -fstack-protector -fstack-protector-strong |
19 | CFLAGS_REMOVE_zmem.o += -fstack-protector -fstack-protector-strong | 21 | CFLAGS_REMOVE_zmem.o += -fstack-protector -fstack-protector-strong |
20 | CFLAGS_REMOVE_inftrees.o += -fstack-protector -fstack-protector-strong | 22 | CFLAGS_REMOVE_inftrees.o += -fstack-protector -fstack-protector-strong |
diff --git a/arch/xtensa/include/asm/kasan.h b/arch/xtensa/include/asm/kasan.h new file mode 100644 index 000000000000..54be80876e57 --- /dev/null +++ b/arch/xtensa/include/asm/kasan.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | #ifndef __ASM_KASAN_H | ||
3 | #define __ASM_KASAN_H | ||
4 | |||
5 | #ifndef __ASSEMBLY__ | ||
6 | |||
7 | #ifdef CONFIG_KASAN | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/sizes.h> | ||
11 | #include <asm/kmem_layout.h> | ||
12 | |||
13 | /* Start of area covered by KASAN */ | ||
14 | #define KASAN_START_VADDR __XTENSA_UL_CONST(0x90000000) | ||
15 | /* Start of the shadow map */ | ||
16 | #define KASAN_SHADOW_START (XCHAL_PAGE_TABLE_VADDR + XCHAL_PAGE_TABLE_SIZE) | ||
17 | /* Size of the shadow map */ | ||
18 | #define KASAN_SHADOW_SIZE (-KASAN_START_VADDR >> KASAN_SHADOW_SCALE_SHIFT) | ||
19 | /* Offset for mem to shadow address transformation */ | ||
20 | #define KASAN_SHADOW_OFFSET __XTENSA_UL_CONST(CONFIG_KASAN_SHADOW_OFFSET) | ||
21 | |||
22 | void __init kasan_early_init(void); | ||
23 | void __init kasan_init(void); | ||
24 | |||
25 | #else | ||
26 | |||
27 | static inline void kasan_early_init(void) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | static inline void kasan_init(void) | ||
32 | { | ||
33 | } | ||
34 | |||
35 | #endif | ||
36 | #endif | ||
37 | #endif | ||
diff --git a/arch/xtensa/include/asm/kmem_layout.h b/arch/xtensa/include/asm/kmem_layout.h index 28f9260a766c..2317c835a4db 100644 --- a/arch/xtensa/include/asm/kmem_layout.h +++ b/arch/xtensa/include/asm/kmem_layout.h | |||
@@ -71,7 +71,11 @@ | |||
71 | 71 | ||
72 | #endif | 72 | #endif |
73 | 73 | ||
74 | #ifndef CONFIG_KASAN | ||
74 | #define KERNEL_STACK_SHIFT 13 | 75 | #define KERNEL_STACK_SHIFT 13 |
76 | #else | ||
77 | #define KERNEL_STACK_SHIFT 15 | ||
78 | #endif | ||
75 | #define KERNEL_STACK_SIZE (1 << KERNEL_STACK_SHIFT) | 79 | #define KERNEL_STACK_SIZE (1 << KERNEL_STACK_SHIFT) |
76 | 80 | ||
77 | #endif | 81 | #endif |
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index 30dd5b2e4ad5..38802259978f 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h | |||
@@ -12,9 +12,9 @@ | |||
12 | #define _XTENSA_PGTABLE_H | 12 | #define _XTENSA_PGTABLE_H |
13 | 13 | ||
14 | #define __ARCH_USE_5LEVEL_HACK | 14 | #define __ARCH_USE_5LEVEL_HACK |
15 | #include <asm-generic/pgtable-nopmd.h> | ||
16 | #include <asm/page.h> | 15 | #include <asm/page.h> |
17 | #include <asm/kmem_layout.h> | 16 | #include <asm/kmem_layout.h> |
17 | #include <asm-generic/pgtable-nopmd.h> | ||
18 | 18 | ||
19 | /* | 19 | /* |
20 | * We only use two ring levels, user and kernel space. | 20 | * We only use two ring levels, user and kernel space. |
@@ -170,6 +170,7 @@ | |||
170 | #define PAGE_SHARED_EXEC \ | 170 | #define PAGE_SHARED_EXEC \ |
171 | __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_WRITABLE | _PAGE_HW_EXEC) | 171 | __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_WRITABLE | _PAGE_HW_EXEC) |
172 | #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_HW_WRITE) | 172 | #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_HW_WRITE) |
173 | #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT) | ||
173 | #define PAGE_KERNEL_EXEC __pgprot(_PAGE_PRESENT|_PAGE_HW_WRITE|_PAGE_HW_EXEC) | 174 | #define PAGE_KERNEL_EXEC __pgprot(_PAGE_PRESENT|_PAGE_HW_WRITE|_PAGE_HW_EXEC) |
174 | 175 | ||
175 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) | 176 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) |
diff --git a/arch/xtensa/include/asm/string.h b/arch/xtensa/include/asm/string.h index 8d5d9dfadb09..586bad9fe187 100644 --- a/arch/xtensa/include/asm/string.h +++ b/arch/xtensa/include/asm/string.h | |||
@@ -108,14 +108,33 @@ static inline int strncmp(const char *__cs, const char *__ct, size_t __n) | |||
108 | 108 | ||
109 | #define __HAVE_ARCH_MEMSET | 109 | #define __HAVE_ARCH_MEMSET |
110 | extern void *memset(void *__s, int __c, size_t __count); | 110 | extern void *memset(void *__s, int __c, size_t __count); |
111 | extern void *__memset(void *__s, int __c, size_t __count); | ||
111 | 112 | ||
112 | #define __HAVE_ARCH_MEMCPY | 113 | #define __HAVE_ARCH_MEMCPY |
113 | extern void *memcpy(void *__to, __const__ void *__from, size_t __n); | 114 | extern void *memcpy(void *__to, __const__ void *__from, size_t __n); |
115 | extern void *__memcpy(void *__to, __const__ void *__from, size_t __n); | ||
114 | 116 | ||
115 | #define __HAVE_ARCH_MEMMOVE | 117 | #define __HAVE_ARCH_MEMMOVE |
116 | extern void *memmove(void *__dest, __const__ void *__src, size_t __n); | 118 | extern void *memmove(void *__dest, __const__ void *__src, size_t __n); |
119 | extern void *__memmove(void *__dest, __const__ void *__src, size_t __n); | ||
117 | 120 | ||
118 | /* Don't build bcopy at all ... */ | 121 | /* Don't build bcopy at all ... */ |
119 | #define __HAVE_ARCH_BCOPY | 122 | #define __HAVE_ARCH_BCOPY |
120 | 123 | ||
124 | #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) | ||
125 | |||
126 | /* | ||
127 | * For files that are not instrumented (e.g. mm/slub.c) we | ||
128 | * should use not instrumented version of mem* functions. | ||
129 | */ | ||
130 | |||
131 | #define memcpy(dst, src, len) __memcpy(dst, src, len) | ||
132 | #define memmove(dst, src, len) __memmove(dst, src, len) | ||
133 | #define memset(s, c, n) __memset(s, c, n) | ||
134 | |||
135 | #ifndef __NO_FORTIFY | ||
136 | #define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */ | ||
137 | #endif | ||
138 | #endif | ||
139 | |||
121 | #endif /* _XTENSA_STRING_H */ | 140 | #endif /* _XTENSA_STRING_H */ |
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 960212e72a70..a931af9075f2 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #include <asm/bootparam.h> | 38 | #include <asm/bootparam.h> |
39 | #include <asm/kasan.h> | ||
39 | #include <asm/mmu_context.h> | 40 | #include <asm/mmu_context.h> |
40 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
41 | #include <asm/processor.h> | 42 | #include <asm/processor.h> |
@@ -251,6 +252,10 @@ void __init init_arch(bp_tag_t *bp_start) | |||
251 | 252 | ||
252 | init_mmu(); | 253 | init_mmu(); |
253 | 254 | ||
255 | /* Initialize initial KASAN shadow map */ | ||
256 | |||
257 | kasan_early_init(); | ||
258 | |||
254 | /* Parse boot parameters */ | 259 | /* Parse boot parameters */ |
255 | 260 | ||
256 | if (bp_start) | 261 | if (bp_start) |
@@ -388,7 +393,7 @@ void __init setup_arch(char **cmdline_p) | |||
388 | #endif | 393 | #endif |
389 | parse_early_param(); | 394 | parse_early_param(); |
390 | bootmem_init(); | 395 | bootmem_init(); |
391 | 396 | kasan_init(); | |
392 | unflatten_and_copy_device_tree(); | 397 | unflatten_and_copy_device_tree(); |
393 | 398 | ||
394 | #ifdef CONFIG_SMP | 399 | #ifdef CONFIG_SMP |
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 672391003e40..3a443f83ae87 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -41,6 +41,9 @@ | |||
41 | EXPORT_SYMBOL(memset); | 41 | EXPORT_SYMBOL(memset); |
42 | EXPORT_SYMBOL(memcpy); | 42 | EXPORT_SYMBOL(memcpy); |
43 | EXPORT_SYMBOL(memmove); | 43 | EXPORT_SYMBOL(memmove); |
44 | EXPORT_SYMBOL(__memset); | ||
45 | EXPORT_SYMBOL(__memcpy); | ||
46 | EXPORT_SYMBOL(__memmove); | ||
44 | EXPORT_SYMBOL(__strncpy_user); | 47 | EXPORT_SYMBOL(__strncpy_user); |
45 | EXPORT_SYMBOL(clear_page); | 48 | EXPORT_SYMBOL(clear_page); |
46 | EXPORT_SYMBOL(copy_page); | 49 | EXPORT_SYMBOL(copy_page); |
diff --git a/arch/xtensa/lib/memcopy.S b/arch/xtensa/lib/memcopy.S index 24d650864c3a..c0f6981719d6 100644 --- a/arch/xtensa/lib/memcopy.S +++ b/arch/xtensa/lib/memcopy.S | |||
@@ -109,7 +109,8 @@ | |||
109 | addi a5, a5, 2 | 109 | addi a5, a5, 2 |
110 | j .Ldstaligned # dst is now aligned, return to main algorithm | 110 | j .Ldstaligned # dst is now aligned, return to main algorithm |
111 | 111 | ||
112 | ENTRY(memcpy) | 112 | ENTRY(__memcpy) |
113 | WEAK(memcpy) | ||
113 | 114 | ||
114 | entry sp, 16 # minimal stack frame | 115 | entry sp, 16 # minimal stack frame |
115 | # a2/ dst, a3/ src, a4/ len | 116 | # a2/ dst, a3/ src, a4/ len |
@@ -271,7 +272,7 @@ ENTRY(memcpy) | |||
271 | s8i a6, a5, 0 | 272 | s8i a6, a5, 0 |
272 | retw | 273 | retw |
273 | 274 | ||
274 | ENDPROC(memcpy) | 275 | ENDPROC(__memcpy) |
275 | 276 | ||
276 | /* | 277 | /* |
277 | * void bcopy(const void *src, void *dest, size_t n); | 278 | * void bcopy(const void *src, void *dest, size_t n); |
@@ -376,7 +377,8 @@ ENDPROC(bcopy) | |||
376 | j .Lbackdstaligned # dst is now aligned, | 377 | j .Lbackdstaligned # dst is now aligned, |
377 | # return to main algorithm | 378 | # return to main algorithm |
378 | 379 | ||
379 | ENTRY(memmove) | 380 | ENTRY(__memmove) |
381 | WEAK(memmove) | ||
380 | 382 | ||
381 | entry sp, 16 # minimal stack frame | 383 | entry sp, 16 # minimal stack frame |
382 | # a2/ dst, a3/ src, a4/ len | 384 | # a2/ dst, a3/ src, a4/ len |
@@ -548,4 +550,4 @@ ENTRY(memmove) | |||
548 | s8i a6, a5, 0 | 550 | s8i a6, a5, 0 |
549 | retw | 551 | retw |
550 | 552 | ||
551 | ENDPROC(memmove) | 553 | ENDPROC(__memmove) |
diff --git a/arch/xtensa/lib/memset.S b/arch/xtensa/lib/memset.S index a6cd04ba966f..276747dec300 100644 --- a/arch/xtensa/lib/memset.S +++ b/arch/xtensa/lib/memset.S | |||
@@ -31,7 +31,8 @@ | |||
31 | */ | 31 | */ |
32 | 32 | ||
33 | .text | 33 | .text |
34 | ENTRY(memset) | 34 | ENTRY(__memset) |
35 | WEAK(memset) | ||
35 | 36 | ||
36 | entry sp, 16 # minimal stack frame | 37 | entry sp, 16 # minimal stack frame |
37 | # a2/ dst, a3/ c, a4/ length | 38 | # a2/ dst, a3/ c, a4/ length |
@@ -140,7 +141,7 @@ EX(10f) s8i a3, a5, 0 | |||
140 | .Lbytesetdone: | 141 | .Lbytesetdone: |
141 | retw | 142 | retw |
142 | 143 | ||
143 | ENDPROC(memset) | 144 | ENDPROC(__memset) |
144 | 145 | ||
145 | .section .fixup, "ax" | 146 | .section .fixup, "ax" |
146 | .align 4 | 147 | .align 4 |
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile index 0b3d296a016a..734888a00dc8 100644 --- a/arch/xtensa/mm/Makefile +++ b/arch/xtensa/mm/Makefile | |||
@@ -5,3 +5,8 @@ | |||
5 | obj-y := init.o misc.o | 5 | obj-y := init.o misc.o |
6 | obj-$(CONFIG_MMU) += cache.o fault.o ioremap.o mmu.o tlb.o | 6 | obj-$(CONFIG_MMU) += cache.o fault.o ioremap.o mmu.o tlb.o |
7 | obj-$(CONFIG_HIGHMEM) += highmem.o | 7 | obj-$(CONFIG_HIGHMEM) += highmem.o |
8 | obj-$(CONFIG_KASAN) += kasan_init.o | ||
9 | |||
10 | KASAN_SANITIZE_fault.o := n | ||
11 | KASAN_SANITIZE_kasan_init.o := n | ||
12 | KASAN_SANITIZE_mmu.o := n | ||
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 6fc1cb093fb3..0d980f05da82 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
@@ -100,6 +100,9 @@ void __init mem_init(void) | |||
100 | 100 | ||
101 | mem_init_print_info(NULL); | 101 | mem_init_print_info(NULL); |
102 | pr_info("virtual kernel memory layout:\n" | 102 | pr_info("virtual kernel memory layout:\n" |
103 | #ifdef CONFIG_KASAN | ||
104 | " kasan : 0x%08lx - 0x%08lx (%5lu MB)\n" | ||
105 | #endif | ||
103 | #ifdef CONFIG_MMU | 106 | #ifdef CONFIG_MMU |
104 | " vmalloc : 0x%08lx - 0x%08lx (%5lu MB)\n" | 107 | " vmalloc : 0x%08lx - 0x%08lx (%5lu MB)\n" |
105 | #endif | 108 | #endif |
@@ -108,6 +111,10 @@ void __init mem_init(void) | |||
108 | " fixmap : 0x%08lx - 0x%08lx (%5lu kB)\n" | 111 | " fixmap : 0x%08lx - 0x%08lx (%5lu kB)\n" |
109 | #endif | 112 | #endif |
110 | " lowmem : 0x%08lx - 0x%08lx (%5lu MB)\n", | 113 | " lowmem : 0x%08lx - 0x%08lx (%5lu MB)\n", |
114 | #ifdef CONFIG_KASAN | ||
115 | KASAN_SHADOW_START, KASAN_SHADOW_START + KASAN_SHADOW_SIZE, | ||
116 | KASAN_SHADOW_SIZE >> 20, | ||
117 | #endif | ||
111 | #ifdef CONFIG_MMU | 118 | #ifdef CONFIG_MMU |
112 | VMALLOC_START, VMALLOC_END, | 119 | VMALLOC_START, VMALLOC_END, |
113 | (VMALLOC_END - VMALLOC_START) >> 20, | 120 | (VMALLOC_END - VMALLOC_START) >> 20, |
diff --git a/arch/xtensa/mm/kasan_init.c b/arch/xtensa/mm/kasan_init.c new file mode 100644 index 000000000000..6b532b6bd785 --- /dev/null +++ b/arch/xtensa/mm/kasan_init.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Xtensa KASAN shadow map initialization | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2017 Cadence Design Systems Inc. | ||
9 | */ | ||
10 | |||
11 | #include <linux/bootmem.h> | ||
12 | #include <linux/init_task.h> | ||
13 | #include <linux/kasan.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/memblock.h> | ||
16 | #include <asm/initialize_mmu.h> | ||
17 | #include <asm/tlbflush.h> | ||
18 | #include <asm/traps.h> | ||
19 | |||
20 | void __init kasan_early_init(void) | ||
21 | { | ||
22 | unsigned long vaddr = KASAN_SHADOW_START; | ||
23 | pgd_t *pgd = pgd_offset_k(vaddr); | ||
24 | pmd_t *pmd = pmd_offset(pgd, vaddr); | ||
25 | int i; | ||
26 | |||
27 | for (i = 0; i < PTRS_PER_PTE; ++i) | ||
28 | set_pte(kasan_zero_pte + i, | ||
29 | mk_pte(virt_to_page(kasan_zero_page), PAGE_KERNEL)); | ||
30 | |||
31 | for (vaddr = 0; vaddr < KASAN_SHADOW_SIZE; vaddr += PMD_SIZE, ++pmd) { | ||
32 | BUG_ON(!pmd_none(*pmd)); | ||
33 | set_pmd(pmd, __pmd((unsigned long)kasan_zero_pte)); | ||
34 | } | ||
35 | early_trap_init(); | ||
36 | } | ||
37 | |||
38 | static void __init populate(void *start, void *end) | ||
39 | { | ||
40 | unsigned long n_pages = (end - start) / PAGE_SIZE; | ||
41 | unsigned long n_pmds = n_pages / PTRS_PER_PTE; | ||
42 | unsigned long i, j; | ||
43 | unsigned long vaddr = (unsigned long)start; | ||
44 | pgd_t *pgd = pgd_offset_k(vaddr); | ||
45 | pmd_t *pmd = pmd_offset(pgd, vaddr); | ||
46 | pte_t *pte = memblock_virt_alloc(n_pages * sizeof(pte_t), PAGE_SIZE); | ||
47 | |||
48 | pr_debug("%s: %p - %p\n", __func__, start, end); | ||
49 | |||
50 | for (i = j = 0; i < n_pmds; ++i) { | ||
51 | int k; | ||
52 | |||
53 | for (k = 0; k < PTRS_PER_PTE; ++k, ++j) { | ||
54 | phys_addr_t phys = | ||
55 | memblock_alloc_base(PAGE_SIZE, PAGE_SIZE, | ||
56 | MEMBLOCK_ALLOC_ANYWHERE); | ||
57 | |||
58 | set_pte(pte + j, pfn_pte(PHYS_PFN(phys), PAGE_KERNEL)); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | for (i = 0; i < n_pmds ; ++i, pte += PTRS_PER_PTE) | ||
63 | set_pmd(pmd + i, __pmd((unsigned long)pte)); | ||
64 | |||
65 | local_flush_tlb_all(); | ||
66 | memset(start, 0, end - start); | ||
67 | } | ||
68 | |||
69 | void __init kasan_init(void) | ||
70 | { | ||
71 | int i; | ||
72 | |||
73 | BUILD_BUG_ON(KASAN_SHADOW_OFFSET != KASAN_SHADOW_START - | ||
74 | (KASAN_START_VADDR >> KASAN_SHADOW_SCALE_SHIFT)); | ||
75 | BUILD_BUG_ON(VMALLOC_START < KASAN_START_VADDR); | ||
76 | |||
77 | /* | ||
78 | * Replace shadow map pages that cover addresses from VMALLOC area | ||
79 | * start to the end of KSEG with clean writable pages. | ||
80 | */ | ||
81 | populate(kasan_mem_to_shadow((void *)VMALLOC_START), | ||
82 | kasan_mem_to_shadow((void *)XCHAL_KSEG_BYPASS_VADDR)); | ||
83 | |||
84 | /* Write protect kasan_zero_page and zero-initialize it again. */ | ||
85 | for (i = 0; i < PTRS_PER_PTE; ++i) | ||
86 | set_pte(kasan_zero_pte + i, | ||
87 | mk_pte(virt_to_page(kasan_zero_page), PAGE_KERNEL_RO)); | ||
88 | |||
89 | local_flush_tlb_all(); | ||
90 | memset(kasan_zero_page, 0, PAGE_SIZE); | ||
91 | |||
92 | /* At this point kasan is fully initialized. Enable error messages. */ | ||
93 | current->kasan_depth = 0; | ||
94 | pr_info("KernelAddressSanitizer initialized\n"); | ||
95 | } | ||