* [RFC PATCH v1 0/4] KASAN for nohash PPC32
@ 2018-07-13 16:23 Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 1/4] powerpc/mm: prepare kernel for KAsan on PPC32 Christophe Leroy
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Christophe Leroy @ 2018-07-13 16:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
npiggin, aneesh.kumar
Cc: linux-kernel, linuxppc-dev, linux-mm
This serie adds support to nohash PPC32
Tested on MPC8xx
Christophe Leroy (4):
powerpc/mm: prepare kernel for KAsan on PPC32
powerpc: add missing header in pgtable-types.h
powerpc/32: Move early_init() in a separate file
powerpc/nohash32: Add KASAN support
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/kasan.h | 21 ++++++++
arch/powerpc/include/asm/nohash/32/pgtable.h | 2 +
arch/powerpc/include/asm/pgtable-types.h | 2 +
arch/powerpc/include/asm/ppc_asm.h | 5 ++
arch/powerpc/include/asm/setup.h | 5 ++
arch/powerpc/include/asm/string.h | 14 ++++++
arch/powerpc/kernel/Makefile | 5 +-
arch/powerpc/kernel/cputable.c | 4 +-
arch/powerpc/kernel/early_32.c | 35 +++++++++++++
arch/powerpc/kernel/setup-common.c | 2 +
arch/powerpc/kernel/setup_32.c | 33 ++-----------
arch/powerpc/lib/Makefile | 2 +
arch/powerpc/lib/copy_32.S | 9 ++--
arch/powerpc/mm/Makefile | 3 ++
arch/powerpc/mm/dump_linuxpagetables.c | 8 +++
arch/powerpc/mm/kasan_init.c | 73 ++++++++++++++++++++++++++++
arch/powerpc/mm/mem.c | 4 ++
18 files changed, 193 insertions(+), 35 deletions(-)
create mode 100644 arch/powerpc/include/asm/kasan.h
create mode 100644 arch/powerpc/kernel/early_32.c
create mode 100644 arch/powerpc/mm/kasan_init.c
--
2.13.3
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC PATCH v1 1/4] powerpc/mm: prepare kernel for KAsan on PPC32
2018-07-13 16:23 [RFC PATCH v1 0/4] KASAN for nohash PPC32 Christophe Leroy
@ 2018-07-13 16:23 ` Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 2/4] powerpc: add missing header in pgtable-types.h Christophe Leroy
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2018-07-13 16:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
npiggin, aneesh.kumar
Cc: linux-kernel, linuxppc-dev, linux-mm
In kernel/cputable.c, explicitly use memcpy() in order
to allow GCC to replace it with __memcpy() when KASAN is
selected.
Since commit 400c47d81ca38 ("powerpc32: memset: only use dcbz once cache is
enabled"), memset() can be used before activation of the cache,
so no need to use memset_io() for zeroing the BSS.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/kernel/cputable.c | 4 ++--
arch/powerpc/kernel/setup_32.c | 6 ++----
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index c8fc9691f8c7..60ee5900bf12 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -2183,7 +2183,7 @@ void __init set_cur_cpu_spec(struct cpu_spec *s)
struct cpu_spec *t = &the_cpu_spec;
t = PTRRELOC(t);
- *t = *s;
+ memcpy(t, s, sizeof(*t));
*PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
}
@@ -2198,7 +2198,7 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,
old = *t;
/* Copy everything, then do fixups */
- *t = *s;
+ memcpy(t, s, sizeof(*t));
/*
* If we are overriding a previous value derived from the real
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 74457485574b..6a394b9e109e 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -70,10 +70,8 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
{
unsigned long offset = reloc_offset();
- /* First zero the BSS -- use memset_io, some platforms don't have
- * caches on yet */
- memset_io((void __iomem *)PTRRELOC(&__bss_start), 0,
- __bss_stop - __bss_start);
+ /* First zero the BSS */
+ memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
/*
* Identify the CPU type and fix up code sections
--
2.13.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC PATCH v1 2/4] powerpc: add missing header in pgtable-types.h
2018-07-13 16:23 [RFC PATCH v1 0/4] KASAN for nohash PPC32 Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 1/4] powerpc/mm: prepare kernel for KAsan on PPC32 Christophe Leroy
@ 2018-07-13 16:23 ` Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 3/4] powerpc/32: Move early_init() in a separate file Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 4/4] powerpc/nohash32: Add KASAN support Christophe Leroy
3 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2018-07-13 16:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
npiggin, aneesh.kumar
Cc: linux-kernel, linuxppc-dev, linux-mm
pte_basic_t is defined in page.h
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/pgtable-types.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h
index eccb30b38b47..3d8f68aebea3 100644
--- a/arch/powerpc/include/asm/pgtable-types.h
+++ b/arch/powerpc/include/asm/pgtable-types.h
@@ -2,6 +2,8 @@
#ifndef _ASM_POWERPC_PGTABLE_TYPES_H
#define _ASM_POWERPC_PGTABLE_TYPES_H
+#include <asm/page.h>
+
/* PTE level */
typedef struct { pte_basic_t pte; } pte_t;
#define __pte(x) ((pte_t) { (x) })
--
2.13.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC PATCH v1 3/4] powerpc/32: Move early_init() in a separate file
2018-07-13 16:23 [RFC PATCH v1 0/4] KASAN for nohash PPC32 Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 1/4] powerpc/mm: prepare kernel for KAsan on PPC32 Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 2/4] powerpc: add missing header in pgtable-types.h Christophe Leroy
@ 2018-07-13 16:23 ` Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 4/4] powerpc/nohash32: Add KASAN support Christophe Leroy
3 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2018-07-13 16:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
npiggin, aneesh.kumar
Cc: linux-kernel, linuxppc-dev, linux-mm
In preparation of KASAN, move early_init() into a separate
file in order to allow deactivation of KASAN for that function.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/kernel/Makefile | 2 +-
arch/powerpc/kernel/early_32.c | 35 +++++++++++++++++++++++++++++++++++
arch/powerpc/kernel/setup_32.c | 26 --------------------------
3 files changed, 36 insertions(+), 27 deletions(-)
create mode 100644 arch/powerpc/kernel/early_32.c
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 2b4c40b255e4..70e9dbdc55f5 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -89,7 +89,7 @@ extra-y += vmlinux.lds
obj-$(CONFIG_RELOCATABLE) += reloc_$(BITS).o
-obj-$(CONFIG_PPC32) += entry_32.o setup_32.o
+obj-$(CONFIG_PPC32) += entry_32.o setup_32.o early_32.o
obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
diff --git a/arch/powerpc/kernel/early_32.c b/arch/powerpc/kernel/early_32.c
new file mode 100644
index 000000000000..b3e40d6d651c
--- /dev/null
+++ b/arch/powerpc/kernel/early_32.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Early init before relocation
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/setup.h>
+#include <asm/sections.h>
+
+/*
+ * We're called here very early in the boot.
+ *
+ * Note that the kernel may be running at an address which is different
+ * from the address that it was linked at, so we must use RELOC/PTRRELOC
+ * to access static data (including strings). -- paulus
+ */
+notrace unsigned long __init early_init(unsigned long dt_ptr)
+{
+ unsigned long offset = reloc_offset();
+
+ /* First zero the BSS */
+ memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
+
+ /*
+ * Identify the CPU type and fix up code sections
+ * that depend on which cpu we have.
+ */
+ identify_cpu(offset, mfspr(SPRN_PVR));
+
+ apply_feature_fixups();
+
+ return KERNELBASE + offset;
+}
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 6a394b9e109e..1c62f81cb257 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -60,32 +60,6 @@ EXPORT_SYMBOL(DMA_MODE_READ);
EXPORT_SYMBOL(DMA_MODE_WRITE);
/*
- * We're called here very early in the boot.
- *
- * Note that the kernel may be running at an address which is different
- * from the address that it was linked at, so we must use RELOC/PTRRELOC
- * to access static data (including strings). -- paulus
- */
-notrace unsigned long __init early_init(unsigned long dt_ptr)
-{
- unsigned long offset = reloc_offset();
-
- /* First zero the BSS */
- memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
-
- /*
- * Identify the CPU type and fix up code sections
- * that depend on which cpu we have.
- */
- identify_cpu(offset, mfspr(SPRN_PVR));
-
- apply_feature_fixups();
-
- return KERNELBASE + offset;
-}
-
-
-/*
* This is run before start_kernel(), the kernel has been relocated
* and we are running with enough of the MMU enabled to have our
* proper kernel virtual addresses
--
2.13.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC PATCH v1 4/4] powerpc/nohash32: Add KASAN support
2018-07-13 16:23 [RFC PATCH v1 0/4] KASAN for nohash PPC32 Christophe Leroy
` (2 preceding siblings ...)
2018-07-13 16:23 ` [RFC PATCH v1 3/4] powerpc/32: Move early_init() in a separate file Christophe Leroy
@ 2018-07-13 16:23 ` Christophe Leroy
3 siblings, 0 replies; 5+ messages in thread
From: Christophe Leroy @ 2018-07-13 16:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
npiggin, aneesh.kumar
Cc: linux-kernel, linuxppc-dev, linux-mm
This patch adds KASAN support for nohash PPC32.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/kasan.h | 21 ++++++++
arch/powerpc/include/asm/nohash/32/pgtable.h | 2 +
arch/powerpc/include/asm/ppc_asm.h | 5 ++
arch/powerpc/include/asm/setup.h | 5 ++
arch/powerpc/include/asm/string.h | 14 ++++++
arch/powerpc/kernel/Makefile | 3 ++
arch/powerpc/kernel/setup-common.c | 2 +
arch/powerpc/kernel/setup_32.c | 5 +-
arch/powerpc/lib/Makefile | 2 +
arch/powerpc/lib/copy_32.S | 9 ++--
arch/powerpc/mm/Makefile | 3 ++
arch/powerpc/mm/dump_linuxpagetables.c | 8 +++
arch/powerpc/mm/kasan_init.c | 73 ++++++++++++++++++++++++++++
arch/powerpc/mm/mem.c | 4 ++
15 files changed, 153 insertions(+), 4 deletions(-)
create mode 100644 arch/powerpc/include/asm/kasan.h
create mode 100644 arch/powerpc/mm/kasan_init.c
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9f2b75fe2c2d..7519ec67fdea 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -174,6 +174,7 @@ config PPC
select GENERIC_TIME_VSYSCALL
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
+ select HAVE_ARCH_KASAN if PPC32 && PPC_MMU_NOHASH
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
new file mode 100644
index 000000000000..419366bcd5f4
--- /dev/null
+++ b/arch/powerpc/include/asm/kasan.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_KASAN_H
+#define __ASM_KASAN_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/pgtable-types.h>
+#include <asm/fixmap.h>
+
+#define KASAN_SHADOW_SCALE_SHIFT 3
+#define KASAN_SHADOW_SIZE ((~0UL - PAGE_OFFSET + 1) >> KASAN_SHADOW_SCALE_SHIFT)
+
+#define KASAN_SHADOW_START (ALIGN_DOWN(FIXADDR_START - KASAN_SHADOW_SIZE, PGDIR_SIZE))
+#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
+#define KASAN_SHADOW_OFFSET (KASAN_SHADOW_START - (PAGE_OFFSET >> KASAN_SHADOW_SCALE_SHIFT))
+
+void kasan_early_init(void);
+void kasan_init(void);
+
+#endif
+#endif
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 7c46a98cc7f4..0f1205a74212 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -70,6 +70,8 @@ extern int icache_44x_need_flush;
*/
#ifdef CONFIG_HIGHMEM
#define KVIRT_TOP PKMAP_BASE
+#elif defined(CONFIG_KASAN)
+#define KVIRT_TOP KASAN_SHADOW_START
#else
#define KVIRT_TOP (0xfe000000UL) /* for now, could be FIXMAP_BASE ? */
#endif
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 75ece56dcd62..947d945293fa 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -250,6 +250,11 @@ GLUE(.,name):
#define _GLOBAL_TOC(name) _GLOBAL(name)
+#define KASAN_OVERRIDE(x, y) \
+ .weak x; \
+ .set x, y
+
+
#endif
/*
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index 8721fd004291..2da38c990278 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -62,6 +62,11 @@ void do_barrier_nospec_fixups_range(bool enable, void *start, void *end);
static inline void do_barrier_nospec_fixups_range(bool enable, void *start, void *end) { };
#endif
+#ifndef CONFIG_KASAN
+static inline void kasan_early_init(void) { }
+static inline void kasan_init(void) { }
+#endif
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_POWERPC_SETUP_H */
diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h
index 9b8cedf618f4..93be88bfe439 100644
--- a/arch/powerpc/include/asm/string.h
+++ b/arch/powerpc/include/asm/string.h
@@ -27,6 +27,20 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
extern void * memchr(const void *,int,__kernel_size_t);
extern void * memcpy_flushcache(void *,const void *,__kernel_size_t);
+void * __memset(void *, int, __kernel_size_t);
+void * __memcpy(void *, const void *, __kernel_size_t);
+void * __memmove(void *, const void *, __kernel_size_t);
+
+#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+/*
+ * For files that are not instrumented (e.g. mm/slub.c) we
+ * should use not instrumented version of mem* functions.
+ */
+#define memcpy(dst, src, len) __memcpy(dst, src, len)
+#define memmove(dst, src, len) __memmove(dst, src, len)
+#define memset(s, c, n) __memset(s, c, n)
+#endif
+
#ifdef CONFIG_PPC64
#define __HAVE_ARCH_MEMSET32
#define __HAVE_ARCH_MEMSET64
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 70e9dbdc55f5..b08072f19349 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -28,6 +28,9 @@ CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
endif
+KASAN_SANITIZE_early_32.o := n
+KASAN_SANITIZE_cputable.o := n
+
obj-y := cputable.o ptrace.o syscalls.o \
irq.o align.o signal_32.o pmc.o vdso.o \
process.o systbl.o idle.o \
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 40b44bb53a4e..a030a373fbb3 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -974,6 +974,8 @@ void __init setup_arch(char **cmdline_p)
paging_init();
+ kasan_init();
+
/* Initialize the MMU context management stuff. */
mmu_context_init();
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 1c62f81cb257..c581f1c6adcd 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -17,6 +17,7 @@
#include <linux/console.h>
#include <linux/memblock.h>
#include <linux/export.h>
+#include <linux/kasan.h>
#include <asm/io.h>
#include <asm/prom.h>
@@ -74,13 +75,15 @@ notrace void __init machine_init(u64 dt_ptr)
unsigned int *addr = &memset_nocache_branch;
unsigned long insn;
+ kasan_early_init();
+
/* Configure static keys first, now that we're relocated. */
setup_feature_keys();
/* Enable early debugging if any specified (see udbg.h) */
udbg_early_init();
- patch_instruction((unsigned int *)&memcpy, PPC_INST_NOP);
+ patch_instruction((unsigned int *)&__memcpy, PPC_INST_NOP);
insn = create_cond_branch(addr, branch_target(addr), 0x820000);
patch_instruction(addr, insn); /* replace b by bne cr0 */
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index d0ca13ad8231..4a378d10fd83 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -10,6 +10,8 @@ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE)
+KASAN_SANITIZE_feature-fixups.o := n
+
obj-y += string.o alloc.o code-patching.o feature-fixups.o
obj-$(CONFIG_PPC32) += div64.o copy_32.o crtsavres.o
diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index da425bb6b369..76b4d86c0c8f 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -90,7 +90,8 @@ EXPORT_SYMBOL(memset16)
* We therefore skip the optimised bloc that uses dcbz. This jump is
* replaced by a nop once cache is active. This is done in machine_init()
*/
-_GLOBAL(memset)
+_GLOBAL(__memset)
+KASAN_OVERRIDE(memset, __memset)
cmplwi 0,r5,4
blt 7f
@@ -162,12 +163,14 @@ EXPORT_SYMBOL(memset)
* We therefore jump to generic_memcpy which doesn't use dcbz. This jump is
* replaced by a nop once cache is active. This is done in machine_init()
*/
-_GLOBAL(memmove)
+_GLOBAL(__memmove)
+KASAN_OVERRIDE(memmove, __memmove)
cmplw 0,r3,r4
bgt backwards_memcpy
/* fall through */
-_GLOBAL(memcpy)
+_GLOBAL(__memcpy)
+KASAN_OVERRIDE(memcpy, __memcpy)
b generic_memcpy
add r7,r3,r5 /* test if the src & dst overlap */
add r8,r4,r5
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index f06f3577d8d1..8b755143204b 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -7,6 +7,8 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
+KASAN_SANITIZE_kasan_init.o := n
+
obj-y := fault.o mem.o pgtable.o mmap.o \
init_$(BITS).o pgtable_$(BITS).o \
init-common.o mmu_context.o drmem.o
@@ -45,3 +47,4 @@ obj-$(CONFIG_SPAPR_TCE_IOMMU) += mmu_context_iommu.o
obj-$(CONFIG_PPC_PTDUMP) += dump_linuxpagetables.o
obj-$(CONFIG_PPC_HTDUMP) += dump_hashpagetable.o
obj-$(CONFIG_PPC_MEM_KEYS) += pkeys.o
+obj-$(CONFIG_KASAN) += kasan_init.o
diff --git a/arch/powerpc/mm/dump_linuxpagetables.c b/arch/powerpc/mm/dump_linuxpagetables.c
index 876e2a3c79f2..8e0c8a0f06ba 100644
--- a/arch/powerpc/mm/dump_linuxpagetables.c
+++ b/arch/powerpc/mm/dump_linuxpagetables.c
@@ -91,6 +91,10 @@ static struct addr_marker address_markers[] = {
{ 0, "Consistent mem start" },
{ 0, "Consistent mem end" },
#endif
+#ifdef CONFIG_KASAN
+ { 0, "kasan shadow mem start" },
+ { 0, "kasan shadow mem end" },
+#endif
#ifdef CONFIG_HIGHMEM
{ 0, "Highmem PTEs start" },
{ 0, "Highmem PTEs end" },
@@ -459,6 +463,10 @@ static void populate_markers(void)
address_markers[i++].start_address = IOREMAP_TOP +
CONFIG_CONSISTENT_SIZE;
#endif
+#ifdef CONFIG_KASAN
+ address_markers[i++].start_address = KASAN_SHADOW_START;
+ address_markers[i++].start_address = KASAN_SHADOW_END;
+#endif
#ifdef CONFIG_HIGHMEM
address_markers[i++].start_address = PKMAP_BASE;
address_markers[i++].start_address = PKMAP_ADDR(LAST_PKMAP);
diff --git a/arch/powerpc/mm/kasan_init.c b/arch/powerpc/mm/kasan_init.c
new file mode 100644
index 000000000000..3331239edcbb
--- /dev/null
+++ b/arch/powerpc/mm/kasan_init.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/kasan.h>
+#include <linux/printk.h>
+#include <linux/memblock.h>
+#include <linux/bootmem.h>
+#include <asm/pgalloc.h>
+
+void __init kasan_early_init(void)
+{
+ unsigned long addr = KASAN_SHADOW_START & PGDIR_MASK;
+ unsigned long end = KASAN_SHADOW_END;
+ unsigned long next;
+ pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(addr), addr), addr);
+ int i;
+ phys_addr_t pa = __pa(kasan_zero_page);
+
+ for (i = 0; i < PTRS_PER_PTE; i++)
+ kasan_zero_pte[i] = pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL_RO);
+
+ do {
+ next = pgd_addr_end(addr, end);
+ pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+ } while (pmd++, addr = next, addr != end);
+
+ pr_info("KASAN early init done\n");
+}
+
+static void __init kasan_init_region(struct memblock_region *reg)
+{
+ void *start = __va(reg->base);
+ void *end = __va(reg->base + reg->size);
+ unsigned long k_start, k_end, k_cur, k_next;
+ pmd_t *pmd;
+
+ if (start >= end)
+ return;
+
+ k_start = (unsigned long)kasan_mem_to_shadow(start);
+ k_end = (unsigned long)kasan_mem_to_shadow(end);
+ pmd = pmd_offset(pud_offset(pgd_offset_k(k_start), k_start), k_start);
+
+ for (k_cur = k_start; k_cur != k_end; k_cur = k_next, pmd++) {
+ k_next = pgd_addr_end(k_cur, k_end);
+ if ((void*)pmd_page_vaddr(*pmd) == kasan_zero_pte) {
+ pte_t *new = pte_alloc_one_kernel(&init_mm, k_cur);
+
+ if (!new)
+ panic("kasan: pte_alloc_one_kernel() failed");
+ memcpy(new, kasan_zero_pte, PTE_TABLE_SIZE);
+ pmd_populate_kernel(&init_mm, pmd, new);
+ }
+ };
+
+ for (k_cur = k_start; k_cur < k_end; k_cur += PAGE_SIZE) {
+ phys_addr_t pa = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+ pte_t pte = pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL);
+
+ pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur);
+ pte_update(pte_offset_kernel(pmd, k_cur), ~0, pte_val(pte));
+ }
+ flush_tlb_kernel_range(k_start, k_end);
+}
+
+void __init kasan_init(void)
+{
+ struct memblock_region *reg;
+
+ for_each_memblock(memory, reg)
+ kasan_init_region(reg);
+
+ pr_info("KASAN init done\n");
+}
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 5c8530d0c611..b5f6c2c2ac45 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -381,6 +381,10 @@ void __init mem_init(void)
pr_info(" * 0x%08lx..0x%08lx : highmem PTEs\n",
PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP));
#endif /* CONFIG_HIGHMEM */
+#ifdef CONFIG_KASAN
+ pr_info(" * 0x%08lx..0x%08lx : kasan shadow mem\n",
+ KASAN_SHADOW_START, KASAN_SHADOW_END);
+#endif
#ifdef CONFIG_NOT_COHERENT_CACHE
pr_info(" * 0x%08lx..0x%08lx : consistent mem\n",
IOREMAP_TOP, IOREMAP_TOP + CONFIG_CONSISTENT_SIZE);
--
2.13.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-07-13 16:23 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-13 16:23 [RFC PATCH v1 0/4] KASAN for nohash PPC32 Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 1/4] powerpc/mm: prepare kernel for KAsan on PPC32 Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 2/4] powerpc: add missing header in pgtable-types.h Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 3/4] powerpc/32: Move early_init() in a separate file Christophe Leroy
2018-07-13 16:23 ` [RFC PATCH v1 4/4] powerpc/nohash32: Add KASAN support Christophe Leroy
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.