diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-12-14 11:58:45 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-12-14 11:58:45 +0000 |
commit | 420820e830a012939240db12c52a5d340a4298f1 (patch) | |
tree | fe8db9e9313c58c65c0aa8958d71ad3ed938d590 /tools/misc/xen-detect.c | |
parent | bda0da7f26a50938a97db6865aa019e0ec42a6c8 (diff) | |
download | xen-420820e830a012939240db12c52a5d340a4298f1.tar.gz xen-420820e830a012939240db12c52a5d340a4298f1.tar.bz2 xen-420820e830a012939240db12c52a5d340a4298f1.zip |
xen-detect: Avoid dumping core
F12 introduces a tool to automatically report bugs when there are core
dumps. Since xen-detect relies on fork+waitpid in order to trap a
SIGILL from a child, every time someone runs xen-detect on a bare
metal kernel a bug is reported into Red Hat's Bugzilla. :-)
However, even without this contingent need, leaving core dumps around
is not nice. So this patch just traps SIGILL using
signal/sentjmp/longjmp, without the need to fork.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'tools/misc/xen-detect.c')
-rw-r--r-- | tools/misc/xen-detect.c | 58 |
1 files changed, 20 insertions, 38 deletions
diff --git a/tools/misc/xen-detect.c b/tools/misc/xen-detect.c index 7bb767989a..b14d3acb23 100644 --- a/tools/misc/xen-detect.c +++ b/tools/misc/xen-detect.c @@ -26,19 +26,16 @@ #include <stdint.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -static int pv_context; +#include <setjmp.h> +#include <signal.h> static void cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, - uint32_t *edx) + uint32_t *edx, + int pv_context) { asm volatile ( "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid" @@ -46,7 +43,7 @@ static void cpuid(uint32_t idx, : "0" (idx), "1" (pv_context) ); } -static int check_for_xen(void) +static int check_for_xen(int pv_context) { uint32_t eax, ebx, ecx, edx; char signature[13]; @@ -54,7 +51,7 @@ static int check_for_xen(void) for ( base = 0x40000000; base < 0x40010000; base += 0x100 ) { - cpuid(base, &eax, &ebx, &ecx, &edx); + cpuid(base, &eax, &ebx, &ecx, &edx, pv_context); *(uint32_t *)(signature + 0) = ebx; *(uint32_t *)(signature + 4) = ecx; @@ -68,47 +65,32 @@ static int check_for_xen(void) return 0; found: - cpuid(base + 1, &eax, &ebx, &ecx, &edx); + cpuid(base + 1, &eax, &ebx, &ecx, &edx, pv_context); printf("Running in %s context on Xen v%d.%d.\n", pv_context ? "PV" : "HVM", (uint16_t)(eax >> 16), (uint16_t)eax); return 1; } -int main(void) +static jmp_buf sigill_jmp; +void sigill_handler(int sig) { - pid_t pid; - int status; - uint32_t dummy; + longjmp(sigill_jmp, 1); +} +int main(void) +{ /* Check for execution in HVM context. */ - if ( check_for_xen() ) - return 0; - - /* Now we check for execution in PV context. */ - pv_context = 1; - - /* - * Fork a child to test the paravirtualised CPUID instruction. - * If executed outside Xen PV context, the extended opcode will fault. - */ - pid = fork(); - switch ( pid ) - { - case 0: - /* Child: test paravirtualised CPUID opcode and then exit cleanly. */ - cpuid(0x40000000, &dummy, &dummy, &dummy, &dummy); - exit(0); - case -1: - fprintf(stderr, "Fork failed.\n"); + if ( check_for_xen(0) ) return 0; - } /* - * Parent waits for child to terminate and checks for clean exit. - * Only if the exit is clean is it safe for us to try the extended CPUID. + * Set up a signal handler to test the paravirtualised CPUID instruction. + * If executed outside Xen PV context, the extended opcode will fault, we + * will longjmp via the signal handler, and print "Not running on Xen". */ - waitpid(pid, &status, 0); - if ( WIFEXITED(status) && check_for_xen() ) + if ( !setjmp(sigill_jmp) + && (signal(SIGILL, sigill_handler) != SIG_ERR) + && check_for_xen(1) ) return 0; printf("Not running on Xen.\n"); |