From 744b8a9440fa2bd78ae64861667337439e25a6dc Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Wed, 16 Sep 2015 12:59:42 +0300 Subject: target-i386/kvm: Hyper-V HV_X64_MSR_RESET support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HV_X64_MSR_RESET msr is used by Hyper-V based Windows guest to reset guest VM by hypervisor. This msr is stateless so no migration/fetch/update is required. This code checks cpu option "hv-reset" and support by kernel. If both conditions are met appropriate Hyper-V features cpuid bit is set. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Richard Henderson CC: Eduardo Habkost CC: "Andreas Färber" CC: Marcelo Tosatti Message-Id: <1442397584-16698-2-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini --- target-i386/cpu.c | 1 + 1 file changed, 1 insertion(+) (limited to 'target-i386/cpu.c') diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 05d7f26bf1..230ecf42fd 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3140,6 +3140,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false), DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false), DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false), + DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false), DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false), DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false), DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), -- cgit 1.4.1 From 8c145d7ca9b4267d2ec1eabe801c6b2aee636f1f Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Wed, 16 Sep 2015 12:59:43 +0300 Subject: target-i386/kvm: set Hyper-V features cpuid bit HV_X64_MSR_VP_INDEX_AVAILABLE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hyper-V features bit HV_X64_MSR_VP_INDEX_AVAILABLE value is based on cpu option "hv-vpindex" and kernel support of HV_X64_MSR_VP_INDEX. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Richard Henderson CC: Eduardo Habkost CC: "Andreas Färber" CC: Marcelo Tosatti Message-Id: <1442397584-16698-3-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini --- target-i386/cpu-qom.h | 1 + target-i386/cpu.c | 1 + target-i386/kvm.c | 11 ++++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'target-i386/cpu.c') diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index ed8fd18457..8b5439b9d1 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -91,6 +91,7 @@ typedef struct X86CPU { bool hyperv_time; bool hyperv_crash; bool hyperv_reset; + bool hyperv_vpindex; bool check_cpuid; bool enforce_cpuid; bool expose_kvm; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 230ecf42fd..741b94e9cd 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3141,6 +3141,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false), DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false), DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false), + DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false), DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false), DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false), DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 401a2f3c3f..4d5ff9a253 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -83,6 +83,7 @@ static bool has_msr_hv_vapic; static bool has_msr_hv_tsc; static bool has_msr_hv_crash; static bool has_msr_hv_reset; +static bool has_msr_hv_vpindex; static bool has_msr_mtrr; static bool has_msr_xss; @@ -462,7 +463,8 @@ static bool hyperv_enabled(X86CPU *cpu) cpu->hyperv_time || cpu->hyperv_relaxed_timing || cpu->hyperv_crash || - cpu->hyperv_reset); + cpu->hyperv_reset || + cpu->hyperv_vpindex); } static Error *invtsc_mig_blocker; @@ -534,6 +536,9 @@ int kvm_arch_init_vcpu(CPUState *cs) if (cpu->hyperv_reset && has_msr_hv_reset) { c->eax |= HV_X64_MSR_RESET_AVAILABLE; } + if (cpu->hyperv_vpindex && has_msr_hv_vpindex) { + c->eax |= HV_X64_MSR_VP_INDEX_AVAILABLE; + } c = &cpuid_data.entries[cpuid_i++]; c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; if (cpu->hyperv_relaxed_timing) { @@ -866,6 +871,10 @@ static int kvm_get_supported_msrs(KVMState *s) has_msr_hv_reset = true; continue; } + if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_INDEX) { + has_msr_hv_vpindex = true; + continue; + } } } -- cgit 1.4.1 From 46eb8f98f2ce402e384d60ddd15020720994c7ca Mon Sep 17 00:00:00 2001 From: Andrey Smetanin Date: Wed, 16 Sep 2015 12:59:44 +0300 Subject: target-i386/kvm: Hyper-V HV_X64_MSR_VP_RUNTIME support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HV_X64_MSR_VP_RUNTIME msr used by guest to get "the time the virtual processor consumes running guest code, and the time the associated logical processor spends running hypervisor code on behalf of that guest." Calculation of that time is performed by task_cputime_adjusted() for vcpu task by KVM side. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev CC: Paolo Bonzini CC: Richard Henderson CC: Eduardo Habkost CC: "Andreas Färber" CC: Marcelo Tosatti Message-Id: <1442397584-16698-4-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini --- target-i386/cpu-qom.h | 1 + target-i386/cpu.c | 1 + target-i386/cpu.h | 1 + target-i386/kvm.c | 21 ++++++++++++++++++++- target-i386/machine.c | 20 ++++++++++++++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) (limited to 'target-i386/cpu.c') diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 8b5439b9d1..9eab41b19e 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -92,6 +92,7 @@ typedef struct X86CPU { bool hyperv_crash; bool hyperv_reset; bool hyperv_vpindex; + bool hyperv_runtime; bool check_cpuid; bool enforce_cpuid; bool expose_kvm; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 741b94e9cd..d2b06195f0 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3142,6 +3142,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false), DEFINE_PROP_BOOL("hv-reset", X86CPU, hyperv_reset, false), DEFINE_PROP_BOOL("hv-vpindex", X86CPU, hyperv_vpindex, false), + DEFINE_PROP_BOOL("hv-runtime", X86CPU, hyperv_runtime, false), DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false), DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false), DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true), diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 54d9d50140..a395b4b07a 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -911,6 +911,7 @@ typedef struct CPUX86State { uint64_t msr_hv_vapic; uint64_t msr_hv_tsc; uint64_t msr_hv_crash_params[HV_X64_MSR_CRASH_PARAMS]; + uint64_t msr_hv_runtime; /* exception/interrupt handling */ int error_code; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 4d5ff9a253..65cd944f0e 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -84,6 +84,7 @@ static bool has_msr_hv_tsc; static bool has_msr_hv_crash; static bool has_msr_hv_reset; static bool has_msr_hv_vpindex; +static bool has_msr_hv_runtime; static bool has_msr_mtrr; static bool has_msr_xss; @@ -464,7 +465,8 @@ static bool hyperv_enabled(X86CPU *cpu) cpu->hyperv_relaxed_timing || cpu->hyperv_crash || cpu->hyperv_reset || - cpu->hyperv_vpindex); + cpu->hyperv_vpindex || + cpu->hyperv_runtime); } static Error *invtsc_mig_blocker; @@ -539,6 +541,9 @@ int kvm_arch_init_vcpu(CPUState *cs) if (cpu->hyperv_vpindex && has_msr_hv_vpindex) { c->eax |= HV_X64_MSR_VP_INDEX_AVAILABLE; } + if (cpu->hyperv_runtime && has_msr_hv_runtime) { + c->eax |= HV_X64_MSR_VP_RUNTIME_AVAILABLE; + } c = &cpuid_data.entries[cpuid_i++]; c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; if (cpu->hyperv_relaxed_timing) { @@ -875,6 +880,10 @@ static int kvm_get_supported_msrs(KVMState *s) has_msr_hv_vpindex = true; continue; } + if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_RUNTIME) { + has_msr_hv_runtime = true; + continue; + } } } @@ -1420,6 +1429,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level) kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_CTL, HV_X64_MSR_CRASH_CTL_NOTIFY); } + if (has_msr_hv_runtime) { + kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_VP_RUNTIME, + env->msr_hv_runtime); + } if (has_msr_mtrr) { kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype); kvm_msr_entry_set(&msrs[n++], @@ -1785,6 +1798,9 @@ static int kvm_get_msrs(X86CPU *cpu) msrs[n++].index = HV_X64_MSR_CRASH_P0 + j; } } + if (has_msr_hv_runtime) { + msrs[n++].index = HV_X64_MSR_VP_RUNTIME; + } if (has_msr_mtrr) { msrs[n++].index = MSR_MTRRdefType; msrs[n++].index = MSR_MTRRfix64K_00000; @@ -1938,6 +1954,9 @@ static int kvm_get_msrs(X86CPU *cpu) case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4: env->msr_hv_crash_params[index - HV_X64_MSR_CRASH_P0] = msrs[i].data; break; + case HV_X64_MSR_VP_RUNTIME: + env->msr_hv_runtime = msrs[i].data; + break; case MSR_MTRRdefType: env->mtrr_deftype = msrs[i].data; break; diff --git a/target-i386/machine.c b/target-i386/machine.c index 9fa056341a..67373663d0 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -687,6 +687,25 @@ static const VMStateDescription vmstate_msr_hyperv_crash = { } }; +static bool hyperv_runtime_enable_needed(void *opaque) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + + return env->msr_hv_runtime != 0; +} + +static const VMStateDescription vmstate_msr_hyperv_runtime = { + .name = "cpu/msr_hyperv_runtime", + .version_id = 1, + .minimum_version_id = 1, + .needed = hyperv_runtime_enable_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64(env.msr_hv_runtime, X86CPU), + VMSTATE_END_OF_LIST() + } +}; + static bool avx512_needed(void *opaque) { X86CPU *cpu = opaque; @@ -869,6 +888,7 @@ VMStateDescription vmstate_x86_cpu = { &vmstate_msr_hyperv_vapic, &vmstate_msr_hyperv_time, &vmstate_msr_hyperv_crash, + &vmstate_msr_hyperv_runtime, &vmstate_avx512, &vmstate_xss, NULL -- cgit 1.4.1 From 1c4a55dbed9a47fde9294f7de6c8bb060d874c88 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Fri, 16 Oct 2015 09:38:22 -0600 Subject: kvm: Allow the Hyper-V vendor ID to be specified According to Microsoft documentation, the signature in the standard hypervisor CPUID leaf at 0x40000000 identifies the Vendor ID and is for reporting and diagnostic purposes only. We can therefore allow the user to change it to whatever they want, within the 12 character limit. Add a new hv-vendor-id option to the -cpu flag to allow for this, ex: -cpu host,hv_time,hv-vendor-id=KeenlyKVM Link: http://msdn.microsoft.com/library/windows/hardware/hh975392 Signed-off-by: Alex Williamson Message-Id: <20151016153356.28104.48612.stgit@gimli.home> [Adjust error message to match the property name, use error_report. - Paolo] Signed-off-by: Paolo Bonzini --- target-i386/cpu-qom.h | 1 + target-i386/cpu.c | 1 + target-i386/kvm.c | 14 +++++++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'target-i386/cpu.c') diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 9eab41b19e..e3bfe9d07e 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -88,6 +88,7 @@ typedef struct X86CPU { bool hyperv_vapic; bool hyperv_relaxed_timing; int hyperv_spinlock_attempts; + char *hyperv_vendor_id; bool hyperv_time; bool hyperv_crash; bool hyperv_reset; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index d2b06195f0..5f53af248f 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3149,6 +3149,7 @@ static Property x86_cpu_properties[] = { DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, 0), DEFINE_PROP_UINT32("xlevel", X86CPU, env.cpuid_xlevel, 0), DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0), + DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id), DEFINE_PROP_END_OF_LIST() }; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 010ac51563..64046cb69d 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -28,6 +28,7 @@ #include "exec/gdbstub.h" #include "qemu/host-utils.h" #include "qemu/config-file.h" +#include "qemu/error-report.h" #include "hw/i386/pc.h" #include "hw/i386/apic.h" #include "hw/i386/apic_internal.h" @@ -505,7 +506,18 @@ int kvm_arch_init_vcpu(CPUState *cs) if (hyperv_enabled(cpu)) { c = &cpuid_data.entries[cpuid_i++]; c->function = HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS; - memcpy(signature, "Microsoft Hv", 12); + if (!cpu->hyperv_vendor_id) { + memcpy(signature, "Microsoft Hv", 12); + } else { + size_t len = strlen(cpu->hyperv_vendor_id); + + if (len > 12) { + error_report("hv-vendor-id truncated to 12 characters"); + len = 12; + } + memset(signature, 0, 12); + memcpy(signature, cpu->hyperv_vendor_id, len); + } c->eax = HYPERV_CPUID_MIN; c->ebx = signature[0]; c->ecx = signature[1]; -- cgit 1.4.1