]> git.karo-electronics.de Git - karo-tx-linux.git/commit
x86: fix assembly constraints in native_save_fl()
authorH. Peter Anvin <hpa@zytor.com>
Mon, 3 Aug 2009 23:33:40 +0000 (16:33 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sun, 16 Aug 2009 21:26:52 +0000 (14:26 -0700)
commit04101e4e4ef4ff5035ce5ad4510db02eb54c4985
tree782044182f065cc1463824e8450edc74564b9d60
parentb2d13246b6eb439aee5baf8552b9463b553b5bc9
x86: fix assembly constraints in native_save_fl()

commit f1f029c7bfbf4ee1918b90a431ab823bed812504 upstream.

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: Gabe Black <spamforgabe@umich.edu>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
include/asm-x86/irqflags.h