• Nadav Amit's avatar
    x86/tlb: Disable interrupts when changing CR4 · 9d0b6232
    Nadav Amit authored
    CR4 modifications are implemented as RMW operations which update a shadow
    variable and write the result to CR4. The RMW operation is protected by
    preemption disable, but there is no enforcement or debugging mechanism.
    
    CR4 modifications happen also in interrupt context via
    __native_flush_tlb_global(). This implementation does not affect a
    interrupted thread context CR4 operation, because the CR4 toggle restores
    the original content and does not modify the shadow variable.
    
    So the current situation seems to be safe, but a recent patch tried to add
    an actual RMW operation in interrupt context, which will cause subtle
    corruptions.
    
    To prevent that and make the CR4 handling future proof:
    
     - Add a lockdep assertion to __cr4_set() which will catch interrupt
       enabled invocations
    
     - Disable interrupts in the cr4 manipulator inlines
    
     - Rename cr4_toggle_bits() to cr4_toggle_bits_irqsoff(). This is called
       from __switch_to_xtra() where interrupts are already disabled and
       performance matters.
    
    All other call sites are not performance critical, so the extra overhead of
    an additional local_irq_save/restore() pair is not a problem. If new call
    sites care about performance then the necessary _irqsoff() variants can be
    added.
    
    [ tglx: Condensed the patch by moving the irq protection inside the
      	manipulator functions. Updated changelog ]
    Signed-off-by: default avatarNadav Amit <namit@vmware.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Cc: Luck <tony.luck@intel.com>
    Cc: Radim Krčmář <rkrcmar@redhat.com>
    Cc: Andy Lutomirski <luto@kernel.org>
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: nadav.amit@gmail.com
    Cc: linux-edac@vger.kernel.org
    Link: https://lkml.kernel.org/r/20171125032907.2241-3-namit@vmware.com
    9d0b6232
tlbflush.h 10.7 KB