Re: [PATCH] x86/alternative: fix undefined reference to __ibt_endbr_seal[_end]

From: Miaohe Lin
Date: Sun Oct 09 2022 - 08:44:37 EST


On 2022/10/9 20:28, Peter Zijlstra wrote:
> On Sun, Oct 09, 2022 at 11:45:32PM +0800, Miaohe Lin wrote:
>> When I compile the kernel bzImage, there are several compile errors:
>>
>> ld: arch/x86/kernel/alternative.o: in function
>> `alternative_instructions':
>> alternative.c:(.init.text+0x15d): undefined reference to
>> `__ibt_endbr_seal_end'
>> ld: alternative.c:(.init.text+0x164): undefined reference to
>> `__ibt_endbr_seal'
>>
>> It's because __ibt_endbr_seal and __ibt_endbr_seal_end are not optimized
>> away when CONFIG_X86_KERNEL_IBT isn't enabled. Remove noinline attribute
>> to help gcc optimize them away.
>>
>> Signed-off-by: Miaohe Lin <linmiaohe@xxxxxxxxxx>
>> ---
>> arch/x86/kernel/alternative.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
>> index 5cadcea035e0..beaf9fc44e2f 100644
>> --- a/arch/x86/kernel/alternative.c
>> +++ b/arch/x86/kernel/alternative.c
>> @@ -624,7 +624,7 @@ void __init_or_module noinline apply_ibt_endbr(s32 *start, s32 *end)
>>
>> #else
>>
>> -void __init_or_module noinline apply_ibt_endbr(s32 *start, s32 *end) { }
>> +void __init_or_module apply_ibt_endbr(s32 *start, s32 *end) { }
>>
>> #endif /* CONFIG_X86_KERNEL_IBT */
>>
>
> None of this makes any sense...

This compile error occurs in my env when CONFIG_X86_KERNEL_IBT isn't enabled with gcc version 7.3.0 (GCC).
And the generated assembly code looks like below:

0000000000000104 <alternative_instructions>:
104: e8 90 ff ff ff callq 99 <int3_selftest>
109: e8 00 00 00 00 callq 10e <alternative_instructions+0xa>
10e: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
115: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
11c: e8 00 00 00 00 callq 121 <alternative_instructions+0x1d>
121: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
128: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
12f: e8 00 00 00 00 callq 134 <alternative_instructions+0x30>
134: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
13b: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
142: e8 00 00 00 00 callq 147 <alternative_instructions+0x43>
147: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
14e: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
155: e8 00 00 00 00 callq 15a <alternative_instructions+0x56>
>15a: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
>161: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
>168: e8 00 00 00 00 callq 16d <alternative_instructions+0x69>
>16d: 83 3d 00 00 00 00 00 cmpl $0x0,0x0(%rip) # 174 <alternative_instructions+0x70>
>174: 75 4a jne 1c0 <alternative_instructions+0xbc>

It seems the call to apply_ibt_endbr() is not optimized out when CONFIG_X86_KERNEL_IBT isn't enabled.
And after the patch, the generated assembly code looks like below:

0000000000000104 <alternative_instructions>:
104: e8 90 ff ff ff callq 99 <int3_selftest>
109: e8 00 00 00 00 callq 10e <alternative_instructions+0xa>
10e: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
115: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
11c: e8 00 00 00 00 callq 121 <alternative_instructions+0x1d>
121: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
128: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
12f: e8 00 00 00 00 callq 134 <alternative_instructions+0x30>
134: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
13b: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
142: e8 00 00 00 00 callq 147 <alternative_instructions+0x43>
147: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
14e: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
155: e8 00 00 00 00 callq 15a <alternative_instructions+0x56>
>15a: 83 3d 00 00 00 00 00 cmpl $0x0,0x0(%rip) # 161 <alternative_instructions+0x5d>
>161: 75 4a jne 1ad <alternative_instructions+0xa9>

The call to apply_ibt_endbr() is optimized out this time. Maybe it's the problem of gcc. But remove
noinline attribute make compile works in my env. Am I miss something?

Thanks,
Miaohe Lin


>
> .
>