| From 6d78a7906b69054a4798b1b68548f59fec9e5da8 Mon Sep 17 00:00:00 2001 |
| From: Vadim Rozenfeld <vrozenfe@redhat.com> |
| Date: Mon, 3 Mar 2014 12:09:13 +0100 |
| Subject: [PATCH 01/12] target-i386: Move hyperv_* static globals to X86CPU |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| RH-Author: Vadim Rozenfeld <vrozenfe@redhat.com> |
| Message-id: <1393848564-10511-2-git-send-email-vrozenfe@redhat.com> |
| Patchwork-id: 57957 |
| O-Subject: [RHEL-7.0 qemu-kvm v4 PATCH 01/12] target-i386: Move hyperv_* static globals to X86CPU |
| Bugzilla: 1004773 |
| RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com> |
| RH-Acked-by: Igor Mammedov <imammedo@redhat.com> |
| RH-Acked-by: Juan Quintela <quintela@redhat.com> |
| RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com> |
| |
| From: Igor Mammedov <imammedo@redhat.com> |
| |
| since hyperv_* helper functions are used only in target-i386/kvm.c |
| move them there as static helpers |
| |
| Requested-by: Eduardo Habkost <ehabkost@redhat.com> |
| Signed-off-by: Igor Mammedov <imammedo@redhat.com> |
| Signed-off-by: Andreas Färber <afaerber@suse.de> |
| (cherry picked from commit 92067bf4bfa144ea3967a9951808f5e587bdab18) |
| |
| Conflicts: |
| target-i386/cpu.h |
| target-i386/kvm.c |
| |
| target-i386/Makefile.objs | 2 +- |
| target-i386/cpu-qom.h | 4 +++ |
| target-i386/cpu.c | 16 ++++++++---- |
| target-i386/cpu.h | 4 +++ |
| target-i386/hyperv.c | 64 ----------------------------------------------- |
| target-i386/hyperv.h | 45 --------------------------------- |
| target-i386/kvm.c | 36 ++++++++++++++++++-------- |
| 7 files changed, 46 insertions(+), 125 deletions(-) |
| delete mode 100644 target-i386/hyperv.c |
| delete mode 100644 target-i386/hyperv.h |
| |
| Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com> |
| |
| target-i386/Makefile.objs | 2 +- |
| target-i386/cpu-qom.h | 4 +++ |
| target-i386/cpu.c | 16 +++++++--- |
| target-i386/cpu.h | 4 +++ |
| target-i386/hyperv.c | 64 --------------------------------------------- |
| target-i386/hyperv.h | 45 ------------------------------- |
| target-i386/kvm.c | 36 ++++++++++++++++++------- |
| 7 files changed, 46 insertions(+), 125 deletions(-) |
| delete mode 100644 target-i386/hyperv.c |
| delete mode 100644 target-i386/hyperv.h |
| |
| diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs |
| index c1d4f05..887dca7 100644 |
| |
| |
| @@ -2,7 +2,7 @@ obj-y += translate.o helper.o cpu.o |
| obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o |
| obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o |
| obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o |
| -obj-$(CONFIG_KVM) += kvm.o hyperv.o |
| +obj-$(CONFIG_KVM) += kvm.o |
| obj-$(CONFIG_NO_KVM) += kvm-stub.o |
| obj-$(CONFIG_LINUX_USER) += ioport-user.o |
| obj-$(CONFIG_BSD_USER) += ioport-user.o |
| diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h |
| index 12c7bea..ac56fec 100644 |
| |
| |
| @@ -66,6 +66,10 @@ typedef struct X86CPU { |
| |
| CPUX86State env; |
| |
| + bool hyperv_vapic; |
| + bool hyperv_relaxed_timing; |
| + int hyperv_spinlock_attempts; |
| + |
| /* Features that were filtered out because of missing host capabilities */ |
| uint32_t filtered_features[FEATURE_WORDS]; |
| |
| diff --git a/target-i386/cpu.c b/target-i386/cpu.c |
| index 31ff568..826d8d6 100644 |
| |
| |
| @@ -35,8 +35,6 @@ |
| #include "qapi/visitor.h" |
| #include "sysemu/arch_init.h" |
| |
| -#include "hyperv.h" |
| - |
| #include "hw/hw.h" |
| #if defined(CONFIG_KVM) |
| #include <linux/kvm_para.h> |
| @@ -1629,12 +1627,19 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp) |
| object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp); |
| } else if (!strcmp(featurestr, "hv-spinlocks")) { |
| char *err; |
| + const int min = 0xFFF; |
| numvalue = strtoul(val, &err, 0); |
| if (!*val || *err) { |
| error_setg(errp, "bad numerical value %s", val); |
| goto out; |
| } |
| - hyperv_set_spinlock_retries(numvalue); |
| + if (numvalue < min) { |
| + fprintf(stderr, "hv-spinlocks value shall always be >= 0x%x" |
| + ", fixup will be removed in future versions\n", |
| + min); |
| + numvalue = min; |
| + } |
| + cpu->hyperv_spinlock_attempts = numvalue; |
| } else { |
| error_setg(errp, "unrecognized feature %s", featurestr); |
| goto out; |
| @@ -1644,9 +1649,9 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp) |
| } else if (!strcmp(featurestr, "enforce")) { |
| check_cpuid = enforce_cpuid = 1; |
| } else if (!strcmp(featurestr, "hv_relaxed")) { |
| - hyperv_enable_relaxed_timing(true); |
| + cpu->hyperv_relaxed_timing = true; |
| } else if (!strcmp(featurestr, "hv_vapic")) { |
| - hyperv_enable_vapic_recommended(true); |
| + cpu->hyperv_vapic = true; |
| } else { |
| error_setg(errp, "feature string `%s' not in format (+feature|" |
| "-feature|feature=xyz)", featurestr); |
| @@ -2559,6 +2564,7 @@ static void x86_cpu_initfn(Object *obj) |
| x86_cpu_get_feature_words, |
| NULL, NULL, (void *)cpu->filtered_features, NULL); |
| |
| + cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY; |
| env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index); |
| |
| /* init various static tables used in TCG mode */ |
| diff --git a/target-i386/cpu.h b/target-i386/cpu.h |
| index 37ff264..4c4c9ff 100644 |
| |
| |
| @@ -565,6 +565,10 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; |
| #define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */ |
| #define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */ |
| |
| +#ifndef HYPERV_SPINLOCK_NEVER_RETRY |
| +#define HYPERV_SPINLOCK_NEVER_RETRY 0xFFFFFFFF |
| +#endif |
| + |
| #define EXCP00_DIVZ 0 |
| #define EXCP01_DB 1 |
| #define EXCP02_NMI 2 |
| diff --git a/target-i386/hyperv.c b/target-i386/hyperv.c |
| deleted file mode 100644 |
| index f284e99..0000000 |
| |
| |
| @@ -1,64 +0,0 @@ |
| -/* |
| - * QEMU Hyper-V support |
| - * |
| - * Copyright Red Hat, Inc. 2011 |
| - * |
| - * Author: Vadim Rozenfeld <vrozenfe@redhat.com> |
| - * |
| - * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| - * See the COPYING file in the top-level directory. |
| - * |
| - */ |
| - |
| -#include "hyperv.h" |
| - |
| -static bool hyperv_vapic; |
| -static bool hyperv_relaxed_timing; |
| -static int hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY; |
| - |
| -void hyperv_enable_vapic_recommended(bool val) |
| -{ |
| - hyperv_vapic = val; |
| -} |
| - |
| -void hyperv_enable_relaxed_timing(bool val) |
| -{ |
| - hyperv_relaxed_timing = val; |
| -} |
| - |
| -void hyperv_set_spinlock_retries(int val) |
| -{ |
| - hyperv_spinlock_attempts = val; |
| - if (hyperv_spinlock_attempts < 0xFFF) { |
| - hyperv_spinlock_attempts = 0xFFF; |
| - } |
| -} |
| - |
| -bool hyperv_enabled(void) |
| -{ |
| - return hyperv_hypercall_available() || hyperv_relaxed_timing_enabled(); |
| -} |
| - |
| -bool hyperv_hypercall_available(void) |
| -{ |
| - if (hyperv_vapic || |
| - (hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY)) { |
| - return true; |
| - } |
| - return false; |
| -} |
| - |
| -bool hyperv_vapic_recommended(void) |
| -{ |
| - return hyperv_vapic; |
| -} |
| - |
| -bool hyperv_relaxed_timing_enabled(void) |
| -{ |
| - return hyperv_relaxed_timing; |
| -} |
| - |
| -int hyperv_get_spinlock_retries(void) |
| -{ |
| - return hyperv_spinlock_attempts; |
| -} |
| diff --git a/target-i386/hyperv.h b/target-i386/hyperv.h |
| deleted file mode 100644 |
| index bacb1d4..0000000 |
| |
| |
| @@ -1,45 +0,0 @@ |
| -/* |
| - * QEMU Hyper-V support |
| - * |
| - * Copyright Red Hat, Inc. 2011 |
| - * |
| - * Author: Vadim Rozenfeld <vrozenfe@redhat.com> |
| - * |
| - * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| - * See the COPYING file in the top-level directory. |
| - * |
| - */ |
| - |
| -#ifndef QEMU_HW_HYPERV_H |
| -#define QEMU_HW_HYPERV_H 1 |
| - |
| -#include "qemu-common.h" |
| -#ifdef CONFIG_KVM |
| -#include <asm/hyperv.h> |
| -#endif |
| - |
| -#ifndef HYPERV_SPINLOCK_NEVER_RETRY |
| -#define HYPERV_SPINLOCK_NEVER_RETRY 0xFFFFFFFF |
| -#endif |
| - |
| -#ifndef KVM_CPUID_SIGNATURE_NEXT |
| -#define KVM_CPUID_SIGNATURE_NEXT 0x40000100 |
| -#endif |
| - |
| -#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_KVM) |
| -void hyperv_enable_vapic_recommended(bool val); |
| -void hyperv_enable_relaxed_timing(bool val); |
| -void hyperv_set_spinlock_retries(int val); |
| -#else |
| -static inline void hyperv_enable_vapic_recommended(bool val) { } |
| -static inline void hyperv_enable_relaxed_timing(bool val) { } |
| -static inline void hyperv_set_spinlock_retries(int val) { } |
| -#endif |
| - |
| -bool hyperv_enabled(void); |
| -bool hyperv_hypercall_available(void); |
| -bool hyperv_vapic_recommended(void); |
| -bool hyperv_relaxed_timing_enabled(void); |
| -int hyperv_get_spinlock_retries(void); |
| - |
| -#endif /* QEMU_HW_HYPERV_H */ |
| diff --git a/target-i386/kvm.c b/target-i386/kvm.c |
| index 4b470e4..c7fabd7 100644 |
| |
| |
| @@ -31,7 +31,7 @@ |
| #include "hw/i386/pc.h" |
| #include "hw/i386/apic.h" |
| #include "exec/ioport.h" |
| -#include "hyperv.h" |
| +#include <asm/hyperv.h> |
| #include "hw/pci/pci.h" |
| |
| //#define DEBUG_KVM |
| @@ -421,6 +421,22 @@ unsigned long kvm_arch_vcpu_id(CPUState *cs) |
| return cpu->env.cpuid_apic_id; |
| } |
| |
| +#ifndef KVM_CPUID_SIGNATURE_NEXT |
| +#define KVM_CPUID_SIGNATURE_NEXT 0x40000100 |
| +#endif |
| + |
| +static bool hyperv_hypercall_available(X86CPU *cpu) |
| +{ |
| + return cpu->hyperv_vapic || |
| + (cpu->hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY); |
| +} |
| + |
| +static bool hyperv_enabled(X86CPU *cpu) |
| +{ |
| + return hyperv_hypercall_available(cpu) || |
| + cpu->hyperv_relaxed_timing; |
| +} |
| + |
| #define KVM_MAX_CPUID_ENTRIES 100 |
| |
| int kvm_arch_init_vcpu(CPUState *cs) |
| @@ -443,7 +459,7 @@ int kvm_arch_init_vcpu(CPUState *cs) |
| c = &cpuid_data.entries[cpuid_i++]; |
| memset(c, 0, sizeof(*c)); |
| c->function = KVM_CPUID_SIGNATURE; |
| - if (!hyperv_enabled()) { |
| + if (!hyperv_enabled(cpu)) { |
| memcpy(signature, "KVMKVMKVM\0\0\0", 12); |
| c->eax = 0; |
| } else { |
| @@ -459,7 +475,7 @@ int kvm_arch_init_vcpu(CPUState *cs) |
| c->function = KVM_CPUID_FEATURES; |
| c->eax = env->features[FEAT_KVM]; |
| |
| - if (hyperv_enabled()) { |
| + if (hyperv_enabled(cpu)) { |
| memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12); |
| c->eax = signature[0]; |
| |
| @@ -472,10 +488,10 @@ int kvm_arch_init_vcpu(CPUState *cs) |
| c = &cpuid_data.entries[cpuid_i++]; |
| memset(c, 0, sizeof(*c)); |
| c->function = HYPERV_CPUID_FEATURES; |
| - if (hyperv_relaxed_timing_enabled()) { |
| + if (cpu->hyperv_relaxed_timing) { |
| c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; |
| } |
| - if (hyperv_vapic_recommended()) { |
| + if (cpu->hyperv_vapic) { |
| c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; |
| c->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE; |
| } |
| @@ -483,13 +499,13 @@ int kvm_arch_init_vcpu(CPUState *cs) |
| c = &cpuid_data.entries[cpuid_i++]; |
| memset(c, 0, sizeof(*c)); |
| c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; |
| - if (hyperv_relaxed_timing_enabled()) { |
| + if (cpu->hyperv_relaxed_timing) { |
| c->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED; |
| } |
| - if (hyperv_vapic_recommended()) { |
| + if (cpu->hyperv_vapic) { |
| c->eax |= HV_X64_APIC_ACCESS_RECOMMENDED; |
| } |
| - c->ebx = hyperv_get_spinlock_retries(); |
| + c->ebx = cpu->hyperv_spinlock_attempts; |
| |
| c = &cpuid_data.entries[cpuid_i++]; |
| memset(c, 0, sizeof(*c)); |
| @@ -1177,11 +1193,11 @@ static int kvm_put_msrs(X86CPU *cpu, int level) |
| kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_CTRL, |
| env->msr_global_ctrl); |
| } |
| - if (hyperv_hypercall_available()) { |
| + if (hyperv_hypercall_available(cpu)) { |
| kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0); |
| kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0); |
| } |
| - if (hyperv_vapic_recommended()) { |
| + if (cpu->hyperv_vapic) { |
| kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0); |
| } |
| } |
| -- |
| 1.7.1 |
| |