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 <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 25 26class 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 40class 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 73class 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 97controls = [ 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 223for c in controls: 224 c.show() 225