qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

vmxcap (9637B)


      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 
     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 MSR_IA32_VMX_VMFUNC = 0x491
     26 MSR_IA32_VMX_PROCBASED_CTLS3 = 0x492
     27 
     28 class 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 
     42 class 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
     76 class Allowed1Control(Control):
     77     def read2(self, nr):
     78         m = msr()
     79         val = m.read(nr, 0)
     80         return (0, val)
     81 
     82 class 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 
    107 controls = [
    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             },
    119         msr = MSR_IA32_VMX_BASIC,
    120         ),
    121     Control(
    122         name = 'pin-based controls',
    123         bits = {
    124             0: 'External interrupt exiting',
    125             3: 'NMI exiting',
    126             5: 'Virtual NMIs',
    127             6: 'Activate VMX-preemption timer',
    128             7: 'Process posted interrupts',
    129             },
    130         cap_msr = MSR_IA32_VMX_PINBASED_CTLS,
    131         true_cap_msr = MSR_IA32_VMX_TRUE_PINBASED_CTLS,
    132         ),
    133 
    134     Control(
    135         name = 'primary processor-based controls',
    136         bits = {
    137             2: 'Interrupt window exiting',
    138             3: 'Use TSC offsetting',
    139             7: 'HLT exiting',
    140             9: 'INVLPG exiting',
    141             10: 'MWAIT exiting',
    142             11: 'RDPMC exiting',
    143             12: 'RDTSC exiting',
    144             15: 'CR3-load exiting',
    145             16: 'CR3-store exiting',
    146             17: 'Activate tertiary controls',
    147             19: 'CR8-load exiting',
    148             20: 'CR8-store exiting',
    149             21: 'Use TPR shadow',
    150             22: 'NMI-window exiting',
    151             23: 'MOV-DR exiting',
    152             24: 'Unconditional I/O exiting',
    153             25: 'Use I/O bitmaps',
    154             27: 'Monitor trap flag',
    155             28: 'Use MSR bitmaps',
    156             29: 'MONITOR exiting',
    157             30: 'PAUSE exiting',
    158             31: 'Activate secondary control',
    159             },
    160         cap_msr = MSR_IA32_VMX_PROCBASED_CTLS,
    161         true_cap_msr = MSR_IA32_VMX_TRUE_PROCBASED_CTLS,
    162         ),
    163 
    164     Control(
    165         name = 'secondary processor-based controls',
    166         bits = {
    167             0: 'Virtualize APIC accesses',
    168             1: 'Enable EPT',
    169             2: 'Descriptor-table exiting',
    170             3: 'Enable RDTSCP',
    171             4: 'Virtualize x2APIC mode',
    172             5: 'Enable VPID',
    173             6: 'WBINVD exiting',
    174             7: 'Unrestricted guest',
    175             8: 'APIC register emulation',
    176             9: 'Virtual interrupt delivery',
    177             10: 'PAUSE-loop exiting',
    178             11: 'RDRAND exiting',
    179             12: 'Enable INVPCID',
    180             13: 'Enable VM functions',
    181             14: 'VMCS shadowing',
    182             15: 'Enable ENCLS exiting',
    183             16: 'RDSEED exiting',
    184             17: 'Enable PML',
    185             18: 'EPT-violation #VE',
    186             19: 'Conceal non-root operation from PT',
    187             20: 'Enable XSAVES/XRSTORS',
    188             22: 'Mode-based execute control (XS/XU)',
    189             23: 'Sub-page write permissions',
    190             24: 'GPA translation for PT',
    191             25: 'TSC scaling',
    192             26: 'User wait and pause',
    193             28: 'ENCLV exiting',
    194             },
    195         cap_msr = MSR_IA32_VMX_PROCBASED_CTLS2,
    196         ),
    197 
    198     Allowed1Control(
    199         name = 'tertiary processor-based controls',
    200         bits = {
    201             4: 'Enable IPI virtualization'
    202             },
    203         cap_msr = MSR_IA32_VMX_PROCBASED_CTLS3,
    204         ),
    205 
    206     Control(
    207         name = 'VM-Exit controls',
    208         bits = {
    209             2: 'Save debug controls',
    210             9: 'Host address-space size',
    211             12: 'Load IA32_PERF_GLOBAL_CTRL',
    212             15: 'Acknowledge interrupt on exit',
    213             18: 'Save IA32_PAT',
    214             19: 'Load IA32_PAT',
    215             20: 'Save IA32_EFER',
    216             21: 'Load IA32_EFER',
    217             22: 'Save VMX-preemption timer value',
    218             23: 'Clear IA32_BNDCFGS',
    219             24: 'Conceal VM exits from PT',
    220             25: 'Clear IA32_RTIT_CTL',
    221             },
    222         cap_msr = MSR_IA32_VMX_EXIT_CTLS,
    223         true_cap_msr = MSR_IA32_VMX_TRUE_EXIT_CTLS,
    224         ),
    225 
    226     Control(
    227         name = 'VM-Entry controls',
    228         bits = {
    229             2: 'Load debug controls',
    230             9: 'IA-32e mode guest',
    231             10: 'Entry to SMM',
    232             11: 'Deactivate dual-monitor treatment',
    233             13: 'Load IA32_PERF_GLOBAL_CTRL',
    234             14: 'Load IA32_PAT',
    235             15: 'Load IA32_EFER',
    236             16: 'Load IA32_BNDCFGS',
    237             17: 'Conceal VM entries from PT',
    238             18: 'Load IA32_RTIT_CTL',
    239             },
    240         cap_msr = MSR_IA32_VMX_ENTRY_CTLS,
    241         true_cap_msr = MSR_IA32_VMX_TRUE_ENTRY_CTLS,
    242         ),
    243 
    244     Misc(
    245         name = 'Miscellaneous data',
    246         bits = {
    247             (0,4): 'VMX-preemption timer scale (log2)',
    248             5: 'Store EFER.LMA into IA-32e mode guest control',
    249             6: 'HLT activity state',
    250             7: 'Shutdown activity state',
    251             8: 'Wait-for-SIPI activity state',
    252             14: 'PT in VMX operation',
    253             15: 'IA32_SMBASE support',
    254             (16,24): 'Number of CR3-target values',
    255             (25,27): 'MSR-load/store count recommendation',
    256             28: 'IA32_SMM_MONITOR_CTL[2] can be set to 1',
    257             29: 'VMWRITE to VM-exit information fields',
    258             30: 'Inject event with insn length=0',
    259             (32,63): 'MSEG revision identifier',
    260             },
    261         msr = MSR_IA32_VMX_MISC_CTLS,
    262         ),
    263 
    264     Misc(
    265         name = 'VPID and EPT capabilities',
    266         bits = {
    267             0: 'Execute-only EPT translations',
    268             6: 'Page-walk length 4',
    269             7: 'Page-walk length 5',
    270             8: 'Paging-structure memory type UC',
    271             14: 'Paging-structure memory type WB',
    272             16: '2MB EPT pages',
    273             17: '1GB EPT pages',
    274             20: 'INVEPT supported',
    275             21: 'EPT accessed and dirty flags',
    276             22: 'Advanced VM-exit information for EPT violations',
    277             25: 'Single-context INVEPT',
    278             26: 'All-context INVEPT',
    279             32: 'INVVPID supported',
    280             40: 'Individual-address INVVPID',
    281             41: 'Single-context INVVPID',
    282             42: 'All-context INVVPID',
    283             43: 'Single-context-retaining-globals INVVPID',
    284             },
    285         msr = MSR_IA32_VMX_EPT_VPID_CAP,
    286         ),
    287     Misc(
    288         name = 'VM Functions',
    289         bits = {
    290             0: 'EPTP Switching',
    291             },
    292         msr = MSR_IA32_VMX_VMFUNC,
    293         ),
    294     ]
    295 
    296 if __name__ == '__main__':
    297     for c in controls:
    298         c.show()