summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlaf Hering <olaf@aepfle.de>2012-12-13 16:48:46 +0100
committerSimon Horman <horms@verge.net.au>2012-12-14 22:31:03 +0900
commit6b2450ec4d45b32d1c2f6925753a46dbeeeca545 (patch)
treebfebb7ed0d6144ac565c704e76a853178e04ed16
parent8908ee4b164abe6f038b74d2067e6271346422ac (diff)
downloadkexec-tools-6b2450ec4d45b32d1c2f6925753a46dbeeeca545.tar.gz
Fix xen_cpuid() inline asm to not clobber stack's red zone
Port xen-unstable changeset 24344:72f4e4cb7440 to kexec-tools: Pushing stuff onto the stack on x86-64 when we do not specify -mno-red-zone is unsafe. Since the complicated asm is due to register pressure on i386, we simply implement an all-new simpler alternative for x86-64. Signed-off-by: Olaf Hering <olaf@aepfle.de> Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--kexec/crashdump-xen.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/kexec/crashdump-xen.c b/kexec/crashdump-xen.c
index 9dfabf82..d8bd0f4d 100644
--- a/kexec/crashdump-xen.c
+++ b/kexec/crashdump-xen.c
@@ -41,18 +41,21 @@ void xen_sigill_handler(int sig)
static void xen_cpuid(uint32_t idx, uint32_t *regs, int pv_context)
{
- asm volatile (
#ifdef __i386__
-#define R(x) "%%e"#x"x"
+ /* Use the stack to avoid reg constraint failures with some gcc flags */
+ asm volatile (
+ "push %%eax; push %%ebx; push %%ecx; push %%edx\n\t"
+ "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid\n\t"
+ "mov %%eax,(%2); mov %%ebx,4(%2)\n\t"
+ "mov %%ecx,8(%2); mov %%edx,12(%2)\n\t"
+ "pop %%edx; pop %%ecx; pop %%ebx; pop %%eax\n\t"
+ : : "a" (idx), "c" (pv_context), "S" (regs) : "memory" );
#else
-#define R(x) "%%r"#x"x"
+ asm volatile (
+ "test %5,%5 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid\n\t"
+ : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
+ : "0" (idx), "1" (pv_context), "2" (0) );
#endif
- "push "R(a)"; push "R(b)"; push "R(c)"; push "R(d)"\n\t"
- "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid\n\t"
- "mov %%eax,(%2); mov %%ebx,4(%2)\n\t"
- "mov %%ecx,8(%2); mov %%edx,12(%2)\n\t"
- "pop "R(d)"; pop "R(c)"; pop "R(b)"; pop "R(a)"\n\t"
- : : "a" (idx), "c" (pv_context), "S" (regs) : "memory" );
}
static int check_for_xen(int pv_context)