• H. Peter Anvin's avatar
    x86: fix assembly constraints in native_save_fl() · f1f029c7
    H. Peter Anvin authored
    From Gabe Black in bugzilla 13888:
    
    native_save_fl is implemented as follows:
    
      11static inline unsigned long native_save_fl(void)
      12{
      13        unsigned long flags;
      14
      15        asm volatile("# __raw_save_flags\n\t"
      16                     "pushf ; pop %0"
      17                     : "=g" (flags)
      18                     : /* no input */
      19                     : "memory");
      20
      21        return flags;
      22}
    
    If gcc chooses to put flags on the stack, for instance because this is
    inlined into a larger function with more register pressure, the offset
    of the flags variable from the stack pointer will change when the
    pushf is performed. gcc doesn't attempt to understand that fact, and
    address used for pop will still be the same. It will write to
    somewhere near flags on the stack but not actually into it and
    overwrite some other value.
    
    I saw this happen in the ide_device_add_all function when running in a
    simulator I work on. I'm assuming that some quirk of how the simulated
    hardware is set up caused the code path this is on to be executed when
    it normally wouldn't.
    
    A simple fix might be to change "=g" to "=r".
    Reported-by: default avatarGabe Black <spamforgabe@umich.edu>
    Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
    Cc: Stable Team <stable@kernel.org>
    f1f029c7
irqflags.h 4.16 KB