linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Josh Poimboeuf <jpoimboe@redhat.com>
To: Jiri Slaby <jslaby@suse.cz>
Cc: mingo@redhat.com, tglx@linutronix.de, hpa@zytor.com,
	x86@kernel.org, linux-kernel@vger.kernel.org,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	Juergen Gross <jgross@suse.com>,
	xen-devel@lists.xenproject.org
Subject: Re: [PATCH v3 04/29] x86: assembly, use ENDPROC for functions
Date: Fri, 12 May 2017 17:15:32 -0500	[thread overview]
Message-ID: <20170512221532.s2wuaoq65uvaprgq@treble> (raw)
In-Reply-To: <4c3b765e-483a-4d9b-c451-6eccc02403f3@suse.cz>

On Fri, May 12, 2017 at 09:53:48AM +0200, Jiri Slaby wrote:
> On 04/26/2017, 03:42 AM, Josh Poimboeuf wrote:
> >> @@ -323,7 +323,7 @@ ENTRY(resume_userspace)
> >>  	movl	%esp, %eax
> >>  	call	prepare_exit_to_usermode
> >>  	jmp	restore_all
> >> -END(ret_from_exception)
> >> +ENDPROC(ret_from_exception)
> > 
> > What exactly is the motivation of this patch?  It would be good to
> > describe that in the commit message.
> > 
> > Is the point to allow objtool to generate CFI for it?  If so, I don't
> > really see how that would work.  Today, objtool considers ENDPROC to
> > annotate a *callable* function which conforms to the C calling ABI and
> > can be called by another function.  The stack is in a known state at
> > function entry, and so the CFI (or frame pointer info) can be reliably
> > determined.
> 
> Ugh, I haven't checked this in 100 % of cases, but this looks pretty
> fragile to me. From reading the code, the use of END or ENDPROC is
> rather random -- depending on mood and who wrote the code.

Yes, it would be fragile, but objtool has a fix for that.  It looks at
every instruction in the object file and warns if it finds a return
instruction outside of an ENDPROC function.  That works because all
callable instructions have return instructions (except when they have
sibling calls, but objtool detects those too).  So objtool will flag any
C-type functions that forgot to use ENDPROC.

> > But entry code is different.  In most cases, the global symbols aren't
> > actually called, and they don't follow any conventions.  The code is
> > spaghetti-esque, with HW handlers and jumps everywhere.  The state of
> > the stack at symbol entry varies per "function".  That's why objtool
> > ignores these files.
> 
> Unfortunately, this is true.
> 
> > For special cases (like entry code), I was thinking we'd need manual CFI
> > annotations, like we had before.  Or maybe there's another way, like
> > some new macros which tell objtool about the HW entry points and the
> > state of the registers there.
> > 
> > But I'm having trouble seeing how marking these code snippets with
> > ENTRY/ENDPROC would help objtool make any sense of the code and where
> > things are on the stack.
> 
> Ok, my intention was to have every line of assembly code in between of
> FUNC_START/FUNC_END. That way, every rsp related push/pop/sub/add can be
> annotated very easily. For the C-like functions this is all what needs
> to be done.
> 
> Then there is the spaghetti code. And I was thinking about manual
> annotations like:
> 
>   # skip the frame pointer checking between START+END here
>   OBJTOOL(SKIP_CHECKING)
> 
>   # this fn has unusual frame (like interrupts have),
>     and you can find return RIP stored at fp + 0x20
>   OBJTOOL(RIP_IS_AT, 0x20)
> 
>   # put this raw CFI for this location into eh_frame
>   OBJTOOL(RAW_CFI, 0x00, 0x00, 0x00)
> 
> 
> Similarly, I have OBJTOOL(START_FUNC) and OBJTOOL(END_FUNC) emitted with
> each FUNC_START/FUNC_END. So far, when manually expanded for simplicity,
> it looks like this:

I like the idea of making objtool smart enough to read the entry code,
and of combining automated annotations (where possible) with manual
annotations (where necessary).  And it does make sense for objtool to
automate every rsp-related push/pop/sub/add annotation.  That will make
the entry code quite a bit cleaner since we don't need 'push_cfi' and
friends anymore.

However, I think trying to force the entry code snippets into being
normal functions would be awkward.  For example, C-type functions all
start off with the following initial CFI state:

     LOC           CFA      ra
  0000000000000000 rsp+8    c-8

That means the previous frame's stack pointer was at rsp+8 and the
return instruction pointer is (rsp).  But those assumptions don't hold
for non-C-type functions, which usually start with pt_regs or iret regs
on the stack, or a blank slate.

So the initial CFI state is different between the two types of
"functions".  And there are a lot of other differences.  C-type
functions have to follow frame pointer conventions, for example.  So
your FUNC_START macro (and objtool) would have to somehow figure out a
way to make a distinction between the two.  So it would probably work
out better if we kept the distinction between C-type functions and other
code.

I think ENDPROC (or FUNC_START/FUNC_END) should mean "this function is
100% standardized to the C ABI and its debuginfo can be completely
automated".  And any code outside of that would be "this code is special
and needs a mix of automated and manual debuginfo annotations."

