diff options
author | Keir Fraser <keir@xen.org> | 2011-12-02 06:31:14 -0800 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2011-12-02 06:31:14 -0800 |
commit | 51b4edac5476726be451614b2ddbd645b4ce1de4 (patch) | |
tree | 7050c10ac0b781ca892b4e30faba8f419ca08868 /tools/misc | |
parent | b010d7f5b8b9ab1f95e59bc8d4f0a290a1f1a21b (diff) | |
download | xen-51b4edac5476726be451614b2ddbd645b4ce1de4.tar.gz xen-51b4edac5476726be451614b2ddbd645b4ce1de4.tar.bz2 xen-51b4edac5476726be451614b2ddbd645b4ce1de4.zip |
tools/x86_64: Fix cpuid() inline asm to not clobber stack's red zone
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: Keir Fraser <keir@xen.org>
Acked-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'tools/misc')
-rw-r--r-- | tools/misc/xen-detect.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/tools/misc/xen-detect.c b/tools/misc/xen-detect.c index 565f27adb4..787b5da90d 100644 --- a/tools/misc/xen-detect.c +++ b/tools/misc/xen-detect.c @@ -35,18 +35,21 @@ static void cpuid(uint32_t idx, uint32_t *regs, int pv_context) { - asm volatile ( #ifdef __i386__ -#define R(x) "%%e"#x"x" -#else -#define R(x) "%%r"#x"x" -#endif - "push "R(a)"; push "R(b)"; push "R(c)"; push "R(d)"\n\t" + /* 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 "R(d)"; pop "R(c)"; pop "R(b)"; pop "R(a)"\n\t" + "pop %%edx; pop %%ecx; pop %%ebx; pop %%eax\n\t" : : "a" (idx), "c" (pv_context), "S" (regs) : "memory" ); +#else + 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 } static int check_for_xen(int pv_context) |