Re: WARNING: can't access registers at asm_common_interrupt

From: Peter Zijlstra
Date: Wed Nov 11 2020 - 15:35:50 EST


On Wed, Nov 11, 2020 at 02:15:06PM -0600, Josh Poimboeuf wrote:
> On Wed, Nov 11, 2020 at 09:07:30PM +0100, Peter Zijlstra wrote:

> > Possible, we just need to be _really_ careful to not allow changing
> > those static_call()s. So maybe we need DEFINE_STATIC_CALL_RO() which
> > does a __ro_after_init on the whole thing.
>
> But what if you want to live migrate to another hypervisor ;-)

Then you get to keep the pieces ;-)

> > > Either way it doesn't make objtool's job much easier. But it would be
> > > nice to consolidate runtime patching mechanisms and get rid of
> > > .parainstructions.
> >
> > I think the above (combining alternative and paravirt/static_call) does
> > make objtool's job easier, since then we at least have the actual
> > alternative instructions available to inspect, or am I mis-understanding
> > things?
>
> Right, it makes objtool's job a _little_ easier, since it already knows
> how to read alternatives. But it still has to learn to deal with the
> conflicting stack layouts.

Right, but at least now it can see the instructions. Which is a lot
better than: `add a magic +1 ORC entry when you see an indirect call to
$magic`.

Anyway, __orc_find(addr) looks for the ORC entry with the highest IP <=
@addr. So if we have:

alt0 alt1

0x00 CALL *foo 0x00 PUSHF
0x07 insn 0x01 POP %rax
0x02 .nops 5
0x07 insn

we have ORC entries for alt1.0x00 and alt1.0x01. Then if we hit insn,
it'll find the alt1.0x01 entry, but that had better be the same as the
state at 0x00.

This means that for every alt, we have to unwind using the CFI of every
other alt and match for every instruction. Which should be doable I
think.

Certainly more complicated that outright disallowing CFI changes inside
alt groups though :/