Skip to content

Commit 840b239

Browse files
melvertorvalds
authored andcommitted
arm64, kfence: enable KFENCE for ARM64
Add architecture specific implementation details for KFENCE and enable KFENCE for the arm64 architecture. In particular, this implements the required interface in <asm/kfence.h>. KFENCE requires that attributes for pages from its memory pool can individually be set. Therefore, force the entire linear map to be mapped at page granularity. Doing so may result in extra memory allocated for page tables in case rodata=full is not set; however, currently CONFIG_RODATA_FULL_DEFAULT_ENABLED=y is the default, and the common case is therefore not affected by this change. [[email protected]: add missing copyright and description header] Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Alexander Potapenko <[email protected]> Signed-off-by: Marco Elver <[email protected]> Reviewed-by: Dmitry Vyukov <[email protected]> Co-developed-by: Alexander Potapenko <[email protected]> Reviewed-by: Jann Horn <[email protected]> Reviewed-by: Mark Rutland <[email protected]> Cc: Andrey Konovalov <[email protected]> Cc: Andrey Ryabinin <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Christopher Lameter <[email protected]> Cc: Dave Hansen <[email protected]> Cc: David Rientjes <[email protected]> Cc: Eric Dumazet <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Hillf Danton <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Joern Engel <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Joonsoo Kim <[email protected]> Cc: Kees Cook <[email protected]> Cc: Paul E. McKenney <[email protected]> Cc: Pekka Enberg <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: SeongJae Park <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: Will Deacon <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 1dc0da6 commit 840b239

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

arch/arm64/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ config ARM64
140140
select HAVE_ARCH_KASAN if !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
141141
select HAVE_ARCH_KASAN_SW_TAGS if HAVE_ARCH_KASAN
142142
select HAVE_ARCH_KASAN_HW_TAGS if (HAVE_ARCH_KASAN && ARM64_MTE)
143+
select HAVE_ARCH_KFENCE
143144
select HAVE_ARCH_KGDB
144145
select HAVE_ARCH_MMAP_RND_BITS
145146
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT

arch/arm64/include/asm/kfence.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* arm64 KFENCE support.
4+
*
5+
* Copyright (C) 2020, Google LLC.
6+
*/
7+
8+
#ifndef __ASM_KFENCE_H
9+
#define __ASM_KFENCE_H
10+
11+
#include <asm/cacheflush.h>
12+
13+
#define KFENCE_SKIP_ARCH_FAULT_HANDLER "el1_sync"
14+
15+
static inline bool arch_kfence_init_pool(void) { return true; }
16+
17+
static inline bool kfence_protect_page(unsigned long addr, bool protect)
18+
{
19+
set_memory_valid(addr, 1, !protect);
20+
21+
return true;
22+
}
23+
24+
#endif /* __ASM_KFENCE_H */

arch/arm64/mm/fault.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/acpi.h>
1111
#include <linux/bitfield.h>
1212
#include <linux/extable.h>
13+
#include <linux/kfence.h>
1314
#include <linux/signal.h>
1415
#include <linux/mm.h>
1516
#include <linux/hardirq.h>
@@ -389,6 +390,9 @@ static void __do_kernel_fault(unsigned long addr, unsigned int esr,
389390
} else if (addr < PAGE_SIZE) {
390391
msg = "NULL pointer dereference";
391392
} else {
393+
if (kfence_handle_page_fault(addr))
394+
return;
395+
392396
msg = "paging request";
393397
}
394398

arch/arm64/mm/mmu.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1465,7 +1465,13 @@ int arch_add_memory(int nid, u64 start, u64 size,
14651465
int ret, flags = 0;
14661466

14671467
VM_BUG_ON(!mhp_range_allowed(start, size, true));
1468-
if (rodata_full || debug_pagealloc_enabled())
1468+
1469+
/*
1470+
* KFENCE requires linear map to be mapped at page granularity, so that
1471+
* it is possible to protect/unprotect single pages in the KFENCE pool.
1472+
*/
1473+
if (rodata_full || debug_pagealloc_enabled() ||
1474+
IS_ENABLED(CONFIG_KFENCE))
14691475
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
14701476

14711477
__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),

0 commit comments

Comments
 (0)