WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] xen 3.3 unstable: xend segfaults on amd64 when start

To: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] xen 3.3 unstable: xend segfaults on amd64 when starting a hvm domain
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
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Reply-to: Juergen Keil <jk@xxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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
<Prev in Thread] Current Thread [Next in Thread>