Files

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

313 lines
9.9 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
2011-10-07 09:37:57 +02:00
#
# tool for querying VMX capabilities
#
# Copyright 2009-2010 Red Hat, Inc.
#
# Authors:
# Avi Kivity <avi@redhat.com>
#
# This work is licensed under the terms of the GNU GPL, version 2. See
# the COPYING file in the top-level directory.
MSR_IA32_VMX_BASIC = 0x480
MSR_IA32_VMX_PINBASED_CTLS = 0x481
MSR_IA32_VMX_PROCBASED_CTLS = 0x482
MSR_IA32_VMX_EXIT_CTLS = 0x483
MSR_IA32_VMX_ENTRY_CTLS = 0x484
MSR_IA32_VMX_MISC_CTLS = 0x485
MSR_IA32_VMX_PROCBASED_CTLS2 = 0x48B
MSR_IA32_VMX_EPT_VPID_CAP = 0x48C
MSR_IA32_VMX_TRUE_PINBASED_CTLS = 0x48D
MSR_IA32_VMX_TRUE_PROCBASED_CTLS = 0x48E
MSR_IA32_VMX_TRUE_EXIT_CTLS = 0x48F
MSR_IA32_VMX_TRUE_ENTRY_CTLS = 0x490
MSR_IA32_VMX_VMFUNC = 0x491
2022-05-11 18:39:12 +02:00
MSR_IA32_VMX_PROCBASED_CTLS3 = 0x492
2023-11-08 23:20:10 -08:00
MSR_IA32_VMX_EXIT_CTLS2 = 0x493
2011-10-07 09:37:57 +02:00
class msr(object):
def __init__(self):
try:
2017-02-21 09:29:34 +01:00
self.f = open('/dev/cpu/0/msr', 'rb', 0)
2011-10-07 09:37:57 +02:00
except:
2017-02-21 09:29:34 +01:00
self.f = open('/dev/msr0', 'rb', 0)
2011-10-07 09:37:57 +02:00
def read(self, index, default = None):
import struct
self.f.seek(index)
try:
return struct.unpack('Q', self.f.read(8))[0]
except:
return default
class Control(object):
def __init__(self, name, bits, cap_msr, true_cap_msr = None):
self.name = name
self.bits = bits
self.cap_msr = cap_msr
self.true_cap_msr = true_cap_msr
def read2(self, nr):
m = msr()
val = m.read(nr, 0)
return (val & 0xffffffff, val >> 32)
def show(self):
2017-02-21 09:29:34 +01:00
print(self.name)
2019-07-01 16:51:24 +02:00
mb1, cb1 = self.read2(self.cap_msr)
tmb1, tcb1 = 0, 0
2011-10-07 09:37:57 +02:00
if self.true_cap_msr:
2019-07-01 16:51:24 +02:00
tmb1, tcb1 = self.read2(self.true_cap_msr)
2011-10-07 09:37:57 +02:00
for bit in sorted(self.bits.keys()):
2019-07-01 16:51:24 +02:00
zero = not (mb1 & (1 << bit))
one = cb1 & (1 << bit)
true_zero = not (tmb1 & (1 << bit))
true_one = tcb1 & (1 << bit)
2011-10-07 09:37:57 +02:00
s= '?'
if (self.true_cap_msr and true_zero and true_one
and one and not zero):
s = 'default'
elif zero and not one:
s = 'no'
elif one and not zero:
s = 'forced'
elif one and zero:
s = 'yes'
2017-02-21 09:29:34 +01:00
print(' %-40s %s' % (self.bits[bit], s))
2011-10-07 09:37:57 +02:00
2022-05-11 18:39:12 +02:00
# All 64 bits in the tertiary controls MSR are allowed-1
class Allowed1Control(Control):
def read2(self, nr):
m = msr()
val = m.read(nr, 0)
return (0, val)
2011-10-07 09:37:57 +02:00
class Misc(object):
def __init__(self, name, bits, msr):
self.name = name
self.bits = bits
self.msr = msr
def show(self):
2017-02-21 09:29:34 +01:00
print(self.name)
2011-10-07 09:37:57 +02:00
value = msr().read(self.msr, 0)
2017-02-21 09:29:34 +01:00
print(' Hex: 0x%x' % (value))
2011-10-07 09:37:57 +02:00
def first_bit(key):
if type(key) is tuple:
return key[0]
else:
return key
for bits in sorted(self.bits.keys(), key = first_bit):
if type(bits) is tuple:
lo, hi = bits
fmt = int
else:
lo = hi = bits
def fmt(x):
return { True: 'yes', False: 'no' }[x]
v = (value >> lo) & ((1 << (hi - lo + 1)) - 1)
2017-02-21 09:29:34 +01:00
print(' %-40s %s' % (self.bits[bits], fmt(v)))
2011-10-07 09:37:57 +02:00
controls = [
2013-02-13 12:44:06 +01:00
Misc(
name = 'Basic VMX Information',
bits = {
(0, 30): 'Revision',
2013-02-13 12:44:06 +01:00
(32,44): 'VMCS size',
48: 'VMCS restricted to 32 bit addresses',
49: 'Dual-monitor support',
(50, 53): 'VMCS memory type',
54: 'INS/OUTS instruction information',
55: 'IA32_VMX_TRUE_*_CTLS support',
56: 'Skip checks on event error code',
58: 'VMX nested exception support',
2013-02-13 12:44:06 +01:00
},
msr = MSR_IA32_VMX_BASIC,
),
2011-10-07 09:37:57 +02:00
Control(
name = 'pin-based controls',
bits = {
0: 'External interrupt exiting',
3: 'NMI exiting',
5: 'Virtual NMIs',
6: 'Activate VMX-preemption timer',
2013-02-13 12:44:06 +01:00
7: 'Process posted interrupts',
2011-10-07 09:37:57 +02:00
},
cap_msr = MSR_IA32_VMX_PINBASED_CTLS,
true_cap_msr = MSR_IA32_VMX_TRUE_PINBASED_CTLS,
),
Control(
name = 'primary processor-based controls',
bits = {
2: 'Interrupt window exiting',
3: 'Use TSC offsetting',
7: 'HLT exiting',
9: 'INVLPG exiting',
10: 'MWAIT exiting',
11: 'RDPMC exiting',
12: 'RDTSC exiting',
15: 'CR3-load exiting',
16: 'CR3-store exiting',
2022-05-11 18:39:12 +02:00
17: 'Activate tertiary controls',
2011-10-07 09:37:57 +02:00
19: 'CR8-load exiting',
20: 'CR8-store exiting',
21: 'Use TPR shadow',
22: 'NMI-window exiting',
23: 'MOV-DR exiting',
24: 'Unconditional I/O exiting',
25: 'Use I/O bitmaps',
27: 'Monitor trap flag',
28: 'Use MSR bitmaps',
29: 'MONITOR exiting',
30: 'PAUSE exiting',
31: 'Activate secondary control',
},
cap_msr = MSR_IA32_VMX_PROCBASED_CTLS,
true_cap_msr = MSR_IA32_VMX_TRUE_PROCBASED_CTLS,
),
Control(
name = 'secondary processor-based controls',
bits = {
0: 'Virtualize APIC accesses',
1: 'Enable EPT',
2: 'Descriptor-table exiting',
3: 'Enable RDTSCP',
2011-10-07 09:37:57 +02:00
4: 'Virtualize x2APIC mode',
5: 'Enable VPID',
6: 'WBINVD exiting',
7: 'Unrestricted guest',
8: 'APIC register emulation',
9: 'Virtual interrupt delivery',
2011-10-07 09:37:57 +02:00
10: 'PAUSE-loop exiting',
11: 'RDRAND exiting',
12: 'Enable INVPCID',
13: 'Enable VM functions',
14: 'VMCS shadowing',
2017-02-21 09:35:45 +01:00
15: 'Enable ENCLS exiting',
16: 'RDSEED exiting',
2017-02-21 09:35:45 +01:00
17: 'Enable PML',
18: 'EPT-violation #VE',
2017-02-21 09:35:45 +01:00
19: 'Conceal non-root operation from PT',
20: 'Enable XSAVES/XRSTORS',
2017-02-21 09:35:45 +01:00
22: 'Mode-based execute control (XS/XU)',
2019-08-13 08:29:33 +02:00
23: 'Sub-page write permissions',
24: 'GPA translation for PT',
2016-08-25 23:10:25 -04:00
25: 'TSC scaling',
2019-08-13 08:29:33 +02:00
26: 'User wait and pause',
28: 'ENCLV exiting',
2011-10-07 09:37:57 +02:00
},
cap_msr = MSR_IA32_VMX_PROCBASED_CTLS2,
),
2022-05-11 18:39:12 +02:00
Allowed1Control(
name = 'tertiary processor-based controls',
bits = {
4: 'Enable IPI virtualization'
},
cap_msr = MSR_IA32_VMX_PROCBASED_CTLS3,
),
2011-10-07 09:37:57 +02:00
Control(
name = 'VM-Exit controls',
bits = {
2: 'Save debug controls',
9: 'Host address-space size',
12: 'Load IA32_PERF_GLOBAL_CTRL',
15: 'Acknowledge interrupt on exit',
18: 'Save IA32_PAT',
19: 'Load IA32_PAT',
20: 'Save IA32_EFER',
21: 'Load IA32_EFER',
22: 'Save VMX-preemption timer value',
2017-02-21 09:35:45 +01:00
23: 'Clear IA32_BNDCFGS',
24: 'Conceal VM exits from PT',
2019-08-13 08:29:33 +02:00
25: 'Clear IA32_RTIT_CTL',
2023-11-08 23:20:10 -08:00
31: 'Activate secondary VM-exit controls',
2011-10-07 09:37:57 +02:00
},
cap_msr = MSR_IA32_VMX_EXIT_CTLS,
true_cap_msr = MSR_IA32_VMX_TRUE_EXIT_CTLS,
),
2023-11-08 23:20:10 -08:00
Allowed1Control(
name = 'secondary VM-Exit controls',
bits = {
0: 'Save IA32 FRED MSRs',
1: 'Load IA32 FRED MSRs',
},
cap_msr = MSR_IA32_VMX_EXIT_CTLS2,
),
2011-10-07 09:37:57 +02:00
Control(
name = 'VM-Entry controls',
bits = {
2: 'Load debug controls',
9: 'IA-32e mode guest',
2011-10-07 09:37:57 +02:00
10: 'Entry to SMM',
11: 'Deactivate dual-monitor treatment',
13: 'Load IA32_PERF_GLOBAL_CTRL',
14: 'Load IA32_PAT',
15: 'Load IA32_EFER',
2017-02-21 09:35:45 +01:00
16: 'Load IA32_BNDCFGS',
17: 'Conceal VM entries from PT',
2019-08-13 08:29:33 +02:00
18: 'Load IA32_RTIT_CTL',
2023-11-08 23:20:10 -08:00
23: 'Load IA32 FRED MSRs',
2011-10-07 09:37:57 +02:00
},
cap_msr = MSR_IA32_VMX_ENTRY_CTLS,
true_cap_msr = MSR_IA32_VMX_TRUE_ENTRY_CTLS,
),
Misc(
name = 'Miscellaneous data',
bits = {
(0,4): 'VMX-preemption timer scale (log2)',
5: 'Store EFER.LMA into IA-32e mode guest control',
6: 'HLT activity state',
7: 'Shutdown activity state',
8: 'Wait-for-SIPI activity state',
2019-08-13 08:29:33 +02:00
14: 'PT in VMX operation',
15: 'IA32_SMBASE support',
2011-10-07 09:37:57 +02:00
(16,24): 'Number of CR3-target values',
(25,27): 'MSR-load/store count recommendation',
28: 'IA32_SMM_MONITOR_CTL[2] can be set to 1',
29: 'VMWRITE to VM-exit information fields',
2017-02-21 09:35:45 +01:00
30: 'Inject event with insn length=0',
(32,63): 'MSEG revision identifier',
2011-10-07 09:37:57 +02:00
},
msr = MSR_IA32_VMX_MISC_CTLS,
),
Misc(
name = 'VPID and EPT capabilities',
bits = {
0: 'Execute-only EPT translations',
6: 'Page-walk length 4',
2022-02-21 15:53:16 +01:00
7: 'Page-walk length 5',
2011-10-07 09:37:57 +02:00
8: 'Paging-structure memory type UC',
14: 'Paging-structure memory type WB',
16: '2MB EPT pages',
17: '1GB EPT pages',
20: 'INVEPT supported',
21: 'EPT accessed and dirty flags',
2019-08-13 08:29:33 +02:00
22: 'Advanced VM-exit information for EPT violations',
2011-10-07 09:37:57 +02:00
25: 'Single-context INVEPT',
26: 'All-context INVEPT',
32: 'INVVPID supported',
40: 'Individual-address INVVPID',
41: 'Single-context INVVPID',
42: 'All-context INVVPID',
43: 'Single-context-retaining-globals INVVPID',
},
msr = MSR_IA32_VMX_EPT_VPID_CAP,
),
Misc(
name = 'VM Functions',
bits = {
0: 'EPTP Switching',
},
msr = MSR_IA32_VMX_VMFUNC,
),
2011-10-07 09:37:57 +02:00
]
if __name__ == '__main__':
for c in controls:
c.show()