Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
02678a58
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
02678a58
编写于
10月 06, 2018
作者:
I
Ingo Molnar
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'core/core' into x86/build, to prevent conflicts
Signed-off-by:
N
Ingo Molnar
<
mingo@kernel.org
>
上级
bce6824c
77ac1c02
变更
21
隐藏空白更改
内联
并排
Showing
21 changed file
with
226 addition
and
174 deletion
+226
-174
arch/Kconfig
arch/Kconfig
+3
-0
arch/arm64/Kconfig
arch/arm64/Kconfig
+1
-0
arch/arm64/include/asm/jump_label.h
arch/arm64/include/asm/jump_label.h
+18
-20
arch/arm64/kernel/jump_label.c
arch/arm64/kernel/jump_label.c
+3
-3
arch/s390/Kconfig
arch/s390/Kconfig
+1
-0
arch/s390/include/asm/jump_label.h
arch/s390/include/asm/jump_label.h
+16
-24
arch/s390/kernel/jump_label.c
arch/s390/kernel/jump_label.c
+6
-5
arch/s390/kernel/vmlinux.lds.S
arch/s390/kernel/vmlinux.lds.S
+1
-0
arch/x86/Kconfig
arch/x86/Kconfig
+1
-0
arch/x86/include/asm/elf.h
arch/x86/include/asm/elf.h
+1
-2
arch/x86/include/asm/jump_label.h
arch/x86/include/asm/jump_label.h
+8
-16
arch/x86/kernel/jump_label.c
arch/x86/kernel/jump_label.c
+25
-37
arch/x86/kernel/module.c
arch/x86/kernel/module.c
+6
-0
arch/x86/tools/relocs.c
arch/x86/tools/relocs.c
+10
-0
arch/x86/um/asm/elf.h
arch/x86/um/asm/elf.h
+1
-2
include/asm-generic/vmlinux.lds.h
include/asm-generic/vmlinux.lds.h
+7
-4
include/linux/jump_label.h
include/linux/jump_label.h
+62
-3
init/main.c
init/main.c
+0
-1
kernel/jump_label.c
kernel/jump_label.c
+45
-55
kernel/module.c
kernel/module.c
+9
-0
tools/objtool/special.c
tools/objtool/special.c
+2
-2
未找到文件。
arch/Kconfig
浏览文件 @
02678a58
...
@@ -359,6 +359,9 @@ config HAVE_PERF_USER_STACK_DUMP
...
@@ -359,6 +359,9 @@ config HAVE_PERF_USER_STACK_DUMP
config HAVE_ARCH_JUMP_LABEL
config HAVE_ARCH_JUMP_LABEL
bool
bool
config HAVE_ARCH_JUMP_LABEL_RELATIVE
bool
config HAVE_RCU_TABLE_FREE
config HAVE_RCU_TABLE_FREE
bool
bool
...
...
arch/arm64/Kconfig
浏览文件 @
02678a58
...
@@ -104,6 +104,7 @@ config ARM64
...
@@ -104,6 +104,7 @@ config ARM64
select HAVE_ARCH_BITREVERSE
select HAVE_ARCH_BITREVERSE
select HAVE_ARCH_HUGE_VMAP
select HAVE_ARCH_HUGE_VMAP
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KASAN if !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
select HAVE_ARCH_KASAN if !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
select HAVE_ARCH_KGDB
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_BITS
...
...
arch/arm64/include/asm/jump_label.h
浏览文件 @
02678a58
...
@@ -26,13 +26,16 @@
...
@@ -26,13 +26,16 @@
#define JUMP_LABEL_NOP_SIZE AARCH64_INSN_SIZE
#define JUMP_LABEL_NOP_SIZE AARCH64_INSN_SIZE
static
__always_inline
bool
arch_static_branch
(
struct
static_key
*
key
,
bool
branch
)
static
__always_inline
bool
arch_static_branch
(
struct
static_key
*
key
,
bool
branch
)
{
{
asm_volatile_goto
(
"1: nop
\n\t
"
asm_volatile_goto
(
".pushsection __jump_table,
\"
aw
\"\n\t
"
"1: nop
\n\t
"
".align 3
\n\t
"
" .pushsection __jump_table,
\"
aw
\"
\n\t
"
".quad 1b, %l[l_yes], %c0
\n\t
"
" .align 3
\n\t
"
".popsection
\n\t
"
" .long 1b - ., %l[l_yes] - .
\n\t
"
" .quad %c0 - .
\n\t
"
" .popsection
\n\t
"
:
:
"i"
(
&
((
char
*
)
key
)[
branch
])
:
:
l_yes
);
:
:
"i"
(
&
((
char
*
)
key
)[
branch
])
:
:
l_yes
);
return
false
;
return
false
;
...
@@ -40,13 +43,16 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran
...
@@ -40,13 +43,16 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran
return
true
;
return
true
;
}
}
static
__always_inline
bool
arch_static_branch_jump
(
struct
static_key
*
key
,
bool
branch
)
static
__always_inline
bool
arch_static_branch_jump
(
struct
static_key
*
key
,
bool
branch
)
{
{
asm_volatile_goto
(
"1: b %l[l_yes]
\n\t
"
asm_volatile_goto
(
".pushsection __jump_table,
\"
aw
\"\n\t
"
"1: b %l[l_yes]
\n\t
"
".align 3
\n\t
"
" .pushsection __jump_table,
\"
aw
\"
\n\t
"
".quad 1b, %l[l_yes], %c0
\n\t
"
" .align 3
\n\t
"
".popsection
\n\t
"
" .long 1b - ., %l[l_yes] - .
\n\t
"
" .quad %c0 - .
\n\t
"
" .popsection
\n\t
"
:
:
"i"
(
&
((
char
*
)
key
)[
branch
])
:
:
l_yes
);
:
:
"i"
(
&
((
char
*
)
key
)[
branch
])
:
:
l_yes
);
return
false
;
return
false
;
...
@@ -54,13 +60,5 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
...
@@ -54,13 +60,5 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
return
true
;
return
true
;
}
}
typedef
u64
jump_label_t
;
struct
jump_entry
{
jump_label_t
code
;
jump_label_t
target
;
jump_label_t
key
;
};
#endif
/* __ASSEMBLY__ */
#endif
/* __ASSEMBLY__ */
#endif
/* __ASM_JUMP_LABEL_H */
#endif
/* __ASM_JUMP_LABEL_H */
arch/arm64/kernel/jump_label.c
浏览文件 @
02678a58
...
@@ -25,12 +25,12 @@
...
@@ -25,12 +25,12 @@
void
arch_jump_label_transform
(
struct
jump_entry
*
entry
,
void
arch_jump_label_transform
(
struct
jump_entry
*
entry
,
enum
jump_label_type
type
)
enum
jump_label_type
type
)
{
{
void
*
addr
=
(
void
*
)
entry
->
code
;
void
*
addr
=
(
void
*
)
jump_entry_code
(
entry
)
;
u32
insn
;
u32
insn
;
if
(
type
==
JUMP_LABEL_JMP
)
{
if
(
type
==
JUMP_LABEL_JMP
)
{
insn
=
aarch64_insn_gen_branch_imm
(
entry
->
code
,
insn
=
aarch64_insn_gen_branch_imm
(
jump_entry_code
(
entry
)
,
entry
->
target
,
jump_entry_target
(
entry
)
,
AARCH64_INSN_BRANCH_NOLINK
);
AARCH64_INSN_BRANCH_NOLINK
);
}
else
{
}
else
{
insn
=
aarch64_insn_gen_nop
();
insn
=
aarch64_insn_gen_nop
();
...
...
arch/s390/Kconfig
浏览文件 @
02678a58
...
@@ -120,6 +120,7 @@ config S390
...
@@ -120,6 +120,7 @@ config S390
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES
select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_SOFT_DIRTY
select HAVE_ARCH_SOFT_DIRTY
...
...
arch/s390/include/asm/jump_label.h
浏览文件 @
02678a58
...
@@ -14,41 +14,33 @@
...
@@ -14,41 +14,33 @@
* We use a brcl 0,2 instruction for jump labels at compile time so it
* We use a brcl 0,2 instruction for jump labels at compile time so it
* can be easily distinguished from a hotpatch generated instruction.
* can be easily distinguished from a hotpatch generated instruction.
*/
*/
static
__always_
inline
bool
arch_static_branch
(
struct
static_key
*
key
,
bool
branch
)
static
inline
bool
arch_static_branch
(
struct
static_key
*
key
,
bool
branch
)
{
{
asm_volatile_goto
(
"0: brcl
0,"
__stringify
(
JUMP_LABEL_NOP_OFFSET
)
"
\n
"
asm_volatile_goto
(
"0: brcl
0,"
__stringify
(
JUMP_LABEL_NOP_OFFSET
)
"
\n
"
".pushsection __jump_table,
\"
aw
\"\n
"
".pushsection __jump_table,
\"
aw
\"\n
"
".balign
8
\n
"
".balign
8
\n
"
".quad 0b, %l[label], %0
\n
"
".long 0b-.,%l[label]-.
\n
"
".popsection
\n
"
".quad %0-.
\n
"
:
:
"X"
(
&
((
char
*
)
key
)[
branch
])
:
:
label
);
".popsection
\n
"
:
:
"X"
(
&
((
char
*
)
key
)[
branch
])
:
:
label
);
return
false
;
return
false
;
label:
label:
return
true
;
return
true
;
}
}
static
__always_
inline
bool
arch_static_branch_jump
(
struct
static_key
*
key
,
bool
branch
)
static
inline
bool
arch_static_branch_jump
(
struct
static_key
*
key
,
bool
branch
)
{
{
asm_volatile_goto
(
"0: brcl 15,
%l[label]
\n
"
asm_volatile_goto
(
"0: brcl 15,%l[label]
\n
"
".pushsection __jump_table,
\"
aw
\"\n
"
".pushsection __jump_table,
\"
aw
\"\n
"
".balign
8
\n
"
".balign
8
\n
"
".quad 0b, %l[label], %0
\n
"
".long 0b-.,%l[label]-.
\n
"
".popsection
\n
"
".quad %0-.
\n
"
:
:
"X"
(
&
((
char
*
)
key
)[
branch
])
:
:
label
);
".popsection
\n
"
:
:
"X"
(
&
((
char
*
)
key
)[
branch
])
:
:
label
);
return
false
;
return
false
;
label:
label:
return
true
;
return
true
;
}
}
typedef
unsigned
long
jump_label_t
;
struct
jump_entry
{
jump_label_t
code
;
jump_label_t
target
;
jump_label_t
key
;
};
#endif
/* __ASSEMBLY__ */
#endif
/* __ASSEMBLY__ */
#endif
#endif
arch/s390/kernel/jump_label.c
浏览文件 @
02678a58
...
@@ -33,13 +33,13 @@ static void jump_label_make_branch(struct jump_entry *entry, struct insn *insn)
...
@@ -33,13 +33,13 @@ static void jump_label_make_branch(struct jump_entry *entry, struct insn *insn)
{
{
/* brcl 15,offset */
/* brcl 15,offset */
insn
->
opcode
=
0xc0f4
;
insn
->
opcode
=
0xc0f4
;
insn
->
offset
=
(
entry
->
target
-
entry
->
code
)
>>
1
;
insn
->
offset
=
(
jump_entry_target
(
entry
)
-
jump_entry_code
(
entry
)
)
>>
1
;
}
}
static
void
jump_label_bug
(
struct
jump_entry
*
entry
,
struct
insn
*
expected
,
static
void
jump_label_bug
(
struct
jump_entry
*
entry
,
struct
insn
*
expected
,
struct
insn
*
new
)
struct
insn
*
new
)
{
{
unsigned
char
*
ipc
=
(
unsigned
char
*
)
entry
->
code
;
unsigned
char
*
ipc
=
(
unsigned
char
*
)
jump_entry_code
(
entry
)
;
unsigned
char
*
ipe
=
(
unsigned
char
*
)
expected
;
unsigned
char
*
ipe
=
(
unsigned
char
*
)
expected
;
unsigned
char
*
ipn
=
(
unsigned
char
*
)
new
;
unsigned
char
*
ipn
=
(
unsigned
char
*
)
new
;
...
@@ -59,6 +59,7 @@ static void __jump_label_transform(struct jump_entry *entry,
...
@@ -59,6 +59,7 @@ static void __jump_label_transform(struct jump_entry *entry,
enum
jump_label_type
type
,
enum
jump_label_type
type
,
int
init
)
int
init
)
{
{
void
*
code
=
(
void
*
)
jump_entry_code
(
entry
);
struct
insn
old
,
new
;
struct
insn
old
,
new
;
if
(
type
==
JUMP_LABEL_JMP
)
{
if
(
type
==
JUMP_LABEL_JMP
)
{
...
@@ -69,13 +70,13 @@ static void __jump_label_transform(struct jump_entry *entry,
...
@@ -69,13 +70,13 @@ static void __jump_label_transform(struct jump_entry *entry,
jump_label_make_nop
(
entry
,
&
new
);
jump_label_make_nop
(
entry
,
&
new
);
}
}
if
(
init
)
{
if
(
init
)
{
if
(
memcmp
(
(
void
*
)
entry
->
code
,
&
orignop
,
sizeof
(
orignop
)))
if
(
memcmp
(
code
,
&
orignop
,
sizeof
(
orignop
)))
jump_label_bug
(
entry
,
&
orignop
,
&
new
);
jump_label_bug
(
entry
,
&
orignop
,
&
new
);
}
else
{
}
else
{
if
(
memcmp
(
(
void
*
)
entry
->
code
,
&
old
,
sizeof
(
old
)))
if
(
memcmp
(
code
,
&
old
,
sizeof
(
old
)))
jump_label_bug
(
entry
,
&
old
,
&
new
);
jump_label_bug
(
entry
,
&
old
,
&
new
);
}
}
s390_kernel_write
(
(
void
*
)
entry
->
code
,
&
new
,
sizeof
(
new
));
s390_kernel_write
(
code
,
&
new
,
sizeof
(
new
));
}
}
static
int
__sm_arch_jump_label_transform
(
void
*
data
)
static
int
__sm_arch_jump_label_transform
(
void
*
data
)
...
...
arch/s390/kernel/vmlinux.lds.S
浏览文件 @
02678a58
...
@@ -64,6 +64,7 @@ SECTIONS
...
@@ -64,6 +64,7 @@ SECTIONS
__start_ro_after_init
=
.
;
__start_ro_after_init
=
.
;
.
data..
ro_after_init
:
{
.
data..
ro_after_init
:
{
*(.
data..
ro_after_init
)
*(.
data..
ro_after_init
)
JUMP_TABLE_DATA
}
}
EXCEPTION_TABLE
(16)
EXCEPTION_TABLE
(16)
.
=
ALIGN
(
PAGE_SIZE
)
;
.
=
ALIGN
(
PAGE_SIZE
)
;
...
...
arch/x86/Kconfig
浏览文件 @
02678a58
...
@@ -119,6 +119,7 @@ config X86
...
@@ -119,6 +119,7 @@ config X86
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_HUGE_VMAP if X86_64 || X86_PAE
select HAVE_ARCH_HUGE_VMAP if X86_64 || X86_PAE
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KASAN if X86_64
select HAVE_ARCH_KASAN if X86_64
select HAVE_ARCH_KGDB
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS if MMU
select HAVE_ARCH_MMAP_RND_BITS if MMU
...
...
arch/x86/include/asm/elf.h
浏览文件 @
02678a58
...
@@ -62,8 +62,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
...
@@ -62,8 +62,7 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
#define R_X86_64_PC16 13
/* 16 bit sign extended pc relative */
#define R_X86_64_PC16 13
/* 16 bit sign extended pc relative */
#define R_X86_64_8 14
/* Direct 8 bit sign extended */
#define R_X86_64_8 14
/* Direct 8 bit sign extended */
#define R_X86_64_PC8 15
/* 8 bit sign extended pc relative */
#define R_X86_64_PC8 15
/* 8 bit sign extended pc relative */
#define R_X86_64_PC64 24
/* Place relative 64-bit signed */
#define R_X86_64_NUM 16
/*
/*
* These are used to set parameters in the core dumps.
* These are used to set parameters in the core dumps.
...
...
arch/x86/include/asm/jump_label.h
浏览文件 @
02678a58
...
@@ -37,7 +37,8 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran
...
@@ -37,7 +37,8 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran
".byte "
__stringify
(
STATIC_KEY_INIT_NOP
)
"
\n\t
"
".byte "
__stringify
(
STATIC_KEY_INIT_NOP
)
"
\n\t
"
".pushsection __jump_table,
\"
aw
\"
\n\t
"
".pushsection __jump_table,
\"
aw
\"
\n\t
"
_ASM_ALIGN
"
\n\t
"
_ASM_ALIGN
"
\n\t
"
_ASM_PTR
"1b, %l[l_yes], %c0 + %c1
\n\t
"
".long 1b - ., %l[l_yes] - .
\n\t
"
_ASM_PTR
"%c0 + %c1 - .
\n\t
"
".popsection
\n\t
"
".popsection
\n\t
"
:
:
"i"
(
key
),
"i"
(
branch
)
:
:
l_yes
);
:
:
"i"
(
key
),
"i"
(
branch
)
:
:
l_yes
);
...
@@ -53,7 +54,8 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
...
@@ -53,7 +54,8 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
"2:
\n\t
"
"2:
\n\t
"
".pushsection __jump_table,
\"
aw
\"
\n\t
"
".pushsection __jump_table,
\"
aw
\"
\n\t
"
_ASM_ALIGN
"
\n\t
"
_ASM_ALIGN
"
\n\t
"
_ASM_PTR
"1b, %l[l_yes], %c0 + %c1
\n\t
"
".long 1b - ., %l[l_yes] - .
\n\t
"
_ASM_PTR
"%c0 + %c1 - .
\n\t
"
".popsection
\n\t
"
".popsection
\n\t
"
:
:
"i"
(
key
),
"i"
(
branch
)
:
:
l_yes
);
:
:
"i"
(
key
),
"i"
(
branch
)
:
:
l_yes
);
...
@@ -62,18 +64,6 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
...
@@ -62,18 +64,6 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
return
true
;
return
true
;
}
}
#ifdef CONFIG_X86_64
typedef
u64
jump_label_t
;
#else
typedef
u32
jump_label_t
;
#endif
struct
jump_entry
{
jump_label_t
code
;
jump_label_t
target
;
jump_label_t
key
;
};
#else
/* __ASSEMBLY__ */
#else
/* __ASSEMBLY__ */
.
macro
STATIC_JUMP_IF_TRUE
target
,
key
,
def
.
macro
STATIC_JUMP_IF_TRUE
target
,
key
,
def
...
@@ -88,7 +78,8 @@ struct jump_entry {
...
@@ -88,7 +78,8 @@ struct jump_entry {
.
endif
.
endif
.
pushsection
__jump_table
,
"aw"
.
pushsection
__jump_table
,
"aw"
_ASM_ALIGN
_ASM_ALIGN
_ASM_PTR
.
Lstatic_jump_
\@
,
\
target
,
\
key
.
long
.
Lstatic_jump_
\@
-
.,
\
target
-
.
_ASM_PTR
\
key
-
.
.
popsection
.
popsection
.
endm
.
endm
...
@@ -104,7 +95,8 @@ struct jump_entry {
...
@@ -104,7 +95,8 @@ struct jump_entry {
.
endif
.
endif
.
pushsection
__jump_table
,
"aw"
.
pushsection
__jump_table
,
"aw"
_ASM_ALIGN
_ASM_ALIGN
_ASM_PTR
.
Lstatic_jump_
\@
,
\
target
,
\
key
+
1
.
long
.
Lstatic_jump_
\@
-
.,
\
target
-
.
_ASM_PTR
\
key
+
1
-
.
.
popsection
.
popsection
.
endm
.
endm
...
...
arch/x86/kernel/jump_label.c
浏览文件 @
02678a58
...
@@ -42,55 +42,40 @@ static void __ref __jump_label_transform(struct jump_entry *entry,
...
@@ -42,55 +42,40 @@ static void __ref __jump_label_transform(struct jump_entry *entry,
void
*
(
*
poker
)(
void
*
,
const
void
*
,
size_t
),
void
*
(
*
poker
)(
void
*
,
const
void
*
,
size_t
),
int
init
)
int
init
)
{
{
union
jump_code_union
code
;
union
jump_code_union
jmp
;
const
unsigned
char
default_nop
[]
=
{
STATIC_KEY_INIT_NOP
};
const
unsigned
char
default_nop
[]
=
{
STATIC_KEY_INIT_NOP
};
const
unsigned
char
*
ideal_nop
=
ideal_nops
[
NOP_ATOMIC5
];
const
unsigned
char
*
ideal_nop
=
ideal_nops
[
NOP_ATOMIC5
];
const
void
*
expect
,
*
code
;
int
line
;
jmp
.
jump
=
0xe9
;
jmp
.
offset
=
jump_entry_target
(
entry
)
-
(
jump_entry_code
(
entry
)
+
JUMP_LABEL_NOP_SIZE
);
if
(
early_boot_irqs_disabled
)
if
(
early_boot_irqs_disabled
)
poker
=
text_poke_early
;
poker
=
text_poke_early
;
if
(
type
==
JUMP_LABEL_JMP
)
{
if
(
type
==
JUMP_LABEL_JMP
)
{
if
(
init
)
{
if
(
init
)
{
/*
expect
=
default_nop
;
line
=
__LINE__
;
* Jump label is enabled for the first time.
* So we expect a default_nop...
*/
if
(
unlikely
(
memcmp
((
void
*
)
entry
->
code
,
default_nop
,
5
)
!=
0
))
bug_at
((
void
*
)
entry
->
code
,
__LINE__
);
}
else
{
}
else
{
/*
expect
=
ideal_nop
;
line
=
__LINE__
;
* ...otherwise expect an ideal_nop. Otherwise
* something went horribly wrong.
*/
if
(
unlikely
(
memcmp
((
void
*
)
entry
->
code
,
ideal_nop
,
5
)
!=
0
))
bug_at
((
void
*
)
entry
->
code
,
__LINE__
);
}
}
code
.
jump
=
0xe9
;
code
=
&
jmp
.
code
;
code
.
offset
=
entry
->
target
-
(
entry
->
code
+
JUMP_LABEL_NOP_SIZE
);
}
else
{
}
else
{
/*
* We are disabling this jump label. If it is not what
* we think it is, then something must have gone wrong.
* If this is the first initialization call, then we
* are converting the default nop to the ideal nop.
*/
if
(
init
)
{
if
(
init
)
{
if
(
unlikely
(
memcmp
((
void
*
)
entry
->
code
,
default_nop
,
5
)
!=
0
))
expect
=
default_nop
;
line
=
__LINE__
;
bug_at
((
void
*
)
entry
->
code
,
__LINE__
);
}
else
{
}
else
{
code
.
jump
=
0xe9
;
expect
=
&
jmp
.
code
;
line
=
__LINE__
;
code
.
offset
=
entry
->
target
-
(
entry
->
code
+
JUMP_LABEL_NOP_SIZE
);
if
(
unlikely
(
memcmp
((
void
*
)
entry
->
code
,
&
code
,
5
)
!=
0
))
bug_at
((
void
*
)
entry
->
code
,
__LINE__
);
}
}
memcpy
(
&
code
,
ideal_nops
[
NOP_ATOMIC5
],
JUMP_LABEL_NOP_SIZE
);
code
=
ideal_nop
;
}
}
if
(
memcmp
((
void
*
)
jump_entry_code
(
entry
),
expect
,
JUMP_LABEL_NOP_SIZE
))
bug_at
((
void
*
)
jump_entry_code
(
entry
),
line
);
/*
/*
* Make text_poke_bp() a default fallback poker.
* Make text_poke_bp() a default fallback poker.
*
*
...
@@ -99,11 +84,14 @@ static void __ref __jump_label_transform(struct jump_entry *entry,
...
@@ -99,11 +84,14 @@ static void __ref __jump_label_transform(struct jump_entry *entry,
* always nop being the 'currently valid' instruction
* always nop being the 'currently valid' instruction
*
*
*/
*/
if
(
poker
)
if
(
poker
)
{
(
*
poker
)((
void
*
)
entry
->
code
,
&
code
,
JUMP_LABEL_NOP_SIZE
);
(
*
poker
)((
void
*
)
jump_entry_code
(
entry
),
code
,
else
JUMP_LABEL_NOP_SIZE
);
text_poke_bp
((
void
*
)
entry
->
code
,
&
code
,
JUMP_LABEL_NOP_SIZE
,
return
;
(
void
*
)
entry
->
code
+
JUMP_LABEL_NOP_SIZE
);
}
text_poke_bp
((
void
*
)
jump_entry_code
(
entry
),
code
,
JUMP_LABEL_NOP_SIZE
,
(
void
*
)
jump_entry_code
(
entry
)
+
JUMP_LABEL_NOP_SIZE
);
}
}
void
arch_jump_label_transform
(
struct
jump_entry
*
entry
,
void
arch_jump_label_transform
(
struct
jump_entry
*
entry
,
...
...
arch/x86/kernel/module.c
浏览文件 @
02678a58
...
@@ -201,6 +201,12 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
...
@@ -201,6 +201,12 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
goto overflow;
goto overflow;
#endif
#endif
break
;
break
;
case
R_X86_64_PC64
:
if
(
*
(
u64
*
)
loc
!=
0
)
goto
invalid_relocation
;
val
-=
(
u64
)
loc
;
*
(
u64
*
)
loc
=
val
;
break
;
default:
default:
pr_err
(
"%s: Unknown rela relocation: %llu
\n
"
,
pr_err
(
"%s: Unknown rela relocation: %llu
\n
"
,
me
->
name
,
ELF64_R_TYPE
(
rel
[
i
].
r_info
));
me
->
name
,
ELF64_R_TYPE
(
rel
[
i
].
r_info
));
...
...
arch/x86/tools/relocs.c
浏览文件 @
02678a58
...
@@ -196,6 +196,7 @@ static const char *rel_type(unsigned type)
...
@@ -196,6 +196,7 @@ static const char *rel_type(unsigned type)
#if ELF_BITS == 64
#if ELF_BITS == 64
REL_TYPE
(
R_X86_64_NONE
),
REL_TYPE
(
R_X86_64_NONE
),
REL_TYPE
(
R_X86_64_64
),
REL_TYPE
(
R_X86_64_64
),
REL_TYPE
(
R_X86_64_PC64
),
REL_TYPE
(
R_X86_64_PC32
),
REL_TYPE
(
R_X86_64_PC32
),
REL_TYPE
(
R_X86_64_GOT32
),
REL_TYPE
(
R_X86_64_GOT32
),
REL_TYPE
(
R_X86_64_PLT32
),
REL_TYPE
(
R_X86_64_PLT32
),
...
@@ -782,6 +783,15 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
...
@@ -782,6 +783,15 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
add_reloc
(
&
relocs32neg
,
offset
);
add_reloc
(
&
relocs32neg
,
offset
);
break
;
break
;
case
R_X86_64_PC64
:
/*
* Only used by jump labels
*/
if
(
is_percpu_sym
(
sym
,
symname
))
die
(
"Invalid R_X86_64_PC64 relocation against per-CPU symbol %s
\n
"
,
symname
);
break
;
case
R_X86_64_32
:
case
R_X86_64_32
:
case
R_X86_64_32S
:
case
R_X86_64_32S
:
case
R_X86_64_64
:
case
R_X86_64_64
:
...
...
arch/x86/um/asm/elf.h
浏览文件 @
02678a58
...
@@ -116,8 +116,7 @@ do { \
...
@@ -116,8 +116,7 @@ do { \
#define R_X86_64_PC16 13
/* 16 bit sign extended pc relative */
#define R_X86_64_PC16 13
/* 16 bit sign extended pc relative */
#define R_X86_64_8 14
/* Direct 8 bit sign extended */
#define R_X86_64_8 14
/* Direct 8 bit sign extended */
#define R_X86_64_PC8 15
/* 8 bit sign extended pc relative */
#define R_X86_64_PC8 15
/* 8 bit sign extended pc relative */
#define R_X86_64_PC64 24
/* Place relative 64-bit signed */
#define R_X86_64_NUM 16
/*
/*
* This is used to ensure we don't load something for the wrong architecture.
* This is used to ensure we don't load something for the wrong architecture.
...
...
include/asm-generic/vmlinux.lds.h
浏览文件 @
02678a58
...
@@ -253,10 +253,6 @@
...
@@ -253,10 +253,6 @@
STRUCT_ALIGN(); \
STRUCT_ALIGN(); \
*(__tracepoints) \
*(__tracepoints) \
/* implement dynamic printk debug */
\
/* implement dynamic printk debug */
\
. = ALIGN(8); \
__start___jump_table = .; \
KEEP(*(__jump_table)) \
__stop___jump_table = .; \
. = ALIGN(8); \
. = ALIGN(8); \
__start___verbose = .; \
__start___verbose = .; \
KEEP(*(__verbose)) \
KEEP(*(__verbose)) \
...
@@ -300,6 +296,12 @@
...
@@ -300,6 +296,12 @@
. = __start_init_task + THREAD_SIZE; \
. = __start_init_task + THREAD_SIZE; \
__end_init_task = .;
__end_init_task = .;
#define JUMP_TABLE_DATA \
. = ALIGN(8); \
__start___jump_table = .; \
KEEP(*(__jump_table)) \
__stop___jump_table = .;
/*
/*
* Allow architectures to handle ro_after_init data on their
* Allow architectures to handle ro_after_init data on their
* own by defining an empty RO_AFTER_INIT_DATA.
* own by defining an empty RO_AFTER_INIT_DATA.
...
@@ -308,6 +310,7 @@
...
@@ -308,6 +310,7 @@
#define RO_AFTER_INIT_DATA \
#define RO_AFTER_INIT_DATA \
__start_ro_after_init = .; \
__start_ro_after_init = .; \
*(.data..ro_after_init) \
*(.data..ro_after_init) \
JUMP_TABLE_DATA \
__end_ro_after_init = .;
__end_ro_after_init = .;
#endif
#endif
...
...
include/linux/jump_label.h
浏览文件 @
02678a58
...
@@ -119,6 +119,68 @@ struct static_key {
...
@@ -119,6 +119,68 @@ struct static_key {
#ifdef HAVE_JUMP_LABEL
#ifdef HAVE_JUMP_LABEL
#include <asm/jump_label.h>
#include <asm/jump_label.h>
#ifndef __ASSEMBLY__
#ifdef CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE
struct
jump_entry
{
s32
code
;
s32
target
;
long
key
;
// key may be far away from the core kernel under KASLR
};
static
inline
unsigned
long
jump_entry_code
(
const
struct
jump_entry
*
entry
)
{
return
(
unsigned
long
)
&
entry
->
code
+
entry
->
code
;
}
static
inline
unsigned
long
jump_entry_target
(
const
struct
jump_entry
*
entry
)
{
return
(
unsigned
long
)
&
entry
->
target
+
entry
->
target
;
}
static
inline
struct
static_key
*
jump_entry_key
(
const
struct
jump_entry
*
entry
)
{
long
offset
=
entry
->
key
&
~
3L
;
return
(
struct
static_key
*
)((
unsigned
long
)
&
entry
->
key
+
offset
);
}
#else
static
inline
unsigned
long
jump_entry_code
(
const
struct
jump_entry
*
entry
)
{
return
entry
->
code
;
}
static
inline
unsigned
long
jump_entry_target
(
const
struct
jump_entry
*
entry
)
{
return
entry
->
target
;
}
static
inline
struct
static_key
*
jump_entry_key
(
const
struct
jump_entry
*
entry
)
{
return
(
struct
static_key
*
)((
unsigned
long
)
entry
->
key
&
~
3UL
);
}
#endif
static
inline
bool
jump_entry_is_branch
(
const
struct
jump_entry
*
entry
)
{
return
(
unsigned
long
)
entry
->
key
&
1UL
;
}
static
inline
bool
jump_entry_is_init
(
const
struct
jump_entry
*
entry
)
{
return
(
unsigned
long
)
entry
->
key
&
2UL
;
}
static
inline
void
jump_entry_set_init
(
struct
jump_entry
*
entry
)
{
entry
->
key
|=
2
;
}
#endif
#endif
#endif
#ifndef __ASSEMBLY__
#ifndef __ASSEMBLY__
...
@@ -151,7 +213,6 @@ extern struct jump_entry __start___jump_table[];
...
@@ -151,7 +213,6 @@ extern struct jump_entry __start___jump_table[];
extern
struct
jump_entry
__stop___jump_table
[];
extern
struct
jump_entry
__stop___jump_table
[];
extern
void
jump_label_init
(
void
);
extern
void
jump_label_init
(
void
);
extern
void
jump_label_invalidate_initmem
(
void
);
extern
void
jump_label_lock
(
void
);
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
,
...
@@ -199,8 +260,6 @@ static __always_inline void jump_label_init(void)
...
@@ -199,8 +260,6 @@ static __always_inline void jump_label_init(void)
static_key_initialized
=
true
;
static_key_initialized
=
true
;
}
}
static
inline
void
jump_label_invalidate_initmem
(
void
)
{}
static
__always_inline
bool
static_key_false
(
struct
static_key
*
key
)
static
__always_inline
bool
static_key_false
(
struct
static_key
*
key
)
{
{
if
(
unlikely
(
static_key_count
(
key
)
>
0
))
if
(
unlikely
(
static_key_count
(
key
)
>
0
))
...
...
init/main.c
浏览文件 @
02678a58
...
@@ -1064,7 +1064,6 @@ static int __ref kernel_init(void *unused)
...
@@ -1064,7 +1064,6 @@ static int __ref kernel_init(void *unused)
/* need to finish all async __init code before freeing the memory */
/* need to finish all async __init code before freeing the memory */
async_synchronize_full
();
async_synchronize_full
();
ftrace_free_init_mem
();
ftrace_free_init_mem
();
jump_label_invalidate_initmem
();
free_initmem
();
free_initmem
();
mark_readonly
();
mark_readonly
();
...
...
kernel/jump_label.c
浏览文件 @
02678a58
...
@@ -38,23 +38,43 @@ static int jump_label_cmp(const void *a, const void *b)
...
@@ -38,23 +38,43 @@ static int jump_label_cmp(const void *a, const void *b)
const
struct
jump_entry
*
jea
=
a
;
const
struct
jump_entry
*
jea
=
a
;
const
struct
jump_entry
*
jeb
=
b
;
const
struct
jump_entry
*
jeb
=
b
;
if
(
j
ea
->
key
<
jeb
->
key
)
if
(
j
ump_entry_key
(
jea
)
<
jump_entry_key
(
jeb
)
)
return
-
1
;
return
-
1
;
if
(
j
ea
->
key
>
jeb
->
key
)
if
(
j
ump_entry_key
(
jea
)
>
jump_entry_key
(
jeb
)
)
return
1
;
return
1
;
return
0
;
return
0
;
}
}
static
void
jump_label_swap
(
void
*
a
,
void
*
b
,
int
size
)
{
long
delta
=
(
unsigned
long
)
a
-
(
unsigned
long
)
b
;
struct
jump_entry
*
jea
=
a
;
struct
jump_entry
*
jeb
=
b
;
struct
jump_entry
tmp
=
*
jea
;
jea
->
code
=
jeb
->
code
-
delta
;
jea
->
target
=
jeb
->
target
-
delta
;
jea
->
key
=
jeb
->
key
-
delta
;
jeb
->
code
=
tmp
.
code
+
delta
;
jeb
->
target
=
tmp
.
target
+
delta
;
jeb
->
key
=
tmp
.
key
+
delta
;
}
static
void
static
void
jump_label_sort_entries
(
struct
jump_entry
*
start
,
struct
jump_entry
*
stop
)
jump_label_sort_entries
(
struct
jump_entry
*
start
,
struct
jump_entry
*
stop
)
{
{
unsigned
long
size
;
unsigned
long
size
;
void
*
swapfn
=
NULL
;
if
(
IS_ENABLED
(
CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE
))
swapfn
=
jump_label_swap
;
size
=
(((
unsigned
long
)
stop
-
(
unsigned
long
)
start
)
size
=
(((
unsigned
long
)
stop
-
(
unsigned
long
)
start
)
/
sizeof
(
struct
jump_entry
));
/
sizeof
(
struct
jump_entry
));
sort
(
start
,
size
,
sizeof
(
struct
jump_entry
),
jump_label_cmp
,
NULL
);
sort
(
start
,
size
,
sizeof
(
struct
jump_entry
),
jump_label_cmp
,
swapfn
);
}
}
static
void
jump_label_update
(
struct
static_key
*
key
);
static
void
jump_label_update
(
struct
static_key
*
key
);
...
@@ -261,8 +281,8 @@ EXPORT_SYMBOL_GPL(jump_label_rate_limit);
...
@@ -261,8 +281,8 @@ EXPORT_SYMBOL_GPL(jump_label_rate_limit);
static
int
addr_conflict
(
struct
jump_entry
*
entry
,
void
*
start
,
void
*
end
)
static
int
addr_conflict
(
struct
jump_entry
*
entry
,
void
*
start
,
void
*
end
)
{
{
if
(
entry
->
code
<=
(
unsigned
long
)
end
&&
if
(
jump_entry_code
(
entry
)
<=
(
unsigned
long
)
end
&&
entry
->
code
+
JUMP_LABEL_NOP_SIZE
>
(
unsigned
long
)
start
)
jump_entry_code
(
entry
)
+
JUMP_LABEL_NOP_SIZE
>
(
unsigned
long
)
start
)
return
1
;
return
1
;
return
0
;
return
0
;
...
@@ -321,16 +341,6 @@ static inline void static_key_set_linked(struct static_key *key)
...
@@ -321,16 +341,6 @@ static inline void static_key_set_linked(struct static_key *key)
key
->
type
|=
JUMP_TYPE_LINKED
;
key
->
type
|=
JUMP_TYPE_LINKED
;
}
}
static
inline
struct
static_key
*
jump_entry_key
(
struct
jump_entry
*
entry
)
{
return
(
struct
static_key
*
)((
unsigned
long
)
entry
->
key
&
~
1UL
);
}
static
bool
jump_entry_branch
(
struct
jump_entry
*
entry
)
{
return
(
unsigned
long
)
entry
->
key
&
1UL
;
}
/***
/***
* A 'struct static_key' uses a union such that it either points directly
* A 'struct static_key' uses a union such that it either points directly
* to a table of 'struct jump_entry' or to a linked list of modules which in
* to a table of 'struct jump_entry' or to a linked list of modules which in
...
@@ -355,7 +365,7 @@ static enum jump_label_type jump_label_type(struct jump_entry *entry)
...
@@ -355,7 +365,7 @@ static enum jump_label_type jump_label_type(struct jump_entry *entry)
{
{
struct
static_key
*
key
=
jump_entry_key
(
entry
);
struct
static_key
*
key
=
jump_entry_key
(
entry
);
bool
enabled
=
static_key_enabled
(
key
);
bool
enabled
=
static_key_enabled
(
key
);
bool
branch
=
jump_entry_branch
(
entry
);
bool
branch
=
jump_entry_
is_
branch
(
entry
);
/* See the comment in linux/jump_label.h */
/* See the comment in linux/jump_label.h */
return
enabled
^
branch
;
return
enabled
^
branch
;
...
@@ -363,19 +373,20 @@ static enum jump_label_type jump_label_type(struct jump_entry *entry)
...
@@ -363,19 +373,20 @@ static enum jump_label_type jump_label_type(struct jump_entry *entry)
static
void
__jump_label_update
(
struct
static_key
*
key
,
static
void
__jump_label_update
(
struct
static_key
*
key
,
struct
jump_entry
*
entry
,
struct
jump_entry
*
entry
,
struct
jump_entry
*
stop
)
struct
jump_entry
*
stop
,
bool
init
)
{
{
for
(;
(
entry
<
stop
)
&&
(
jump_entry_key
(
entry
)
==
key
);
entry
++
)
{
for
(;
(
entry
<
stop
)
&&
(
jump_entry_key
(
entry
)
==
key
);
entry
++
)
{
/*
/*
* An entry->code of 0 indicates an entry which has been
* An entry->code of 0 indicates an entry which has been
* disabled because it was in an init text area.
* disabled because it was in an init text area.
*/
*/
if
(
entry
->
code
)
{
if
(
init
||
!
jump_entry_is_init
(
entry
)
)
{
if
(
kernel_text_address
(
entry
->
code
))
if
(
kernel_text_address
(
jump_entry_code
(
entry
)
))
arch_jump_label_transform
(
entry
,
jump_label_type
(
entry
));
arch_jump_label_transform
(
entry
,
jump_label_type
(
entry
));
else
else
WARN_ONCE
(
1
,
"can't patch jump_label at %pS"
,
WARN_ONCE
(
1
,
"can't patch jump_label at %pS"
,
(
void
*
)
(
unsigned
long
)
entry
->
code
);
(
void
*
)
jump_entry_code
(
entry
)
);
}
}
}
}
}
}
...
@@ -410,6 +421,9 @@ void __init jump_label_init(void)
...
@@ -410,6 +421,9 @@ void __init jump_label_init(void)
if
(
jump_label_type
(
iter
)
==
JUMP_LABEL_NOP
)
if
(
jump_label_type
(
iter
)
==
JUMP_LABEL_NOP
)
arch_jump_label_transform_static
(
iter
,
JUMP_LABEL_NOP
);
arch_jump_label_transform_static
(
iter
,
JUMP_LABEL_NOP
);
if
(
init_section_contains
((
void
*
)
jump_entry_code
(
iter
),
1
))
jump_entry_set_init
(
iter
);
iterk
=
jump_entry_key
(
iter
);
iterk
=
jump_entry_key
(
iter
);
if
(
iterk
==
key
)
if
(
iterk
==
key
)
continue
;
continue
;
...
@@ -422,26 +436,13 @@ void __init jump_label_init(void)
...
@@ -422,26 +436,13 @@ void __init jump_label_init(void)
cpus_read_unlock
();
cpus_read_unlock
();
}
}
/* Disable any jump label entries in __init/__exit code */
void
__init
jump_label_invalidate_initmem
(
void
)
{
struct
jump_entry
*
iter_start
=
__start___jump_table
;
struct
jump_entry
*
iter_stop
=
__stop___jump_table
;
struct
jump_entry
*
iter
;
for
(
iter
=
iter_start
;
iter
<
iter_stop
;
iter
++
)
{
if
(
init_section_contains
((
void
*
)(
unsigned
long
)
iter
->
code
,
1
))
iter
->
code
=
0
;
}
}
#ifdef CONFIG_MODULES
#ifdef CONFIG_MODULES
static
enum
jump_label_type
jump_label_init_type
(
struct
jump_entry
*
entry
)
static
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
);
bool
branch
=
jump_entry_branch
(
entry
);
bool
branch
=
jump_entry_
is_
branch
(
entry
);
/* See the comment in linux/jump_label.h */
/* See the comment in linux/jump_label.h */
return
type
^
branch
;
return
type
^
branch
;
...
@@ -514,7 +515,8 @@ static void __jump_label_mod_update(struct static_key *key)
...
@@ -514,7 +515,8 @@ static void __jump_label_mod_update(struct static_key *key)
stop
=
__stop___jump_table
;
stop
=
__stop___jump_table
;
else
else
stop
=
m
->
jump_entries
+
m
->
num_jump_entries
;
stop
=
m
->
jump_entries
+
m
->
num_jump_entries
;
__jump_label_update
(
key
,
mod
->
entries
,
stop
);
__jump_label_update
(
key
,
mod
->
entries
,
stop
,
m
&&
m
->
state
==
MODULE_STATE_COMING
);
}
}
}
}
...
@@ -560,12 +562,15 @@ static int jump_label_add_module(struct module *mod)
...
@@ -560,12 +562,15 @@ static int jump_label_add_module(struct module *mod)
for
(
iter
=
iter_start
;
iter
<
iter_stop
;
iter
++
)
{
for
(
iter
=
iter_start
;
iter
<
iter_stop
;
iter
++
)
{
struct
static_key
*
iterk
;
struct
static_key
*
iterk
;
if
(
within_module_init
(
jump_entry_code
(
iter
),
mod
))
jump_entry_set_init
(
iter
);
iterk
=
jump_entry_key
(
iter
);
iterk
=
jump_entry_key
(
iter
);
if
(
iterk
==
key
)
if
(
iterk
==
key
)
continue
;
continue
;
key
=
iterk
;
key
=
iterk
;
if
(
within_module
(
iter
->
key
,
mod
))
{
if
(
within_module
(
(
unsigned
long
)
key
,
mod
))
{
static_key_set_entries
(
key
,
iter
);
static_key_set_entries
(
key
,
iter
);
continue
;
continue
;
}
}
...
@@ -595,7 +600,7 @@ static int jump_label_add_module(struct module *mod)
...
@@ -595,7 +600,7 @@ static int jump_label_add_module(struct module *mod)
/* Only update if we've changed from our initial state */
/* Only update if we've changed from our initial state */
if
(
jump_label_type
(
iter
)
!=
jump_label_init_type
(
iter
))
if
(
jump_label_type
(
iter
)
!=
jump_label_init_type
(
iter
))
__jump_label_update
(
key
,
iter
,
iter_stop
);
__jump_label_update
(
key
,
iter
,
iter_stop
,
true
);
}
}
return
0
;
return
0
;
...
@@ -615,7 +620,7 @@ static void jump_label_del_module(struct module *mod)
...
@@ -615,7 +620,7 @@ static void jump_label_del_module(struct module *mod)
key
=
jump_entry_key
(
iter
);
key
=
jump_entry_key
(
iter
);
if
(
within_module
(
iter
->
key
,
mod
))
if
(
within_module
(
(
unsigned
long
)
key
,
mod
))
continue
;
continue
;
/* No memory during module load */
/* No memory during module load */
...
@@ -651,19 +656,6 @@ static void jump_label_del_module(struct module *mod)
...
@@ -651,19 +656,6 @@ static void jump_label_del_module(struct module *mod)
}
}
}
}
/* Disable any jump label entries in module init code */
static
void
jump_label_invalidate_module_init
(
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
;
for
(
iter
=
iter_start
;
iter
<
iter_stop
;
iter
++
)
{
if
(
within_module_init
(
iter
->
code
,
mod
))
iter
->
code
=
0
;
}
}
static
int
static
int
jump_label_module_notify
(
struct
notifier_block
*
self
,
unsigned
long
val
,
jump_label_module_notify
(
struct
notifier_block
*
self
,
unsigned
long
val
,
void
*
data
)
void
*
data
)
...
@@ -685,9 +677,6 @@ jump_label_module_notify(struct notifier_block *self, unsigned long val,
...
@@ -685,9 +677,6 @@ jump_label_module_notify(struct notifier_block *self, unsigned long val,
case
MODULE_STATE_GOING
:
case
MODULE_STATE_GOING
:
jump_label_del_module
(
mod
);
jump_label_del_module
(
mod
);
break
;
break
;
case
MODULE_STATE_LIVE
:
jump_label_invalidate_module_init
(
mod
);
break
;
}
}
jump_label_unlock
();
jump_label_unlock
();
...
@@ -757,7 +746,8 @@ static void jump_label_update(struct static_key *key)
...
@@ -757,7 +746,8 @@ static void jump_label_update(struct static_key *key)
entry
=
static_key_entries
(
key
);
entry
=
static_key_entries
(
key
);
/* if there are no users, entry can be NULL */
/* if there are no users, entry can be NULL */
if
(
entry
)
if
(
entry
)
__jump_label_update
(
key
,
entry
,
stop
);
__jump_label_update
(
key
,
entry
,
stop
,
system_state
<
SYSTEM_RUNNING
);
}
}
#ifdef CONFIG_STATIC_KEYS_SELFTEST
#ifdef CONFIG_STATIC_KEYS_SELFTEST
...
...
kernel/module.c
浏览文件 @
02678a58
...
@@ -3315,6 +3315,15 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
...
@@ -3315,6 +3315,15 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
* Note: ro_after_init sections also have SHF_{WRITE,ALLOC} set.
* Note: ro_after_init sections also have SHF_{WRITE,ALLOC} set.
*/
*/
ndx
=
find_sec
(
info
,
".data..ro_after_init"
);
ndx
=
find_sec
(
info
,
".data..ro_after_init"
);
if
(
ndx
)
info
->
sechdrs
[
ndx
].
sh_flags
|=
SHF_RO_AFTER_INIT
;
/*
* Mark the __jump_table section as ro_after_init as well: these data
* structures are never modified, with the exception of entries that
* refer to code in the __init section, which are annotated as such
* at module load time.
*/
ndx
=
find_sec
(
info
,
"__jump_table"
);
if
(
ndx
)
if
(
ndx
)
info
->
sechdrs
[
ndx
].
sh_flags
|=
SHF_RO_AFTER_INIT
;
info
->
sechdrs
[
ndx
].
sh_flags
|=
SHF_RO_AFTER_INIT
;
...
...
tools/objtool/special.c
浏览文件 @
02678a58
...
@@ -30,9 +30,9 @@
...
@@ -30,9 +30,9 @@
#define EX_ORIG_OFFSET 0
#define EX_ORIG_OFFSET 0
#define EX_NEW_OFFSET 4
#define EX_NEW_OFFSET 4
#define JUMP_ENTRY_SIZE
24
#define JUMP_ENTRY_SIZE
16
#define JUMP_ORIG_OFFSET 0
#define JUMP_ORIG_OFFSET 0
#define JUMP_NEW_OFFSET
8
#define JUMP_NEW_OFFSET
4
#define ALT_ENTRY_SIZE 13
#define ALT_ENTRY_SIZE 13
#define ALT_ORIG_OFFSET 0
#define ALT_ORIG_OFFSET 0
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录