From patchwork Wed Jun 5 13:18:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Mammedov X-Patchwork-Id: 249055 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id ABAE12C0079 for ; Wed, 5 Jun 2013 23:24:54 +1000 (EST) Received: from localhost ([::1]:54252 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UkDhs-0001QY-Oh for incoming@patchwork.ozlabs.org; Wed, 05 Jun 2013 09:24:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49746) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UkDcR-0003YE-UH for qemu-devel@nongnu.org; Wed, 05 Jun 2013 09:19:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UkDcM-0001HY-It for qemu-devel@nongnu.org; Wed, 05 Jun 2013 09:19:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:20693) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UkDcM-0001HN-8x for qemu-devel@nongnu.org; Wed, 05 Jun 2013 09:19:10 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r55DJ9Bp017928 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 5 Jun 2013 09:19:09 -0400 Received: from dell-pet610-01.lab.eng.brq.redhat.com (dell-pet610-01.lab.eng.brq.redhat.com [10.34.42.20]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r55DIuVE017218; Wed, 5 Jun 2013 09:19:08 -0400 From: Igor Mammedov To: qemu-devel@nongnu.org Date: Wed, 5 Jun 2013 15:18:40 +0200 Message-Id: <1370438326-27054-10-git-send-email-imammedo@redhat.com> In-Reply-To: <1370438326-27054-1-git-send-email-imammedo@redhat.com> References: <1370438326-27054-1-git-send-email-imammedo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: ehabkost@redhat.com, afaerber@suse.de Subject: [Qemu-devel] [PATCH 09/15] target-i386: move hyperv_* static globals to CPUState X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org - since hyperv_* helper functions are used only in target-i386/kvm.c move them there as static helpers Signed-off-by: Igor Mammedov Requestd-By: Eduardo Habkost Reviewed-by: Eduardo Habkost --- target-i386/Makefile.objs | 2 +- target-i386/cpu.c | 16 +++++++--- target-i386/cpu.h | 7 +++++ target-i386/hyperv.c | 64 --------------------------------------------- target-i386/hyperv.h | 45 ------------------------------- target-i386/kvm.c | 36 ++++++++++++++++++------- 6 files changed, 45 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 --- a/target-i386/Makefile.objs +++ b/target-i386/Makefile.objs @@ -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.c b/target-i386/cpu.c index ec6d33f..40f2a7c 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -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 @@ -1633,12 +1631,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; + } + env->hyperv_spinlock_attempts = numvalue; } else { error_setg(errp, "unrecognized feature %s", featurestr); goto out; @@ -1648,9 +1653,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); + env->hyperv_relaxed_timing = true; } else if (!strcmp(featurestr, "hv_vapic")) { - hyperv_enable_vapic_recommended(true); + env->hyperv_vapic = true; } else { error_setg(errp, "feature string `%s' not in format (+feature|" "-feature|feature=xyz)", featurestr); @@ -1797,6 +1802,7 @@ static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp) def->features[FEAT_KVM] |= kvm_default_features; } def->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR; + env->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY; object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp); object_property_set_int(OBJECT(cpu), def->level, "level", errp); diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 058c57f..ea9143f 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -549,6 +549,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 @@ -845,6 +849,9 @@ typedef struct CPUX86State { FeatureWordArray features; uint32_t cpuid_model[12]; uint32_t cpuid_apic_id; + bool hyperv_vapic; + bool hyperv_relaxed_timing; + int hyperv_spinlock_attempts; /* MTRRs */ uint64_t mtrr_fixed[11]; diff --git a/target-i386/hyperv.c b/target-i386/hyperv.c deleted file mode 100644 index f284e99..0000000 --- a/target-i386/hyperv.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * QEMU Hyper-V support - * - * Copyright Red Hat, Inc. 2011 - * - * Author: Vadim Rozenfeld - * - * 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 --- a/target-i386/hyperv.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * QEMU Hyper-V support - * - * Copyright Red Hat, Inc. 2011 - * - * Author: Vadim Rozenfeld - * - * 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 -#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 9ffb6ca..0e88072 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -31,7 +31,7 @@ #include "hw/i386/pc.h" #include "hw/i386/apic.h" #include "exec/ioport.h" -#include "hyperv.h" +#include #include "hw/pci/pci.h" //#define DEBUG_KVM @@ -418,6 +418,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(CPUX86State *env) +{ + return env->hyperv_vapic || + (env->hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY); +} + +static bool hyperv_enabled(CPUX86State *env) +{ + return hyperv_hypercall_available(env) || + env->hyperv_relaxed_timing; +} + #define KVM_MAX_CPUID_ENTRIES 100 int kvm_arch_init_vcpu(CPUState *cs) @@ -440,7 +456,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(env)) { memcpy(signature, "KVMKVMKVM\0\0\0", 12); c->eax = 0; } else { @@ -456,7 +472,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(env)) { memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12); c->eax = signature[0]; @@ -469,10 +485,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 (env->hyperv_relaxed_timing) { c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; } - if (hyperv_vapic_recommended()) { + if (env->hyperv_vapic) { c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; c->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE; } @@ -480,13 +496,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 (env->hyperv_relaxed_timing) { c->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED; } - if (hyperv_vapic_recommended()) { + if (env->hyperv_vapic) { c->eax |= HV_X64_APIC_ACCESS_RECOMMENDED; } - c->ebx = hyperv_get_spinlock_retries(); + c->ebx = env->hyperv_spinlock_attempts; c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); @@ -1115,11 +1131,11 @@ static int kvm_put_msrs(X86CPU *cpu, int level) kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME, env->steal_time_msr); } - if (hyperv_hypercall_available()) { + if (hyperv_hypercall_available(env)) { 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 (env->hyperv_vapic) { kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0); } }