Re: a problem in cpucheck.c on x86
From: Denys Vlasenko
Date: Thu Dec 15 2011 - 03:31:08 EST
On Thu, Dec 15, 2011 at 8:51 AM, ttlxzz ccc <boyzccc@xxxxxxxxx> 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@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/