xen detect

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 */
26
27#include <stdint.h>
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <setjmp.h>
32#include <signal.h>
33#include <unistd.h>
34#include <getopt.h>
35
36static void cpuid(uint32_t idx,
37 uint32_t *eax,
38 uint32_t *ebx,
39 uint32_t *ecx,
40 uint32_t *edx,
41 int pv_context)
42{
43 asm volatile (
44 "test %1,%1 ; jz 1f ; ud2a ; .ascii \"xen\" ; 1: cpuid"
45 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
46 : "0" (idx), "1" (pv_context) );
47}
48
49static int check_for_xen(int pv_context)
50{
51 uint32_t eax, ebx, ecx, edx;
52 char signature[13];
53 uint32_t base;
54
55 for ( base = 0x40000000; base < 0x40010000; base += 0x100 )
56 {
57 cpuid(base, &eax, &ebx, &ecx, &edx, pv_context);
58
59 *(uint32_t *)(signature + 0) = ebx;
60 *(uint32_t *)(signature + 4) = ecx;
61 *(uint32_t *)(signature + 8) = edx;
62 signature[12] = '\0';
63
64 if ( !strcmp(" XenVMMXenVMM", signature) && (eax >= (base + 2)) )
65 goto found;
66 }
67
68 return 0;
69
70 found:
71 cpuid(base + 1, &eax, &ebx, &ecx, &edx, pv_context);
72 return 1;
73}
74
75static jmp_buf sigill_jmp;
76void sigill_handler(int sig)
77{
78 longjmp(sigill_jmp, 1);
79}
80
81static void usage(void)
82{
83 printf("Usage: xen_detect [options]\n");
84 printf("Options:\n");
85 printf(" -h, --help Display this information\n");
86 printf(" -q, --quiet Quiesce normal informational output\n");
87 printf(" -P, --pv Exit status 1 if not running as PV guest\n");
88 printf(" -H, --hvm Exit status 1 if not running as HVM guest.\n");
89 printf(" -N, --none Exit status 1 if running on Xen (PV or HVM)\n");
90}
91
92int main(int argc, char **argv)
93{
94 enum { XEN_PV = 1, XEN_HVM = 2, XEN_NONE = 3 } detected = 0, expected = 0;
95 uint32_t version = 0;
96 int ch, quiet = 0;
97
98 const static char sopts[] = "hqPHN";
99 const static struct option lopts[] = {
100 { "help", 0, NULL, 'h' },
101 { "quiet", 0, NULL, 'q' },
102 { "pv", 0, NULL, 'P' },
103 { "hvm", 0, NULL, 'H' },
104 { "none", 0, NULL, 'N' },
105 { 0, 0, 0, 0}
106 };
107
108 while ( (ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1 )
109 {
110 switch ( ch )
111 {
112 case 'q':
113 quiet = 1;
114 break;
115 case 'P':
116 expected = XEN_PV;
117 break;
118 case 'H':
119 expected = XEN_HVM;
120 break;
121 case 'N':
122 expected = XEN_NONE;
123 break;
124 default:
125 usage();
126 exit(1);
127 }
128 }
129
130 /* Check for execution in HVM context. */
131 detected = XEN_HVM;
132 if ( (version = check_for_xen(0)) != 0 )
133 goto out;
134
135 /*
136 * Set up a signal handler to test the paravirtualised CPUID instruction.
137 * If executed outside Xen PV context, the extended opcode will fault, we
138 * will longjmp via the signal handler, and print "Not running on Xen".
139 */
140 detected = XEN_PV;
141 if ( !setjmp(sigill_jmp)
142 && (signal(SIGILL, sigill_handler) != SIG_ERR)
143 && ((version = check_for_xen(1)) != 0) )
144 goto out;
145
146 detected = XEN_NONE;
147
148 out:
149 if ( quiet )
150 /* nothing */;
151 else if ( detected == XEN_NONE )
152 printf("Not running on Xen.\n");
153 else
154 printf("Running in %s context on Xen v%d.%d.\n",
155 (detected == XEN_PV) ? "PV" : "HVM",
156 (uint16_t)(version >> 16), (uint16_t)version);
157
158 return expected && (expected != detected);
159}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值