debuggers.hg

annotate tools/misc/xen-detect.c @ 22848:6341fe0f4e5a

Added tag 4.1.0-rc2 for changeset 9dca60d88c63
author Keir Fraser <keir@xen.org>
date Tue Jan 25 14:06:55 2011 +0000 (2011-01-25)
parents 526af7ddb9bd
children
rev   line source
keir@13874 1 /******************************************************************************
keir@13874 2 * xen_detect.c
keir@13874 3 *
keir@13874 4 * Simple GNU C / POSIX application to detect execution on Xen VMM platform.
keir@13874 5 *
keir@13874 6 * Copyright (c) 2007, XenSource Inc.
keir@13874 7 *
keir@13874 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
keir@13874 9 * of this software and associated documentation files (the "Software"), to
keir@13874 10 * deal in the Software without restriction, including without limitation the
keir@13874 11 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
keir@13874 12 * sell copies of the Software, and to permit persons to whom the Software is
keir@13874 13 * furnished to do so, subject to the following conditions:
keir@13874 14 *
keir@13874 15 * The above copyright notice and this permission notice shall be included in
keir@13874 16 * all copies or substantial portions of the Software.
keir@13874 17 *
keir@13874 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
keir@13874 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
keir@13874 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
keir@13874 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
keir@13874 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
keir@13874 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
keir@13874 24 * DEALINGS IN THE SOFTWARE.
keir@13874 25 */
keir@13874 26
keir@13874 27 #include <stdint.h>
keir@20764 28 #include <stdlib.h>
keir@13874 29 #include <stdio.h>
keir@13874 30 #include <string.h>
keir@20691 31 #include <setjmp.h>
keir@20691 32 #include <signal.h>
keir@20764 33 #include <unistd.h>
keir@20764 34 #include <getopt.h>
keir@13874 35
keir@13874 36 static void cpuid(uint32_t idx,
keir@13874 37 uint32_t *eax,
keir@13874 38 uint32_t *ebx,
keir@13874 39 uint32_t *ecx,
keir@20691 40 uint32_t *edx,
keir@20691 41 int pv_context)
keir@13874 42 {
keir@13874 43 asm volatile (
keir@13874 44 "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid"
keir@13874 45 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
keir@13874 46 : "0" (idx), "1" (pv_context) );
keir@13874 47 }
keir@13874 48
keir@20691 49 static int check_for_xen(int pv_context)
keir@13874 50 {
keir@13874 51 uint32_t eax, ebx, ecx, edx;
keir@13874 52 char signature[13];
keir@18963 53 uint32_t base;
keir@13874 54
keir@20251 55 for ( base = 0x40000000; base < 0x40010000; base += 0x100 )
keir@18963 56 {
keir@20691 57 cpuid(base, &eax, &ebx, &ecx, &edx, pv_context);
keir@18963 58
keir@18963 59 *(uint32_t *)(signature + 0) = ebx;
keir@18963 60 *(uint32_t *)(signature + 4) = ecx;
keir@18963 61 *(uint32_t *)(signature + 8) = edx;
keir@18963 62 signature[12] = '\0';
keir@13874 63
keir@18963 64 if ( !strcmp("XenVMMXenVMM", signature) && (eax >= (base + 2)) )
keir@18963 65 goto found;
keir@18963 66 }
keir@13874 67
keir@18963 68 return 0;
keir@18963 69
keir@18963 70 found:
keir@20691 71 cpuid(base + 1, &eax, &ebx, &ecx, &edx, pv_context);
keir@20930 72 return eax;
keir@13874 73 }
keir@13874 74
keir@20691 75 static jmp_buf sigill_jmp;
keir@20691 76 void sigill_handler(int sig)
keir@20691 77 {
keir@20691 78 longjmp(sigill_jmp, 1);
keir@20691 79 }
keir@20691 80
keir@20764 81 static void usage(void)
keir@20764 82 {
keir@20764 83 printf("Usage: xen_detect [options]\n");
keir@20764 84 printf("Options:\n");
keir@20764 85 printf(" -h, --help Display this information\n");
keir@20764 86 printf(" -q, --quiet Quiesce normal informational output\n");
keir@20764 87 printf(" -P, --pv Exit status 1 if not running as PV guest\n");
keir@20764 88 printf(" -H, --hvm Exit status 1 if not running as HVM guest.\n");
keir@20764 89 printf(" -N, --none Exit status 1 if running on Xen (PV or HVM)\n");
keir@20764 90 }
keir@20764 91
keir@20764 92 int main(int argc, char **argv)
keir@13874 93 {
keir@20764 94 enum { XEN_PV = 1, XEN_HVM = 2, XEN_NONE = 3 } detected = 0, expected = 0;
keir@20764 95 uint32_t version = 0;
keir@20764 96 int ch, quiet = 0;
keir@20764 97
keir@20764 98 const static char sopts[] = "hqPHN";
keir@20764 99 const static struct option lopts[] = {
keir@20764 100 { "help", 0, NULL, 'h' },
keir@20764 101 { "quiet", 0, NULL, 'q' },
keir@20764 102 { "pv", 0, NULL, 'P' },
keir@20764 103 { "hvm", 0, NULL, 'H' },
keir@20764 104 { "none", 0, NULL, 'N' },
keir@20764 105 { 0, 0, 0, 0}
keir@20764 106 };
keir@20764 107
keir@20764 108 while ( (ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1 )
keir@20764 109 {
keir@20764 110 switch ( ch )
keir@20764 111 {
keir@20764 112 case 'q':
keir@20764 113 quiet = 1;
keir@20764 114 break;
keir@20764 115 case 'P':
keir@20764 116 expected = XEN_PV;
keir@20764 117 break;
keir@20764 118 case 'H':
keir@20764 119 expected = XEN_HVM;
keir@20764 120 break;
keir@20764 121 case 'N':
keir@20764 122 expected = XEN_NONE;
keir@20764 123 break;
keir@20764 124 default:
keir@20764 125 usage();
keir@20764 126 exit(1);
keir@20764 127 }
keir@20764 128 }
keir@20764 129
keir@13874 130 /* Check for execution in HVM context. */
keir@20764 131 detected = XEN_HVM;
keir@20764 132 if ( (version = check_for_xen(0)) != 0 )
keir@20764 133 goto out;
keir@13874 134
keir@13874 135 /*
keir@20691 136 * Set up a signal handler to test the paravirtualised CPUID instruction.
keir@20691 137 * If executed outside Xen PV context, the extended opcode will fault, we
keir@20691 138 * will longjmp via the signal handler, and print "Not running on Xen".
keir@13874 139 */
keir@20764 140 detected = XEN_PV;
keir@20691 141 if ( !setjmp(sigill_jmp)
keir@20691 142 && (signal(SIGILL, sigill_handler) != SIG_ERR)
keir@20764 143 && ((version = check_for_xen(1)) != 0) )
keir@20764 144 goto out;
keir@20764 145
keir@20764 146 detected = XEN_NONE;
keir@13874 147
keir@20764 148 out:
keir@20764 149 if ( quiet )
keir@20764 150 /* nothing */;
keir@20764 151 else if ( detected == XEN_NONE )
keir@20764 152 printf("Not running on Xen.\n");
keir@20764 153 else
keir@20764 154 printf("Running in %s context on Xen v%d.%d.\n",
keir@20764 155 (detected == XEN_PV) ? "PV" : "HVM",
keir@20764 156 (uint16_t)(version >> 16), (uint16_t)version);
keir@20764 157
keir@20764 158 return expected && (expected != detected);
keir@13874 159 }