1#!/usr/bin/env python3 2# 3# tool for querying VMX capabilities 4# 5# Copyright 2009-2010 Red Hat, Inc. 6# 7# Authors: 8# Avi Kivity <avi@redhat.com> 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 13MSR_IA32_VMX_BASIC = 0x480 14MSR_IA32_VMX_PINBASED_CTLS = 0x481 15MSR_IA32_VMX_PROCBASED_CTLS = 0x482 16MSR_IA32_VMX_EXIT_CTLS = 0x483 17MSR_IA32_VMX_ENTRY_CTLS = 0x484 18MSR_IA32_VMX_MISC_CTLS = 0x485 19MSR_IA32_VMX_PROCBASED_CTLS2 = 0x48B 20MSR_IA32_VMX_EPT_VPID_CAP = 0x48C 21MSR_IA32_VMX_TRUE_PINBASED_CTLS = 0x48D 22MSR_IA32_VMX_TRUE_PROCBASED_CTLS = 0x48E 23MSR_IA32_VMX_TRUE_EXIT_CTLS = 0x48F 24MSR_IA32_VMX_TRUE_ENTRY_CTLS = 0x490 25MSR_IA32_VMX_VMFUNC = 0x491 26MSR_IA32_VMX_PROCBASED_CTLS3 = 0x492 27MSR_IA32_VMX_EXIT_CTLS2 = 0x493 28 29class msr(object): 30 def __init__(self): 31 try: 32 self.f = open('/dev/cpu/0/msr', 'rb', 0) 33 except: 34 self.f = open('/dev/msr0', 'rb', 0) 35 def read(self, index, default = None): 36 import struct 37 self.f.seek(index) 38 try: 39 return struct.unpack('Q', self.f.read(8))[0] 40 except: 41 return default 42 43class Control(object): 44 def __init__(self, name, bits, cap_msr, true_cap_msr = None): 45 self.name = name 46 self.bits = bits 47 self.cap_msr = cap_msr 48 self.true_cap_msr = true_cap_msr 49 def read2(self, nr): 50 m = msr() 51 val = m.read(nr, 0) 52 return (val & 0xffffffff, val >> 32) 53 def show(self): 54 print(self.name) 55 mb1, cb1 = self.read2(self.cap_msr) 56 tmb1, tcb1 = 0, 0 57 if self.true_cap_msr: 58 tmb1, tcb1 = self.read2(self.true_cap_msr) 59 for bit in sorted(self.bits.keys()): 60 zero = not (mb1 & (1 << bit)) 61 one = cb1 & (1 << bit) 62 true_zero = not (tmb1 & (1 << bit)) 63 true_one = tcb1 & (1 << bit) 64 s= '?' 65 if (self.true_cap_msr and true_zero and true_one 66 and one and not zero): 67 s = 'default' 68 elif zero and not one: 69 s = 'no' 70 elif one and not zero: 71 s = 'forced' 72 elif one and zero: 73 s = 'yes' 74 print(' %-40s %s' % (self.bits[bit], s)) 75 76# All 64 bits in the tertiary controls MSR are allowed-1 77class Allowed1Control(Control): 78 def read2(self, nr): 79 m = msr() 80 val = m.read(nr, 0) 81 return (0, val) 82 83class Misc(object): 84 def __init__(self, name, bits, msr): 85 self.name = name 86 self.bits = bits 87 self.msr = msr 88 def show(self): 89 print(self.name) 90 value = msr().read(self.msr, 0) 91 print(' Hex: 0x%x' % (value)) 92 def first_bit(key): 93 if type(key) is tuple: 94 return key[0] 95 else: 96 return key 97 for bits in sorted(self.bits.keys(), key = first_bit): 98 if type(bits) is tuple: 99 lo, hi = bits 100 fmt = int 101 else: 102 lo = hi = bits 103 def fmt(x): 104 return { True: 'yes', False: 'no' }[x] 105 v = (value >> lo) & ((1 << (hi - lo + 1)) - 1) 106 print(' %-40s %s' % (self.bits[bits], fmt(v))) 107 108controls = [ 109 Misc( 110 name = 'Basic VMX Information', 111 bits = { 112 (0, 30): 'Revision', 113 (32,44): 'VMCS size', 114 48: 'VMCS restricted to 32 bit addresses', 115 49: 'Dual-monitor support', 116 (50, 53): 'VMCS memory type', 117 54: 'INS/OUTS instruction information', 118 55: 'IA32_VMX_TRUE_*_CTLS support', 119 56: 'Skip checks on event error code', 120 58: 'VMX nested exception support', 121 }, 122 msr = MSR_IA32_VMX_BASIC, 123 ), 124 Control( 125 name = 'pin-based controls', 126 bits = { 127 0: 'External interrupt exiting', 128 3: 'NMI exiting', 129 5: 'Virtual NMIs', 130 6: 'Activate VMX-preemption timer', 131 7: 'Process posted interrupts', 132 }, 133 cap_msr = MSR_IA32_VMX_PINBASED_CTLS, 134 true_cap_msr = MSR_IA32_VMX_TRUE_PINBASED_CTLS, 135 ), 136 137 Control( 138 name = 'primary processor-based controls', 139 bits = { 140 2: 'Interrupt window exiting', 141 3: 'Use TSC offsetting', 142 7: 'HLT exiting', 143 9: 'INVLPG exiting', 144 10: 'MWAIT exiting', 145 11: 'RDPMC exiting', 146 12: 'RDTSC exiting', 147 15: 'CR3-load exiting', 148 16: 'CR3-store exiting', 149 17: 'Activate tertiary controls', 150 19: 'CR8-load exiting', 151 20: 'CR8-store exiting', 152 21: 'Use TPR shadow', 153 22: 'NMI-window exiting', 154 23: 'MOV-DR exiting', 155 24: 'Unconditional I/O exiting', 156 25: 'Use I/O bitmaps', 157 27: 'Monitor trap flag', 158 28: 'Use MSR bitmaps', 159 29: 'MONITOR exiting', 160 30: 'PAUSE exiting', 161 31: 'Activate secondary control', 162 }, 163 cap_msr = MSR_IA32_VMX_PROCBASED_CTLS, 164 true_cap_msr = MSR_IA32_VMX_TRUE_PROCBASED_CTLS, 165 ), 166 167 Control( 168 name = 'secondary processor-based controls', 169 bits = { 170 0: 'Virtualize APIC accesses', 171 1: 'Enable EPT', 172 2: 'Descriptor-table exiting', 173 3: 'Enable RDTSCP', 174 4: 'Virtualize x2APIC mode', 175 5: 'Enable VPID', 176 6: 'WBINVD exiting', 177 7: 'Unrestricted guest', 178 8: 'APIC register emulation', 179 9: 'Virtual interrupt delivery', 180 10: 'PAUSE-loop exiting', 181 11: 'RDRAND exiting', 182 12: 'Enable INVPCID', 183 13: 'Enable VM functions', 184 14: 'VMCS shadowing', 185 15: 'Enable ENCLS exiting', 186 16: 'RDSEED exiting', 187 17: 'Enable PML', 188 18: 'EPT-violation #VE', 189 19: 'Conceal non-root operation from PT', 190 20: 'Enable XSAVES/XRSTORS', 191 22: 'Mode-based execute control (XS/XU)', 192 23: 'Sub-page write permissions', 193 24: 'GPA translation for PT', 194 25: 'TSC scaling', 195 26: 'User wait and pause', 196 28: 'ENCLV exiting', 197 }, 198 cap_msr = MSR_IA32_VMX_PROCBASED_CTLS2, 199 ), 200 201 Allowed1Control( 202 name = 'tertiary processor-based controls', 203 bits = { 204 4: 'Enable IPI virtualization' 205 }, 206 cap_msr = MSR_IA32_VMX_PROCBASED_CTLS3, 207 ), 208 209 Control( 210 name = 'VM-Exit controls', 211 bits = { 212 2: 'Save debug controls', 213 9: 'Host address-space size', 214 12: 'Load IA32_PERF_GLOBAL_CTRL', 215 15: 'Acknowledge interrupt on exit', 216 18: 'Save IA32_PAT', 217 19: 'Load IA32_PAT', 218 20: 'Save IA32_EFER', 219 21: 'Load IA32_EFER', 220 22: 'Save VMX-preemption timer value', 221 23: 'Clear IA32_BNDCFGS', 222 24: 'Conceal VM exits from PT', 223 25: 'Clear IA32_RTIT_CTL', 224 31: 'Activate secondary VM-exit controls', 225 }, 226 cap_msr = MSR_IA32_VMX_EXIT_CTLS, 227 true_cap_msr = MSR_IA32_VMX_TRUE_EXIT_CTLS, 228 ), 229 230 Allowed1Control( 231 name = 'secondary VM-Exit controls', 232 bits = { 233 0: 'Save IA32 FRED MSRs', 234 1: 'Load IA32 FRED MSRs', 235 }, 236 cap_msr = MSR_IA32_VMX_EXIT_CTLS2, 237 ), 238 239 Control( 240 name = 'VM-Entry controls', 241 bits = { 242 2: 'Load debug controls', 243 9: 'IA-32e mode guest', 244 10: 'Entry to SMM', 245 11: 'Deactivate dual-monitor treatment', 246 13: 'Load IA32_PERF_GLOBAL_CTRL', 247 14: 'Load IA32_PAT', 248 15: 'Load IA32_EFER', 249 16: 'Load IA32_BNDCFGS', 250 17: 'Conceal VM entries from PT', 251 18: 'Load IA32_RTIT_CTL', 252 23: 'Load IA32 FRED MSRs', 253 }, 254 cap_msr = MSR_IA32_VMX_ENTRY_CTLS, 255 true_cap_msr = MSR_IA32_VMX_TRUE_ENTRY_CTLS, 256 ), 257 258 Misc( 259 name = 'Miscellaneous data', 260 bits = { 261 (0,4): 'VMX-preemption timer scale (log2)', 262 5: 'Store EFER.LMA into IA-32e mode guest control', 263 6: 'HLT activity state', 264 7: 'Shutdown activity state', 265 8: 'Wait-for-SIPI activity state', 266 14: 'PT in VMX operation', 267 15: 'IA32_SMBASE support', 268 (16,24): 'Number of CR3-target values', 269 (25,27): 'MSR-load/store count recommendation', 270 28: 'IA32_SMM_MONITOR_CTL[2] can be set to 1', 271 29: 'VMWRITE to VM-exit information fields', 272 30: 'Inject event with insn length=0', 273 (32,63): 'MSEG revision identifier', 274 }, 275 msr = MSR_IA32_VMX_MISC_CTLS, 276 ), 277 278 Misc( 279 name = 'VPID and EPT capabilities', 280 bits = { 281 0: 'Execute-only EPT translations', 282 6: 'Page-walk length 4', 283 7: 'Page-walk length 5', 284 8: 'Paging-structure memory type UC', 285 14: 'Paging-structure memory type WB', 286 16: '2MB EPT pages', 287 17: '1GB EPT pages', 288 20: 'INVEPT supported', 289 21: 'EPT accessed and dirty flags', 290 22: 'Advanced VM-exit information for EPT violations', 291 25: 'Single-context INVEPT', 292 26: 'All-context INVEPT', 293 32: 'INVVPID supported', 294 40: 'Individual-address INVVPID', 295 41: 'Single-context INVVPID', 296 42: 'All-context INVVPID', 297 43: 'Single-context-retaining-globals INVVPID', 298 }, 299 msr = MSR_IA32_VMX_EPT_VPID_CAP, 300 ), 301 Misc( 302 name = 'VM Functions', 303 bits = { 304 0: 'EPTP Switching', 305 }, 306 msr = MSR_IA32_VMX_VMFUNC, 307 ), 308 ] 309 310if __name__ == '__main__': 311 for c in controls: 312 c.show() 313