[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
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |