forked from torvalds/linux
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add architecture specific implementation details for KFENCE and enable KFENCE for the x86 architecture. In particular, this implements the required interface in <asm/kfence.h> for setting up the pool and providing helper functions for protecting and unprotecting pages. For x86, we need to ensure that the pool uses 4K pages, which is done using the set_memory_4k() helper function. Co-developed-by: Marco Elver <elver@google.com> Signed-off-by: Marco Elver <elver@google.com> Signed-off-by: Alexander Potapenko <glider@google.com>
- Loading branch information
1 parent
3ac0cf4
commit 347eefe
Showing
3 changed files
with
66 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
|
||
#ifndef _ASM_X86_KFENCE_H | ||
#define _ASM_X86_KFENCE_H | ||
|
||
#include <linux/bug.h> | ||
#include <linux/kfence.h> | ||
|
||
#include <asm/pgalloc.h> | ||
#include <asm/pgtable.h> | ||
#include <asm/set_memory.h> | ||
#include <asm/tlbflush.h> | ||
|
||
/* The alignment should be at least a 4K page. */ | ||
#define KFENCE_POOL_ALIGNMENT PAGE_SIZE | ||
|
||
/* | ||
* The page fault handler entry function, up to which the stack trace is | ||
* truncated in reports. | ||
*/ | ||
#define KFENCE_SKIP_ARCH_FAULT_HANDLER "asm_exc_page_fault" | ||
|
||
/* Force 4K pages for __kfence_pool. */ | ||
static inline bool arch_kfence_initialize_pool(void) | ||
{ | ||
unsigned long addr; | ||
|
||
for (addr = (unsigned long)__kfence_pool; is_kfence_address((void *)addr); | ||
addr += PAGE_SIZE) { | ||
unsigned int level; | ||
|
||
if (!lookup_address(addr, &level)) | ||
return false; | ||
|
||
if (level != PG_LEVEL_4K) | ||
set_memory_4k(addr, 1); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/* Protect the given page and flush TLBs. */ | ||
static inline bool kfence_protect_page(unsigned long addr, bool protect) | ||
{ | ||
unsigned int level; | ||
pte_t *pte = lookup_address(addr, &level); | ||
|
||
if (!pte || level != PG_LEVEL_4K) | ||
return false; | ||
|
||
if (protect) | ||
set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT)); | ||
else | ||
set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT)); | ||
|
||
flush_tlb_one_kernel(addr); | ||
return true; | ||
} | ||
|
||
#endif /* _ASM_X86_KFENCE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters