• Andy Lutomirski's avatar
    x86/paravirt: Replace the paravirt nop with a bona fide empty function · 938d2b33
    Andy Lutomirski authored
    commit fc57a7c6 upstream.
    
    PARAVIRT_ADJUST_EXCEPTION_FRAME generates this code (using nmi as an
    example, trimmed for readability):
    
        ff 15 00 00 00 00       callq  *0x0(%rip)        # 2796 <nmi+0x6>
                  2792: R_X86_64_PC32     pv_irq_ops+0x2c
    
    That's a call through a function pointer to regular C function that
    does nothing on native boots, but that function isn't protected
    against kprobes, isn't marked notrace, and is certainly not
    guaranteed to preserve any registers if the compiler is feeling
    perverse.  This is bad news for a CLBR_NONE operation.
    
    Of course, if everything works correctly, once paravirt ops are
    patched, it gets nopped out, but what if we hit this code before
    paravirt ops are patched in?  This can potentially cause breakage
    that is very difficult to debug.
    
    A more subtle failure is possible here, too: if _paravirt_nop uses
    the stack at all (even just to push RBP), it will overwrite the "NMI
    executing" variable if it's called in the NMI prologue.
    
    The Xen case, perhaps surprisingly, is fine, because it's already
    written in asm.
    
    Fix all of the cases that default to paravirt_nop (including
    adjust_exception_frame) with a big hammer: replace paravirt_nop with
    an asm function that is just a ret instruction.
    
    The Xen case may have other problems, so document them.
    
    This is part of a fix for some random crashes that Sasha saw.
    Reported-and-tested-by: default avatarSasha Levin <sasha.levin@oracle.com>
    Signed-off-by: default avatarAndy Lutomirski <luto@kernel.org>
    Link: http://lkml.kernel.org/r/8f5d2ba295f9d73751c33d97fda03e0495d9ade0.1442791737.git.luto@kernel.orgSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    [ luis: backported to 3.16:
      - file rename: arch/x86/entry/entry_64.S -> arch/x86/kernel/entry_64.S
      - adjusted context ]
    Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
    938d2b33
paravirt.c 12.2 KB