[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] xen 3.3 unstable: xend segfaults on amd64 when starting a hvm domain


  • To: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: Juergen Keil <jk@xxxxxxxx>
  • Date: Wed, 21 May 2008 17:32:19 +0200 (CEST)
  • Delivery-date: Wed, 21 May 2008 08:32:46 -0700
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.