From 401680a7c930b841f802f8cac77db416a2a74e1c Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Fri, 30 May 2014 08:35:44 -0500 Subject: [PATCH] create-diff-object: tracepoint & jump label fixes The current approach of trying to include the tracepoint-related sections doesn't work at all. The new tracepoints don't show up in "perf list". And also, with one patch (issue #219) I've seen a panic in jump_label_del_module(). I suspect it's because the kernel is confused by dynamic relocations' changing of the jump table after it was registered with the jump table code. I think the best approach for now is to just always exclude these sections. It should be harmless, with the only consequence being that tracepoints and jump labels can't be enabled in patched functions (which is already the case with the current code anyway). Fixes #221. --- kpatch-build/create-diff-object.c | 29 +++++++++++++++++-------- test/integration/data-read-mostly.patch | 12 ++++++++++ 2 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 test/integration/data-read-mostly.patch diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 32a13e0..ad77a1d 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -1048,7 +1048,6 @@ int smp_locks_group_size(struct section *sec, int offset) { return 4; } int parainstructions_group_size(struct section *sec, int offset) { return 16; } int ex_table_group_size(struct section *sec, int offset) { return 8; } int altinstructions_group_size(struct section *sec, int offset) { return 12; } -int jump_table_group_size(struct section *sec, int offset) { return 24; } int fixup_group_size(struct section *sec, int offset) { @@ -1087,10 +1086,6 @@ struct special_section special_sections[] = { .name = "__ex_table", .group_size = ex_table_group_size, }, - { - .name = "__jump_table", - .group_size = jump_table_group_size, - }, { .name = ".altinstructions", .group_size = altinstructions_group_size, @@ -1227,10 +1222,7 @@ void kpatch_process_special_sections(struct kpatch_elf *kelf) * non-included symbols, so their entire rela section can be included. */ list_for_each_entry(sec, &kelf->sections, list) { - if (strcmp(sec->name, ".altinstr_replacement") && - strcmp(sec->name, "__tracepoints") && - strcmp(sec->name, "__tracepoints_ptrs") && - strcmp(sec->name, "__tracepoints_strings")) + if (strcmp(sec->name, ".altinstr_replacement")) continue; /* include base section */ @@ -1249,6 +1241,25 @@ void kpatch_process_special_sections(struct kpatch_elf *kelf) rela->sym->include = 1; } } + + /* + * The following special sections aren't supported, so make sure we + * don't ever try to include them. Otherwise the kernel will see the + * jump table during module loading and get confused. Generally it + * should be safe to exclude them, it just means that you can't modify + * jump labels and enable tracepoints in a patched function. + */ + list_for_each_entry(sec, &kelf->sections, list) { + if (strcmp(sec->name, "__jump_table") && + strcmp(sec->name, "__tracepoints") && + strcmp(sec->name, "__tracepoints_ptrs") && + strcmp(sec->name, "__tracepoints_strings")) + continue; + + sec->status = SAME; + if (sec->rela) + sec->rela->status = SAME; + } } void print_strtab(char *buf, size_t size) diff --git a/test/integration/data-read-mostly.patch b/test/integration/data-read-mostly.patch new file mode 100644 index 0000000..a6ede64 --- /dev/null +++ b/test/integration/data-read-mostly.patch @@ -0,0 +1,12 @@ +Index: src/net/core/dev.c +=================================================================== +--- src.orig/net/core/dev.c ++++ src/net/core/dev.c +@@ -3609,6 +3609,7 @@ ncls: + case RX_HANDLER_PASS: + break; + default: ++ printk("BUG!\n"); + BUG(); + } + }