|
|
1.1 root 1: #!/usr/bin/python
2: #
3: # tool for querying VMX capabilities
4: #
5: # Copyright 2009-2010 Red Hat, Inc.
6: #
7: # Authors:
8: # Avi Kivity <[email protected]>
9: #
10: # This work is licensed under the terms of the GNU GPL, version 2. See
11: # the COPYING file in the top-level directory.
12:
13: MSR_IA32_VMX_BASIC = 0x480
14: MSR_IA32_VMX_PINBASED_CTLS = 0x481
15: MSR_IA32_VMX_PROCBASED_CTLS = 0x482
16: MSR_IA32_VMX_EXIT_CTLS = 0x483
17: MSR_IA32_VMX_ENTRY_CTLS = 0x484
18: MSR_IA32_VMX_MISC_CTLS = 0x485
19: MSR_IA32_VMX_PROCBASED_CTLS2 = 0x48B
20: MSR_IA32_VMX_EPT_VPID_CAP = 0x48C
21: MSR_IA32_VMX_TRUE_PINBASED_CTLS = 0x48D
22: MSR_IA32_VMX_TRUE_PROCBASED_CTLS = 0x48E
23: MSR_IA32_VMX_TRUE_EXIT_CTLS = 0x48F
24: MSR_IA32_VMX_TRUE_ENTRY_CTLS = 0x490
25:
26: class msr(object):
27: def __init__(self):
28: try:
29: self.f = file('/dev/cpu/0/msr')
30: except:
31: self.f = file('/dev/msr0')
32: def read(self, index, default = None):
33: import struct
34: self.f.seek(index)
35: try:
36: return struct.unpack('Q', self.f.read(8))[0]
37: except:
38: return default
39:
40: class Control(object):
41: def __init__(self, name, bits, cap_msr, true_cap_msr = None):
42: self.name = name
43: self.bits = bits
44: self.cap_msr = cap_msr
45: self.true_cap_msr = true_cap_msr
46: def read2(self, nr):
47: m = msr()
48: val = m.read(nr, 0)
49: return (val & 0xffffffff, val >> 32)
50: def show(self):
51: print self.name
52: mbz, mb1 = self.read2(self.cap_msr)
53: tmbz, tmb1 = 0, 0
54: if self.true_cap_msr:
55: tmbz, tmb1 = self.read2(self.true_cap_msr)
56: for bit in sorted(self.bits.keys()):
57: zero = not (mbz & (1 << bit))
58: one = mb1 & (1 << bit)
59: true_zero = not (tmbz & (1 << bit))
60: true_one = tmb1 & (1 << bit)
61: s= '?'
62: if (self.true_cap_msr and true_zero and true_one
63: and one and not zero):
64: s = 'default'
65: elif zero and not one:
66: s = 'no'
67: elif one and not zero:
68: s = 'forced'
69: elif one and zero:
70: s = 'yes'
71: print ' %-40s %s' % (self.bits[bit], s)
72:
73: class Misc(object):
74: def __init__(self, name, bits, msr):
75: self.name = name
76: self.bits = bits
77: self.msr = msr
78: def show(self):
79: print self.name
80: value = msr().read(self.msr, 0)
81: def first_bit(key):
82: if type(key) is tuple:
83: return key[0]
84: else:
85: return key
86: for bits in sorted(self.bits.keys(), key = first_bit):
87: if type(bits) is tuple:
88: lo, hi = bits
89: fmt = int
90: else:
91: lo = hi = bits
92: def fmt(x):
93: return { True: 'yes', False: 'no' }[x]
94: v = (value >> lo) & ((1 << (hi - lo + 1)) - 1)
95: print ' %-40s %s' % (self.bits[bits], fmt(v))
96:
97: controls = [
98: Control(
99: name = 'pin-based controls',
100: bits = {
101: 0: 'External interrupt exiting',
102: 3: 'NMI exiting',
103: 5: 'Virtual NMIs',
104: 6: 'Activate VMX-preemption timer',
105: },
106: cap_msr = MSR_IA32_VMX_PINBASED_CTLS,
107: true_cap_msr = MSR_IA32_VMX_TRUE_PINBASED_CTLS,
108: ),
109:
110: Control(
111: name = 'primary processor-based controls',
112: bits = {
113: 2: 'Interrupt window exiting',
114: 3: 'Use TSC offsetting',
115: 7: 'HLT exiting',
116: 9: 'INVLPG exiting',
117: 10: 'MWAIT exiting',
118: 11: 'RDPMC exiting',
119: 12: 'RDTSC exiting',
120: 15: 'CR3-load exiting',
121: 16: 'CR3-store exiting',
122: 19: 'CR8-load exiting',
123: 20: 'CR8-store exiting',
124: 21: 'Use TPR shadow',
125: 22: 'NMI-window exiting',
126: 23: 'MOV-DR exiting',
127: 24: 'Unconditional I/O exiting',
128: 25: 'Use I/O bitmaps',
129: 27: 'Monitor trap flag',
130: 28: 'Use MSR bitmaps',
131: 29: 'MONITOR exiting',
132: 30: 'PAUSE exiting',
133: 31: 'Activate secondary control',
134: },
135: cap_msr = MSR_IA32_VMX_PROCBASED_CTLS,
136: true_cap_msr = MSR_IA32_VMX_TRUE_PROCBASED_CTLS,
137: ),
138:
139: Control(
140: name = 'secondary processor-based controls',
141: bits = {
142: 0: 'Virtualize APIC accesses',
143: 1: 'Enable EPT',
144: 2: 'Descriptor-table exiting',
145: 4: 'Virtualize x2APIC mode',
146: 5: 'Enable VPID',
147: 6: 'WBINVD exiting',
148: 7: 'Unrestricted guest',
149: 10: 'PAUSE-loop exiting',
150: },
151: cap_msr = MSR_IA32_VMX_PROCBASED_CTLS2,
152: ),
153:
154: Control(
155: name = 'VM-Exit controls',
156: bits = {
157: 2: 'Save debug controls',
158: 9: 'Host address-space size',
159: 12: 'Load IA32_PERF_GLOBAL_CTRL',
160: 15: 'Acknowledge interrupt on exit',
161: 18: 'Save IA32_PAT',
162: 19: 'Load IA32_PAT',
163: 20: 'Save IA32_EFER',
164: 21: 'Load IA32_EFER',
165: 22: 'Save VMX-preemption timer value',
166: },
167: cap_msr = MSR_IA32_VMX_EXIT_CTLS,
168: true_cap_msr = MSR_IA32_VMX_TRUE_EXIT_CTLS,
169: ),
170:
171: Control(
172: name = 'VM-Entry controls',
173: bits = {
174: 2: 'Load debug controls',
175: 9: 'IA-64 mode guest',
176: 10: 'Entry to SMM',
177: 11: 'Deactivate dual-monitor treatment',
178: 13: 'Load IA32_PERF_GLOBAL_CTRL',
179: 14: 'Load IA32_PAT',
180: 15: 'Load IA32_EFER',
181: },
182: cap_msr = MSR_IA32_VMX_ENTRY_CTLS,
183: true_cap_msr = MSR_IA32_VMX_TRUE_ENTRY_CTLS,
184: ),
185:
186: Misc(
187: name = 'Miscellaneous data',
188: bits = {
189: (0,4): 'VMX-preemption timer scale (log2)',
190: 5: 'Store EFER.LMA into IA-32e mode guest control',
191: 6: 'HLT activity state',
192: 7: 'Shutdown activity state',
193: 8: 'Wait-for-SIPI activity state',
194: (16,24): 'Number of CR3-target values',
195: (25,27): 'MSR-load/store count recommenation',
196: (32,62): 'MSEG revision identifier',
197: },
198: msr = MSR_IA32_VMX_MISC_CTLS,
199: ),
200:
201: Misc(
202: name = 'VPID and EPT capabilities',
203: bits = {
204: 0: 'Execute-only EPT translations',
205: 6: 'Page-walk length 4',
206: 8: 'Paging-structure memory type UC',
207: 14: 'Paging-structure memory type WB',
208: 16: '2MB EPT pages',
209: 17: '1GB EPT pages',
210: 20: 'INVEPT supported',
211: 25: 'Single-context INVEPT',
212: 26: 'All-context INVEPT',
213: 32: 'INVVPID supported',
214: 40: 'Individual-address INVVPID',
215: 41: 'Single-context INVVPID',
216: 42: 'All-context INVVPID',
217: 43: 'Single-context-retaining-globals INVVPID',
218: },
219: msr = MSR_IA32_VMX_EPT_VPID_CAP,
220: ),
221: ]
222:
223: for c in controls:
224: c.show()
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.