mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-31 14:23:49 +01:00
The memory reserved for module tags does not need to be backed by physical pages until there are tags to store there. Change the way we reserve this memory to allocate only virtual area for the tags and populate it with physical pages as needed when we load a module. [[email protected]: avoid execmem_vmap() when !MMU] Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Suren Baghdasaryan <[email protected]> Reviewed-by: Pasha Tatashin <[email protected]> Cc: Ard Biesheuvel <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Borislav Petkov (AMD) <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Daniel Gomez <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: Davidlohr Bueso <[email protected]> Cc: David Rientjes <[email protected]> Cc: Dennis Zhou <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: John Hubbard <[email protected]> Cc: Jonathan Corbet <[email protected]> Cc: Joonsoo Kim <[email protected]> Cc: Kalesh Singh <[email protected]> Cc: Kees Cook <[email protected]> Cc: Kent Overstreet <[email protected]> Cc: Liam R. Howlett <[email protected]> Cc: Luis Chamberlain <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Mike Rapoport (Microsoft) <[email protected]> Cc: Minchan Kim <[email protected]> Cc: Paul E. McKenney <[email protected]> Cc: Petr Pavlu <[email protected]> Cc: Roman Gushchin <[email protected]> Cc: Sami Tolvanen <[email protected]> Cc: Sourav Panda <[email protected]> Cc: Steven Rostedt (Google) <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Thomas Huth <[email protected]> Cc: Uladzislau Rezki (Sony) <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: Xiongwei Song <[email protected]> Cc: Yu Zhao <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
182 lines
5.6 KiB
C
182 lines
5.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_EXECMEM_ALLOC_H
|
|
#define _LINUX_EXECMEM_ALLOC_H
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/moduleloader.h>
|
|
|
|
#if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \
|
|
!defined(CONFIG_KASAN_VMALLOC)
|
|
#include <linux/kasan.h>
|
|
#define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
|
|
#else
|
|
#define MODULE_ALIGN PAGE_SIZE
|
|
#endif
|
|
|
|
/**
|
|
* enum execmem_type - types of executable memory ranges
|
|
*
|
|
* There are several subsystems that allocate executable memory.
|
|
* Architectures define different restrictions on placement,
|
|
* permissions, alignment and other parameters for memory that can be used
|
|
* by these subsystems.
|
|
* Types in this enum identify subsystems that allocate executable memory
|
|
* and let architectures define parameters for ranges suitable for
|
|
* allocations by each subsystem.
|
|
*
|
|
* @EXECMEM_DEFAULT: default parameters that would be used for types that
|
|
* are not explicitly defined.
|
|
* @EXECMEM_MODULE_TEXT: parameters for module text sections
|
|
* @EXECMEM_KPROBES: parameters for kprobes
|
|
* @EXECMEM_FTRACE: parameters for ftrace
|
|
* @EXECMEM_BPF: parameters for BPF
|
|
* @EXECMEM_MODULE_DATA: parameters for module data sections
|
|
* @EXECMEM_TYPE_MAX:
|
|
*/
|
|
enum execmem_type {
|
|
EXECMEM_DEFAULT,
|
|
EXECMEM_MODULE_TEXT = EXECMEM_DEFAULT,
|
|
EXECMEM_KPROBES,
|
|
EXECMEM_FTRACE,
|
|
EXECMEM_BPF,
|
|
EXECMEM_MODULE_DATA,
|
|
EXECMEM_TYPE_MAX,
|
|
};
|
|
|
|
/**
|
|
* enum execmem_range_flags - options for executable memory allocations
|
|
* @EXECMEM_KASAN_SHADOW: allocate kasan shadow
|
|
* @EXECMEM_ROX_CACHE: allocations should use ROX cache of huge pages
|
|
*/
|
|
enum execmem_range_flags {
|
|
EXECMEM_KASAN_SHADOW = (1 << 0),
|
|
EXECMEM_ROX_CACHE = (1 << 1),
|
|
};
|
|
|
|
#ifdef CONFIG_ARCH_HAS_EXECMEM_ROX
|
|
/**
|
|
* execmem_fill_trapping_insns - set memory to contain instructions that
|
|
* will trap
|
|
* @ptr: pointer to memory to fill
|
|
* @size: size of the range to fill
|
|
* @writable: is the memory poited by @ptr is writable or ROX
|
|
*
|
|
* A hook for architecures to fill execmem ranges with invalid instructions.
|
|
* Architectures that use EXECMEM_ROX_CACHE must implement this.
|
|
*/
|
|
void execmem_fill_trapping_insns(void *ptr, size_t size, bool writable);
|
|
#endif
|
|
|
|
/**
|
|
* struct execmem_range - definition of an address space suitable for code and
|
|
* related data allocations
|
|
* @start: address space start
|
|
* @end: address space end (inclusive)
|
|
* @fallback_start: start of the secondary address space range for fallback
|
|
* allocations on architectures that require it
|
|
* @fallback_end: start of the secondary address space (inclusive)
|
|
* @pgprot: permissions for memory in this address space
|
|
* @alignment: alignment required for text allocations
|
|
* @flags: options for memory allocations for this range
|
|
*/
|
|
struct execmem_range {
|
|
unsigned long start;
|
|
unsigned long end;
|
|
unsigned long fallback_start;
|
|
unsigned long fallback_end;
|
|
pgprot_t pgprot;
|
|
unsigned int alignment;
|
|
enum execmem_range_flags flags;
|
|
};
|
|
|
|
/**
|
|
* struct execmem_info - architecture parameters for code allocations
|
|
* @ranges: array of parameter sets defining architecture specific
|
|
* parameters for executable memory allocations. The ranges that are not
|
|
* explicitly initialized by an architecture use parameters defined for
|
|
* @EXECMEM_DEFAULT.
|
|
*/
|
|
struct execmem_info {
|
|
struct execmem_range ranges[EXECMEM_TYPE_MAX];
|
|
};
|
|
|
|
/**
|
|
* execmem_arch_setup - define parameters for allocations of executable memory
|
|
*
|
|
* A hook for architectures to define parameters for allocations of
|
|
* executable memory. These parameters should be filled into the
|
|
* @execmem_info structure.
|
|
*
|
|
* For architectures that do not implement this method a default set of
|
|
* parameters will be used
|
|
*
|
|
* Return: a structure defining architecture parameters and restrictions
|
|
* for allocations of executable memory
|
|
*/
|
|
struct execmem_info *execmem_arch_setup(void);
|
|
|
|
/**
|
|
* execmem_alloc - allocate executable memory
|
|
* @type: type of the allocation
|
|
* @size: how many bytes of memory are required
|
|
*
|
|
* Allocates memory that will contain executable code, either generated or
|
|
* loaded from kernel modules.
|
|
*
|
|
* Allocates memory that will contain data coupled with executable code,
|
|
* like data sections in kernel modules.
|
|
*
|
|
* The memory will have protections defined by architecture for executable
|
|
* region of the @type.
|
|
*
|
|
* Return: a pointer to the allocated memory or %NULL
|
|
*/
|
|
void *execmem_alloc(enum execmem_type type, size_t size);
|
|
|
|
/**
|
|
* execmem_free - free executable memory
|
|
* @ptr: pointer to the memory that should be freed
|
|
*/
|
|
void execmem_free(void *ptr);
|
|
|
|
#ifdef CONFIG_MMU
|
|
/**
|
|
* execmem_vmap - create virtual mapping for EXECMEM_MODULE_DATA memory
|
|
* @size: size of the virtual mapping in bytes
|
|
*
|
|
* Maps virtually contiguous area in the range suitable for EXECMEM_MODULE_DATA.
|
|
*
|
|
* Return: the area descriptor on success or %NULL on failure.
|
|
*/
|
|
struct vm_struct *execmem_vmap(size_t size);
|
|
#endif
|
|
|
|
/**
|
|
* execmem_update_copy - copy an update to executable memory
|
|
* @dst: destination address to update
|
|
* @src: source address containing the data
|
|
* @size: how many bytes of memory shold be copied
|
|
*
|
|
* Copy @size bytes from @src to @dst using text poking if the memory at
|
|
* @dst is read-only.
|
|
*
|
|
* Return: a pointer to @dst or NULL on error
|
|
*/
|
|
void *execmem_update_copy(void *dst, const void *src, size_t size);
|
|
|
|
/**
|
|
* execmem_is_rox - check if execmem is read-only
|
|
* @type - the execmem type to check
|
|
*
|
|
* Return: %true if the @type is read-only, %false if it's writable
|
|
*/
|
|
bool execmem_is_rox(enum execmem_type type);
|
|
|
|
#if defined(CONFIG_EXECMEM) && !defined(CONFIG_ARCH_WANTS_EXECMEM_LATE)
|
|
void execmem_init(void);
|
|
#else
|
|
static inline void execmem_init(void) {}
|
|
#endif
|
|
|
|
#endif /* _LINUX_EXECMEM_ALLOC_H */
|