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