From: Josh Poimboeuf <jpoimboe@redhat.com>
To: Matthias Kaehlcke <mka@chromium.org>
Cc: Ingo Molnar <mingo@kernel.org>,
linux-kernel@vger.kernel.org, torvalds@linux-foundation.org,
peterz@infradead.org, hpa@zytor.com, tglx@linutronix.de
Subject: Re: [PATCH 2/2] x86/unwind: Make CONFIG_UNWINDER_ORC=y the default in kconfig for 64-bit
Date: Tue, 20 Mar 2018 21:45:07 -0500 [thread overview]
Message-ID: <20180321024507.ud4lu4xndr5jfpkd@treble> (raw)
In-Reply-To: <20180319232255.GF37438@google.com>
On Mon, Mar 19, 2018 at 04:22:55PM -0700, Matthias Kaehlcke wrote:
> arch/x86/mm/pti.o: warning: objtool: pti_init() falls through to next
> function pti_user_pagetable_walk_pmd()
> s/debugfs/file.o: warning: objtool: full_proxy_llseek() falls through to next function full_proxy_read()
> fs/debugfs/file.o: warning: objtool: full_proxy_read() falls through to next function full_proxy_write()
> fs/debugfs/file.o: warning: objtool: full_proxy_write() falls through to next function full_proxy_poll()
> fs/debugfs/file.o: warning: objtool: full_proxy_poll() falls through to next function full_proxy_unlocked_ioctl()
> fs/debugfs/file.o: warning: objtool: full_proxy_unlocked_ioctl() falls
> through to next function fops_u8_open()
Ok, I did a little more digging. Surprise, these objtool warnings are
actually correct. Somehow the WARN macros are causing Clang to produce
bad code. In some cases, Clang is assuming that a WARN is "noreturn",
i.e. that the UD2 doesn't return from the exception.
As an example, here's the full_proxy_llseek() function and its compiled
code:
#define FULL_PROXY_FUNC(name, ret_type, filp, proto, args) \
static ret_type full_proxy_ ## name(proto) \
{ \
struct dentry *dentry = F_DENTRY(filp); \
const struct file_operations *real_fops; \
ret_type r; \
\
r = debugfs_file_get(dentry); \
if (unlikely(r)) \
return r; \
real_fops = debugfs_real_fops(filp); \
r = real_fops->name(args); \
debugfs_file_put(dentry); \
return r; \
}
FULL_PROXY_FUNC(llseek, loff_t, filp,
PROTO(struct file *filp, loff_t offset, int whence),
ARGS(filp, offset, whence));
0000000000000ca0 <full_proxy_llseek>:
ca0: 55 push %rbp
ca1: 41 57 push %r15
ca3: 41 56 push %r14
ca5: 53 push %rbx
ca6: 48 83 ec 10 sub $0x10,%rsp
caa: 41 89 d6 mov %edx,%r14d
cad: 49 89 f7 mov %rsi,%r15
cb0: 48 89 fd mov %rdi,%rbp
cb3: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax
cba: 00 00
cbc: 48 89 44 24 08 mov %rax,0x8(%rsp)
cc1: 48 8b 5d 18 mov 0x18(%rbp),%rbx
cc5: 48 89 df mov %rbx,%rdi
cc8: e8 00 00 00 00 callq ccd <full_proxy_llseek+0x2d>
cc9: R_X86_64_PC32 debugfs_file_get-0x4
ccd: 85 c0 test %eax,%eax
ccf: 75 65 jne d36 <full_proxy_llseek+0x96>
cd1: 48 8b 45 18 mov 0x18(%rbp),%rax
cd5: 48 8b 40 78 mov 0x78(%rax),%rax
cd9: a8 01 test $0x1,%al
cdb: 75 63 jne d40 <full_proxy_llseek+0xa0>
...
d40: 0f 0b ud2
d42: 0f 1f 40 00 nopl 0x0(%rax)
d46: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
d4d: 00 00 00
0000000000000d50 <full_proxy_read>:
After the debugfs_file_get() call, the debugfs_real_fops() call is
inlined. Here it is:
const struct file_operations *debugfs_real_fops(const struct file *filp)
{
struct debugfs_fsdata *fsd = F_DENTRY(filp)->d_fsdata;
if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) {
/*
* Urgh, we've been called w/o a protecting
* debugfs_file_get().
*/
WARN_ON(1);
return NULL;
}
return fsd->real_fops;
}
The WARN_ON() is the UD2 at offset d40. Notice that, as objtool found,
it just falls through to the next function instead of "returning" to
full_proxy_llseek().
At first I thought this might be some kind of "optimization", since, if
you look closely, you'll see that the warning can never happen in this
situation. But no, I downloaded the Clang binary, changed the
if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) /* DEBUGFS_FSDATA_IS_REAL_FOPS_BIT == 1 */
to
if ((unsigned long)fsd & 0x2)
and still got the same issue.
Then I figured that Clang must be peeking into the inline asm, and is
assuming that UD2 is a dead end. But no, I changed ASM_UD2 to a 2-byte
NOP, and got the same issue.
So unless I'm missing some "undefined behavior", this looks like a Clang
bug to me. Somehow it doesn't like the WARN macros (but apparently only
in a small number of cases).
--
Josh
next prev parent reply other threads:[~2018-03-21 2:45 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20171013052544.euk7yawni47lhmdq@gmail.com>
2017-10-13 20:02 ` [PATCH 1/2] x86/unwind: Rename unwinder config options to 'CONFIG_UNWINDER_*' Josh Poimboeuf
2017-10-14 10:49 ` [tip:x86/asm] " tip-bot for Josh Poimboeuf
2017-10-13 20:02 ` [PATCH 2/2] x86/unwind: Make CONFIG_UNWINDER_ORC=y the default in kconfig for 64-bit Josh Poimboeuf
2017-10-14 10:50 ` [tip:x86/asm] " tip-bot for Josh Poimboeuf
2017-10-19 16:51 ` [2/2] " Andrei Vagin
2017-10-19 18:16 ` Josh Poimboeuf
2017-10-19 22:35 ` Andrei Vagin
2017-10-20 0:38 ` Andrei Vagin
2017-10-20 1:28 ` Josh Poimboeuf
2017-10-20 6:54 ` Andrei Vagin
2018-03-19 18:57 ` [PATCH 2/2] " Matthias Kaehlcke
2018-03-19 19:29 ` Josh Poimboeuf
2018-03-19 20:31 ` Matthias Kaehlcke
2018-03-19 21:20 ` Josh Poimboeuf
2018-03-19 23:22 ` Matthias Kaehlcke
2018-03-20 2:28 ` Josh Poimboeuf
2018-03-20 19:39 ` Matthias Kaehlcke
2018-03-21 2:45 ` Josh Poimboeuf [this message]
2018-03-21 21:19 ` Matthias Kaehlcke
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=20180321024507.ud4lu4xndr5jfpkd@treble \
--to=jpoimboe@redhat.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=mka@chromium.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/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).