Messages in this thread | | | From | Denys Vlasenko <> | Date | Thu, 15 Dec 2011 09:30:45 +0100 | Subject | Re: a problem in cpucheck.c on x86 |
| |
On Thu, Dec 15, 2011 at 8:51 AM, ttlxzz ccc <boyzccc@gmail.com> wrote: > Hi,all: > > In arch/x86/boot/cpucheck.c > static int has_eflag(u32 mask) > { > u32 f0, f1; > > asm("pushfl ; " > "pushfl ; " > "popl %0 ; " > "movl %0,%1 ; " > "xorl %2,%1 ; " > "pushl %1 ; " > "popfl ; " > "pushfl ; " > "popl %1 ; " > "popfl" > : "=&r" (f0), "=&r" (f1) > : "ri" (mask)); > > return !!((f0^f1) & mask); > } > > "pushl %1 ; " > "popfl ; " > "pushfl ; " > "popl %1 ; " > I don't know what does above 4 instructions do,
They move value from register %1 to EFLAGS register, and back. Some bits in EFLAGS are immutable, thus this operation can change %1.
Basically, this operation checks whether bit we flipped by xor is really mutable in EFLAGS, or not.
> and I rewirte it like this: > > static int has_eflag(u32 mask) > { > u32 f0; > > asm("pushfl ; " > "pushfl ; " > "popl %0 ; " > "popfl" > : "=&r" (f0));
Well, you can get rid of outer pair of pushfl/popfl too, then...
> return ~f0 & mask; > > } > It works well, and I just want to know is there some special meanings > of the 4 instructions?
Maybe it works on your particular CPU (meaning: kernel doesn't misdetect anything dangerous on your CPU), but in general what you did is wrong, and will surely cause breakage on other CPUs.
-- vda -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |