Re: x86 entry perf unwinding failure (missing IRET_REGS annotation on stack switch?)
From: Peter Zijlstra
Date: Tue Apr 28 2020 - 12:44:56 EST
On Tue, Apr 28, 2020 at 10:49:09AM -0500, Josh Poimboeuf wrote:
> > @@ -2439,12 +2445,6 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
> >
> > sec = insn->sec;
> >
> > - if (insn->alt_group && list_empty(&insn->alts)) {
> > - WARN_FUNC("don't know how to handle branch to middle of alternative instruction group",
> > - sec, insn->offset);
> > - return 1;
> > - }
> > -
>
> ACK (separate patch)
>
> > while (1) {
> > next_insn = next_insn_same_sec(file, insn);
> >
Yeah, there is one from Julien that does this:
20200327152847.15294-6-jthierry@xxxxxxxxxx
> > @@ -2494,8 +2494,16 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
> > }
> > }
> >
> > - if (skip_orig)
> > + if (skip_orig) {
> > + struct instruction *prev_insn = insn;
> > + sec_for_each_insn_continue(file, insn) {
> > + if (!insn->alt_group)
> > + break;
> > + if (!insn->visited)
> > + insn->cfi = prev_insn->cfi;
> > + }
> > return 0;
> > + }
>
> NACK :-)
>
> What happens if you have two alternatives adjacent to each other (which
> can definitely happen in this scenario)?
Alexandre's alt_group would help:
20200414103618.12657-3-alexandre.chartre@xxxxxxxxxx
Then we can do something like:
static void fill_alternative(struct instruction *insn)
{
struct instruction *first_insn = insn;
int alt_group = insn->alt_group;
sec_for_each_insn_continue(file, insn) {
if (insn->alt_group != alt_group)
break;
if (!insn->visited)
insn->cfi = first_insn->cfi;
}
}
> I still like my patch, at least the hack is done before the validate
> code, so validate_branch() itself is simpler.
But it doesn't handle the case where the alternatives themselves have
unreachable holes in them, if that happens we'll generate spurious ORC
entries for them.