diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-10-19 10:52:39 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-10-19 10:52:39 +0100 |
commit | 526d5809a0714edc7f19196f14ec2e607dbd9753 (patch) | |
tree | 4ac5abd443d968ce5c6495cf8030a1301ecae3ee /target-i386 | |
parent | aedc8806172dd1ae904f04169ee3b19fce1d7893 (diff) | |
parent | 1c4a55dbed9a47fde9294f7de6c8bb060d874c88 (diff) | |
download | qemu-526d5809a0714edc7f19196f14ec2e607dbd9753.zip qemu-526d5809a0714edc7f19196f14ec2e607dbd9753.tar.gz qemu-526d5809a0714edc7f19196f14ec2e607dbd9753.tar.bz2 |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* KVM page size fix for PPC
* Support for Linux 4.4's new Hyper-V features
* Eliminate g_slice from areas I maintain
* checkpatch fix
* Peter's cpu_reload_memory_map() cleanups
* More changes to MAINTAINERS
* Require Python 2.6
* chardev creation fixes
* PCI requester id for ARM KVM
* cleanups and doc fixes
* Allow customization of the Hyper-V vendor id
# gpg: Signature made Mon 19 Oct 2015 09:13:10 BST using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>"
* remotes/bonzini/tags/for-upstream: (49 commits)
kvm: Allow the Hyper-V vendor ID to be specified
kvm: Move x86-specific functions into target-i386/kvm.c
kvm: Pass PCI device pointer to MSI routing functions
hw/pci: Introduce pci_requester_id()
kvm: Make KVM_CAP_SIGNAL_MSI globally available
doc/rcu: fix g_free_rcu() usage example
qemu-char: cleanup after completed conversion to cd->create
qemu-char: convert ringbuf backend to data-driven creation
qemu-char: convert vc backend to data-driven creation
qemu-char: convert spice backend to data-driven creation
qemu-char: convert console backend to data-driven creation
qemu-char: convert stdio backend to data-driven creation
qemu-char: convert testdev backend to data-driven creation
qemu-char: convert braille backend to data-driven creation
qemu-char: convert msmouse backend to data-driven creation
qemu-char: convert mux backend to data-driven creation
qemu-char: convert null backend to data-driven creation
qemu-char: convert pty backend to data-driven creation
qemu-char: convert UDP backend to data-driven creation
qemu-char: convert socket backend to data-driven creation
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/cpu-qom.h | 4 | ||||
-rw-r--r-- | target-i386/cpu.c | 4 | ||||
-rw-r--r-- | target-i386/cpu.h | 1 | ||||
-rw-r--r-- | target-i386/kvm.c | 87 | ||||
-rw-r--r-- | target-i386/machine.c | 20 |
5 files changed, 107 insertions, 9 deletions
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index c35b624..e3bfe9d 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -88,8 +88,12 @@ 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; + 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 05d7f26..5f53af2 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -3140,12 +3140,16 @@ 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("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), 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/cpu.h b/target-i386/cpu.h index 54d9d50..a395b4b 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 80d1a7e..64046cb 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" @@ -82,12 +83,24 @@ static bool has_msr_hv_hypercall; 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_hv_runtime; static bool has_msr_mtrr; static bool has_msr_xss; static bool has_msr_architectural_pmu; static uint32_t num_architectural_pmu_counters; +static int has_xsave; +static int has_xcrs; +static int has_pit_state2; + +int kvm_has_pit_state2(void) +{ + return has_pit_state2; +} + bool kvm_has_smm(void) { return kvm_check_extension(kvm_state, KVM_CAP_X86_SMM); @@ -460,7 +473,10 @@ static bool hyperv_enabled(X86CPU *cpu) (hyperv_hypercall_available(cpu) || cpu->hyperv_time || cpu->hyperv_relaxed_timing || - cpu->hyperv_crash); + cpu->hyperv_crash || + cpu->hyperv_reset || + cpu->hyperv_vpindex || + cpu->hyperv_runtime); } static Error *invtsc_mig_blocker; @@ -490,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]; @@ -529,7 +556,15 @@ int kvm_arch_init_vcpu(CPUState *cs) if (cpu->hyperv_crash && has_msr_hv_crash) { c->edx |= HV_X64_GUEST_CRASH_MSR_AVAILABLE; } - + 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; + } + 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) { @@ -752,7 +787,7 @@ int kvm_arch_init_vcpu(CPUState *cs) } } - if (kvm_has_xsave()) { + if (has_xsave) { env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave)); } @@ -858,6 +893,18 @@ static int kvm_get_supported_msrs(KVMState *s) has_msr_hv_crash = true; continue; } + if (kvm_msr_list->indices[i] == HV_X64_MSR_RESET) { + has_msr_hv_reset = true; + continue; + } + if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_INDEX) { + has_msr_hv_vpindex = true; + continue; + } + if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_RUNTIME) { + has_msr_hv_runtime = true; + continue; + } } } @@ -908,6 +955,18 @@ int kvm_arch_init(MachineState *ms, KVMState *s) int ret; struct utsname utsname; +#ifdef KVM_CAP_XSAVE + has_xsave = kvm_check_extension(s, KVM_CAP_XSAVE); +#endif + +#ifdef KVM_CAP_XCRS + has_xcrs = kvm_check_extension(s, KVM_CAP_XCRS); +#endif + +#ifdef KVM_CAP_PIT_STATE2 + has_pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2); +#endif + ret = kvm_get_supported_msrs(s); if (ret < 0) { return ret; @@ -1116,7 +1175,7 @@ static int kvm_put_xsave(X86CPU *cpu) uint8_t *xmm, *ymmh, *zmmh; int i, r; - if (!kvm_has_xsave()) { + if (!has_xsave) { return kvm_put_fpu(cpu); } @@ -1170,7 +1229,7 @@ static int kvm_put_xcrs(X86CPU *cpu) CPUX86State *env = &cpu->env; struct kvm_xcrs xcrs = {}; - if (!kvm_has_xcrs()) { + if (!has_xcrs) { return 0; } @@ -1403,6 +1462,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++], @@ -1495,7 +1558,7 @@ static int kvm_get_xsave(X86CPU *cpu) const uint8_t *xmm, *ymmh, *zmmh; uint16_t cwd, swd, twd; - if (!kvm_has_xsave()) { + if (!has_xsave) { return kvm_get_fpu(cpu); } @@ -1554,7 +1617,7 @@ static int kvm_get_xcrs(X86CPU *cpu) int i, ret; struct kvm_xcrs xcrs; - if (!kvm_has_xcrs()) { + if (!has_xcrs) { return 0; } @@ -1768,6 +1831,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; @@ -1921,6 +1987,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; @@ -2956,7 +3025,7 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id) } int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, - uint64_t address, uint32_t data) + uint64_t address, uint32_t data, PCIDevice *dev) { return 0; } diff --git a/target-i386/machine.c b/target-i386/machine.c index 9fa0563..6737366 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 |