From nobody Thu Nov 6 19:40:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1488213866616556.8535231018406; Mon, 27 Feb 2017 08:44:26 -0800 (PST) Received: from localhost ([::1]:54216 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciOPQ-0007YX-1C for importer@patchew.org; Mon, 27 Feb 2017 11:44:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43721) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciO6u-0007wE-O2 for qemu-devel@nongnu.org; Mon, 27 Feb 2017 11:25:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciO6s-0005Cs-Iv for qemu-devel@nongnu.org; Mon, 27 Feb 2017 11:25:16 -0500 Received: from mx1.redhat.com ([209.132.183.28]:53350) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciO6s-0005Cf-AF for qemu-devel@nongnu.org; Mon, 27 Feb 2017 11:25:14 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 72D34C05AA6F; Mon, 27 Feb 2017 16:25:14 +0000 (UTC) Received: from localhost (ovpn-116-24.gru2.redhat.com [10.97.116.24]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1RGPDHR031829; Mon, 27 Feb 2017 11:25:13 -0500 From: Eduardo Habkost To: Peter Maydell Date: Mon, 27 Feb 2017 13:24:54 -0300 Message-Id: <20170227162501.29280-5-ehabkost@redhat.com> In-Reply-To: <20170227162501.29280-1-ehabkost@redhat.com> References: <20170227162501.29280-1-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Mon, 27 Feb 2017 16:25:14 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 04/11] i386: Reorganize and document CPUID initialization steps X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , qemu-devel@nongnu.org, Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" CPU runnability checks and CPU model expansion have slightly different requirements. Document the steps involved in loading a CPU model and realizing a CPU, so their requirements and purpose are clearly defined. This patch doesn't change any implementation. It just add comments, rename the x86_cpu_load_features() function for clarity (so it won't be confused with x86_cpu_load_def()), and move x86_cpu_filter_features() closer to it. Message-Id: <20170116211124.29245-2-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost --- target/i386/cpu.c | 102 +++++++++++++++++++++++++++++++++++++-------------= ---- 1 file changed, 71 insertions(+), 31 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 87affbfcd6..b614887a61 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -2059,7 +2059,7 @@ static void x86_cpu_parse_featurestr(const char *type= name, char *features, } } =20 -static void x86_cpu_load_features(X86CPU *cpu, Error **errp); +static void x86_cpu_expand_features(X86CPU *cpu, Error **errp); static int x86_cpu_filter_features(X86CPU *cpu); =20 /* Check for missing features that may prevent the CPU class from @@ -2082,9 +2082,9 @@ static void x86_cpu_class_check_missing_features(X86C= PUClass *xcc, =20 xc =3D X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc)))); =20 - x86_cpu_load_features(xc, &err); + x86_cpu_expand_features(xc, &err); if (err) { - /* Errors at x86_cpu_load_features should never happen, + /* Errors at x86_cpu_expand_features should never happen, * but in case it does, just report the model as not * runnable at all using the "type" property. */ @@ -2245,31 +2245,6 @@ static uint32_t x86_cpu_get_supported_feature_word(F= eatureWord w, return r; } =20 -/* - * Filters CPU feature words based on host availability of each feature. - * - * Returns: 0 if all flags are supported by the host, non-zero otherwise. - */ -static int x86_cpu_filter_features(X86CPU *cpu) -{ - CPUX86State *env =3D &cpu->env; - FeatureWord w; - int rv =3D 0; - - for (w =3D 0; w < FEATURE_WORDS; w++) { - uint32_t host_feat =3D - x86_cpu_get_supported_feature_word(w, false); - uint32_t requested_features =3D env->features[w]; - env->features[w] &=3D host_feat; - cpu->filtered_features[w] =3D requested_features & ~env->features[= w]; - if (cpu->filtered_features[w]) { - rv =3D 1; - } - } - - return rv; -} - static void x86_cpu_report_filtered_features(X86CPU *cpu) { FeatureWord w; @@ -3093,8 +3068,47 @@ static void x86_cpu_enable_xsave_components(X86CPU *= cpu) env->features[FEAT_XSAVE_COMP_HI] =3D mask >> 32; } =20 -/* Load CPUID data based on configured features */ -static void x86_cpu_load_features(X86CPU *cpu, Error **errp) +/***** Steps involved on loading and filtering CPUID data + * + * When initializing and realizing a CPU object, the steps + * involved in setting up CPUID data are: + * + * 1) Loading CPU model definition (X86CPUDefinition). This is + * implemented by x86_cpu_load_def() and should be completely + * transparent, as it is done automatically by instance_init. + * No code should need to look at X86CPUDefinition structs + * outside instance_init. + * + * 2) CPU expansion. This is done by realize before CPUID + * filtering, and will make sure host/accelerator data is + * loaded for CPU models that depend on host capabilities + * (e.g. "host"). Done by x86_cpu_expand_features(). + * + * 3) CPUID filtering. This initializes extra data related to + * CPUID, and checks if the host supports all capabilities + * required by the CPU. Runnability of a CPU model is + * determined at this step. Done by x86_cpu_filter_features(). + * + * Some operations don't require all steps to be performed. + * More precisely: + * + * - CPU instance creation (instance_init) will run only CPU + * model loading. CPU expansion can't run at instance_init-time + * because host/accelerator data may be not available yet. + * - CPU realization will perform both CPU model expansion and CPUID + * filtering, and return an error in case one of them fails. + * - query-cpu-definitions needs to run all 3 steps. It needs + * to run CPUID filtering, as the 'unavailable-features' + * field is set based on the filtering results. + * - The query-cpu-model-expansion QMP command only needs to run + * CPU model loading and CPU expansion. It should not filter + * any CPUID data based on host capabilities. + */ + +/* Expand CPU configuration data, based on configured features + * and host/accelerator capabilities when appropriate. + */ +static void x86_cpu_expand_features(X86CPU *cpu, Error **errp) { CPUX86State *env =3D &cpu->env; FeatureWord w; @@ -3171,6 +3185,32 @@ out: } } =20 +/* + * Finishes initialization of CPUID data, filters CPU feature + * words based on host availability of each feature. + * + * Returns: 0 if all flags are supported by the host, non-zero otherwise. + */ +static int x86_cpu_filter_features(X86CPU *cpu) +{ + CPUX86State *env =3D &cpu->env; + FeatureWord w; + int rv =3D 0; + + for (w =3D 0; w < FEATURE_WORDS; w++) { + uint32_t host_feat =3D + x86_cpu_get_supported_feature_word(w, false); + uint32_t requested_features =3D env->features[w]; + env->features[w] &=3D host_feat; + cpu->filtered_features[w] =3D requested_features & ~env->features[= w]; + if (cpu->filtered_features[w]) { + rv =3D 1; + } + } + + return rv; +} + #define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 =3D=3D CPUID_VENDOR_INTEL_= 1 && \ (env)->cpuid_vendor2 =3D=3D CPUID_VENDOR_INTEL_= 2 && \ (env)->cpuid_vendor3 =3D=3D CPUID_VENDOR_INTEL_= 3) @@ -3198,7 +3238,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error= **errp) return; } =20 - x86_cpu_load_features(cpu, &local_err); + x86_cpu_expand_features(cpu, &local_err); if (local_err) { goto out; } --=20 2.11.0.259.g40922b1