-
Notifications
You must be signed in to change notification settings - Fork 305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
S390x kpatch support #1203
S390x kpatch support #1203
Changes from all commits
c6d0b54
10002f5
f0d00a9
eb4a85f
b0330ab
0308d52
48d997f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
### s390 backporting | ||
|
||
**Prerequisite gcc patches (all backported to releases/gcc-11 branch):** | ||
- gcc-mirror/gcc@a1c1b7a IBM Z: Define NO_PROFILE_COUNTERS | ||
- gcc-mirror/gcc@0990d93 IBM Z: Use @PLT symbols for local functions in 64-bit mode | ||
- gcc-mirror/gcc@935b522 S/390: New option -mpic-data-is-text-relative | ||
- gcc-mirror/gcc@8753b13 IBM Z: fix section type conflict with -mindirect-branch-table | ||
|
||
**Prerequisite kernel patches:** | ||
**v5.19:** | ||
- 69505e3d9a39 bug: Use normal relative pointers in 'struct bug_entry' | ||
|
||
**v5.18:** | ||
- 602bf1687e6f s390/nospec: align and size extern thunks | ||
- 1d2ad084800e s390/nospec: add an option to use thunk-extern | ||
- eed38cd2f46f s390/nospec: generate single register thunks if possible | ||
- 2268169c14e5 s390: remove unused expoline to BC instructions | ||
- f0003a9e4c18 s390/entry: remove unused expoline thunk | ||
|
||
**v5.16:** | ||
- torvalds/linux@f6ac18f sched: Improve try_invoke_on_locked_down_task() | ||
- torvalds/linux@9b3c4ab sched,rcu: Rework try_invoke_on_locked_down_task() | ||
- torvalds/linux@00619f7 sched,livepatch: Use task_call_func() | ||
- torvalds/linux@8850cb6 sched: Simplify wake_up_*idle*() | ||
- torvalds/linux@5de62ea sched,livepatch: Use wake_up_if_idle() | ||
- torvalds/linux@96611c2 sched: Improve wake_up_all_idle_cpus() take #2 | ||
|
||
**v5.15** | ||
- torvalds/linux@de5012b s390/ftrace: implement hotpatching | ||
- torvalds/linux@67ccddf ftrace: Introduce ftrace_need_init_nop() | ||
|
||
**v5.14:** | ||
- torvalds/linux@7561c14 s390/vdso: add .got.plt in vdso linker script |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,8 @@ GCC_PLUGINS_DIR := $(shell $(CROSS_COMPILE)gcc -print-file-name=plugin) | |
PLUGIN_CFLAGS := $(filter-out -Wconversion, $(CFLAGS)) | ||
PLUGIN_CFLAGS += -shared -I$(GCC_PLUGINS_DIR)/include \ | ||
-Igcc-plugins -fPIC -fno-rtti -O2 -Wall | ||
else ifneq ($(ARCH),x86_64) | ||
endif | ||
ifeq ($(filter $(ARCH),s390x x86_64 ppc64le),) | ||
$(error Unsupported architecture ${ARCH}, check https://github.com/dynup/kpatch/#supported-architectures) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Depending on how confident we feel after this PR, we could update the referenced README.md There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After this is merged, we can update s390x as supported in README.md. |
||
endif | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,6 +118,16 @@ static bool is_bundleable(struct symbol *sym) | |
!strcmp(sym->sec->name + 13, sym->name)) | ||
return true; | ||
|
||
if (sym->type == STT_OBJECT && | ||
!strncmp(sym->sec->name, ".data.rel.ro.local.", 19) && | ||
!strcmp(sym->sec->name + 19, sym->name)) | ||
return 1; | ||
|
||
if (sym->type == STT_OBJECT && | ||
!strncmp(sym->sec->name, ".data.rel.local.", 16) && | ||
!strcmp(sym->sec->name + 16, sym->name)) | ||
return 1; | ||
|
||
if (sym->type == STT_OBJECT && | ||
!strncmp(sym->sec->name, ".rodata.",8) && | ||
!strcmp(sym->sec->name + 8, sym->name)) | ||
|
@@ -163,6 +173,8 @@ static bool is_gcc6_localentry_bundled_sym(struct kpatch_elf *kelf, | |
sym->sym.st_value == 8); | ||
case X86_64: | ||
return false; | ||
case S390: | ||
return false; | ||
default: | ||
ERROR("unsupported arch"); | ||
} | ||
|
@@ -304,8 +316,7 @@ static bool is_dynamic_debug_symbol(struct symbol *sym) | |
|
||
static bool is_string_literal_section(struct section *sec) | ||
{ | ||
return !strncmp(sec->name, ".rodata.", 8) && | ||
strstr(sec->name, ".str1."); | ||
return !strncmp(sec->name, ".rodata.", 8) && strstr(sec->name, ".str"); | ||
} | ||
|
||
/* | ||
|
@@ -2104,6 +2115,17 @@ static int fixup_barrier_nospec_group_size(struct kpatch_elf *kelf, int offset) | |
return 8; | ||
} | ||
|
||
/* | ||
* .s390_indirect_jump, .s390_indirect_call, .s390_indirect_branches, | ||
* .s390_return_reg, .s390_return_mem contains indirect branch locations. This | ||
* is an array of 32 bit elements. These sections could be used during runtime | ||
* to replace the expolines with the normal indirect jump. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, I wish x86 gcc had this feature. We had to implement it manually with objtool. |
||
*/ | ||
static int s390_expolines_group_size(struct kpatch_elf *kelf, int offset) | ||
{ | ||
return 4; | ||
} | ||
|
||
/* | ||
* The rela groups in the .fixup section vary in size. The beginning of each | ||
* .fixup rela group is referenced by the __ex_table section. To find the size | ||
|
@@ -2157,27 +2179,27 @@ static int fixup_group_size(struct kpatch_elf *kelf, int offset) | |
static struct special_section special_sections[] = { | ||
{ | ||
.name = "__bug_table", | ||
.arch = X86_64 | PPC64, | ||
.arch = X86_64 | PPC64 | S390, | ||
.group_size = bug_table_group_size, | ||
}, | ||
{ | ||
.name = ".fixup", | ||
.arch = X86_64 | PPC64, | ||
.arch = X86_64 | PPC64 | S390, | ||
.group_size = fixup_group_size, | ||
}, | ||
{ | ||
.name = "__ex_table", /* must come after .fixup */ | ||
.arch = X86_64 | PPC64, | ||
.arch = X86_64 | PPC64 | S390, | ||
.group_size = ex_table_group_size, | ||
}, | ||
{ | ||
.name = "__jump_table", | ||
.arch = X86_64 | PPC64, | ||
.arch = X86_64 | PPC64 | S390, | ||
.group_size = jump_table_group_size, | ||
}, | ||
{ | ||
.name = ".printk_index", | ||
.arch = X86_64 | PPC64, | ||
.arch = X86_64 | PPC64 | S390, | ||
.group_size = printk_index_group_size, | ||
}, | ||
{ | ||
|
@@ -2192,7 +2214,7 @@ static struct special_section special_sections[] = { | |
}, | ||
{ | ||
.name = ".altinstructions", | ||
.arch = X86_64, | ||
.arch = X86_64 | S390, | ||
.group_size = altinstructions_group_size, | ||
}, | ||
{ | ||
|
@@ -2230,6 +2252,31 @@ static struct special_section special_sections[] = { | |
.arch = PPC64, | ||
.group_size = fixup_barrier_nospec_group_size, | ||
}, | ||
{ | ||
.name = ".s390_return_mem", | ||
.arch = S390, | ||
.group_size = s390_expolines_group_size, | ||
}, | ||
{ | ||
.name = ".s390_return_reg", | ||
.arch = S390, | ||
.group_size = s390_expolines_group_size, | ||
}, | ||
{ | ||
.name = ".s390_indirect_call", | ||
.arch = S390, | ||
.group_size = s390_expolines_group_size, | ||
}, | ||
{ | ||
.name = ".s390_indirect_branches", | ||
.arch = S390, | ||
.group_size = s390_expolines_group_size, | ||
}, | ||
{ | ||
.name = ".s390_indirect_jump", | ||
.arch = S390, | ||
.group_size = s390_expolines_group_size, | ||
}, | ||
{}, | ||
}; | ||
|
||
|
@@ -3024,6 +3071,11 @@ static bool kpatch_is_core_module_symbol(char *name) | |
!strcmp(name, "kpatch_shadow_get")); | ||
} | ||
|
||
static bool is_expoline(struct kpatch_elf *kelf, char *name) | ||
{ | ||
return kelf->arch == S390 && !strncmp(name, "__s390_indirect_jump_r", 22); | ||
} | ||
|
||
static int function_ptr_rela(const struct rela *rela) | ||
{ | ||
const struct rela *rela_toc = toc_rela(rela); | ||
|
@@ -3082,6 +3134,13 @@ static bool need_dynrela(struct kpatch_elf *kelf, struct lookup_table *table, | |
if (kpatch_is_core_module_symbol(rela->sym->name)) | ||
return false; | ||
|
||
/* | ||
* Allow references to s390 expolines to remain as normal relas. They | ||
* will be generated in the module by the kernel module link. | ||
*/ | ||
if (is_expoline(kelf, rela->sym->name)) | ||
return false; | ||
|
||
if (rela->sym->sec) { | ||
/* | ||
* Internal symbols usually don't need dynrelas, because they | ||
|
@@ -3548,6 +3607,10 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf) | |
rela->type = R_X86_64_PC32; | ||
break; | ||
} | ||
case S390: { | ||
insn_offset = sym->sym.st_value; | ||
break; | ||
} | ||
default: | ||
ERROR("unsupported arch"); | ||
} | ||
|
@@ -3713,6 +3776,7 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf) | |
{ | ||
struct symbol *sym; | ||
struct rela *rela; | ||
unsigned char *insn; | ||
list_for_each_entry(sym, &kelf->symbols, list) { | ||
if (sym->type != STT_FUNC || !sym->sec || !sym->sec->rela) | ||
continue; | ||
|
@@ -3737,6 +3801,14 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf) | |
|
||
sym->has_func_profiling = 1; | ||
break; | ||
case S390: | ||
/* Check for compiler generated fentry nop - jgnop 0 */ | ||
insn = sym->sec->data->d_buf; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A short comment here with the name of the instruction would be helpful. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added |
||
if (insn[0] == 0xc0 && insn[1] == 0x04 && | ||
insn[2] == 0x00 && insn[3] == 0x00 && | ||
insn[4] == 0x00 && insn[5] == 0x00) | ||
sym->has_func_profiling = 1; | ||
break; | ||
default: | ||
ERROR("unsupported arch"); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most likely this will end up in 5.19, so it's probably safe to add a v5.19 header for this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added