From: Sathvika Vasireddy <sv@linux.vnet.ibm.com>
To: Nathan Chancellor <nathan@kernel.org>,
Sathvika Vasireddy <sv@linux.ibm.com>
Cc: nicolas@fjasle.eu, linux-kbuild@vger.kernel.org,
peterz@infradead.org, masahiroy@kernel.org, mahesh@linux.ibm.com,
mingo@kernel.org, npiggin@gmail.com, naveen.n.rao@linux.ibm.com,
linuxppc-dev@lists.ozlabs.org, jpoimboe@kernel.org
Subject: Re: [RFC PATCH 2/2] objtool/powerpc: Enhance objtool to fixup alternate feature relative addresses
Date: Mon, 3 Jun 2024 13:59:28 +0530 [thread overview]
Message-ID: <9393df04-403d-4530-8f13-c8a5c6d302d2@linux.vnet.ibm.com> (raw)
In-Reply-To: <20240423002833.GA1436185@dev-arch.thelio-3990X>
Hi Nathan,
On 4/23/24 5:58 AM, Nathan Chancellor wrote:
> Hi Sathvika,
>
> On Mon, Apr 22, 2024 at 02:52:06PM +0530, Sathvika Vasireddy wrote:
>> Implement build-time fixup of alternate feature relative addresses for
>> the out-of-line (else) patch code. Initial posting to achieve the same
>> using another tool can be found at [1]. Idea is to implement this using
>> objtool instead of introducing another tool since it already has elf
>> parsing and processing covered.
>>
>> Introduce --ftr-fixup as an option to objtool to do feature fixup at
>> build-time.
>>
>> Couple of issues and warnings encountered while implementing feature
>> fixup using objtool are as follows:
>>
>> 1. libelf is creating corrupted vmlinux file after writing necessary
>> changes to the file. Due to this, kexec is not able to load new
>> kernel.
>>
>> It gives the following error:
>> ELF Note corrupted !
>> Cannot determine the file type of vmlinux
>>
>> To fix this issue, after opening vmlinux file, make a call to
>> elf_flagelf (e, ELF_C_SET, ELF_F_LAYOUT). This instructs libelf not
>> to touch the segment and section layout. It informs the library
>> that the application will take responsibility for the layout of the
>> file and that the library should not insert any padding between
>> sections.
>>
>> 2. Fix can't find starting instruction warnings when run on vmlinux
>>
>> Objtool throws a lot of can't find starting instruction warnings
>> when run on vmlinux with --ftr-fixup option.
>>
>> These warnings are seen because find_insn() function looks for
>> instructions at offsets that are relative to the start of the section.
>> In case of individual object files (.o), there are no can't find
>> starting instruction warnings seen because the actual offset
>> associated with an instruction is itself a relative offset since the
>> sections start at offset 0x0.
>>
>> However, in case of vmlinux, find_insn() function fails to find
>> instructions at the actual offset associated with an instruction
>> since the sections in vmlinux do not start at offset 0x0. Due to
>> this, find_insn() will look for absolute offset and not the relative
>> offset. This is resulting in a lot of can't find starting instruction
>> warnings when objtool is run on vmlinux.
>>
>> To fix this, pass offset that is relative to the start of the section
>> to find_insn().
>>
>> find_insn() is also looking for symbols of size 0. But, objtool does
>> not store empty STT_NOTYPE symbols in the rbtree. Due to this,
>> for empty symbols, objtool is throwing can't find starting
>> instruction warnings. Fix this by ignoring symbols that are of
>> size 0 since objtool does not add them to the rbtree.
>>
>> 3. Objtool is throwing unannotated intra-function call warnings
>> when run on vmlinux with --ftr-fixup option.
>>
>> One such example:
>>
>> vmlinux: warning: objtool: .text+0x3d94:
>> unannotated intra-function call
>>
>> .text + 0x3d94 = c000000000008000 + 3d94 = c0000000000081d4
>>
>> c0000000000081d4: 45 24 02 48 bl c00000000002a618
>> <system_reset_exception+0x8>
>>
>> c00000000002a610 <system_reset_exception>:
>> c00000000002a610: 0e 01 4c 3c addis r2,r12,270
>> c00000000002a610: R_PPC64_REL16_HA .TOC.
>> c00000000002a614: f0 6c 42 38 addi r2,r2,27888
>> c00000000002a614: R_PPC64_REL16_LO .TOC.+0x4
>> c00000000002a618: a6 02 08 7c mflr r0
>>
>> This is happening because we should be looking for destination
>> symbols that are at absolute offsets instead of relative offsets.
>> After fixing dest_off to point to absolute offset, there are still
>> a lot of these warnings shown.
>>
>> In the above example, objtool is computing the destination
>> offset to be c00000000002a618, which points to a completely
>> different instruction. find_call_destination() is looking for this
>> offset and failing. Instead, we should be looking for destination
>> offset c00000000002a610 which points to system_reset_exception
>> function.
>>
>> Even after fixing the way destination offset is computed, and
>> after looking for dest_off - 0x8 in cases where the original offset
>> is not found, there are still a lot of unannotated intra-function
>> call warnings generated. This is due to symbols that are not
>> properly annotated.
>>
>> So, for now, as a hack to curb these warnings, do not emit
>> unannotated intra-function call warnings when objtool is run
>> with --ftr-fixup option.
>>
>> TODO:
>> This patch enables build time feature fixup only for powerpc little
>> endian configs. There are boot failures with big endian configs.
>> Posting this as an initial RFC to get some review comments while I work
>> on big endian issues.
>>
>> [1]
>> https://lore.kernel.org/linuxppc-dev/20170521010130.13552-1-npiggin@gmail.com/
>>
>> Co-developed-by: Nicholas Piggin <npiggin@gmail.com>
>> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
>> Signed-off-by: Sathvika Vasireddy <sv@linux.ibm.com>
> When I build this series with LLVM 14 [1] (due to an issue I report
> below), I am getting a crash when CONFIG_FTR_FIXUP_SELFTEST is disabled.
>
> diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
> index 544a65fda77b..95d2906ec814 100644
> --- a/arch/powerpc/configs/ppc64_defconfig
> +++ b/arch/powerpc/configs/ppc64_defconfig
> @@ -427,7 +427,6 @@ CONFIG_BLK_DEV_IO_TRACE=y
> CONFIG_IO_STRICT_DEVMEM=y
> CONFIG_PPC_EMULATED_STATS=y
> CONFIG_CODE_PATCHING_SELFTEST=y
> -CONFIG_FTR_FIXUP_SELFTEST=y
> CONFIG_MSI_BITMAP_SELFTEST=y
> CONFIG_XMON=y
> CONFIG_BOOTX_TEXT=y
>
> $ make -kj"$(nproc)" ARCH=powerpc LLVM=$PWD/llvm-14.0.6-x86_64/bin/ ppc64le_defconfig vmlinux
> ...
> LD vmlinux
> NM System.map
> SORTTAB vmlinux
> CHKHEAD vmlinux
> CHKREL vmlinux
> make[4]: *** [scripts/Makefile.vmlinux:38: vmlinux] Error 139
> make[4]: *** Deleting file 'vmlinux
> ...
>
> I do not see the objtool command in V=1 output but I do see the end of
> scripts/link-vmlinux.sh, so it does seem like it is crashing in objtool.
>
> [1]: from https://mirrors.edge.kernel.org/pub/tools/llvm/
Thanks for reporting this, and apologies for the delay in response.
This issue is happening while processing __fw_ftr_fixup section, which
has no data and dereferencing this null pointer is causing segmentation
fault. I was able to recreate the issue, and the below diff fixes it for me.
diff --git a/tools/objtool/arch/powerpc/special.c
b/tools/objtool/arch/powerpc/special.c
index 5ec3eed34eb0..67329d44db24 100644
--- a/tools/objtool/arch/powerpc/special.c
+++ b/tools/objtool/arch/powerpc/special.c
@@ -53,38 +53,39 @@ int process_fixup_entries(struct objtool_file *file)
if (strstr(sec->name, "_ftr_fixup") != NULL) {
Elf_Data *data = sec->data;
- if (data && data->d_size > 0)
+ if (data && data->d_size > 0) {
nr = data->d_size / sizeof(struct
fixup_entry);
- for (i = 0; i < nr; i++) {
- struct fixup_entry *dst;
- unsigned long idx;
- unsigned long long off;
- struct fixup_entry *src;
+ for (i = 0; i < nr; i++) {
+ struct fixup_entry *dst;
+ unsigned long idx;
+ unsigned long long off;
+ struct fixup_entry *src;
- idx = i * sizeof(struct fixup_entry);
- off = sec->sh.sh_addr + data->d_off + idx;
- src = data->d_buf + idx;
+ idx = i * sizeof(struct
fixup_entry);
+ off = sec->sh.sh_addr +
data->d_off + idx;
+ src = data->d_buf + idx;
- if (src->alt_start_off == src->alt_end_off)
- continue;
+ if (src->alt_start_off ==
src->alt_end_off)
+ continue;
- fes = realloc(fes, (nr_fes + 1) *
sizeof(struct fixup_entry));
- dst = &fes[nr_fes];
- nr_fes++;
+ fes = realloc(fes, (nr_fes + 1)
* sizeof(struct fixup_entry));
+ dst = &fes[nr_fes];
+ nr_fes++;
- dst->mask = __le64_to_cpu(src->mask);
- dst->value = __le64_to_cpu(src->value);
- dst->start_off =
__le64_to_cpu(src->start_off) + off;
- dst->end_off =
__le64_to_cpu(src->end_off) + off;
- dst->alt_start_off =
__le64_to_cpu(src->alt_start_off) + off;
- dst->alt_end_off =
__le64_to_cpu(src->alt_end_off) + off;
+ dst->mask =
__le64_to_cpu(src->mask);
+ dst->value =
__le64_to_cpu(src->value);
+ dst->start_off =
__le64_to_cpu(src->start_off) + off;
+ dst->end_off =
__le64_to_cpu(src->end_off) + off;
+ dst->alt_start_off =
__le64_to_cpu(src->alt_start_off) + off;
+ dst->alt_end_off =
__le64_to_cpu(src->alt_end_off) + off;
- if (dst->alt_start_off < fe_alt_start)
- fe_alt_start = dst->alt_start_off;
+ if (dst->alt_start_off <
fe_alt_start)
+ fe_alt_start =
dst->alt_start_off;
- if (dst->alt_end_off > fe_alt_end)
- fe_alt_end = dst->alt_end_off;
+ if (dst->alt_end_off > fe_alt_end)
+ fe_alt_end =
dst->alt_end_off;
+ }
}
}
}
@@ -246,7 +247,6 @@ static struct symbol *find_symbol_at_address(struct
objtool_file *file,
int process_alt_relocations(struct objtool_file *file)
{
struct section *section;
- size_t n = 0;
uint32_t insn;
uint32_t *i;
unsigned int opcode;
@@ -276,8 +276,6 @@ int process_alt_relocations(struct objtool_file *file)
target = target + 0x8;
}
- n++;
-
fe = find_fe_altaddr(addr);
if (fe) {
I'll include these changes in the next version.
Thanks,
Sathvika
next prev parent reply other threads:[~2024-06-03 8:30 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-22 9:22 [RFC PATCH 1/2] objtool: Run objtool only if either of the config options are selected Sathvika Vasireddy
2024-04-22 9:22 ` [RFC PATCH 2/2] objtool/powerpc: Enhance objtool to fixup alternate feature relative addresses Sathvika Vasireddy
2024-04-23 0:28 ` Nathan Chancellor
2024-06-03 8:29 ` Sathvika Vasireddy [this message]
2024-05-06 16:50 ` Masahiro Yamada
2024-04-22 12:09 ` [RFC PATCH 1/2] objtool: Run objtool only if either of the config options are selected Masahiro Yamada
2024-04-22 16:18 ` Sathvika Vasireddy
2024-05-06 17:39 ` Masahiro Yamada
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9393df04-403d-4530-8f13-c8a5c6d302d2@linux.vnet.ibm.com \
--to=sv@linux.vnet.ibm.com \
--cc=jpoimboe@kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=mahesh@linux.ibm.com \
--cc=masahiroy@kernel.org \
--cc=mingo@kernel.org \
--cc=nathan@kernel.org \
--cc=naveen.n.rao@linux.ibm.com \
--cc=nicolas@fjasle.eu \
--cc=npiggin@gmail.com \
--cc=peterz@infradead.org \
--cc=sv@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).