xref: /openbmc/qemu/scripts/kvm/vmxcap (revision 1529ae1b)
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