diff mbox

Add tool to query vmx capabilities

Message ID 1251819755-27638-1-git-send-email-avi@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Avi Kivity Sept. 1, 2009, 3:42 p.m. UTC
This should really be in the kernel, but there are too many of them.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 kvm/scripts/vmxcap |  151 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 151 insertions(+), 0 deletions(-)
 create mode 100755 kvm/scripts/vmxcap

Comments

Jan Kiszka Sept. 1, 2009, 4:07 p.m. UTC | #1
Avi Kivity wrote:
> This should really be in the kernel, but there are too many of them.

Nice (and said as my host cpu has so many 'no').

> 
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
>  kvm/scripts/vmxcap |  151 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 151 insertions(+), 0 deletions(-)
>  create mode 100755 kvm/scripts/vmxcap
> 
> diff --git a/kvm/scripts/vmxcap b/kvm/scripts/vmxcap
> new file mode 100755
> index 0000000..ff22d8c
> --- /dev/null
> +++ b/kvm/scripts/vmxcap
> @@ -0,0 +1,151 @@
> +#!/usr/bin/python
> +
> +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_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
> +
> +class msr(object):
> +    def __init__(self):
> +        self.f = file('/dev/msr0')

For me this is /dev/cpu/0/msr.

Maybe:
        try:
            self.f = file('/dev/msr0')
        except:
            self.f = file('/dev/cpu/0/msr')

Jan

> +    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):
> +        print self.name
> +        mbz, mb1 = self.read2(self.cap_msr)
> +        tmbz, tmb1 = 0, 0
> +        if self.true_cap_msr:
> +            tmbz, tmb1 = self.read2(self.true_cap_msr)
> +        for bit in sorted(self.bits.keys()):
> +            zero = not (mbz & (1 << bit))
> +            one = mb1 & (1 << bit)
> +            true_zero = not (tmbz & (1 << bit))
> +            true_one = tmb1 & (1 << bit)
> +            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'
> +            print '  %-40s %s' % (self.bits[bit], s)
> +
> +controls = [
> +    Control(
> +        name = 'pin-based controls',
> +        bits = {
> +            0: 'External interrupt exiting',
> +            3: 'NMI exiting',
> +            5: 'Virtual NMIs',
> +            6: 'Activate VMX-preemption timer',
> +            7: 'Unrestricted guest',
> +            },
> +        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',
> +            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',
> +            4: 'Virtualize x2APIC mode',
> +            5: 'Enable VPID',
> +            6: 'WBINVD exiting',
> +            },
> +        cap_msr = MSR_IA32_VMX_PROCBASED_CTLS2,
> +        ),
> +
> +    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',
> +            },
> +        cap_msr = MSR_IA32_VMX_EXIT_CTLS,
> +        true_cap_msr = MSR_IA32_VMX_TRUE_EXIT_CTLS,
> +        ),
> +
> +    Control(
> +        name = 'VM-Entry controls',
> +        bits = {
> +            2: 'Load debug controls',
> +            9: 'IA-64 mode guest',
> +            10: 'Entry to SMM',
> +            11: 'Deactivate dual-monitor treatment',
> +            13: 'Load IA32_PERF_GLOBAL_CTRL',
> +            14: 'Load IA32_PAT',
> +            15: 'Load IA32_EFER',
> +            },
> +        cap_msr = MSR_IA32_VMX_ENTRY_CTLS,
> +        true_cap_msr = MSR_IA32_VMX_TRUE_ENTRY_CTLS,
> +        ),
> +    ]
> +
> +for c in controls:
> +    c.show()
> +
> +
Avi Kivity Sept. 1, 2009, 4:15 p.m. UTC | #2
On 09/01/2009 07:07 PM, Jan Kiszka wrote:

> For me this is /dev/cpu/0/msr.
>
> Maybe:
>          try:
>              self.f = file('/dev/msr0')
>          except:
>              self.f = file('/dev/cpu/0/msr')
>
>    

I have /dev/cpu as well, I think that's the canonical location.  Better 
to support both though.  Hurray for stable interfaces!
diff mbox

Patch

diff --git a/kvm/scripts/vmxcap b/kvm/scripts/vmxcap
new file mode 100755
index 0000000..ff22d8c
--- /dev/null
+++ b/kvm/scripts/vmxcap
@@ -0,0 +1,151 @@ 
+#!/usr/bin/python
+
+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_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
+
+class msr(object):
+    def __init__(self):
+        self.f = file('/dev/msr0')
+    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):
+        print self.name
+        mbz, mb1 = self.read2(self.cap_msr)
+        tmbz, tmb1 = 0, 0
+        if self.true_cap_msr:
+            tmbz, tmb1 = self.read2(self.true_cap_msr)
+        for bit in sorted(self.bits.keys()):
+            zero = not (mbz & (1 << bit))
+            one = mb1 & (1 << bit)
+            true_zero = not (tmbz & (1 << bit))
+            true_one = tmb1 & (1 << bit)
+            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'
+            print '  %-40s %s' % (self.bits[bit], s)
+
+controls = [
+    Control(
+        name = 'pin-based controls',
+        bits = {
+            0: 'External interrupt exiting',
+            3: 'NMI exiting',
+            5: 'Virtual NMIs',
+            6: 'Activate VMX-preemption timer',
+            7: 'Unrestricted guest',
+            },
+        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',
+            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',
+            4: 'Virtualize x2APIC mode',
+            5: 'Enable VPID',
+            6: 'WBINVD exiting',
+            },
+        cap_msr = MSR_IA32_VMX_PROCBASED_CTLS2,
+        ),
+
+    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',
+            },
+        cap_msr = MSR_IA32_VMX_EXIT_CTLS,
+        true_cap_msr = MSR_IA32_VMX_TRUE_EXIT_CTLS,
+        ),
+
+    Control(
+        name = 'VM-Entry controls',
+        bits = {
+            2: 'Load debug controls',
+            9: 'IA-64 mode guest',
+            10: 'Entry to SMM',
+            11: 'Deactivate dual-monitor treatment',
+            13: 'Load IA32_PERF_GLOBAL_CTRL',
+            14: 'Load IA32_PAT',
+            15: 'Load IA32_EFER',
+            },
+        cap_msr = MSR_IA32_VMX_ENTRY_CTLS,
+        true_cap_msr = MSR_IA32_VMX_TRUE_ENTRY_CTLS,
+        ),
+    ]
+
+for c in controls:
+    c.show()
+
+