天天看點

xen detect

1

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

131 detected = XEN_HVM;

132 if ( (version = check_for_xen(0)) != 0 )

133 goto out;

134

135

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 ;

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}

繼續閱讀