ia64/xen-unstable

view tools/misc/xen-detect.c @ 13883:6a383beedf83

Add example xen-detect.c code for detecting application execution in
Xen PV or HVM contexts, using the Xen CPUID extensions.
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Thu Feb 08 17:04:26 2007 +0000 (2007-02-08)
parents
children 870370439fb9
line source
1 /******************************************************************************
2 * xen_detect.c
3 *
4 * Simple GNU C / POSIX application to detect execution on Xen VMM platform.
5 *
6 * Copyright (c) 2007, XenSource Inc.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to
10 * deal in the Software without restriction, including without limitation the
11 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 * sell copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 */
27 #include <stdint.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 #include <unistd.h>
34 static int pv_context;
36 static void cpuid(uint32_t idx,
37 uint32_t *eax,
38 uint32_t *ebx,
39 uint32_t *ecx,
40 uint32_t *edx)
41 {
42 asm volatile (
43 "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid"
44 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
45 : "0" (idx), "1" (pv_context) );
46 }
48 static int check_for_xen(void)
49 {
50 uint32_t eax, ebx, ecx, edx;
51 char signature[13];
53 cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
54 *(uint32_t *)(signature + 0) = ebx;
55 *(uint32_t *)(signature + 4) = ecx;
56 *(uint32_t *)(signature + 8) = edx;
57 signature[12] = '\0';
59 if ( strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002) )
60 return 0;
62 cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
63 printf("Running in %s context on Xen v%d.%d.\n",
64 pv_context ? "PV" : "HVM", (uint16_t)(eax >> 16), (uint16_t)eax);
65 return 1;
66 }
68 int main(void)
69 {
70 pid_t pid;
71 int status;
72 uint32_t dummy;
74 /* Check for execution in HVM context. */
75 if ( check_for_xen() )
76 return 0;
78 /* Now we check for execution in PV context. */
79 pv_context = 1;
81 /*
82 * Fork a child to test the paravirtualised CPUID instruction.
83 * If executed outside Xen PV context, the extended opcode will fault.
84 */
85 pid = fork();
86 switch ( pid )
87 {
88 case 0:
89 /* Child: test paravirtualised CPUID opcode and then exit cleanly. */
90 cpuid(0x40000000, &dummy, &dummy, &dummy, &dummy);
91 exit(0);
92 case -1:
93 fprintf(stderr, "Fork failed.\n");
94 return 0;
95 }
97 /*
98 * Parent waits for child to terminate and checks for clean exit.
99 * Only if the exit is clean is it safe for us to try the extended CPUID.
100 */
101 waitpid(pid, &status, 0);
102 if ( WIFEXITED(status) && check_for_xen() )
103 return 0;
105 printf("Not running on Xen.\n");
106 return 0;
107 }