I'm also not sure we need the objtool-specific macros.  It might be
simpler to have macros which just output the cfi instead.  I guess this
goes back to our previous discussions about whether objtool's CFI access
should be read/write or write-only.  I don't remember, did we ever to
come to a conclusion with that?

Either way, from looking at the entry code, we may be able to get away
with only the following .macros:

- DWARF_EMPTY_FRAME signal=0

  Mark all registers as undefined and potentially mark the frame as a
  signal frame.

- DWARF_SET_CFA base=rsp offset=0 c_regs=0 extra_regs=0 iret_regs=0

  Set the CFA value.  Set c_regs, extra_regs, and/or iret_regs to
  indicate which regs (if any) are stored just below the CFA.

- DWARF_SET_INDIRECT_CFA base=rsp offset=0 val_offset=0

  Set CFA = *(base + offset) + val_offset.  I only saw a few places
  where this is needed, where it switches to the irq stack.  We might be
  able to figure out a way to simplify the code in a non-intrusive way
  to get rid of the need for this one.

And we could create higher-level macros from these primitives if needed.

I think we'd only need the macros in relatively few places in the entry
code.  It would be a lot less intrusive than what we had before.

-- 
Josh

  reply	other threads:[~2017-05-12 22:15 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-21 14:12 [PATCH v3 01/29] x86: boot/copy, remove unused functions Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 02/29] x86_32: boot, extract efi_pe_entry from startup_32 Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 03/29] x86_64: boot, extract efi_pe_entry from startup_64 Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 04/29] x86: assembly, use ENDPROC for functions Jiri Slaby
2017-04-26  1:42   ` Josh Poimboeuf
2017-05-12  7:53     ` Jiri Slaby
2017-05-12 22:15       ` Josh Poimboeuf [this message]
2017-05-17 13:23         ` Jiri Slaby
2017-05-19  9:17           ` Jiri Slaby
2017-05-19 19:50             ` Josh Poimboeuf
2017-04-21 14:12 ` [PATCH v3 05/29] x86: assembly, add ENDPROC to functions Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 06/29] x86: assembly, annotate functions by ENTRY, not GLOBAL Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 07/29] x86: bpf_jit, use ENTRY+ENDPROC Jiri Slaby
2017-04-21 19:32   ` Alexei Starovoitov
2017-04-24  6:45     ` Jiri Slaby
2017-04-24 14:41       ` David Miller
2017-04-24 14:52         ` Jiri Slaby
2017-04-24 15:08           ` David Miller
2017-04-24 15:41             ` Jiri Slaby
2017-04-24 15:51               ` David Miller
2017-04-24 15:53                 ` Jiri Slaby
2017-04-24 15:55               ` Ingo Molnar
2017-04-24 16:02                 ` Jiri Slaby
2017-04-24 16:40                   ` Ingo Molnar
2017-04-24 16:47                   ` Alexei Starovoitov
2017-04-24 17:51                     ` Jiri Slaby
2017-04-24 18:24                       ` David Miller
2017-04-25 14:41                         ` Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 08/29] linkage: new macros for assembler symbols Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 09/29] x86: assembly, use DATA_SIMPLE for data Jiri Slaby
2017-04-27 11:53   ` Pavel Machek
2017-04-27 12:30     ` Jiri Slaby
2017-04-27 12:43       ` Pavel Machek
2017-04-21 14:12 ` [PATCH v3 10/29] x86: assembly, annotate relocate_kernel Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 11/29] x86: entry, annotate THUNKs Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 12/29] x86: assembly, annotate local functions Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 13/29] x86: crypto, " Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 14/29] x86: boot, " Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 15/29] x86: assembly, annotate aliases Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 16/29] x86: entry, annotate interrupt symbols properly Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 17/29] x86: head, annotate data appropriatelly Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 18/29] x86: boot, " Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 19/29] x86: um, " Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 20/29] x86: xen-pvh, " Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 21/29] x86: purgatory, start using annotations Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 22/29] x86: assembly, use SYM_FUNC_INNER_LABEL instead of GLOBAL Jiri Slaby
2017-04-21 14:12 ` [PATCH v3 23/29] x86: realmode, use SYM_DATA_* " Jiri Slaby
2017-04-21 14:13 ` [PATCH v3 24/29] x86: assembly, remove GLOBAL macro Jiri Slaby
2017-04-21 14:13 ` [PATCH v3 25/29] x86: assembly, make some functions local Jiri Slaby
2017-04-21 14:13 ` [PATCH v3 26/29] x86_64: assembly, change all ENTRY to SYM_FUNC_START Jiri Slaby
2017-04-21 14:13 ` [PATCH v3 27/29] x86_32: " Jiri Slaby
2017-04-21 14:13 ` [PATCH v3 28/29] x86_32: lguest, use SYM_ENTRY Jiri Slaby
2017-04-21 14:13 ` [PATCH v3 29/29] x86: assembly, replace WEAK uses Jiri Slaby

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=20170512221532.s2wuaoq65uvaprgq@treble \
    --to=jpoimboe@redhat.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=hpa@zytor.com \
    --cc=jgross@suse.com \
    --cc=jslaby@suse.cz \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    --cc=xen-devel@lists.xenproject.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).