From f505a4d74aae6fc8bb5502a6038b5f671aa97713 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 13 Feb 2013 12:43:10 +0100 Subject: [PATCH 1/5] vmxcap: Open MSR file in unbuffered mode Python may otherwise decide to to read larger chunks, applying the seek only on the software buffer. This will return results from the wrong MSRs. Signed-off-by: Jan Kiszka Signed-off-by: Gleb Natapov --- scripts/kvm/vmxcap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap index 0b23f7795a..6363e7368f 100755 --- a/scripts/kvm/vmxcap +++ b/scripts/kvm/vmxcap @@ -27,9 +27,9 @@ MSR_IA32_VMX_VMFUNC = 0x491 class msr(object): def __init__(self): try: - self.f = file('/dev/cpu/0/msr') + self.f = open('/dev/cpu/0/msr', 'r', 0) except: - self.f = file('/dev/msr0') + self.f = open('/dev/msr0', 'r', 0) def read(self, index, default = None): import struct self.f.seek(index) From ea4ee28399f8ffee4eed2d724c28d2d9879b22fa Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 13 Feb 2013 12:44:06 +0100 Subject: [PATCH 2/5] vmxcap: Augment reported information Parse the Basic VMX Information MSR and add the bit for the new posted interrupts. Signed-off-by: Jan Kiszka Signed-off-by: Gleb Natapov --- scripts/kvm/vmxcap | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap index 6363e7368f..a1a44a04b3 100755 --- a/scripts/kvm/vmxcap +++ b/scripts/kvm/vmxcap @@ -96,6 +96,19 @@ class Misc(object): print ' %-40s %s' % (self.bits[bits], fmt(v)) controls = [ + Misc( + name = 'Basic VMX Information', + bits = { + (0, 31): 'Revision', + (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', + }, + msr = MSR_IA32_VMX_BASIC, + ), Control( name = 'pin-based controls', bits = { @@ -103,6 +116,7 @@ controls = [ 3: 'NMI exiting', 5: 'Virtual NMIs', 6: 'Activate VMX-preemption timer', + 7: 'Process posted interrupts', }, cap_msr = MSR_IA32_VMX_PINBASED_CTLS, true_cap_msr = MSR_IA32_VMX_TRUE_PINBASED_CTLS, From 614413f7f9a88d97ab40ecabd1c7920fb288f820 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 18 Feb 2013 07:56:54 +0100 Subject: [PATCH 3/5] vmxcap: Report APIC register emulation and RDTSCP control Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- scripts/kvm/vmxcap | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap index a1a44a04b3..a79f816fe9 100755 --- a/scripts/kvm/vmxcap +++ b/scripts/kvm/vmxcap @@ -157,10 +157,12 @@ controls = [ 0: 'Virtualize APIC accesses', 1: 'Enable EPT', 2: 'Descriptor-table exiting', + 3: 'Enable RDTSCP', 4: 'Virtualize x2APIC mode', 5: 'Enable VPID', 6: 'WBINVD exiting', 7: 'Unrestricted guest', + 8: 'APIC register emulation', 9: 'Virtual interrupt delivery', 10: 'PAUSE-loop exiting', 11: 'RDRAND exiting', From 917367aa968fd4fef29d340e0c7ec8c608dffaab Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Tue, 19 Feb 2013 23:27:20 -0300 Subject: [PATCH 4/5] target-i386: kvm: save/restore steal time MSR Read and write steal time MSR, so that reporting is functional across migration. Signed-off-by: Marcelo Tosatti Signed-off-by: Gleb Natapov --- target-i386/cpu.h | 1 + target-i386/kvm.c | 13 +++++++++++++ target-i386/machine.c | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index cf1b05c28c..a1614e8e50 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -803,6 +803,7 @@ typedef struct CPUX86State { #endif uint64_t system_time_msr; uint64_t wall_clock_msr; + uint64_t steal_time_msr; uint64_t async_pf_en_msr; uint64_t pv_eoi_en_msr; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 397afebecb..0e7cc8113f 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -68,6 +68,7 @@ static bool has_msr_tsc_deadline; static bool has_msr_async_pf_en; static bool has_msr_pv_eoi_en; static bool has_msr_misc_enable; +static bool has_msr_kvm_steal_time; static int lm_capable_kernel; bool kvm_allows_irq0_override(void) @@ -507,6 +508,8 @@ int kvm_arch_init_vcpu(CPUState *cs) has_msr_pv_eoi_en = c->eax & (1 << KVM_FEATURE_PV_EOI); + has_msr_kvm_steal_time = c->eax & (1 << KVM_FEATURE_STEAL_TIME); + cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); for (i = 0; i <= limit; i++) { @@ -1107,6 +1110,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level) kvm_msr_entry_set(&msrs[n++], MSR_KVM_PV_EOI_EN, env->pv_eoi_en_msr); } + if (has_msr_kvm_steal_time) { + kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME, + env->steal_time_msr); + } if (hyperv_hypercall_available()) { kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0); kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0); @@ -1360,6 +1367,9 @@ static int kvm_get_msrs(X86CPU *cpu) if (has_msr_pv_eoi_en) { msrs[n++].index = MSR_KVM_PV_EOI_EN; } + if (has_msr_kvm_steal_time) { + msrs[n++].index = MSR_KVM_STEAL_TIME; + } if (env->mcg_cap) { msrs[n++].index = MSR_MCG_STATUS; @@ -1445,6 +1455,9 @@ static int kvm_get_msrs(X86CPU *cpu) case MSR_KVM_PV_EOI_EN: env->pv_eoi_en_msr = msrs[i].data; break; + case MSR_KVM_STEAL_TIME: + env->steal_time_msr = msrs[i].data; + break; } } diff --git a/target-i386/machine.c b/target-i386/machine.c index ee85e57435..3659db9e94 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -292,6 +292,24 @@ static bool pv_eoi_msr_needed(void *opaque) return cpu->env.pv_eoi_en_msr != 0; } +static bool steal_time_msr_needed(void *opaque) +{ + CPUX86State *cpu = opaque; + + return cpu->steal_time_msr != 0; +} + +static const VMStateDescription vmstate_steal_time_msr = { + .name = "cpu/steal_time_msr", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(steal_time_msr, CPUX86State), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_async_pf_msr = { .name = "cpu/async_pf_msr", .version_id = 1, @@ -502,6 +520,9 @@ const VMStateDescription vmstate_x86_cpu = { } , { .vmsd = &vmstate_pv_eoi_msr, .needed = pv_eoi_msr_needed, + } , { + .vmsd = &vmstate_steal_time_msr, + .needed = steal_time_msr_needed, } , { .vmsd = &vmstate_fpop_ip_dp, .needed = fpop_ip_dp_needed, From 007e986ff2dd140348e76feb21cde1a51ce6c5b4 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sun, 17 Mar 2013 11:45:50 +0100 Subject: [PATCH 5/5] vmxcap: Update according to SDM of January 2013 This adds reporting of VMCS shadowing, #VE, IA32_SMBASE, unrestricted VMWRITE and fixes the range of the MSEG revision ID. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- scripts/kvm/vmxcap | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap index a79f816fe9..c90eda497a 100755 --- a/scripts/kvm/vmxcap +++ b/scripts/kvm/vmxcap @@ -168,6 +168,8 @@ controls = [ 11: 'RDRAND exiting', 12: 'Enable INVPCID', 13: 'Enable VM functions', + 14: 'VMCS shadowing', + 18: 'EPT-violation #VE' }, cap_msr = MSR_IA32_VMX_PROCBASED_CTLS2, ), @@ -212,10 +214,12 @@ controls = [ 6: 'HLT activity state', 7: 'Shutdown activity state', 8: 'Wait-for-SIPI activity state', + 15: 'IA32_SMBASE support', (16,24): 'Number of CR3-target values', (25,27): 'MSR-load/store count recommenation', 28: 'IA32_SMM_MONITOR_CTL[2] can be set to 1', - (32,62): 'MSEG revision identifier', + 29: 'VMWRITE to VM-exit information fields', + (32,63): 'MSEG revision identifier', }, msr = MSR_IA32_VMX_MISC_CTLS, ),