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