forked from Minki/linux
jump_label: make initial NOP patching the special case
Instead of defaulting to patching NOP opcodes at init time, and leaving it to the architectures to override this if this is not needed, switch to a model where doing nothing is the default. This is the common case by far, as only MIPS requires NOP patching at init time. On all other architectures, the correct encodings are emitted by the compiler and so no initial patching is needed. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20220615154142.1574619-4-ardb@kernel.org
This commit is contained in:
parent
fdfd42892f
commit
7e6b9db27d
@ -201,9 +201,6 @@ static_key->entry field makes use of the two least significant bits.
|
|||||||
* ``void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type type)``,
|
* ``void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type type)``,
|
||||||
see: arch/x86/kernel/jump_label.c
|
see: arch/x86/kernel/jump_label.c
|
||||||
|
|
||||||
* ``__init_or_module void arch_jump_label_transform_static(struct jump_entry *entry, enum jump_label_type type)``,
|
|
||||||
see: arch/x86/kernel/jump_label.c
|
|
||||||
|
|
||||||
* ``struct jump_entry``,
|
* ``struct jump_entry``,
|
||||||
see: arch/x86/include/asm/jump_label.h
|
see: arch/x86/include/asm/jump_label.h
|
||||||
|
|
||||||
|
@ -96,19 +96,6 @@ void arch_jump_label_transform(struct jump_entry *entry,
|
|||||||
flush_icache_range(entry->code, entry->code + JUMP_LABEL_NOP_SIZE);
|
flush_icache_range(entry->code, entry->code + JUMP_LABEL_NOP_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_jump_label_transform_static(struct jump_entry *entry,
|
|
||||||
enum jump_label_type type)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We use only one NOP type (1x, 4 byte) in arch_static_branch, so
|
|
||||||
* there's no need to patch an identical NOP over the top of it here.
|
|
||||||
* The generic code calls 'arch_jump_label_transform' if the NOP needs
|
|
||||||
* to be replaced by a branch, so 'arch_jump_label_transform_static' is
|
|
||||||
* never called with type other than JUMP_LABEL_NOP.
|
|
||||||
*/
|
|
||||||
BUG_ON(type != JUMP_LABEL_NOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARC_DBG_JUMP_LABEL
|
#ifdef CONFIG_ARC_DBG_JUMP_LABEL
|
||||||
#define SELFTEST_MSG "ARC: instruction generation self-test: "
|
#define SELFTEST_MSG "ARC: instruction generation self-test: "
|
||||||
|
|
||||||
|
@ -27,9 +27,3 @@ void arch_jump_label_transform(struct jump_entry *entry,
|
|||||||
{
|
{
|
||||||
__arch_jump_label_transform(entry, type, false);
|
__arch_jump_label_transform(entry, type, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_jump_label_transform_static(struct jump_entry *entry,
|
|
||||||
enum jump_label_type type)
|
|
||||||
{
|
|
||||||
__arch_jump_label_transform(entry, type, true);
|
|
||||||
}
|
|
||||||
|
@ -26,14 +26,3 @@ void arch_jump_label_transform(struct jump_entry *entry,
|
|||||||
|
|
||||||
aarch64_insn_patch_text_nosync(addr, insn);
|
aarch64_insn_patch_text_nosync(addr, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_jump_label_transform_static(struct jump_entry *entry,
|
|
||||||
enum jump_label_type type)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We use the architected A64 NOP in arch_static_branch, so there's no
|
|
||||||
* need to patch an identical A64 NOP over the top of it here. The core
|
|
||||||
* will call arch_jump_label_transform from a module notifier if the
|
|
||||||
* NOP needs to be replaced by a branch.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#ifndef _ASM_MIPS_JUMP_LABEL_H
|
#ifndef _ASM_MIPS_JUMP_LABEL_H
|
||||||
#define _ASM_MIPS_JUMP_LABEL_H
|
#define _ASM_MIPS_JUMP_LABEL_H
|
||||||
|
|
||||||
|
#define arch_jump_label_transform_static arch_jump_label_transform
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
@ -42,14 +42,3 @@ void arch_jump_label_transform(struct jump_entry *entry,
|
|||||||
|
|
||||||
patch_text(addr, insn);
|
patch_text(addr, insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_jump_label_transform_static(struct jump_entry *entry,
|
|
||||||
enum jump_label_type type)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We use the architected NOP in arch_static_branch, so there's no
|
|
||||||
* need to patch an identical NOP over the top of it here. The core
|
|
||||||
* will call arch_jump_label_transform from a module notifier if the
|
|
||||||
* NOP needs to be replaced by a branch.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
@ -39,15 +39,3 @@ void arch_jump_label_transform(struct jump_entry *entry,
|
|||||||
patch_text_nosync(addr, &insn, sizeof(insn));
|
patch_text_nosync(addr, &insn, sizeof(insn));
|
||||||
mutex_unlock(&text_mutex);
|
mutex_unlock(&text_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_jump_label_transform_static(struct jump_entry *entry,
|
|
||||||
enum jump_label_type type)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We use the same instructions in the arch_static_branch and
|
|
||||||
* arch_static_branch_jump inline functions, so there's no
|
|
||||||
* need to patch them up here.
|
|
||||||
* The core will call arch_jump_label_transform when those
|
|
||||||
* instructions need to be replaced.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
@ -80,8 +80,3 @@ void arch_jump_label_transform_apply(void)
|
|||||||
{
|
{
|
||||||
text_poke_sync();
|
text_poke_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init_or_module arch_jump_label_transform_static(struct jump_entry *entry,
|
|
||||||
enum jump_label_type type)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
@ -146,16 +146,3 @@ void arch_jump_label_transform_apply(void)
|
|||||||
text_poke_finish();
|
text_poke_finish();
|
||||||
mutex_unlock(&text_mutex);
|
mutex_unlock(&text_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum {
|
|
||||||
JL_STATE_START,
|
|
||||||
JL_STATE_NO_UPDATE,
|
|
||||||
JL_STATE_UPDATE,
|
|
||||||
} jlstate __initdata_or_module = JL_STATE_START;
|
|
||||||
|
|
||||||
__init_or_module void arch_jump_label_transform_static(struct jump_entry *entry,
|
|
||||||
enum jump_label_type type)
|
|
||||||
{
|
|
||||||
if (jlstate == JL_STATE_UPDATE)
|
|
||||||
jump_label_transform(entry, type, 1);
|
|
||||||
}
|
|
||||||
|
@ -220,8 +220,6 @@ extern void jump_label_lock(void);
|
|||||||
extern void jump_label_unlock(void);
|
extern void jump_label_unlock(void);
|
||||||
extern void arch_jump_label_transform(struct jump_entry *entry,
|
extern void arch_jump_label_transform(struct jump_entry *entry,
|
||||||
enum jump_label_type type);
|
enum jump_label_type type);
|
||||||
extern void arch_jump_label_transform_static(struct jump_entry *entry,
|
|
||||||
enum jump_label_type type);
|
|
||||||
extern bool arch_jump_label_transform_queue(struct jump_entry *entry,
|
extern bool arch_jump_label_transform_queue(struct jump_entry *entry,
|
||||||
enum jump_label_type type);
|
enum jump_label_type type);
|
||||||
extern void arch_jump_label_transform_apply(void);
|
extern void arch_jump_label_transform_apply(void);
|
||||||
|
@ -332,17 +332,13 @@ static int __jump_label_text_reserved(struct jump_entry *iter_start,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#ifndef arch_jump_label_transform_static
|
||||||
* Update code which is definitely not currently executing.
|
static void arch_jump_label_transform_static(struct jump_entry *entry,
|
||||||
* Architectures which need heavyweight synchronization to modify
|
enum jump_label_type type)
|
||||||
* running code can override this to make the non-live update case
|
|
||||||
* cheaper.
|
|
||||||
*/
|
|
||||||
void __weak __init_or_module arch_jump_label_transform_static(struct jump_entry *entry,
|
|
||||||
enum jump_label_type type)
|
|
||||||
{
|
{
|
||||||
arch_jump_label_transform(entry, type);
|
/* nothing to do on most architectures */
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline struct jump_entry *static_key_entries(struct static_key *key)
|
static inline struct jump_entry *static_key_entries(struct static_key *key)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user