aboutsummaryrefslogtreecommitdiffstats
path: root/tools/misc
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-12-14 11:58:45 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-12-14 11:58:45 +0000
commit420820e830a012939240db12c52a5d340a4298f1 (patch)
treefe8db9e9313c58c65c0aa8958d71ad3ed938d590 /tools/misc
parentbda0da7f26a50938a97db6865aa019e0ec42a6c8 (diff)
downloadxen-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')
-rw-r--r--tools/misc/xen-detect.c58
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");