Skip to content

Commit edadfc6

Browse files
author
Fox Snowpatch
committed
1 parent d88a1b4 commit edadfc6

16 files changed

Lines changed: 637 additions & 30 deletions

File tree

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,13 @@ ifdef CONFIG_OBJTOOL
15141514
prepare: tools/objtool
15151515
endif
15161516

1517+
# CONFIG_OBJTOOL and CONFIG_HAVE_OBJTOOL_FTR_FIXUP are unrelated, separate
1518+
# options. It was integrated in objtool in order to borrow the elf parser,
1519+
# but this is different from how the other objtool commands are used.
1520+
ifdef CONFIG_HAVE_OBJTOOL_FTR_FIXUP
1521+
prepare: tools/objtool
1522+
endif
1523+
15171524
ifdef CONFIG_BPF
15181525
ifdef CONFIG_DEBUG_INFO_BTF
15191526
prepare: tools/bpf/resolve_btfids

arch/powerpc/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ config 64BIT
2323
bool
2424
default y if PPC64
2525

26+
config HAVE_OBJTOOL_FTR_FIXUP
27+
def_bool y
28+
2629
config LIVEPATCH_64
2730
def_bool PPC64
2831
depends on LIVEPATCH

arch/powerpc/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie --no-dynamic-linker
105105
LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) += -z notext
106106
LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y)
107107

108+
# --emit-relocs required for post-link fixup of alternate feature
109+
# text section relocations.
110+
LDFLAGS_vmlinux += --emit-relocs
111+
KBUILD_LDFLAGS_MODULE += --emit-relocs
112+
108113
ifdef CONFIG_PPC64
109114
ifndef CONFIG_PPC_KERNEL_PCREL
110115
# -mcmodel=medium breaks modules because it uses 32bit offsets from

arch/powerpc/include/asm/feature-fixups.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
#define FTR_SECTION_ELSE_NESTED(label) \
3434
label##2: \
35-
.pushsection __ftr_alt_##label,"a"; \
35+
.pushsection __ftr_alt_##label, "ax"; \
3636
.align 2; \
3737
label##3:
3838

arch/powerpc/kernel/vmlinux.lds.S

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ SECTIONS
9999
.text : AT(ADDR(.text) - LOAD_OFFSET) {
100100
ALIGN_FUNCTION();
101101
#endif
102-
/* careful! __ftr_alt_* sections need to be close to .text */
103-
*(.text.hot .text.hot.* TEXT_MAIN .text.fixup .text.unlikely .text.unlikely.* .fixup __ftr_alt_* .ref.text);
102+
*(.text.hot .text.hot.* TEXT_MAIN .text.fixup .text.unlikely
103+
.text.unlikely.* .fixup .ref.text);
104104
*(.tramp.ftrace.text);
105105
NOINSTR_TEXT
106106
SCHED_TEXT
@@ -267,6 +267,10 @@ SECTIONS
267267
_einittext = .;
268268
} :text
269269

270+
.__ftr_alternates.text : AT(ADDR(.__ftr_alternates.text) - LOAD_OFFSET) {
271+
*(__ftr_alt*);
272+
}
273+
270274
/* .exit.text is discarded at runtime, not link time,
271275
* to deal with references from __bug_table
272276
*/

arch/powerpc/lib/feature-fixups.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,10 @@ static u32 *calc_addr(struct fixup_entry *fcur, long offset)
5353

5454
static int patch_alt_instruction(u32 *src, u32 *dest, u32 *alt_start, u32 *alt_end)
5555
{
56-
int err;
5756
ppc_inst_t instr;
5857

5958
instr = ppc_inst_read(src);
6059

61-
if (instr_is_relative_branch(ppc_inst_read(src))) {
62-
u32 *target = (u32 *)branch_target(src);
63-
64-
/* Branch within the section doesn't need translating */
65-
if (target < alt_start || target > alt_end) {
66-
err = translate_branch(&instr, dest, src);
67-
if (err)
68-
return 1;
69-
}
70-
}
71-
7260
raw_patch_instruction(dest, instr);
7361

7462
return 0;

scripts/Makefile.lib

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,10 @@ cpp_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
179179

180180
ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F))
181181

182-
ifdef CONFIG_OBJTOOL
183-
184182
objtool := $(objtree)/tools/objtool/objtool
185183

184+
ifdef CONFIG_OBJTOOL
185+
186186
objtool-args-$(CONFIG_HAVE_JUMP_LABEL_HACK) += --hacks=jump_label
187187
objtool-args-$(CONFIG_HAVE_NOINSTR_HACK) += --hacks=noinstr
188188
objtool-args-$(CONFIG_MITIGATION_CALL_DEPTH_TRACKING) += --hacks=skylake

scripts/Makefile.vmlinux

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
6565
# Final link of vmlinux with optional arch pass after final link
6666
cmd_link_vmlinux = \
6767
$< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@"; \
68-
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
68+
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true); \
69+
$(if $(CONFIG_HAVE_OBJTOOL_FTR_FIXUP), $(objtool) --ftr-fixup --link $@, true)
6970

7071
targets += vmlinux.unstripped .vmlinux.export.o
7172
vmlinux.unstripped: scripts/link-vmlinux.sh vmlinux.o .vmlinux.export.o $(KBUILD_LDS) FORCE
@@ -81,11 +82,15 @@ endif
8182
# vmlinux
8283
# ---------------------------------------------------------------------------
8384

85+
# These configurations require vmlinux.unstripped to be linked with
86+
# '--emit-relocs', which need to be stripped from the final vmlinux.
87+
uses-emit-relocs := $(or $(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS),$(CONFIG_HAVE_OBJTOOL_FTR_FIXUP))
88+
8489
remove-section-y := .modinfo
85-
remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel*' '!.rel*.dyn'
90+
remove-section-$(uses-emit-relocs) += '.rel*' '!.rel*.dyn'
8691
# for compatibility with binutils < 2.32
8792
# https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=c12d9fa2afe7abcbe407a00e15719e1a1350c2a7
88-
remove-section-$(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS) += '.rel.*'
93+
remove-section-$(uses-emit-relocs) += '.rel.*'
8994

9095
remove-symbols := -w --strip-unneeded-symbol='__mod_device_table__*'
9196

tools/objtool/arch/powerpc/decode.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,26 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
5959
enum insn_type typ;
6060
unsigned long imm;
6161
u32 ins;
62+
unsigned int aa;
6263

6364
ins = bswap_if_needed(file->elf, *(u32 *)(sec->data->d_buf + offset));
6465
opcode = ins >> 26;
6566
typ = INSN_OTHER;
6667
imm = 0;
68+
aa = ins & 2;
6769

6870
switch (opcode) {
71+
case 16:
72+
if (ins & 1)
73+
typ = INSN_OTHER;
74+
else
75+
typ = INSN_JUMP_CONDITIONAL;
76+
imm = ins & 0xfffc;
77+
if (imm & 0x8000)
78+
imm -= 0x10000;
79+
insn->immediate = imm | aa;
80+
break;
81+
6982
case 18: /* b[l][a] */
7083
if (ins == 0x48000005) /* bl .+4 */
7184
typ = INSN_OTHER;
@@ -77,7 +90,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
7790
imm = ins & 0x3fffffc;
7891
if (imm & 0x2000000)
7992
imm -= 0x4000000;
80-
imm |= ins & 2; /* AA flag */
93+
insn->immediate = imm | aa;
8194
break;
8295
}
8396

0 commit comments

Comments
 (0)