jump_label: mips: move module NOP patching into arch code
MIPS is the only remaining architecture that needs to patch jump label NOP encodings to initialize them at load time. So let's move the module patching part of that from generic code into arch/mips, and drop it from the others. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220615154142.1574619-3-ardb@kernel.org
This commit is contained in:
Родитель
0c3b61e00a
Коммит
fdfd42892f
|
@ -88,3 +88,22 @@ void arch_jump_label_transform(struct jump_entry *e,
|
||||||
|
|
||||||
mutex_unlock(&text_mutex);
|
mutex_unlock(&text_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MODULES
|
||||||
|
void jump_label_apply_nops(struct module *mod)
|
||||||
|
{
|
||||||
|
struct jump_entry *iter_start = mod->jump_entries;
|
||||||
|
struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
|
||||||
|
struct jump_entry *iter;
|
||||||
|
|
||||||
|
/* if the module doesn't have jump label entries, just return */
|
||||||
|
if (iter_start == iter_stop)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (iter = iter_start; iter < iter_stop; iter++) {
|
||||||
|
/* Only write NOPs for arch_branch_static(). */
|
||||||
|
if (jump_label_init_type(iter) == JUMP_LABEL_NOP)
|
||||||
|
arch_jump_label_transform(iter, JUMP_LABEL_NOP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/jump_label.h>
|
#include <linux/jump_label.h>
|
||||||
|
|
||||||
|
extern void jump_label_apply_nops(struct module *mod);
|
||||||
|
|
||||||
struct mips_hi16 {
|
struct mips_hi16 {
|
||||||
struct mips_hi16 *next;
|
struct mips_hi16 *next;
|
||||||
|
@ -428,8 +429,8 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||||
const Elf_Shdr *s;
|
const Elf_Shdr *s;
|
||||||
char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
|
char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
|
||||||
|
|
||||||
/* Make jump label nops. */
|
if (IS_ENABLED(CONFIG_JUMP_LABEL))
|
||||||
jump_label_apply_nops(me);
|
jump_label_apply_nops(me);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&me->arch.dbe_list);
|
INIT_LIST_HEAD(&me->arch.dbe_list);
|
||||||
for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
|
for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
|
||||||
|
|
|
@ -548,6 +548,5 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||||
#endif /* CONFIG_FUNCTION_TRACER */
|
#endif /* CONFIG_FUNCTION_TRACER */
|
||||||
}
|
}
|
||||||
|
|
||||||
jump_label_apply_nops(me);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,9 +208,6 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||||
const Elf_Shdr *sechdrs,
|
const Elf_Shdr *sechdrs,
|
||||||
struct module *me)
|
struct module *me)
|
||||||
{
|
{
|
||||||
/* make jump label nops */
|
|
||||||
jump_label_apply_nops(me);
|
|
||||||
|
|
||||||
do_patch_sections(hdr, sechdrs);
|
do_patch_sections(hdr, sechdrs);
|
||||||
|
|
||||||
/* Cheetah's I-cache is fully coherent. */
|
/* Cheetah's I-cache is fully coherent. */
|
||||||
|
|
|
@ -304,9 +304,6 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||||
tseg, tseg + text->sh_size);
|
tseg, tseg + text->sh_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make jump label nops */
|
|
||||||
jump_label_apply_nops(me);
|
|
||||||
|
|
||||||
if (orc && orc_ip)
|
if (orc && orc_ip)
|
||||||
unwind_module_init(me, (void *)orc_ip->sh_addr, orc_ip->sh_size,
|
unwind_module_init(me, (void *)orc_ip->sh_addr, orc_ip->sh_size,
|
||||||
(void *)orc->sh_addr, orc->sh_size);
|
(void *)orc->sh_addr, orc->sh_size);
|
||||||
|
|
|
@ -230,12 +230,12 @@ extern void static_key_slow_inc(struct static_key *key);
|
||||||
extern void static_key_slow_dec(struct static_key *key);
|
extern void static_key_slow_dec(struct static_key *key);
|
||||||
extern void static_key_slow_inc_cpuslocked(struct static_key *key);
|
extern void static_key_slow_inc_cpuslocked(struct static_key *key);
|
||||||
extern void static_key_slow_dec_cpuslocked(struct static_key *key);
|
extern void static_key_slow_dec_cpuslocked(struct static_key *key);
|
||||||
extern void jump_label_apply_nops(struct module *mod);
|
|
||||||
extern int static_key_count(struct static_key *key);
|
extern int static_key_count(struct static_key *key);
|
||||||
extern void static_key_enable(struct static_key *key);
|
extern void static_key_enable(struct static_key *key);
|
||||||
extern void static_key_disable(struct static_key *key);
|
extern void static_key_disable(struct static_key *key);
|
||||||
extern void static_key_enable_cpuslocked(struct static_key *key);
|
extern void static_key_enable_cpuslocked(struct static_key *key);
|
||||||
extern void static_key_disable_cpuslocked(struct static_key *key);
|
extern void static_key_disable_cpuslocked(struct static_key *key);
|
||||||
|
extern enum jump_label_type jump_label_init_type(struct jump_entry *entry);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We should be using ATOMIC_INIT() for initializing .enabled, but
|
* We should be using ATOMIC_INIT() for initializing .enabled, but
|
||||||
|
@ -303,11 +303,6 @@ static inline int jump_label_text_reserved(void *start, void *end)
|
||||||
static inline void jump_label_lock(void) {}
|
static inline void jump_label_lock(void) {}
|
||||||
static inline void jump_label_unlock(void) {}
|
static inline void jump_label_unlock(void) {}
|
||||||
|
|
||||||
static inline int jump_label_apply_nops(struct module *mod)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void static_key_enable(struct static_key *key)
|
static inline void static_key_enable(struct static_key *key)
|
||||||
{
|
{
|
||||||
STATIC_KEY_CHECK_USE(key);
|
STATIC_KEY_CHECK_USE(key);
|
||||||
|
|
|
@ -508,7 +508,7 @@ void __init jump_label_init(void)
|
||||||
|
|
||||||
#ifdef CONFIG_MODULES
|
#ifdef CONFIG_MODULES
|
||||||
|
|
||||||
static enum jump_label_type jump_label_init_type(struct jump_entry *entry)
|
enum jump_label_type jump_label_init_type(struct jump_entry *entry)
|
||||||
{
|
{
|
||||||
struct static_key *key = jump_entry_key(entry);
|
struct static_key *key = jump_entry_key(entry);
|
||||||
bool type = static_key_type(key);
|
bool type = static_key_type(key);
|
||||||
|
@ -596,31 +596,6 @@ static void __jump_label_mod_update(struct static_key *key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
|
||||||
* apply_jump_label_nops - patch module jump labels with arch_get_jump_label_nop()
|
|
||||||
* @mod: module to patch
|
|
||||||
*
|
|
||||||
* Allow for run-time selection of the optimal nops. Before the module
|
|
||||||
* loads patch these with arch_get_jump_label_nop(), which is specified by
|
|
||||||
* the arch specific jump label code.
|
|
||||||
*/
|
|
||||||
void jump_label_apply_nops(struct module *mod)
|
|
||||||
{
|
|
||||||
struct jump_entry *iter_start = mod->jump_entries;
|
|
||||||
struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
|
|
||||||
struct jump_entry *iter;
|
|
||||||
|
|
||||||
/* if the module doesn't have jump label entries, just return */
|
|
||||||
if (iter_start == iter_stop)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (iter = iter_start; iter < iter_stop; iter++) {
|
|
||||||
/* Only write NOPs for arch_branch_static(). */
|
|
||||||
if (jump_label_init_type(iter) == JUMP_LABEL_NOP)
|
|
||||||
arch_jump_label_transform_static(iter, JUMP_LABEL_NOP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int jump_label_add_module(struct module *mod)
|
static int jump_label_add_module(struct module *mod)
|
||||||
{
|
{
|
||||||
struct jump_entry *iter_start = mod->jump_entries;
|
struct jump_entry *iter_start = mod->jump_entries;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче