[1.] gcc -O0 assembly arch/x86/kvm/emulate.c gets compilation failure -- incorrect register restrictions
[2.] Full description of the problem/report:
I'm trying to compile this file at -O0, but gcc chokes in register allocation at the inline assembly.
In the ordinary Linux build, this file compiles with gcc at -O2, without compilation errors.
At -O0, gcc chokes with this message:
gcc? -w -c ./emulateE.c // (using preprocessed file)
./emulateE.c: In function `em_mul_ex':
./emulateE.c:1918:5: error: can't find a register in class `AREG' while reloading `asm'
./emulateE.c:1918:5: error: `asm' operand has impossible constraints
Explanation:
The file contains an inline asm of a kind:
__asm__ __volatile__ ( " ..... " :
"=m" ((ctxt)->eflags), "=&r" (_tmp), "+a" (*rax), "+d" (*rdx), "+qm"(ex) :
"i" (11), "m" ((ctxt)->src . val), "a" (*rax), "d" (*rdx));
Note that "+a" in inputs already means that eax is the return value. An then "a" is used as an output constraint too.
Suggested fix:
Instead of specifying something as both in/out and out operand
__asm__ ( "" : "+a" (rax) : "a" (rax));
it should specify only in/out:
__asm__ ( "" : "+a" (rax));
Or, alternatively in and out:
__asm__ ( "" : "a" (rax) : "a" (rax));
[3.] Keywords (i.e., modules, networking, kernel):
[4.] Kernel information
[4.1.] Kernel version (from /proc/version): cat /proc/version
Linux version 2.6.32-279.el6.i686 ([email protected]) (gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC) ) #1 SMP Wed Jun 13 18:23:32 EDT 2012
[4.2.] Kernel .config file: See attached
[5.] Most recent kernel version which did not have the bug: Unknown
[6.] Output of Oops.. message (if applicable) with symbolic information N/A
resolved (see Documentation/oops-tracing.txt)
[7.] A small shell script or example program which triggers the
problem (if possible) // Omit -O2 from compilation:
gcc -Wp,-MD,arch/x86/kvm/.emulate.o.d -nostdinc -isystem /ref/gcc/4.7.1/rhel60/x86/bin/../lib/gcc/i686-pc-linux-gnu/4.7.1/include -I/local/mb/sandbox/linux-3.5.2/arch/x86/include -Iarch/x86/include/generated -Iinclude -include /local/mb/sandbox/linux-3.5.2/include/linux/kconfig.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -maccumulate-outgoing-args -Wa,-mtune=generic32 -ffreestanding -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_AVX=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -Wframe-larger-than=2048 -Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -pg -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO -w -Ivirt/kvm -Iarch/x86/kvm -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(emulate)" -D"KBUILD_MODNAME=KBUILD_STR(kvm)" -c -o arch/x86/kvm/emulate.o arch/x86/kvm/emulate.c
[8.] Environment
[8.1.] Software (add the output of the ver_linux script here)
Gnu C 4.7.1
Gnu make 3.78.1
binutils 2.20.51.0.2
5.34.
util-linux 2.17.2
mount support
module-init-tools 3.9
e2fsprogs 1.41.12
pcmciautils 015
quota-tools 3.17.
PPP 2.4.5
Linux C Library 2.12
Dynamic linker (ldd) 2.12
Procps 3.2.8
Net-tools 1.60
Kbd 1.15
oprofile 0.9.7
Sh-utils 8.4
wireless-tools 29
Modules Loaded nfs nfsd lockd nfs_acl auth_rpcgss exportfs autofs4 sunrpc target_core_iblock target_core_file target_core_pscsi target_core_mod configfs bnx2fc cnic uio fcoe libfcoe libfc scsi_transport_fc 8021q scsi_tgt garp stp llc pcc_cpufreq cachefiles fscache ipv6 uinput hpilo hpwdt tg3 sg microcode serio_raw iTCO_wdt iTCO_vendor_support ioatdma power_meter igb dca ext3 jbd mbcache sd_mod crc_t10dif sr_mod cdrom hpsa pata_acpi ata_generic ata_piix dm_mirror dm_region_hash dm_log dm_mod
[8.2.] Processor information (from /proc/cpuinfo):
vendor_id : GenuineIntel,cpu family : 6,model : 45,model name : Intel(R) Xeon(R) CPU E5-2650 0 @ 2.00GHz
On 11/14/2012 11:45 AM, Blower, Melanie wrote:
> [1.] gcc -O0 assembly arch/x86/kvm/emulate.c gets compilation failure -- incorrect register restrictions
> [2.] Full description of the problem/report:
> I'm trying to compile this file at -O0, but gcc chokes in register allocation at the inline assembly.
>
> In the ordinary Linux build, this file compiles with gcc at -O2, without compilation errors.
Compiling with -O0 is not really expected to work (although -O1 *is*),
although what you are reporting is an actual bug ("+a" : "a" should
either be "+a" or "=a" : "a").
-hpa
--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.
Thanks for your reply. As you agree there is an actual bug in this code, would you kindly be able to tell me when a fix would be available in the Linux trunk?
Thanks and best regards, Melanie Blower
-----Original Message-----
From: H. Peter Anvin [mailto:[email protected]]
Sent: Wednesday, November 14, 2012 7:14 PM
To: Blower, Melanie
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: PROBLEM: compilation issue, inline assembly arch/x86/kvm/emulate.c fails at -O0
On 11/14/2012 11:45 AM, Blower, Melanie wrote:
> [1.] gcc -O0 assembly arch/x86/kvm/emulate.c gets compilation failure
> -- incorrect register restrictions [2.] Full description of the problem/report:
> I'm trying to compile this file at -O0, but gcc chokes in register allocation at the inline assembly.
>
> In the ordinary Linux build, this file compiles with gcc at -O2, without compilation errors.
Compiling with -O0 is not really expected to work (although -O1 *is*), although what you are reporting is an actual bug ("+a" : "a" should either be "+a" or "=a" : "a").
-hpa
--
H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m????????????I?
Thank you so much, this patch solves the compilation errors that I was seeing in the Intel compiler, and with gcc -O0
BTW, my charter is to compile the kernel with the Intel compiler, and my testing stops short of verifying that the kernel build actually works.
Best regards, Melanie Blower
-----Original Message-----
From: H. Peter Anvin [mailto:[email protected]]
Sent: Wednesday, November 21, 2012 4:35 PM
To: Blower, Melanie
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: PROBLEM: compilation issue, inline assembly arch/x86/kvm/emulate.c fails at -O0
On 11/14/2012 11:45 AM, Blower, Melanie wrote:
> [1.] gcc -O0 assembly arch/x86/kvm/emulate.c gets compilation failure
> -- incorrect register restrictions [2.] Full description of the problem/report:
> I'm trying to compile this file at -O0, but gcc chokes in register allocation at the inline assembly.
>
> In the ordinary Linux build, this file compiles with gcc at -O2, without compilation errors.
>
> At -O0, gcc chokes with this message:
> gcc -w -c ./emulateE.c // (using preprocessed file)
> ./emulateE.c: In function `em_mul_ex':
> ./emulateE.c:1918:5: error: can't find a register in class `AREG' while reloading `asm'
> ./emulateE.c:1918:5: error: `asm' operand has impossible constraints
>
> Explanation:
> The file contains an inline asm of a kind:
>
> __asm__ __volatile__ ( " ..... " :
>
> "=m" ((ctxt)->eflags), "=&r" (_tmp), "+a" (*rax), "+d" (*rdx), "+qm"(ex) :
> "i" (11), "m" ((ctxt)->src . val), "a" (*rax), "d" (*rdx));
>
> Note that "+a" in inputs already means that eax is the return value. An then "a" is used as an output constraint too.
>
Hi Melanie,
Can you test the attached patch?
-hpa
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m????????????I?
From: "H. Peter Anvin" <[email protected]>
In __emulate_1op_rax_rdx, we use "+a" and "+d" which are input/output
constraints, and *then* use "a" and "d" as input constraints. This is
incorrect, but happens to work on some versions of gcc.
However, it breaks gcc with -O0 and icc, and may break on future
versions of gcc.
Reported-and-tested-by: Melanie Blower <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Link: http://lkml.kernel.org/r/B3584E72CFEBED439A3ECA9BCE67A4EF1B17AF90@FMSMSX107.amr.corp.intel.com
---
arch/x86/kvm/emulate.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 39171cb..bba39bf 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
_ASM_EXTABLE(1b, 3b) \
: "=m" ((ctxt)->eflags), "=&r" (_tmp), \
"+a" (*rax), "+d" (*rdx), "+qm"(_ex) \
- : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \
- "a" (*rax), "d" (*rdx)); \
+ : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \
} while (0)
/* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
--
1.7.11.7
On 11/14/2012 11:45 AM, Blower, Melanie wrote:
> [1.] gcc -O0 assembly arch/x86/kvm/emulate.c gets compilation failure -- incorrect register restrictions
> [2.] Full description of the problem/report:
> I'm trying to compile this file at -O0, but gcc chokes in register allocation at the inline assembly.
>
> In the ordinary Linux build, this file compiles with gcc at -O2, without compilation errors.
>
> At -O0, gcc chokes with this message:
> gcc -w -c ./emulateE.c // (using preprocessed file)
> ./emulateE.c: In function `em_mul_ex':
> ./emulateE.c:1918:5: error: can't find a register in class `AREG' while reloading `asm'
> ./emulateE.c:1918:5: error: `asm' operand has impossible constraints
>
> Explanation:
> The file contains an inline asm of a kind:
>
> __asm__ __volatile__ ( " ..... " :
>
> "=m" ((ctxt)->eflags), "=&r" (_tmp), "+a" (*rax), "+d" (*rdx), "+qm"(ex) :
> "i" (11), "m" ((ctxt)->src . val), "a" (*rax), "d" (*rdx));
>
> Note that "+a" in inputs already means that eax is the return value. An then "a" is used as an output constraint too.
>
Hi Melanie,
Can you test the attached patch?
-hpa
Il 21/11/2012 23:41, H. Peter Anvin ha scritto:
> From: "H. Peter Anvin" <[email protected]>
>
> In __emulate_1op_rax_rdx, we use "+a" and "+d" which are input/output
> constraints, and *then* use "a" and "d" as input constraints. This is
> incorrect, but happens to work on some versions of gcc.
>
> However, it breaks gcc with -O0 and icc, and may break on future
> versions of gcc.
>
> Reported-and-tested-by: Melanie Blower <[email protected]>
> Signed-off-by: H. Peter Anvin <[email protected]>
> Link: http://lkml.kernel.org/r/B3584E72CFEBED439A3ECA9BCE67A4EF1B17AF90@FMSMSX107.amr.corp.intel.com
> ---
> arch/x86/kvm/emulate.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 39171cb..bba39bf 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
> _ASM_EXTABLE(1b, 3b) \
> : "=m" ((ctxt)->eflags), "=&r" (_tmp), \
> "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \
> - : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \
> - "a" (*rax), "d" (*rdx)); \
> + : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \
> } while (0)
>
> /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
>
Reviewed-by: Paolo Bonzini <[email protected]>
On 11/25/2012 11:22 PM, Paolo Bonzini wrote:
> Il 21/11/2012 23:41, H. Peter Anvin ha scritto:
>> From: "H. Peter Anvin" <[email protected]>
>>
>> In __emulate_1op_rax_rdx, we use "+a" and "+d" which are input/output
>> constraints, and *then* use "a" and "d" as input constraints. This is
>> incorrect, but happens to work on some versions of gcc.
>>
>> However, it breaks gcc with -O0 and icc, and may break on future
>> versions of gcc.
>>
>> Reported-and-tested-by: Melanie Blower <[email protected]>
>> Signed-off-by: H. Peter Anvin <[email protected]>
>> Link: http://lkml.kernel.org/r/B3584E72CFEBED439A3ECA9BCE67A4EF1B17AF90@FMSMSX107.amr.corp.intel.com
>> ---
>> arch/x86/kvm/emulate.c | 3 +--
>> 1 file changed, 1 insertion(+), 2 deletions(-)
>>
>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
>> index 39171cb..bba39bf 100644
>> --- a/arch/x86/kvm/emulate.c
>> +++ b/arch/x86/kvm/emulate.c
>> @@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
>> _ASM_EXTABLE(1b, 3b) \
>> : "=m" ((ctxt)->eflags), "=&r" (_tmp), \
>> "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \
>> - : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \
>> - "a" (*rax), "d" (*rdx)); \
>> + : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \
>> } while (0)
>>
>> /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
>>
>
> Reviewed-by: Paolo Bonzini <[email protected]>
>
Gleb, Marcelo: are you going to apply this or would you prefer I took it
in x86/urgent?
-hpa
On Mon, Nov 26, 2012 at 02:48:50PM -0800, H. Peter Anvin wrote:
> On 11/25/2012 11:22 PM, Paolo Bonzini wrote:
> > Il 21/11/2012 23:41, H. Peter Anvin ha scritto:
> >> From: "H. Peter Anvin" <[email protected]>
> >>
> >> In __emulate_1op_rax_rdx, we use "+a" and "+d" which are input/output
> >> constraints, and *then* use "a" and "d" as input constraints. This is
> >> incorrect, but happens to work on some versions of gcc.
> >>
> >> However, it breaks gcc with -O0 and icc, and may break on future
> >> versions of gcc.
> >>
> >> Reported-and-tested-by: Melanie Blower <[email protected]>
> >> Signed-off-by: H. Peter Anvin <[email protected]>
> >> Link: http://lkml.kernel.org/r/B3584E72CFEBED439A3ECA9BCE67A4EF1B17AF90@FMSMSX107.amr.corp.intel.com
> >> ---
> >> arch/x86/kvm/emulate.c | 3 +--
> >> 1 file changed, 1 insertion(+), 2 deletions(-)
> >>
> >> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> >> index 39171cb..bba39bf 100644
> >> --- a/arch/x86/kvm/emulate.c
> >> +++ b/arch/x86/kvm/emulate.c
> >> @@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
> >> _ASM_EXTABLE(1b, 3b) \
> >> : "=m" ((ctxt)->eflags), "=&r" (_tmp), \
> >> "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \
> >> - : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \
> >> - "a" (*rax), "d" (*rdx)); \
> >> + : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \
> >> } while (0)
> >>
> >> /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
> >>
> >
> > Reviewed-by: Paolo Bonzini <[email protected]>
> >
>
> Gleb, Marcelo: are you going to apply this or would you prefer I took it
> in x86/urgent?
>
> -hpa
Feel free to merge it through x86/urgent.
On 11/26/2012 03:48 PM, Marcelo Tosatti wrote:
>>
>> Gleb, Marcelo: are you going to apply this or would you prefer I took it
>> in x86/urgent?
>>
>> -hpa
>
> Feel free to merge it through x86/urgent.
>
I presume that's an Acked-by?
-hpa
Commit-ID: cb7cb2864e758a1b040040bc55e404c677c911cb
Gitweb: http://git.kernel.org/tip/cb7cb2864e758a1b040040bc55e404c677c911cb
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 21 Nov 2012 14:41:21 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Mon, 26 Nov 2012 15:52:48 -0800
x86, kvm: Remove incorrect redundant assembly constraint
In __emulate_1op_rax_rdx, we use "+a" and "+d" which are input/output
constraints, and *then* use "a" and "d" as input constraints. This is
incorrect, but happens to work on some versions of gcc.
However, it breaks gcc with -O0 and icc, and may break on future
versions of gcc.
Reported-and-tested-by: Melanie Blower <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
Link: http://lkml.kernel.org/r/B3584E72CFEBED439A3ECA9BCE67A4EF1B17AF90@FMSMSX107.amr.corp.intel.com
Reviewed-by: Paolo Bonzini <[email protected]>
Acked-by: Marcelo Tosatti <[email protected]>
---
arch/x86/kvm/emulate.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 39171cb..bba39bf 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
_ASM_EXTABLE(1b, 3b) \
: "=m" ((ctxt)->eflags), "=&r" (_tmp), \
"+a" (*rax), "+d" (*rdx), "+qm"(_ex) \
- : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \
- "a" (*rax), "d" (*rdx)); \
+ : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \
} while (0)
/* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
On Mon, Nov 26, 2012 at 03:49:36PM -0800, H. Peter Anvin wrote:
> On 11/26/2012 03:48 PM, Marcelo Tosatti wrote:
> >>
> >> Gleb, Marcelo: are you going to apply this or would you prefer I took it
> >> in x86/urgent?
> >>
> >> -hpa
> >
> > Feel free to merge it through x86/urgent.
> >
>
> I presume that's an Acked-by?
>
> -hpa
Yes.