Re: drivers/gpu/drm/i915/i915.prelink.o: warning: objtool: __intel_wait_for_register_fw.cold()+0xce: relocation to !ENDBR: vlv_allow_gt_wake.cold+0x0

Peter Zijlstra
2022-04-05T21:09:57Z

On Mon, Apr 04, 2022 at 12:33:19PM +0800, kernel test robot wrote:
> tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
> head: 3123109284176b1532874591f7c81f3837bbdc17
> commit: d31ed5d767c0452b4f49846d80a0bfeafa3a4ded kbuild: Fixup the IBT kbuild changes
> date: 12 days ago
> config: x86_64-randconfig-a011-20220404 (https://download.01.org/0day-ci/archive/20220404/202204041241.Hw855BWm-lkp@intel.com/config)
> compiler: gcc-11 (Debian 11.2.0-19) 11.2.0
> reproduce (this is a W=1 build):
> # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d31ed5d767c0452b4f49846d80a0bfeafa3a4ded
> git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> git fetch --no-tags linus master
> git checkout d31ed5d767c0452b4f49846d80a0bfeafa3a4ded
> # save the config file to linux build tree
> mkdir build_dir
> make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/gpu/
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
>
> All warnings (new ones prefixed by >>):
>
> >> drivers/gpu/drm/i915/i915.prelink.o: warning: objtool: __intel_wait_for_register_fw.cold()+0xce: relocation to !ENDBR: vlv_allow_gt_wake.cold+0x0
> drivers/gpu/drm/i915/i915.prelink.o: warning: objtool: gen6_alloc_va_range.cold()+0x1c6: relocation to !ENDBR: i915_vma_unpin.cold+0x0
> >> drivers/gpu/drm/i915/i915.prelink.o: warning: objtool: fence_update.cold()+0x14a: relocation to !ENDBR: i915_vma_revoke_fence.cold+0x0
> drivers/gpu/drm/i915/i915.prelink.o: warning: objtool: eb_move_to_gpu.cold()+0x52: relocation to !ENDBR: i915_reset_gen7_sol_offsets.cold+0x0
> >> drivers/gpu/drm/i915/i915.prelink.o: warning: objtool: __i915_gem_object_release_mmap_gtt.cold()+0xce: relocation to !ENDBR: i915_gem_mmap.cold+0x0
> drivers/gpu/drm/i915/i915.prelink.o: warning: objtool: i915_ttm_io_mem_pfn.cold()+0x52: relocation to !ENDBR: i915_ttm_delayed_free.cold+0x0
> >> drivers/gpu/drm/i915/i915.prelink.o: warning: objtool: ttm_vm_close.cold()+0x52: relocation to !ENDBR: ttm_vm_open.cold+0x0
> drivers/gpu/drm/i915/i915.prelink.o: warning: objtool: ttm_vm_open.cold()+0x52: relocation to !ENDBR: i915_ttm_shrinker_release_pages.cold+0x0

---
Subject: objtool/ibt: Allow _THIS_IP_ at: sym+len
From: Peter Zijlstra <peterz@infradead.org>
Date: Tue Apr 5 15:54:41 CEST 2022

0day robot reported:

drivers/gpu/drm/i915/i915.prelink.o: warning: objtool: __intel_wait_for_register_fw.cold()+0xce: relocation to !ENDBR: vlv_allow_gt_wake.cold+0x0

Which turns out to be GCC placing a _THIS_IP_ past the end of the
function:

0000000000001d00 <__intel_wait_for_register_fw.cold>:
...
1dce: 48 c7 c7 00 00 00 00 mov $0x0,%rdi 1dd1: R_X86_64_32S .text.unlikely+0x1df8
1dd5: e8 00 00 00 00 call 1dda <__intel_wait_for_register_fw.cold+0xda> 1dd6: R_X86_64_PLT32 __trace_bprintk-0x4
...
1df6: 0f 0b ud2

Add an exception for this one weird case...

Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
tools/objtool/check.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -3198,6 +3198,8 @@ static void warn_noendbr(const char *msg
static void validate_ibt_dest(struct objtool_file *file, struct instruction *insn,
struct instruction *dest)
{
+ struct instruction *last, *next;
+
if (dest->func && dest->func == insn->func) {
/*
* Anything from->to self is either _THIS_IP_ or IRET-to-self.
@@ -3217,6 +3219,21 @@ static void validate_ibt_dest(struct obj
if (dest->noendbr)
return;

+ /*
+ * Occasionally, when the last instruction of the function is UD2, GCC
+ * manages to generate a text reference to the instruction after it.
+ */
+ last = next = insn;
+ for (;;) {
+ next = next_insn_same_sec(file, next);
+ if (!next || next->func != insn->func)
+ break;
+ last = next;
+ }
+ if (last->type == INSN_BUG &&
+ last->offset + last->len == dest->offset)
+ return;
+
warn_noendbr("", insn->sec, insn->offset, dest);
}