• Andy Lutomirski's avatar
    x86/entry/32: Introduce and use X86_BUG_ESPFIX instead of paravirt_enabled · 58a5aac5
    Andy Lutomirski authored
    x86_64 has very clean espfix handling on paravirt: espfix64 is set
    up in native_iret, so paravirt systems that override iret bypass
    espfix64 automatically.  This is robust and straightforward.
    
    x86_32 is messier.  espfix is set up before the IRET paravirt patch
    point, so it can't be directly conditionalized on whether we use
    native_iret.  We also can't easily move it into native_iret without
    regressing performance due to a bizarre consideration.  Specifically,
    on 64-bit kernels, the logic is:
    
      if (regs->ss & 0x4)
              setup_espfix;
    
    On 32-bit kernels, the logic is:
    
      if ((regs->ss & 0x4) && (regs->cs & 0x3) == 3 &&
          (regs->flags & X86_EFLAGS_VM) == 0)
              setup_espfix;
    
    The performance of setup_espfix itself is essentially irrelevant, but
    the comparison happens on every IRET so its performance matters.  On
    x86_64, there's no need for any registers except flags to implement
    the comparison, so we fold the whole thing into native_iret.  On
    x86_32, we don't do that because we need a free register to
    implement the comparison efficiently.  We therefore do espfix setup
    before restoring registers on x86_32.
    
    This patch gets rid of the explicit paravirt_enabled check by
    introducing X86_BUG_ESPFIX on 32-bit systems and using an ALTERNATIVE
    to skip espfix on paravirt systems where iret != native_iret.  This is
    also messy, but it's at least in line with other things we do.
    
    This improves espfix performance by removing a branch, but no one
    cares.  More importantly, it removes a paravirt_enabled user, which is
    good because paravirt_enabled is ill-defined and is going away.
    Signed-off-by: default avatarAndy Lutomirski <luto@kernel.org>
    Reviewed-by: default avatarBorislav Petkov <bp@suse.de>
    Cc: Andrew Cooper <andrew.cooper3@citrix.com>
    Cc: Andy Lutomirski <luto@amacapital.net>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Brian Gerst <brgerst@gmail.com>
    Cc: Denys Vlasenko <dvlasenk@redhat.com>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Luis R. Rodriguez <mcgrof@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: boris.ostrovsky@oracle.com
    Cc: david.vrabel@citrix.com
    Cc: konrad.wilk@oracle.com
    Cc: lguest@lists.ozlabs.org
    Cc: xen-devel@lists.xensource.com
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    58a5aac5
common.c 36.2 KB