diff options
author | Olaf Hering <olaf@aepfle.de> | 2012-12-13 16:48:46 +0100 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2012-12-14 22:31:03 +0900 |
commit | 6b2450ec4d45b32d1c2f6925753a46dbeeeca545 (patch) | |
tree | bfebb7ed0d6144ac565c704e76a853178e04ed16 | |
parent | 8908ee4b164abe6f038b74d2067e6271346422ac (diff) | |
download | kexec-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.c | 21 |
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) |