Hi,
xen-3.3 unstable contains a new source tools/libxc/xc_cpuid_x86.c
which uses an asm() statement to run the x86 CPUID instruction.
Apparently due to some GCC register allocation issues when compiling x86
32-bit code, it manually saves and restores the 32-bit %ebx register
into a local "bx_temp" temporary variable:
105 static void cpuid(const unsigned int *input, unsigned int *regs)
106 {
107 unsigned int count = (input[1] == XEN_CPUID_INPUT_UNUSED) ? 0 :
input[1];
108 unsigned int bx_temp;
109 asm ( "mov %%ebx,%4; cpuid; mov %%ebx,%1; mov %4,%%ebx"
110 : "=a" (regs[0]), "=r" (regs[1]),
111 "=c" (regs[2]), "=d" (regs[3]), "=m" (bx_temp)
112 : "0" (input[0]), "2" (count) );
113 }
Without the GCC 32-bit register allocation issue, this could
be written as:
static void cpuid(const unsigned int *input, unsigned int *regs)
{
unsigned int count = (input[1] == XEN_CPUID_INPUT_UNUSED) ? 0 :
input[1];
asm ( "cpuid"
: "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
: "0" (input[0]), "2" (count) );
}
Anyway. Problem with the current code is that it is broken for
amd64 / x86_64. When compiling cpuid() for 64-bit x86 code, we have
to save and restore all 64-bits of the %rbx register; the current
asm() statement saves/restores the lower 32-bits only, thashing the
top 32-bits.
Due to this bug, xen-3.3 unstable xend is segfaulting in a 64-bit
opensolaris dom0.
The attached patch fixes the issue (and fixes xen bug #1258).
cpuid() must save/restore full 64bit %rbx register, when compiled for amd64
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -105,11 +105,19 @@ static void cpuid(const unsigned int *in
static void cpuid(const unsigned int *input, unsigned int *regs)
{
unsigned int count = (input[1] == XEN_CPUID_INPUT_UNUSED) ? 0 : input[1];
+#if defined(__x86_64__)
+ unsigned long bx_temp;
+ asm ( "mov %%rbx,%4; cpuid; mov %%ebx,%1; mov %4,%%rbx"
+ : "=a" (regs[0]), "=r" (regs[1]),
+ "=c" (regs[2]), "=d" (regs[3]), "=m" (bx_temp)
+ : "0" (input[0]), "2" (count) );
+#else
unsigned int bx_temp;
asm ( "mov %%ebx,%4; cpuid; mov %%ebx,%1; mov %4,%%ebx"
: "=a" (regs[0]), "=r" (regs[1]),
"=c" (regs[2]), "=d" (regs[3]), "=m" (bx_temp)
: "0" (input[0]), "2" (count) );
+#endif
}
/* Get the manufacturer brand name of the host processor. */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|