From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572598476; cv=none; d=zoho.com; s=zohoarc; b=dgHJ8hEpPWVZzg7PZbE1/gCniGroQ7pbyWwNy72bzlsDXSIDlWG3GAyobAqjjBCGVSL2fl0q115+tBv5JdUAF6U60NChCF8Q6J+9i4gvZr4IUE/oCRhx+2hgkq2+FtWQI1iNp9vw69q88MlDZ/YrFp7GBKSrlEm+KFILzP/MAvA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572598476; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Srj3F1h/sbNE+Gxum0JG3PdUJ/b0DNEd5OxA7XmhC8o=; b=Q32blG00aeEAeILtisjwPkw3klNDUJkJY0ebHUmZzzvFyeTCEmm0CVIdpQwHjgcbTsCzAfd4gw7isje3VtM6dkv+HfnzA5JTJWhF6Tr2zucUJS/zw8PpdaCuOjna30Hl8HKu00EgOd1sEVENzLASqChrj1x+HlvwiFBPbFN+Sm0= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 157259847630962.07469303198036; Fri, 1 Nov 2019 01:54:36 -0700 (PDT) Received: from localhost ([::1]:57506 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQShX-0003Gz-5Y for importer@patchew.org; Fri, 01 Nov 2019 04:54:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56478) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSf0-00014i-Aa for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:52:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSeq-0008Rv-TR for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:51 -0400 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]:33723) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSeq-0008DB-LR for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:48 -0400 Received: by mail-wr1-x442.google.com with SMTP id s1so8974601wro.0 for ; Fri, 01 Nov 2019 01:51:46 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Srj3F1h/sbNE+Gxum0JG3PdUJ/b0DNEd5OxA7XmhC8o=; b=axPUEFLy1NMrpbf3v5yKlm2fXjZMAeI/eJZY4CdQpOzDSeUXrN0DHmNFHUdMDNAb4R 7Dp1zVe0dlARUlIzbChm+PTlIOjwOY/q16wSPj20+UoFXJ6H/8nor4dT6LKd/hFUQidU 6/7l+B/1Yv0NNCn9/91MAZXlGtFIOM+JMHv2TZyeSv2WXmI0Xj0mmkZmx6VU1JH7DfKG ASMTNOGN6FvCqSUjEPWSFnLRQ3RLSazR4MlO4ISqP3FlJYG0mwxXxBptoIXNfuQl6G6b vGRSfFDqDOqiJWlXWG2gRtX+p6s88gTutqEYRp9n2eA4noLWYr0m0rtRzwUtVPgj8yDt WoTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Srj3F1h/sbNE+Gxum0JG3PdUJ/b0DNEd5OxA7XmhC8o=; b=f8BRoJ2lbZGpX2WxU6njid4KjdMh2aSas6/2BYqyciQ/fFH9TrS8bGAZ0/dZMJarwi CmJfS6iLlv83rNfkonGmrCQ2XlOJQ3d26oNi6ouNvFrhDUHKDav3FxMQA9L5SwSL7RNy pzb3dvRGtGegfssw4zCxMFBx4BFfuGCHndn4NLI+e2g5MqhabM6vHAi4P7yPSqmB5Zkj hNvaJ2daLV21SkBmI0mS1wqzsce7Hn5V6cKKCZoEQWUvDPbnBG/yVUHV2yiixZ8yPA2X rZloe/vVrmdS8FHgRsbHXaBWXI7IGldJO4v7D6FwMEkrI/Pj22DZx7TqcEPExtHLLTkJ g9NA== X-Gm-Message-State: APjAAAVsFGdq+tH0dyWy4fz2CT6MnDsKlfrTnUc7DgBuQCi6RWGxdATU 7gDyHAAgzLRLMkZA5dpJ1vuYtrKsQ8M75/PJ X-Google-Smtp-Source: APXvYqwAvN5NS48uP6OVcW53KUpKqmJu1XbN4lYjrD9UoR47INj6lV989d6d/ZcuN6jLL4AUNFmhAg== X-Received: by 2002:adf:f945:: with SMTP id q5mr10228597wrr.33.1572598304475; Fri, 01 Nov 2019 01:51:44 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 01/11] target/arm/monitor: Introduce qmp_query_cpu_model_expansion Date: Fri, 1 Nov 2019 08:51:30 +0000 Message-Id: <20191101085140.5205-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::442 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" From: Andrew Jones Add support for the query-cpu-model-expansion QMP command to Arm. We do this selectively, only exposing CPU properties which represent optional CPU features which the user may want to enable/disable. Additionally we restrict the list of queryable cpu models to 'max', 'host', or the current type when KVM is in use. And, finally, we only implement expansion type 'full', as Arm does not yet have a "base" CPU type. More details and example queries are described in a new document (docs/arm-cpu-features.rst). Note, certainly more features may be added to the list of advertised features, e.g. 'vfp' and 'neon'. The only requirement is that we can detect invalid configurations and emit failures at QMP query time. For 'vfp' and 'neon' this will require some refactoring to share a validation function between the QMP query and the CPU realize functions. Signed-off-by: Andrew Jones Reviewed-by: Richard Henderson Reviewed-by: Eric Auger Reviewed-by: Beata Michalska Message-id: 20191031142734.8590-2-drjones@redhat.com Signed-off-by: Peter Maydell --- qapi/machine-target.json | 6 +- target/arm/monitor.c | 146 ++++++++++++++++++++++++++++++++++++++ docs/arm-cpu-features.rst | 137 +++++++++++++++++++++++++++++++++++ 3 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 docs/arm-cpu-features.rst diff --git a/qapi/machine-target.json b/qapi/machine-target.json index 55310a6aa22..04623224720 100644 --- a/qapi/machine-target.json +++ b/qapi/machine-target.json @@ -212,7 +212,7 @@ ## { 'struct': 'CpuModelExpansionInfo', 'data': { 'model': 'CpuModelInfo' }, - 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' } + 'if': 'defined(TARGET_S390X) || defined(TARGET_I386) || defined(TARGET_A= RM)' } =20 ## # @query-cpu-model-expansion: @@ -237,7 +237,7 @@ # query-cpu-model-expansion while using these is not advised. # # Some architectures may not support all expansion types. s390x supports -# "full" and "static". +# "full" and "static". Arm only supports "full". # # Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU mode= ls is # not supported, if the model cannot be expanded, if the model co= ntains @@ -251,7 +251,7 @@ 'data': { 'type': 'CpuModelExpansionType', 'model': 'CpuModelInfo' }, 'returns': 'CpuModelExpansionInfo', - 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' } + 'if': 'defined(TARGET_S390X) || defined(TARGET_I386) || defined(TARGET_A= RM)' } =20 ## # @CpuDefinitionInfo: diff --git a/target/arm/monitor.c b/target/arm/monitor.c index 6457c3c87f7..560970de7f5 100644 --- a/target/arm/monitor.c +++ b/target/arm/monitor.c @@ -21,8 +21,16 @@ */ =20 #include "qemu/osdep.h" +#include "hw/boards.h" #include "kvm_arm.h" +#include "qapi/error.h" +#include "qapi/visitor.h" +#include "qapi/qobject-input-visitor.h" +#include "qapi/qapi-commands-machine-target.h" #include "qapi/qapi-commands-misc-target.h" +#include "qapi/qmp/qerror.h" +#include "qapi/qmp/qdict.h" +#include "qom/qom-qobject.h" =20 static GICCapability *gic_cap_new(int version) { @@ -81,3 +89,141 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **e= rrp) =20 return head; } + +/* + * These are cpu model features we want to advertise. The order here + * matters as this is the order in which qmp_query_cpu_model_expansion + * will attempt to set them. If there are dependencies between features, + * then the order that considers those dependencies must be used. + */ +static const char *cpu_model_advertised_features[] =3D { + "aarch64", "pmu", + NULL +}; + +CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType= type, + CpuModelInfo *model, + Error **errp) +{ + CpuModelExpansionInfo *expansion_info; + const QDict *qdict_in =3D NULL; + QDict *qdict_out; + ObjectClass *oc; + Object *obj; + const char *name; + int i; + + if (type !=3D CPU_MODEL_EXPANSION_TYPE_FULL) { + error_setg(errp, "The requested expansion type is not supported"); + return NULL; + } + + if (!kvm_enabled() && !strcmp(model->name, "host")) { + error_setg(errp, "The CPU type '%s' requires KVM", model->name); + return NULL; + } + + oc =3D cpu_class_by_name(TYPE_ARM_CPU, model->name); + if (!oc) { + error_setg(errp, "The CPU type '%s' is not a recognized ARM CPU ty= pe", + model->name); + return NULL; + } + + if (kvm_enabled()) { + const char *cpu_type =3D current_machine->cpu_type; + int len =3D strlen(cpu_type) - strlen(ARM_CPU_TYPE_SUFFIX); + bool supported =3D false; + + if (!strcmp(model->name, "host") || !strcmp(model->name, "max")) { + /* These are kvmarm's recommended cpu types */ + supported =3D true; + } else if (strlen(model->name) =3D=3D len && + !strncmp(model->name, cpu_type, len)) { + /* KVM is enabled and we're using this type, so it works. */ + supported =3D true; + } + if (!supported) { + error_setg(errp, "We cannot guarantee the CPU type '%s' works " + "with KVM on this host", model->name); + return NULL; + } + } + + if (model->props) { + qdict_in =3D qobject_to(QDict, model->props); + if (!qdict_in) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict"); + return NULL; + } + } + + obj =3D object_new(object_class_get_name(oc)); + + if (qdict_in) { + Visitor *visitor; + Error *err =3D NULL; + + visitor =3D qobject_input_visitor_new(model->props); + visit_start_struct(visitor, NULL, NULL, 0, &err); + if (err) { + visit_free(visitor); + object_unref(obj); + error_propagate(errp, err); + return NULL; + } + + i =3D 0; + while ((name =3D cpu_model_advertised_features[i++]) !=3D NULL) { + if (qdict_get(qdict_in, name)) { + object_property_set(obj, visitor, name, &err); + if (err) { + break; + } + } + } + + if (!err) { + visit_check_struct(visitor, &err); + } + visit_end_struct(visitor, NULL); + visit_free(visitor); + if (err) { + object_unref(obj); + error_propagate(errp, err); + return NULL; + } + } + + expansion_info =3D g_new0(CpuModelExpansionInfo, 1); + expansion_info->model =3D g_malloc0(sizeof(*expansion_info->model)); + expansion_info->model->name =3D g_strdup(model->name); + + qdict_out =3D qdict_new(); + + i =3D 0; + while ((name =3D cpu_model_advertised_features[i++]) !=3D NULL) { + ObjectProperty *prop =3D object_property_find(obj, name, NULL); + if (prop) { + Error *err =3D NULL; + QObject *value; + + assert(prop->get); + value =3D object_property_get_qobject(obj, name, &err); + assert(!err); + + qdict_put_obj(qdict_out, name, value); + } + } + + if (!qdict_size(qdict_out)) { + qobject_unref(qdict_out); + } else { + expansion_info->model->props =3D QOBJECT(qdict_out); + expansion_info->model->has_props =3D true; + } + + object_unref(obj); + + return expansion_info; +} diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst new file mode 100644 index 00000000000..c79dcffb555 --- /dev/null +++ b/docs/arm-cpu-features.rst @@ -0,0 +1,137 @@ +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +ARM CPU Features +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Examples of probing and using ARM CPU features + +Introduction +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +CPU features are optional features that a CPU of supporting type may +choose to implement or not. In QEMU, optional CPU features have +corresponding boolean CPU proprieties that, when enabled, indicate +that the feature is implemented, and, conversely, when disabled, +indicate that it is not implemented. An example of an ARM CPU feature +is the Performance Monitoring Unit (PMU). CPU types such as the +Cortex-A15 and the Cortex-A57, which respectively implement ARM +architecture reference manuals ARMv7-A and ARMv8-A, may both optionally +implement PMUs. For example, if a user wants to use a Cortex-A15 without +a PMU, then the `-cpu` parameter should contain `pmu=3Doff` on the QEMU +command line, i.e. `-cpu cortex-a15,pmu=3Doff`. + +As not all CPU types support all optional CPU features, then whether or +not a CPU property exists depends on the CPU type. For example, CPUs +that implement the ARMv8-A architecture reference manual may optionally +support the AArch32 CPU feature, which may be enabled by disabling the +`aarch64` CPU property. A CPU type such as the Cortex-A15, which does +not implement ARMv8-A, will not have the `aarch64` CPU property. + +QEMU's support may be limited for some CPU features, only partially +supporting the feature or only supporting the feature under certain +configurations. For example, the `aarch64` CPU feature, which, when +disabled, enables the optional AArch32 CPU feature, is only supported +when using the KVM accelerator and when running on a host CPU type that +supports the feature. + +CPU Feature Probing +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Determining which CPU features are available and functional for a given +CPU type is possible with the `query-cpu-model-expansion` QMP command. +Below are some examples where `scripts/qmp/qmp-shell` (see the top comment +block in the script for usage) is used to issue the QMP commands. + +(1) Determine which CPU features are available for the `max` CPU type + (Note, we started QEMU with qemu-system-aarch64, so `max` is + implementing the ARMv8-A reference manual in this case):: + + (QEMU) query-cpu-model-expansion type=3Dfull model=3D{"name":"max"} + { "return": { + "model": { "name": "max", "props": { + "pmu": true, "aarch64": true + }}}} + +We see that the `max` CPU type has the `pmu` and `aarch64` CPU features. +We also see that the CPU features are enabled, as they are all `true`. + +(2) Let's try to disable the PMU:: + + (QEMU) query-cpu-model-expansion type=3Dfull model=3D{"name":"max","= props":{"pmu":false}} + { "return": { + "model": { "name": "max", "props": { + "pmu": false, "aarch64": true + }}}} + +We see it worked, as `pmu` is now `false`. + +(3) Let's try to disable `aarch64`, which enables the AArch32 CPU feature:: + + (QEMU) query-cpu-model-expansion type=3Dfull model=3D{"name":"max","= props":{"aarch64":false}} + {"error": { + "class": "GenericError", "desc": + "'aarch64' feature cannot be disabled unless KVM is enabled and 32-= bit EL1 is supported" + }} + +It looks like this feature is limited to a configuration we do not +currently have. + +(4) Let's try probing CPU features for the Cortex-A15 CPU type:: + + (QEMU) query-cpu-model-expansion type=3Dfull model=3D{"name":"cortex= -a15"} + {"return": {"model": {"name": "cortex-a15", "props": {"pmu": true}}}} + +Only the `pmu` CPU feature is available. + +A note about CPU feature dependencies +------------------------------------- + +It's possible for features to have dependencies on other features. I.e. +it may be possible to change one feature at a time without error, but +when attempting to change all features at once an error could occur +depending on the order they are processed. It's also possible changing +all at once doesn't generate an error, because a feature's dependencies +are satisfied with other features, but the same feature cannot be changed +independently without error. For these reasons callers should always +attempt to make their desired changes all at once in order to ensure the +collection is valid. + +A note about CPU models and KVM +------------------------------- + +Named CPU models generally do not work with KVM. There are a few cases +that do work, e.g. using the named CPU model `cortex-a57` with KVM on a +seattle host, but mostly if KVM is enabled the `host` CPU type must be +used. This means the guest is provided all the same CPU features as the +host CPU type has. And, for this reason, the `host` CPU type should +enable all CPU features that the host has by default. Indeed it's even +a bit strange to allow disabling CPU features that the host has when using +the `host` CPU type, but in the absence of CPU models it's the best we can +do if we want to launch guests without all the host's CPU features enabled. + +Enabling KVM also affects the `query-cpu-model-expansion` QMP command. The +affect is not only limited to specific features, as pointed out in example +(3) of "CPU Feature Probing", but also to which CPU types may be expanded. +When KVM is enabled, only the `max`, `host`, and current CPU type may be +expanded. This restriction is necessary as it's not possible to know all +CPU types that may work with KVM, but it does impose a small risk of users +experiencing unexpected errors. For example on a seattle, as mentioned +above, the `cortex-a57` CPU type is also valid when KVM is enabled. +Therefore a user could use the `host` CPU type for the current type, but +then attempt to query `cortex-a57`, however that query will fail with our +restrictions. This shouldn't be an issue though as management layers and +users have been preferring the `host` CPU type for use with KVM for quite +some time. Additionally, if the KVM-enabled QEMU instance running on a +seattle host is using the `cortex-a57` CPU type, then querying `cortex-a57` +will work. + +Using CPU Features +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +After determining which CPU features are available and supported for a +given CPU type, then they may be selectively enabled or disabled on the +QEMU command line with that CPU type:: + + $ qemu-system-aarch64 -M virt -cpu max,pmu=3Doff + +The example above disables the PMU for the `max` CPU type. + --=20 2.20.1 From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572598807; cv=none; d=zoho.com; s=zohoarc; b=LSa3dhEQLGqpBMQGOk1UMp4/RwHYQtuqOW0ChRAkYJ9FhS84DbEjWsbxqM6v9rBrboeLV849tz4lxLbfsApdTxitiYPEu6hFbVkFNtT4oaVOrVYzVCBV1CKL8hJ8bx+dapd2TQqAZM6Ocdhr6FTAhWO2bTvDHz1FvopyfnVbY08= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572598807; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=cpklon7lgXWv3V0ZHDlYJqd8G/58j7vD/Z0D6CafQ/4=; b=TXd+sLBtVFxRid/aWCNGZYc+RavzK5kSi8YsPeTnpJVoZnhG9/6wtw3uGJYX0r447EjNWnSkgtg33pfpjbiDO2MeHIttlI/6wzE7ZGuwfQ2PGGZaWRCVsMYw/CTzlDws4ts2AeFOnn5qeYNbJJwC1odSv2MSqPL3B4p/l9XEA5k= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1572598807678943.3792386938268; Fri, 1 Nov 2019 02:00:07 -0700 (PDT) Received: from localhost ([::1]:57622 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSmp-0001K1-R9 for importer@patchew.org; Fri, 01 Nov 2019 05:00:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56459) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSes-00011Y-40 for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSep-0008JT-3u for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:49 -0400 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]:32881) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSeo-0008Eu-SQ for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:47 -0400 Received: by mail-wr1-x436.google.com with SMTP id s1so8974612wro.0 for ; Fri, 01 Nov 2019 01:51:46 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=cpklon7lgXWv3V0ZHDlYJqd8G/58j7vD/Z0D6CafQ/4=; b=DaQ9rMQ4fXPcKskmwk3wJL323XFfODyVR40TiPLuMIYH/eClsJx1LQ5sLz1YdUqTX9 zQpsBweKoK8E508eK/vkDQatr07CP0N/q7NOeNdqSoMnXMv2QhVXvcb4h9my6DRgf/nh +jpFMqMzoPbMeJMZGv7o3gvKrZhYdxi6fG/dt41cyEqa0zVWvHygbaWVpfqi9JeAC/HL p1X3HSKicpQ+k4Ms7aCvwlNCRspuYFjTIUTR9/Yh9sC8NFofnVFraEOe1H6fn+zF9LWR ve4m3xzcDXBIatp2xXyXWf3FD6cIj4vwFihL0o8fpOZZo1x+P5ravsWhO4Vb4hBJj3SI WxOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cpklon7lgXWv3V0ZHDlYJqd8G/58j7vD/Z0D6CafQ/4=; b=ovAz9VQ6z5X51vHJwflrnubKRJe0BgpVsnNCmCmYQIgMitj6OEuBjd8EPIM/nF795L D/e8T6BLxCkUdRnxefSKLW8mzyuKVqp+t+6lc2Si0n6CFJKiaYTz2PBd4DXd4oXor8/g QojXXxVALNssLemmVCBQlr6PlDN2MiGzodp+KPQai4mWm8JbLsgSaTrwp1g6Hb9MRYrK jWJebh7DeCx+ejjrY3Yauw4ai1lPGfknwVwrv7PSFfG+4CZ37HNAH3dTAQdOQSNkfY0V rnAFNUHmxOqFJ3k4DAY7ZqFnFPbUsT/VU3hDD+RnLz8NaXqY5sXL1BcaDdI3bbRqUAR4 O2eQ== X-Gm-Message-State: APjAAAXUf/nfgB1RbIbOd6v0FLqy35WE61mEcf1XG/EjlC7u8iGb/zwG wFKM+RgAYy++TCh9/RAxQSY6E80XU2s/Q6iA X-Google-Smtp-Source: APXvYqy/IA+qO2ewHyXvCKfZINhBgZqefEGWc1fNnlHtKiyternybSqFDClsfibrfH4lJhlXvZjBzA== X-Received: by 2002:adf:ff81:: with SMTP id j1mr607503wrr.98.1572598305514; Fri, 01 Nov 2019 01:51:45 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 02/11] tests: arm: Introduce cpu feature tests Date: Fri, 1 Nov 2019 08:51:31 +0000 Message-Id: <20191101085140.5205-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::436 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" From: Andrew Jones Now that Arm CPUs have advertised features lets add tests to ensure we maintain their expected availability with and without KVM. Signed-off-by: Andrew Jones Reviewed-by: Eric Auger Message-id: 20191031142734.8590-3-drjones@redhat.com Signed-off-by: Peter Maydell --- tests/Makefile.include | 5 +- tests/arm-cpu-features.c | 253 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 tests/arm-cpu-features.c diff --git a/tests/Makefile.include b/tests/Makefile.include index 56f73b46e2a..534ee487436 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -262,6 +262,7 @@ check-qtest-sparc64-$(CONFIG_ISA_TESTDEV) =3D tests/end= ianness-test$(EXESUF) check-qtest-sparc64-y +=3D tests/prom-env-test$(EXESUF) check-qtest-sparc64-y +=3D tests/boot-serial-test$(EXESUF) =20 +check-qtest-arm-y +=3D tests/arm-cpu-features$(EXESUF) check-qtest-arm-y +=3D tests/microbit-test$(EXESUF) check-qtest-arm-y +=3D tests/m25p80-test$(EXESUF) check-qtest-arm-y +=3D tests/test-arm-mptimer$(EXESUF) @@ -269,7 +270,8 @@ check-qtest-arm-y +=3D tests/boot-serial-test$(EXESUF) check-qtest-arm-y +=3D tests/hexloader-test$(EXESUF) check-qtest-arm-$(CONFIG_PFLASH_CFI02) +=3D tests/pflash-cfi02-test$(EXESU= F) =20 -check-qtest-aarch64-y =3D tests/numa-test$(EXESUF) +check-qtest-aarch64-y +=3D tests/arm-cpu-features$(EXESUF) +check-qtest-aarch64-y +=3D tests/numa-test$(EXESUF) check-qtest-aarch64-y +=3D tests/boot-serial-test$(EXESUF) check-qtest-aarch64-y +=3D tests/migration-test$(EXESUF) # TODO: once aarch64 TCG is fixed on ARM 32 bit host, make test unconditio= nal @@ -841,6 +843,7 @@ tests/test-qapi-util$(EXESUF): tests/test-qapi-util.o $= (test-util-obj-y) tests/numa-test$(EXESUF): tests/numa-test.o tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o tests/boot-sector.o test= s/acpi-utils.o tests/cdrom-test$(EXESUF): tests/cdrom-test.o tests/boot-sector.o $(libqos= -obj-y) +tests/arm-cpu-features$(EXESUF): tests/arm-cpu-features.o =20 tests/migration/stress$(EXESUF): tests/migration/stress.o $(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ,"L= INK","$(TARGET_DIR)$@") diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c new file mode 100644 index 00000000000..6ebb03d7ad6 --- /dev/null +++ b/tests/arm-cpu-features.c @@ -0,0 +1,253 @@ +/* + * Arm CPU feature test cases + * + * Copyright (c) 2019 Red Hat Inc. + * Authors: + * Andrew Jones + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ +#include "qemu/osdep.h" +#include "libqtest.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qjson.h" + +#define MACHINE "-machine virt,gic-version=3Dmax,accel=3Dtcg " +#define MACHINE_KVM "-machine virt,gic-version=3Dmax,accel=3Dkvm:tcg " +#define QUERY_HEAD "{ 'execute': 'query-cpu-model-expansion', " \ + " 'arguments': { 'type': 'full', " +#define QUERY_TAIL "}}" + +static bool kvm_enabled(QTestState *qts) +{ + QDict *resp, *qdict; + bool enabled; + + resp =3D qtest_qmp(qts, "{ 'execute': 'query-kvm' }"); + g_assert(qdict_haskey(resp, "return")); + qdict =3D qdict_get_qdict(resp, "return"); + g_assert(qdict_haskey(qdict, "enabled")); + enabled =3D qdict_get_bool(qdict, "enabled"); + qobject_unref(resp); + + return enabled; +} + +static QDict *do_query_no_props(QTestState *qts, const char *cpu_type) +{ + return qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s }" + QUERY_TAIL, cpu_type); +} + +static QDict *do_query(QTestState *qts, const char *cpu_type, + const char *fmt, ...) +{ + QDict *resp; + + if (fmt) { + QDict *args; + va_list ap; + + va_start(ap, fmt); + args =3D qdict_from_vjsonf_nofail(fmt, ap); + va_end(ap); + + resp =3D qtest_qmp(qts, QUERY_HEAD "'model': { 'name': %s, " + "'props': %p }" + QUERY_TAIL, cpu_type, args); + } else { + resp =3D do_query_no_props(qts, cpu_type); + } + + return resp; +} + +static const char *resp_get_error(QDict *resp) +{ + QDict *qdict; + + g_assert(resp); + + qdict =3D qdict_get_qdict(resp, "error"); + if (qdict) { + return qdict_get_str(qdict, "desc"); + } + + return NULL; +} + +#define assert_error(qts, cpu_type, expected_error, fmt, ...) \ +({ \ + QDict *_resp; \ + const char *_error; \ + \ + _resp =3D do_query(qts, cpu_type, fmt, ##__VA_ARGS__); \ + g_assert(_resp); \ + _error =3D resp_get_error(_resp); \ + g_assert(_error); \ + g_assert(g_str_equal(_error, expected_error)); \ + qobject_unref(_resp); \ +}) + +static bool resp_has_props(QDict *resp) +{ + QDict *qdict; + + g_assert(resp); + + if (!qdict_haskey(resp, "return")) { + return false; + } + qdict =3D qdict_get_qdict(resp, "return"); + + if (!qdict_haskey(qdict, "model")) { + return false; + } + qdict =3D qdict_get_qdict(qdict, "model"); + + return qdict_haskey(qdict, "props"); +} + +static QDict *resp_get_props(QDict *resp) +{ + QDict *qdict; + + g_assert(resp); + g_assert(resp_has_props(resp)); + + qdict =3D qdict_get_qdict(resp, "return"); + qdict =3D qdict_get_qdict(qdict, "model"); + qdict =3D qdict_get_qdict(qdict, "props"); + + return qdict; +} + +#define assert_has_feature(qts, cpu_type, feature) \ +({ \ + QDict *_resp =3D do_query_no_props(qts, cpu_type); \ + g_assert(_resp); \ + g_assert(resp_has_props(_resp)); \ + g_assert(qdict_get(resp_get_props(_resp), feature)); \ + qobject_unref(_resp); \ +}) + +#define assert_has_not_feature(qts, cpu_type, feature) \ +({ \ + QDict *_resp =3D do_query_no_props(qts, cpu_type); \ + g_assert(_resp); \ + g_assert(!resp_has_props(_resp) || \ + !qdict_get(resp_get_props(_resp), feature)); \ + qobject_unref(_resp); \ +}) + +static void assert_type_full(QTestState *qts) +{ + const char *error; + QDict *resp; + + resp =3D qtest_qmp(qts, "{ 'execute': 'query-cpu-model-expansion', " + "'arguments': { 'type': 'static', " + "'model': { 'name': 'foo' }}}"); + g_assert(resp); + error =3D resp_get_error(resp); + g_assert(error); + g_assert(g_str_equal(error, + "The requested expansion type is not supported")); + qobject_unref(resp); +} + +static void assert_bad_props(QTestState *qts, const char *cpu_type) +{ + const char *error; + QDict *resp; + + resp =3D qtest_qmp(qts, "{ 'execute': 'query-cpu-model-expansion', " + "'arguments': { 'type': 'full', " + "'model': { 'name': %s, " + "'props': false }}}", + cpu_type); + g_assert(resp); + error =3D resp_get_error(resp); + g_assert(error); + g_assert(g_str_equal(error, + "Invalid parameter type for 'props', expected: di= ct")); + qobject_unref(resp); +} + +static void test_query_cpu_model_expansion(const void *data) +{ + QTestState *qts; + + qts =3D qtest_init(MACHINE "-cpu max"); + + /* Test common query-cpu-model-expansion input validation */ + assert_type_full(qts); + assert_bad_props(qts, "max"); + assert_error(qts, "foo", "The CPU type 'foo' is not a recognized " + "ARM CPU type", NULL); + assert_error(qts, "max", "Parameter 'not-a-prop' is unexpected", + "{ 'not-a-prop': false }"); + assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL); + + /* Test expected feature presence/absence for some cpu types */ + assert_has_feature(qts, "max", "pmu"); + assert_has_feature(qts, "cortex-a15", "pmu"); + assert_has_not_feature(qts, "cortex-a15", "aarch64"); + + if (g_str_equal(qtest_get_arch(), "aarch64")) { + assert_has_feature(qts, "max", "aarch64"); + assert_has_feature(qts, "cortex-a57", "pmu"); + assert_has_feature(qts, "cortex-a57", "aarch64"); + + /* Test that features that depend on KVM generate errors without. = */ + assert_error(qts, "max", + "'aarch64' feature cannot be disabled " + "unless KVM is enabled and 32-bit EL1 " + "is supported", + "{ 'aarch64': false }"); + } + + qtest_quit(qts); +} + +static void test_query_cpu_model_expansion_kvm(const void *data) +{ + QTestState *qts; + + qts =3D qtest_init(MACHINE_KVM "-cpu max"); + + /* + * These tests target the 'host' CPU type, so KVM must be enabled. + */ + if (!kvm_enabled(qts)) { + qtest_quit(qts); + return; + } + + if (g_str_equal(qtest_get_arch(), "aarch64")) { + assert_has_feature(qts, "host", "aarch64"); + assert_has_feature(qts, "host", "pmu"); + + assert_error(qts, "cortex-a15", + "We cannot guarantee the CPU type 'cortex-a15' works " + "with KVM on this host", NULL); + } else { + assert_has_not_feature(qts, "host", "aarch64"); + assert_has_not_feature(qts, "host", "pmu"); + } + + qtest_quit(qts); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + qtest_add_data_func("/arm/query-cpu-model-expansion", + NULL, test_query_cpu_model_expansion); + qtest_add_data_func("/arm/kvm/query-cpu-model-expansion", + NULL, test_query_cpu_model_expansion_kvm); + + return g_test_run(); +} --=20 2.20.1 From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572598486; cv=none; d=zoho.com; s=zohoarc; b=gAHVQACn7pY/rTgk3w2qP1JvoxuvEUSi5kmhsjRjGMGsBKnWQ2QhPYzh16/nyj0zdEIB6JQYd5voo4frooP5U6otGY9FcWL/XS0sHsxU4bm997wRihvZFkiBclyznYm9okl8uO+f8VG0fBdEwSj1gBZBf38pJNgALYS35ttgZMs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572598486; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=cU0ztaO6mnX2lbCzssErMqt/BItGWLQpsUe0rwEBjZo=; b=hpF0YnuBGWbb2nxPwAkFqI3e55ELAbSxptSDldOzajrEH7LGfsfB11TA+EfEWaL3FpAW/NRnsTVKF9HVM5CcuE39wBsPLA3CbIFEh/3zYwhBIiEPNLiuZGatj2DvPdSSMQUldJUwkIRzp8pMsNQoqHrSbUfCgAXwPTX+ZcENKZY= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1572598486642390.2295794608855; Fri, 1 Nov 2019 01:54:46 -0700 (PDT) Received: from localhost ([::1]:57510 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQShg-0003ZQ-Lf for importer@patchew.org; Fri, 01 Nov 2019 04:54:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56480) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSet-00014u-GZ for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSer-0008Tt-4A for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:51 -0400 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]:32871) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSeq-0008KI-TJ for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:49 -0400 Received: by mail-wr1-x42b.google.com with SMTP id s1so8974650wro.0 for ; Fri, 01 Nov 2019 01:51:47 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=cU0ztaO6mnX2lbCzssErMqt/BItGWLQpsUe0rwEBjZo=; b=Cl2BtAo/vQYAETpF4aag+MiOlQGxfoKfG6BzH3m6ZSl4INfag2u/j52l733IlRQDyN B4Ngyy5z4agna0XIJxVI8PRkKPEUsTCh8zNDicucybu9Bai+Hm21ujVGIYlLaPYk0r1R ySIram8iJFGiQrd7D3Ty7jMqZ3jz2foOST9OigLlg03ALz1EteGPI3MEhvKmWRcjELSN FySbWn1cE8gpoRYf8jz0B6uJ5PfcV58k+u+mdVbAypNaKHvMv1bzsxFTL71dzPIjw8mp p7hDXlC5g0CYHQtQtZnzv1HK2fM297FyRHv7zhJxaFFzLmH3QcN/b5Q09cD1N6M9WyPZ ot8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cU0ztaO6mnX2lbCzssErMqt/BItGWLQpsUe0rwEBjZo=; b=mIu3IAaIqXExCixMq5/2GRS0Y3idm2w2XfxPQX7qlOC1LgipeKn5bZzY27DokkpLji uN3T/18eKPd5OtkyTjItowAB+zOl4//IY2m6V3DMY57jP3RSg35a3vRNDG1nsTuFpGZ2 2960pzbb63V8Ud1lZMSfnQdR7n0TofE8HeLZsmm8SEBX9npa+wP7GJsuFCvtvyVo6YXl qPoj7D+cSiwjRaKPxqpPUDHBeZ++LHxzn6DX+bQgbJ2Pt2aIDaKPPeQU3ynptWvD3UO9 nbgz479ABOHQwDqpbaBsHIPlHO2mIHZYtzisaiXQLcsfYVbNPT5YdG6MEb6mV5l9qGgZ FoNQ== X-Gm-Message-State: APjAAAUH9wA8Yl4AmKI8sSxGdbBK065Rx1qhbmSZSnm87RCK7WKTJv3G zLjuBDwnLWGECmL5lh+lf3y/JVV6zkvRO8pM X-Google-Smtp-Source: APXvYqwtOBoYSRo2/7adod2StOo51HTBaW6kIBNJF7iwc2Gmv9sAXSgfKvLcxf4VTyopI3+3CjyOHw== X-Received: by 2002:a05:6000:101:: with SMTP id o1mr9805058wrx.394.1572598306553; Fri, 01 Nov 2019 01:51:46 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 03/11] target/arm: Allow SVE to be disabled via a CPU property Date: Fri, 1 Nov 2019 08:51:32 +0000 Message-Id: <20191101085140.5205-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42b X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" From: Andrew Jones Since 97a28b0eeac14 ("target/arm: Allow VFP and Neon to be disabled via a CPU property") we can disable the 'max' cpu model's VFP and neon features, but there's no way to disable SVE. Add the 'sve=3Don|off' property to give it that flexibility. We also rename cpu_max_get/set_sve_vq to cpu_max_get/set_sve_max_vq in order for them to follow the typical *_get/set_ pattern. Signed-off-by: Andrew Jones Reviewed-by: Richard Henderson Reviewed-by: Eric Auger Tested-by: Masayoshi Mizuma Reviewed-by: Beata Michalska Message-id: 20191031142734.8590-4-drjones@redhat.com Signed-off-by: Peter Maydell --- target/arm/cpu.c | 3 ++- target/arm/cpu64.c | 52 ++++++++++++++++++++++++++++++++++------ target/arm/monitor.c | 2 +- tests/arm-cpu-features.c | 1 + 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index ab3e1a03616..72a27ec4b0e 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -200,7 +200,8 @@ static void arm_cpu_reset(CPUState *s) env->cp15.cpacr_el1 =3D deposit64(env->cp15.cpacr_el1, 16, 2, 3); env->cp15.cptr_el[3] |=3D CPTR_EZ; /* with maximum vector length */ - env->vfp.zcr_el[1] =3D cpu->sve_max_vq - 1; + env->vfp.zcr_el[1] =3D cpu_isar_feature(aa64_sve, cpu) ? + cpu->sve_max_vq - 1 : 0; env->vfp.zcr_el[2] =3D env->vfp.zcr_el[1]; env->vfp.zcr_el[3] =3D env->vfp.zcr_el[1]; /* diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index d7f5bf610a7..89a8ae77fe8 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -256,15 +256,23 @@ static void aarch64_a72_initfn(Object *obj) define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); } =20 -static void cpu_max_get_sve_vq(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) +static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *na= me, + void *opaque, Error **errp) { ARMCPU *cpu =3D ARM_CPU(obj); - visit_type_uint32(v, name, &cpu->sve_max_vq, errp); + uint32_t value; + + /* All vector lengths are disabled when SVE is off. */ + if (!cpu_isar_feature(aa64_sve, cpu)) { + value =3D 0; + } else { + value =3D cpu->sve_max_vq; + } + visit_type_uint32(v, name, &value, errp); } =20 -static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) +static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *na= me, + void *opaque, Error **errp) { ARMCPU *cpu =3D ARM_CPU(obj); Error *err =3D NULL; @@ -279,6 +287,34 @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v= , const char *name, error_propagate(errp, err); } =20 +static void cpu_arm_get_sve(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + ARMCPU *cpu =3D ARM_CPU(obj); + bool value =3D cpu_isar_feature(aa64_sve, cpu); + + visit_type_bool(v, name, &value, errp); +} + +static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + ARMCPU *cpu =3D ARM_CPU(obj); + Error *err =3D NULL; + bool value; + uint64_t t; + + visit_type_bool(v, name, &value, &err); + if (err) { + error_propagate(errp, err); + return; + } + + t =3D cpu->isar.id_aa64pfr0; + t =3D FIELD_DP64(t, ID_AA64PFR0, SVE, value); + cpu->isar.id_aa64pfr0 =3D t; +} + /* -cpu max: if KVM is enabled, like -cpu host (best possible with this ho= st); * otherwise, a CPU with as many features enabled as our emulation support= s. * The version of '-cpu max' for qemu-system-arm is defined in cpu.c; @@ -391,8 +427,10 @@ static void aarch64_max_initfn(Object *obj) #endif =20 cpu->sve_max_vq =3D ARM_MAX_VQ; - object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_v= q, - cpu_max_set_sve_vq, NULL, NULL, &error_fatal); + object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_m= ax_vq, + cpu_max_set_sve_max_vq, NULL, NULL, &error_fat= al); + object_property_add(obj, "sve", "bool", cpu_arm_get_sve, + cpu_arm_set_sve, NULL, NULL, &error_fatal); } } =20 diff --git a/target/arm/monitor.c b/target/arm/monitor.c index 560970de7f5..2209b27b9a0 100644 --- a/target/arm/monitor.c +++ b/target/arm/monitor.c @@ -97,7 +97,7 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **err= p) * then the order that considers those dependencies must be used. */ static const char *cpu_model_advertised_features[] =3D { - "aarch64", "pmu", + "aarch64", "pmu", "sve", NULL }; =20 diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c index 6ebb03d7ad6..d5e18eb6662 100644 --- a/tests/arm-cpu-features.c +++ b/tests/arm-cpu-features.c @@ -197,6 +197,7 @@ static void test_query_cpu_model_expansion(const void *= data) =20 if (g_str_equal(qtest_get_arch(), "aarch64")) { assert_has_feature(qts, "max", "aarch64"); + assert_has_feature(qts, "max", "sve"); assert_has_feature(qts, "cortex-a57", "pmu"); assert_has_feature(qts, "cortex-a57", "aarch64"); =20 --=20 2.20.1 From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572598942; cv=none; d=zoho.com; s=zohoarc; b=aSGMpqZ6iv8teUAJOFSaGYTczobxUGEEHf4+BlRrnIjjCU2JK7quZUN6xwKqBKiLYl8VAg2vPd6IwUAqF7lpchMh2eEJ9KB0M5S6mGoY1yJ4nmFpFsO0ETz0MhazJvtnLNCHSNibnUX5DdiJHfsV3JzcTDumMTC9/qCp9SuV5fg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572598942; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=89fRV9cOr0KN6H8F60S4K5XeQETe6xhRq/4Dfnr/EpA=; b=HZSqzyhxRvN1a4oiV46IoUbrRkpxadIpBsnC5ELEjBPnryepmUCXUc92I52XqdwhqlTZSshN0bykvT6IJNFcA/Of3Cut5EoxckIi5kvKrNvLZHkWGTRyS/lJ/3Cjf5ZYcCBiWDz2s5rBd4dNmw/xFbl2CHg2C+n91Vm+hQ758so= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1572598942299433.6473932946501; Fri, 1 Nov 2019 02:02:22 -0700 (PDT) Received: from localhost ([::1]:57822 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSp2-0002w7-AK for importer@patchew.org; Fri, 01 Nov 2019 05:02:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56527) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSex-00019q-Oq for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:52:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSet-0000GP-Op for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:55 -0400 Received: from mail-wm1-x32c.google.com ([2a00:1450:4864:20::32c]:35940) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSet-000063-DS for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:51 -0400 Received: by mail-wm1-x32c.google.com with SMTP id c22so8387684wmd.1 for ; Fri, 01 Nov 2019 01:51:51 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=89fRV9cOr0KN6H8F60S4K5XeQETe6xhRq/4Dfnr/EpA=; b=BCXnLiIb0V/GdegRmseZRz/bJ6Tbmj7NmatTzbWN4SRPFlX0Q36nqT0rUkBVIiurYJ 1QilL+CZLpvSaxgWlF5zjYtV7rg3A5JaNsv/aGoV7fypQwK9k+MSfwyuWg0Bp2gVCbfd /uzE2VFj3eTwa9GIALbdw1PHB2SQ7tShBj7Kh6Q7gjoGBoRVVbTOnuLul4Nu3pitdWWT 57DLbVTagovxEDdqPXaj5LgQJAHZG2ssZeH8AiQ3EpyELKt7GKMQD7GfkS4cZGxsbaZU FGtgZkWI7cg9TFKeammVhEyh1d0H3AlI2mSpDiJ6TttODZxYOjLe2/WNnC5FglMNmyaZ zhzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=89fRV9cOr0KN6H8F60S4K5XeQETe6xhRq/4Dfnr/EpA=; b=XLWMmdPeax7Iihp9finiSb9EtstLJw4s3kQUBe3RpRmL7+6I6qhxcWc3CME/npG02Y PxbcXLl639AJCv3ig5sovTmgTrgtMPS16BQZtewgxiKd0fJXPmEMYW3ymwPJosKcwx8n uOnepsMNKC5L4R11KtxpfJ1XkxWCunAEHLDojdm8rrw4mZKY+eMpxAwrU/2FkVw1fsMo dmMU3p3Byfuy79hbXwHzUNs41N06HWEFJx6BenAIgviEPn7zlDAs06La0hsj1qDdLumK Z7aJzf5rcfI8VrCOfYcQv+jlifmfPAvzR2Dld8kVXWF5zeP2/txsYeRhyzre24fK4vtV B8iw== X-Gm-Message-State: APjAAAVgxzruh8RgE+o1cE3R54iZDf7NU//o0POhdtX+6M6PbnRpnVaB i3Tky0tNWCPPld5RJ98NnnOVdhaw0HBvafx6 X-Google-Smtp-Source: APXvYqyIRqTcYog/n1eUu+vxUxLNt6V901ub7oMmG3D4Nx0SxTnsG0aqzqAG0qW7vCIj+85Lk33VgQ== X-Received: by 2002:a05:600c:21c4:: with SMTP id x4mr8838241wmj.172.1572598308116; Fri, 01 Nov 2019 01:51:48 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 04/11] target/arm/cpu64: max cpu: Introduce sve properties Date: Fri, 1 Nov 2019 08:51:33 +0000 Message-Id: <20191101085140.5205-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::32c X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" From: Andrew Jones Introduce cpu properties to give fine control over SVE vector lengths. We introduce a property for each valid length up to the current maximum supported, which is 2048-bits. The properties are named, e.g. sve128, sve256, sve384, sve512, ..., where the number is the number of bits. See the updates to docs/arm-cpu-features.rst for a description of the semantics and for example uses. Note, as sve-max-vq is still present and we'd like to be able to support qmp_query_cpu_model_expansion with guests launched with e.g. -cpu max,sve-max-vq=3D8 on their command lines, then we do allow sve-max-vq and sve properties to be provided at the same time, but this is not recommended, and is why sve-max-vq is not mentioned in the document. If sve-max-vq is provided then it enables all lengths smaller than and including the max and disables all lengths larger. It also has the side-effect that no larger lengths may be enabled and that the max itself cannot be disabled. Smaller non-power-of-two lengths may, however, be disabled, e.g. -cpu max,sve-max-vq=3D4,sve384=3Doff provides a guest the vector lengths 128, 256, and 512 bits. This patch has been co-authored with Richard Henderson, who reworked the target/arm/cpu64.c changes in order to push all the validation and auto-enabling/disabling steps into the finalizer, resulting in a nice LOC reduction. Signed-off-by: Andrew Jones Reviewed-by: Richard Henderson Reviewed-by: Eric Auger Tested-by: Masayoshi Mizuma Reviewed-by: Beata Michalska Message-id: 20191031142734.8590-5-drjones@redhat.com Signed-off-by: Peter Maydell --- include/qemu/bitops.h | 1 + target/arm/cpu.h | 19 ++++ target/arm/cpu.c | 19 ++++ target/arm/cpu64.c | 192 ++++++++++++++++++++++++++++++++++++- target/arm/helper.c | 10 +- target/arm/monitor.c | 12 +++ tests/arm-cpu-features.c | 194 ++++++++++++++++++++++++++++++++++++++ docs/arm-cpu-features.rst | 168 +++++++++++++++++++++++++++++++-- 8 files changed, 606 insertions(+), 9 deletions(-) diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h index 3f0926cf40c..ee76552c062 100644 --- a/include/qemu/bitops.h +++ b/include/qemu/bitops.h @@ -20,6 +20,7 @@ #define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE) =20 #define BIT(nr) (1UL << (nr)) +#define BIT_ULL(nr) (1ULL << (nr)) #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(lo= ng)) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index d844ea21d8d..a044d6028b6 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -184,8 +184,13 @@ typedef struct { =20 #ifdef TARGET_AARCH64 # define ARM_MAX_VQ 16 +void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp); +uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq); #else # define ARM_MAX_VQ 1 +static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { } +static inline uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t v= q) +{ return 0; } #endif =20 typedef struct ARMVectorReg { @@ -918,6 +923,18 @@ struct ARMCPU { =20 /* Used to set the maximum vector length the cpu will support. */ uint32_t sve_max_vq; + + /* + * In sve_vq_map each set bit is a supported vector length of + * (bit-number + 1) * 16 bytes, i.e. each bit number + 1 is the vector + * length in quadwords. + * + * While processing properties during initialization, corresponding + * sve_vq_init bits are set for bits in sve_vq_map that have been + * set by properties. + */ + DECLARE_BITMAP(sve_vq_map, ARM_MAX_VQ); + DECLARE_BITMAP(sve_vq_init, ARM_MAX_VQ); }; =20 void arm_cpu_post_init(Object *obj); @@ -1837,6 +1854,8 @@ static inline int arm_feature(CPUARMState *env, int f= eature) return (env->features & (1ULL << feature)) !=3D 0; } =20 +void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp); + #if !defined(CONFIG_USER_ONLY) /* Return true if exception levels below EL3 are in secure state, * or would be following an exception return to that level. diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 72a27ec4b0e..17d1f2b2894 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1198,6 +1198,19 @@ static void arm_cpu_finalizefn(Object *obj) #endif } =20 +void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp) +{ + Error *local_err =3D NULL; + + if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { + arm_cpu_sve_finalize(cpu, &local_err); + if (local_err !=3D NULL) { + error_propagate(errp, local_err); + return; + } + } +} + static void arm_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs =3D CPU(dev); @@ -1254,6 +1267,12 @@ static void arm_cpu_realizefn(DeviceState *dev, Erro= r **errp) return; } =20 + arm_cpu_finalize_features(cpu, &local_err); + if (local_err !=3D NULL) { + error_propagate(errp, local_err); + return; + } + if (arm_feature(env, ARM_FEATURE_AARCH64) && cpu->has_vfp !=3D cpu->has_neon) { /* diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 89a8ae77fe8..34b0ba2cf6f 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -256,6 +256,151 @@ static void aarch64_a72_initfn(Object *obj) define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); } =20 +void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) +{ + /* + * If any vector lengths are explicitly enabled with sve properties, + * then all other lengths are implicitly disabled. If sve-max-vq is + * specified then it is the same as explicitly enabling all lengths + * up to and including the specified maximum, which means all larger + * lengths will be implicitly disabled. If no sve properties + * are enabled and sve-max-vq is not specified, then all lengths not + * explicitly disabled will be enabled. Additionally, all power-of-two + * vector lengths less than the maximum enabled length will be + * automatically enabled and all vector lengths larger than the largest + * disabled power-of-two vector length will be automatically disabled. + * Errors are generated if the user provided input that interferes with + * any of the above. Finally, if SVE is not disabled, then at least o= ne + * vector length must be enabled. + */ + DECLARE_BITMAP(tmp, ARM_MAX_VQ); + uint32_t vq, max_vq =3D 0; + + /* + * Process explicit sve properties. + * From the properties, sve_vq_map implies sve_vq_init. + * Check first for any sve enabled. + */ + if (!bitmap_empty(cpu->sve_vq_map, ARM_MAX_VQ)) { + max_vq =3D find_last_bit(cpu->sve_vq_map, ARM_MAX_VQ) + 1; + + if (cpu->sve_max_vq && max_vq > cpu->sve_max_vq) { + error_setg(errp, "cannot enable sve%d", max_vq * 128); + error_append_hint(errp, "sve%d is larger than the maximum vect= or " + "length, sve-max-vq=3D%d (%d bits)\n", + max_vq * 128, cpu->sve_max_vq, + cpu->sve_max_vq * 128); + return; + } + + /* Propagate enabled bits down through required powers-of-two. */ + for (vq =3D pow2floor(max_vq); vq >=3D 1; vq >>=3D 1) { + if (!test_bit(vq - 1, cpu->sve_vq_init)) { + set_bit(vq - 1, cpu->sve_vq_map); + } + } + } else if (cpu->sve_max_vq =3D=3D 0) { + /* + * No explicit bits enabled, and no implicit bits from sve-max-vq. + */ + if (!cpu_isar_feature(aa64_sve, cpu)) { + /* SVE is disabled and so are all vector lengths. Good. */ + return; + } + + /* Disabling a power-of-two disables all larger lengths. */ + if (test_bit(0, cpu->sve_vq_init)) { + error_setg(errp, "cannot disable sve128"); + error_append_hint(errp, "Disabling sve128 results in all vecto= r " + "lengths being disabled.\n"); + error_append_hint(errp, "With SVE enabled, at least one vector= " + "length must be enabled.\n"); + return; + } + for (vq =3D 2; vq <=3D ARM_MAX_VQ; vq <<=3D 1) { + if (test_bit(vq - 1, cpu->sve_vq_init)) { + break; + } + } + max_vq =3D vq <=3D ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ; + + bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq); + max_vq =3D find_last_bit(cpu->sve_vq_map, max_vq) + 1; + } + + /* + * Process the sve-max-vq property. + * Note that we know from the above that no bit above + * sve-max-vq is currently set. + */ + if (cpu->sve_max_vq !=3D 0) { + max_vq =3D cpu->sve_max_vq; + + if (!test_bit(max_vq - 1, cpu->sve_vq_map) && + test_bit(max_vq - 1, cpu->sve_vq_init)) { + error_setg(errp, "cannot disable sve%d", max_vq * 128); + error_append_hint(errp, "The maximum vector length must be " + "enabled, sve-max-vq=3D%d (%d bits)\n", + max_vq, max_vq * 128); + return; + } + + /* Set all bits not explicitly set within sve-max-vq. */ + bitmap_complement(tmp, cpu->sve_vq_init, max_vq); + bitmap_or(cpu->sve_vq_map, cpu->sve_vq_map, tmp, max_vq); + } + + /* + * We should know what max-vq is now. Also, as we're done + * manipulating sve-vq-map, we ensure any bits above max-vq + * are clear, just in case anybody looks. + */ + assert(max_vq !=3D 0); + bitmap_clear(cpu->sve_vq_map, max_vq, ARM_MAX_VQ - max_vq); + + /* Ensure all required powers-of-two are enabled. */ + for (vq =3D pow2floor(max_vq); vq >=3D 1; vq >>=3D 1) { + if (!test_bit(vq - 1, cpu->sve_vq_map)) { + error_setg(errp, "cannot disable sve%d", vq * 128); + error_append_hint(errp, "sve%d is required as it " + "is a power-of-two length smaller than " + "the maximum, sve%d\n", + vq * 128, max_vq * 128); + return; + } + } + + /* + * Now that we validated all our vector lengths, the only question + * left to answer is if we even want SVE at all. + */ + if (!cpu_isar_feature(aa64_sve, cpu)) { + error_setg(errp, "cannot enable sve%d", max_vq * 128); + error_append_hint(errp, "SVE must be enabled to enable vector " + "lengths.\n"); + error_append_hint(errp, "Add sve=3Don to the CPU property list.\n"= ); + return; + } + + /* From now on sve_max_vq is the actual maximum supported length. */ + cpu->sve_max_vq =3D max_vq; +} + +uint32_t arm_cpu_vq_map_next_smaller(ARMCPU *cpu, uint32_t vq) +{ + uint32_t bitnum; + + /* + * We allow vq =3D=3D ARM_MAX_VQ + 1 to be input because the caller ma= y want + * to find the maximum vq enabled, which may be ARM_MAX_VQ, but this + * function always returns the next smaller than the input. + */ + assert(vq && vq <=3D ARM_MAX_VQ + 1); + + bitnum =3D find_last_bit(cpu->sve_vq_map, vq - 1); + return bitnum =3D=3D vq - 1 ? 0 : bitnum + 1; +} + static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *na= me, void *opaque, Error **errp) { @@ -287,6 +432,44 @@ static void cpu_max_set_sve_max_vq(Object *obj, Visito= r *v, const char *name, error_propagate(errp, err); } =20 +static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + ARMCPU *cpu =3D ARM_CPU(obj); + uint32_t vq =3D atoi(&name[3]) / 128; + bool value; + + /* All vector lengths are disabled when SVE is off. */ + if (!cpu_isar_feature(aa64_sve, cpu)) { + value =3D false; + } else { + value =3D test_bit(vq - 1, cpu->sve_vq_map); + } + visit_type_bool(v, name, &value, errp); +} + +static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + ARMCPU *cpu =3D ARM_CPU(obj); + uint32_t vq =3D atoi(&name[3]) / 128; + Error *err =3D NULL; + bool value; + + visit_type_bool(v, name, &value, &err); + if (err) { + error_propagate(errp, err); + return; + } + + if (value) { + set_bit(vq - 1, cpu->sve_vq_map); + } else { + clear_bit(vq - 1, cpu->sve_vq_map); + } + set_bit(vq - 1, cpu->sve_vq_init); +} + static void cpu_arm_get_sve(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { @@ -323,6 +506,7 @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, co= nst char *name, static void aarch64_max_initfn(Object *obj) { ARMCPU *cpu =3D ARM_CPU(obj); + uint32_t vq; =20 if (kvm_enabled()) { kvm_arm_set_cpu_features_from_host(cpu); @@ -426,11 +610,17 @@ static void aarch64_max_initfn(Object *obj) cpu->dcz_blocksize =3D 7; /* 512 bytes */ #endif =20 - cpu->sve_max_vq =3D ARM_MAX_VQ; object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_m= ax_vq, cpu_max_set_sve_max_vq, NULL, NULL, &error_fat= al); object_property_add(obj, "sve", "bool", cpu_arm_get_sve, cpu_arm_set_sve, NULL, NULL, &error_fatal); + + for (vq =3D 1; vq <=3D ARM_MAX_VQ; ++vq) { + char name[8]; + sprintf(name, "sve%d", vq * 128); + object_property_add(obj, name, "bool", cpu_arm_get_sve_vq, + cpu_arm_set_sve_vq, NULL, NULL, &error_fat= al); + } } } =20 diff --git a/target/arm/helper.c b/target/arm/helper.c index 63815fc4cfc..be67e2c66d6 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -5361,6 +5361,13 @@ int sve_exception_el(CPUARMState *env, int el) return 0; } =20 +static uint32_t sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len) +{ + uint32_t start_vq =3D (start_len & 0xf) + 1; + + return arm_cpu_vq_map_next_smaller(cpu, start_vq + 1) - 1; +} + /* * Given that SVE is enabled, return the vector length for EL. */ @@ -5378,7 +5385,8 @@ uint32_t sve_zcr_len_for_el(CPUARMState *env, int el) if (arm_feature(env, ARM_FEATURE_EL3)) { zcr_len =3D MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]); } - return zcr_len; + + return sve_zcr_get_valid_len(cpu, zcr_len); } =20 static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri, diff --git a/target/arm/monitor.c b/target/arm/monitor.c index 2209b27b9a0..fa054f8a369 100644 --- a/target/arm/monitor.c +++ b/target/arm/monitor.c @@ -90,6 +90,8 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **err= p) return head; } =20 +QEMU_BUILD_BUG_ON(ARM_MAX_VQ > 16); + /* * These are cpu model features we want to advertise. The order here * matters as this is the order in which qmp_query_cpu_model_expansion @@ -98,6 +100,9 @@ GICCapabilityList *qmp_query_gic_capabilities(Error **er= rp) */ static const char *cpu_model_advertised_features[] =3D { "aarch64", "pmu", "sve", + "sve128", "sve256", "sve384", "sve512", + "sve640", "sve768", "sve896", "sve1024", "sve1152", "sve1280", + "sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048", NULL }; =20 @@ -186,6 +191,9 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(Cp= uModelExpansionType type, if (!err) { visit_check_struct(visitor, &err); } + if (!err) { + arm_cpu_finalize_features(ARM_CPU(obj), &err); + } visit_end_struct(visitor, NULL); visit_free(visitor); if (err) { @@ -193,6 +201,10 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(C= puModelExpansionType type, error_propagate(errp, err); return NULL; } + } else { + Error *err =3D NULL; + arm_cpu_finalize_features(ARM_CPU(obj), &err); + assert(err =3D=3D NULL); } =20 expansion_info =3D g_new0(CpuModelExpansionInfo, 1); diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c index d5e18eb6662..7fd01f0ea3f 100644 --- a/tests/arm-cpu-features.c +++ b/tests/arm-cpu-features.c @@ -9,10 +9,17 @@ * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" +#include "qemu/bitops.h" #include "libqtest.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qjson.h" =20 +/* + * We expect the SVE max-vq to be 16. Also it must be <=3D 64 + * for our test code, otherwise 'vls' can't just be a uint64_t. + */ +#define SVE_MAX_VQ 16 + #define MACHINE "-machine virt,gic-version=3Dmax,accel=3Dtcg " #define MACHINE_KVM "-machine virt,gic-version=3Dmax,accel=3Dkvm:tcg " #define QUERY_HEAD "{ 'execute': 'query-cpu-model-expansion', " \ @@ -175,6 +182,183 @@ static void assert_bad_props(QTestState *qts, const c= har *cpu_type) qobject_unref(resp); } =20 +static uint64_t resp_get_sve_vls(QDict *resp) +{ + QDict *props; + const QDictEntry *e; + uint64_t vls =3D 0; + int n =3D 0; + + g_assert(resp); + g_assert(resp_has_props(resp)); + + props =3D resp_get_props(resp); + + for (e =3D qdict_first(props); e; e =3D qdict_next(props, e)) { + if (strlen(e->key) > 3 && !strncmp(e->key, "sve", 3) && + g_ascii_isdigit(e->key[3])) { + char *endptr; + int bits; + + bits =3D g_ascii_strtoll(&e->key[3], &endptr, 10); + if (!bits || *endptr !=3D '\0') { + continue; + } + + if (qdict_get_bool(props, e->key)) { + vls |=3D BIT_ULL((bits / 128) - 1); + } + ++n; + } + } + + g_assert(n =3D=3D SVE_MAX_VQ); + + return vls; +} + +#define assert_sve_vls(qts, cpu_type, expected_vls, fmt, ...) \ +({ \ + QDict *_resp =3D do_query(qts, cpu_type, fmt, ##__VA_ARGS__); \ + g_assert(_resp); \ + g_assert(resp_has_props(_resp)); \ + g_assert(resp_get_sve_vls(_resp) =3D=3D expected_vls); = \ + qobject_unref(_resp); \ +}) + +static void sve_tests_default(QTestState *qts, const char *cpu_type) +{ + /* + * With no sve-max-vq or sve properties on the command line + * the default is to have all vector lengths enabled. This also + * tests that 'sve' is 'on' by default. + */ + assert_sve_vls(qts, cpu_type, BIT_ULL(SVE_MAX_VQ) - 1, NULL); + + /* With SVE off, all vector lengths should also be off. */ + assert_sve_vls(qts, cpu_type, 0, "{ 'sve': false }"); + + /* With SVE on, we must have at least one vector length enabled. */ + assert_error(qts, cpu_type, "cannot disable sve128", "{ 'sve128': fals= e }"); + + /* Basic enable/disable tests. */ + assert_sve_vls(qts, cpu_type, 0x7, "{ 'sve384': true }"); + assert_sve_vls(qts, cpu_type, ((BIT_ULL(SVE_MAX_VQ) - 1) & ~BIT_ULL(2)= ), + "{ 'sve384': false }"); + + /* + * -------------------------------------------------------------------= -- + * power-of-two(vq) all-power- can can + * of-two(< vq) enable disab= le + * -------------------------------------------------------------------= -- + * vq < max_vq no MUST* yes yes + * vq < max_vq yes MUST* yes no + * -------------------------------------------------------------------= -- + * vq =3D=3D max_vq n/a MUST* yes** = yes** + * -------------------------------------------------------------------= -- + * vq > max_vq n/a no no yes + * vq > max_vq n/a yes yes yes + * -------------------------------------------------------------------= -- + * + * [*] "MUST" means this requirement must already be satisfied, + * otherwise 'max_vq' couldn't itself be enabled. + * + * [**] Not testable with the QMP interface, only with the command lin= e. + */ + + /* max_vq :=3D 8 */ + assert_sve_vls(qts, cpu_type, 0x8b, "{ 'sve1024': true }"); + + /* max_vq :=3D 8, vq < max_vq, !power-of-two(vq) */ + assert_sve_vls(qts, cpu_type, 0x8f, + "{ 'sve1024': true, 'sve384': true }"); + assert_sve_vls(qts, cpu_type, 0x8b, + "{ 'sve1024': true, 'sve384': false }"); + + /* max_vq :=3D 8, vq < max_vq, power-of-two(vq) */ + assert_sve_vls(qts, cpu_type, 0x8b, + "{ 'sve1024': true, 'sve256': true }"); + assert_error(qts, cpu_type, "cannot disable sve256", + "{ 'sve1024': true, 'sve256': false }"); + + /* max_vq :=3D 3, vq > max_vq, !all-power-of-two(< vq) */ + assert_error(qts, cpu_type, "cannot disable sve512", + "{ 'sve384': true, 'sve512': false, 'sve640': true }"); + + /* + * We can disable power-of-two vector lengths when all larger lengths + * are also disabled. We only need to disable the power-of-two length, + * as all non-enabled larger lengths will then be auto-disabled. + */ + assert_sve_vls(qts, cpu_type, 0x7, "{ 'sve512': false }"); + + /* max_vq :=3D 3, vq > max_vq, all-power-of-two(< vq) */ + assert_sve_vls(qts, cpu_type, 0x1f, + "{ 'sve384': true, 'sve512': true, 'sve640': true }"); + assert_sve_vls(qts, cpu_type, 0xf, + "{ 'sve384': true, 'sve512': true, 'sve640': false }"); +} + +static void sve_tests_sve_max_vq_8(const void *data) +{ + QTestState *qts; + + qts =3D qtest_init(MACHINE "-cpu max,sve-max-vq=3D8"); + + assert_sve_vls(qts, "max", BIT_ULL(8) - 1, NULL); + + /* + * Disabling the max-vq set by sve-max-vq is not allowed, but + * of course enabling it is OK. + */ + assert_error(qts, "max", "cannot disable sve1024", "{ 'sve1024': false= }"); + assert_sve_vls(qts, "max", 0xff, "{ 'sve1024': true }"); + + /* + * Enabling anything larger than max-vq set by sve-max-vq is not + * allowed, but of course disabling everything larger is OK. + */ + assert_error(qts, "max", "cannot enable sve1152", "{ 'sve1152': true }= "); + assert_sve_vls(qts, "max", 0xff, "{ 'sve1152': false }"); + + /* + * We can enable/disable non power-of-two lengths smaller than the + * max-vq set by sve-max-vq, but, while we can enable power-of-two + * lengths, we can't disable them. + */ + assert_sve_vls(qts, "max", 0xff, "{ 'sve384': true }"); + assert_sve_vls(qts, "max", 0xfb, "{ 'sve384': false }"); + assert_sve_vls(qts, "max", 0xff, "{ 'sve256': true }"); + assert_error(qts, "max", "cannot disable sve256", "{ 'sve256': false }= "); + + qtest_quit(qts); +} + +static void sve_tests_sve_off(const void *data) +{ + QTestState *qts; + + qts =3D qtest_init(MACHINE "-cpu max,sve=3Doff"); + + /* SVE is off, so the map should be empty. */ + assert_sve_vls(qts, "max", 0, NULL); + + /* The map stays empty even if we turn lengths off. */ + assert_sve_vls(qts, "max", 0, "{ 'sve128': false }"); + + /* It's an error to enable lengths when SVE is off. */ + assert_error(qts, "max", "cannot enable sve128", "{ 'sve128': true }"); + + /* With SVE re-enabled we should get all vector lengths enabled. */ + assert_sve_vls(qts, "max", BIT_ULL(SVE_MAX_VQ) - 1, "{ 'sve': true }"); + + /* Or enable SVE with just specific vector lengths. */ + assert_sve_vls(qts, "max", 0x3, + "{ 'sve': true, 'sve128': true, 'sve256': true }"); + + qtest_quit(qts); +} + static void test_query_cpu_model_expansion(const void *data) { QTestState *qts; @@ -198,9 +382,12 @@ static void test_query_cpu_model_expansion(const void = *data) if (g_str_equal(qtest_get_arch(), "aarch64")) { assert_has_feature(qts, "max", "aarch64"); assert_has_feature(qts, "max", "sve"); + assert_has_feature(qts, "max", "sve128"); assert_has_feature(qts, "cortex-a57", "pmu"); assert_has_feature(qts, "cortex-a57", "aarch64"); =20 + sve_tests_default(qts, "max"); + /* Test that features that depend on KVM generate errors without. = */ assert_error(qts, "max", "'aarch64' feature cannot be disabled " @@ -250,5 +437,12 @@ int main(int argc, char **argv) qtest_add_data_func("/arm/kvm/query-cpu-model-expansion", NULL, test_query_cpu_model_expansion_kvm); =20 + if (g_str_equal(qtest_get_arch(), "aarch64")) { + qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-max-vq= -8", + NULL, sve_tests_sve_max_vq_8); + qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off", + NULL, sve_tests_sve_off); + } + return g_test_run(); } diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst index c79dcffb555..2ea4d6e90c0 100644 --- a/docs/arm-cpu-features.rst +++ b/docs/arm-cpu-features.rst @@ -48,18 +48,31 @@ block in the script for usage) is used to issue the QMP= commands. (QEMU) query-cpu-model-expansion type=3Dfull model=3D{"name":"max"} { "return": { "model": { "name": "max", "props": { - "pmu": true, "aarch64": true + "sve1664": true, "pmu": true, "sve1792": true, "sve1920": true, + "sve128": true, "aarch64": true, "sve1024": true, "sve": true, + "sve640": true, "sve768": true, "sve1408": true, "sve256": true, + "sve1152": true, "sve512": true, "sve384": true, "sve1536": true, + "sve896": true, "sve1280": true, "sve2048": true }}}} =20 -We see that the `max` CPU type has the `pmu` and `aarch64` CPU features. -We also see that the CPU features are enabled, as they are all `true`. +We see that the `max` CPU type has the `pmu`, `aarch64`, `sve`, and many +`sve` CPU features. We also see that all the CPU features are +enabled, as they are all `true`. (The `sve` CPU features are all +optional SVE vector lengths (see "SVE CPU Properties"). While with TCG +all SVE vector lengths can be supported, when KVM is in use it's more +likely that only a few lengths will be supported, if SVE is supported at +all.) =20 (2) Let's try to disable the PMU:: =20 (QEMU) query-cpu-model-expansion type=3Dfull model=3D{"name":"max","= props":{"pmu":false}} { "return": { "model": { "name": "max", "props": { - "pmu": false, "aarch64": true + "sve1664": true, "pmu": false, "sve1792": true, "sve1920": true, + "sve128": true, "aarch64": true, "sve1024": true, "sve": true, + "sve640": true, "sve768": true, "sve1408": true, "sve256": true, + "sve1152": true, "sve512": true, "sve384": true, "sve1536": true, + "sve896": true, "sve1280": true, "sve2048": true }}}} =20 We see it worked, as `pmu` is now `false`. @@ -75,7 +88,22 @@ We see it worked, as `pmu` is now `false`. It looks like this feature is limited to a configuration we do not currently have. =20 -(4) Let's try probing CPU features for the Cortex-A15 CPU type:: +(4) Let's disable `sve` and see what happens to all the optional SVE + vector lengths:: + + (QEMU) query-cpu-model-expansion type=3Dfull model=3D{"name":"max","= props":{"sve":false}} + { "return": { + "model": { "name": "max", "props": { + "sve1664": false, "pmu": true, "sve1792": false, "sve1920": false, + "sve128": false, "aarch64": true, "sve1024": false, "sve": false, + "sve640": false, "sve768": false, "sve1408": false, "sve256": fals= e, + "sve1152": false, "sve512": false, "sve384": false, "sve1536": fal= se, + "sve896": false, "sve1280": false, "sve2048": false + }}}} + +As expected they are now all `false`. + +(5) Let's try probing CPU features for the Cortex-A15 CPU type:: =20 (QEMU) query-cpu-model-expansion type=3Dfull model=3D{"name":"cortex= -a15"} {"return": {"model": {"name": "cortex-a15", "props": {"pmu": true}}}} @@ -131,7 +159,133 @@ After determining which CPU features are available an= d supported for a given CPU type, then they may be selectively enabled or disabled on the QEMU command line with that CPU type:: =20 - $ qemu-system-aarch64 -M virt -cpu max,pmu=3Doff + $ qemu-system-aarch64 -M virt -cpu max,pmu=3Doff,sve=3Don,sve128=3Don,sv= e256=3Don =20 -The example above disables the PMU for the `max` CPU type. +The example above disables the PMU and enables the first two SVE vector +lengths for the `max` CPU type. Note, the `sve=3Don` isn't actually +necessary, because, as we observed above with our probe of the `max` CPU +type, `sve` is already on by default. Also, based on our probe of +defaults, it would seem we need to disable many SVE vector lengths, rather +than only enabling the two we want. This isn't the case, because, as +disabling many SVE vector lengths would be quite verbose, the `sve` CPU +properties have special semantics (see "SVE CPU Property Parsing +Semantics"). + +SVE CPU Properties +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +There are two types of SVE CPU properties: `sve` and `sve`. The first +is used to enable or disable the entire SVE feature, just as the `pmu` +CPU property completely enables or disables the PMU. The second type +is used to enable or disable specific vector lengths, where `N` is the +number of bits of the length. The `sve` CPU properties have special +dependencies and constraints, see "SVE CPU Property Dependencies and +Constraints" below. Additionally, as we want all supported vector lengths +to be enabled by default, then, in order to avoid overly verbose command +lines (command lines full of `sve=3Doff`, for all `N` not wanted), we +provide the parsing semantics listed in "SVE CPU Property Parsing +Semantics". + +SVE CPU Property Dependencies and Constraints +--------------------------------------------- + + 1) At least one vector length must be enabled when `sve` is enabled. + + 2) If a vector length `N` is enabled, then all power-of-two vector + lengths smaller than `N` must also be enabled. E.g. if `sve512` + is enabled, then the 128-bit and 256-bit vector lengths must also + be enabled. + +SVE CPU Property Parsing Semantics +---------------------------------- + + 1) If SVE is disabled (`sve=3Doff`), then which SVE vector lengths + are enabled or disabled is irrelevant to the guest, as the entire + SVE feature is disabled and that disables all vector lengths for + the guest. However QEMU will still track any `sve` CPU + properties provided by the user. If later an `sve=3Don` is provided, + then the guest will get only the enabled lengths. If no `sve=3Don` + is provided and there are explicitly enabled vector lengths, then + an error is generated. + + 2) If SVE is enabled (`sve=3Don`), but no `sve` CPU properties are + provided, then all supported vector lengths are enabled, including + the non-power-of-two lengths. + + 3) If SVE is enabled, then an error is generated when attempting to + disable the last enabled vector length (see constraint (1) of "SVE + CPU Property Dependencies and Constraints"). + + 4) If one or more vector lengths have been explicitly enabled and at + at least one of the dependency lengths of the maximum enabled length + has been explicitly disabled, then an error is generated (see + constraint (2) of "SVE CPU Property Dependencies and Constraints"). + + 5) If one or more `sve` CPU properties are set `off`, but no `sve`, + CPU properties are set `on`, then the specified vector lengths are + disabled but the default for any unspecified lengths remains enabled. + Disabling a power-of-two vector length also disables all vector + lengths larger than the power-of-two length (see constraint (2) of + "SVE CPU Property Dependencies and Constraints"). + + 6) If one or more `sve` CPU properties are set to `on`, then they + are enabled and all unspecified lengths default to disabled, except + for the required lengths per constraint (2) of "SVE CPU Property + Dependencies and Constraints", which will even be auto-enabled if + they were not explicitly enabled. + + 7) If SVE was disabled (`sve=3Doff`), allowing all vector lengths to be + explicitly disabled (i.e. avoiding the error specified in (3) of + "SVE CPU Property Parsing Semantics"), then if later an `sve=3Don` is + provided an error will be generated. To avoid this error, one must + enable at least one vector length prior to enabling SVE. + +SVE CPU Property Examples +------------------------- + + 1) Disable SVE:: + + $ qemu-system-aarch64 -M virt -cpu max,sve=3Doff + + 2) Implicitly enable all vector lengths for the `max` CPU type:: + + $ qemu-system-aarch64 -M virt -cpu max + + 3) Only enable the 128-bit vector length:: + + $ qemu-system-aarch64 -M virt -cpu max,sve128=3Don + + 4) Disable the 512-bit vector length and all larger vector lengths, + since 512 is a power-of-two. This results in all the smaller, + uninitialized lengths (128, 256, and 384) defaulting to enabled:: + + $ qemu-system-aarch64 -M virt -cpu max,sve512=3Doff + + 5) Enable the 128-bit, 256-bit, and 512-bit vector lengths:: + + $ qemu-system-aarch64 -M virt -cpu max,sve128=3Don,sve256=3Don,sve512= =3Don + + 6) The same as (5), but since the 128-bit and 256-bit vector + lengths are required for the 512-bit vector length to be enabled, + then allow them to be auto-enabled:: + + $ qemu-system-aarch64 -M virt -cpu max,sve512=3Don + + 7) Do the same as (6), but by first disabling SVE and then re-enabling i= t:: + + $ qemu-system-aarch64 -M virt -cpu max,sve=3Doff,sve512=3Don,sve=3Don + + 8) Force errors regarding the last vector length:: + + $ qemu-system-aarch64 -M virt -cpu max,sve128=3Doff + $ qemu-system-aarch64 -M virt -cpu max,sve=3Doff,sve128=3Doff,sve=3Don + +SVE CPU Property Recommendations +-------------------------------- + +The examples in "SVE CPU Property Examples" exhibit many ways to select +vector lengths which developers may find useful in order to avoid overly +verbose command lines. However, the recommended way to select vector +lengths is to explicitly enable each desired length. Therefore only +example's (1), (3), and (5) exhibit recommended uses of the properties. =20 --=20 2.20.1 From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572598703; cv=none; d=zoho.com; s=zohoarc; b=XX40tNR/mYea/8GU8M+/OgLDC/qK33hcgbANUHpztkYgkISU3pgqIqarUTk21Am3hD+4JIIKyd9aFzF9LGXK2qXLpOsMiVn8+SDgYbQb08uCWmwX025iO0md0vxk9FOkPw0vFFTRngTpQV5Z04rMg3YWxq3m/FbJAf9Jlj3wojE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572598703; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=J5hD5yYPUwyTUfswMlBAMvVW6dnoBoogw5pUaxy5laQ=; b=ZR1k362SSZRC3u9IOIgLDCSPwcF0Hn1DEv8CFdlbFZLZpkzMdp2uBI/5Qp6EtnCMRQCBNX3L0mYXyM6DDpa/Jw6HYFbGtGOVtuJj1Ya4XLSndre9B6B4Ieg4M/gOCMT4NiZjEDR1wXSuZ4u1V+VcyQdFWIK9uvkJcbyyExJ6iu4= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1572598703637913.5505410790656; Fri, 1 Nov 2019 01:58:23 -0700 (PDT) Received: from localhost ([::1]:57568 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSl9-0007i8-KN for importer@patchew.org; Fri, 01 Nov 2019 04:58:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56507) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSex-00018B-DA for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSes-0000AG-Rd for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:54 -0400 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]:52748) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSes-00006k-Hn for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:50 -0400 Received: by mail-wm1-x332.google.com with SMTP id c17so1231115wmk.2 for ; Fri, 01 Nov 2019 01:51:50 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=J5hD5yYPUwyTUfswMlBAMvVW6dnoBoogw5pUaxy5laQ=; b=HgdgYAlChr3DoSybsWHTwoOs/scbz6pLERzKvnOrXD41ERt2VozL5HhAFWdlB4bctX 1DI1GwaSCQvbzE8iboXRy9RGie1+XTM2TLEsLRtlprFL037V+HuzdRrGFHhxJsHTgcH8 KeuRqjcnefB/w+huTSWVuTzTChkOEGJQI6IpHkc8ybn82T5wz1z+HLqSVBVNKANHrozc X1Wy50e9DAW0LmLgoeZDlssUxWaG/jOu7kyB5qB3dQD8jdYyCPgs0Tj+gMna71f8v40/ NhQ5Nl107GDPlybNvU90zUvMOWgKMllOuI1M+nwPmT1rOwq3GHjddH1MZ9F0nzm6bh4S H7kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=J5hD5yYPUwyTUfswMlBAMvVW6dnoBoogw5pUaxy5laQ=; b=KKrfcEKqRcmE8cZZ5rZX+PkkUQdansCd1kU/QM5+c6FTGMv1DbSoX1NEHiENoStS9R cQVM95aRxyPOQJWHCUGsSBEUdlth9V3LrCz5GmHtyyxGsrqsUQp8loF2nNhK9t2K6q91 5XhnK4WrGisqt9KIONrtMtXYAdF/hjQN9DdGsn7Cxolq7HMmc9slLTYtjWPYV+Y2vRkb JFU3JJ8S+eI1/Zql+8r5m7wdBJOEgVcMA0Fq+whTViI8LQzY+Km/z/82fOfROWRS6mAI d/25af/iHQSEVbPrKPqUXXRpVf/rJ2lVANco1/Bj868KE7z2YFU36h1FpzvMydTyADp+ EZDg== X-Gm-Message-State: APjAAAXsSBAvCZJgMq4FstxVZu4B3oxUzhR1OJjLVnxv9VkGcU2TSEVy 25I6zg5kCIy8R+zVPOILnSEpEoBX21sTvV8U X-Google-Smtp-Source: APXvYqzN/3lqqqjqwzW9nkUwTTmcSA+hncJq+0JYQZqCeijUwsZZCMF6wypWPPrqsQzYjJFGrag73w== X-Received: by 2002:a7b:cbc5:: with SMTP id n5mr9391547wmi.65.1572598309236; Fri, 01 Nov 2019 01:51:49 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 05/11] target/arm/kvm64: Add kvm_arch_get/put_sve Date: Fri, 1 Nov 2019 08:51:34 +0000 Message-Id: <20191101085140.5205-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::332 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" From: Andrew Jones These are the SVE equivalents to kvm_arch_get/put_fpsimd. Note, the swabbing is different than it is for fpsmid because the vector format is a little-endian stream of words. Signed-off-by: Andrew Jones Reviewed-by: Richard Henderson Reviewed-by: Eric Auger Tested-by: Masayoshi Mizuma Message-id: 20191031142734.8590-6-drjones@redhat.com Signed-off-by: Peter Maydell --- target/arm/kvm64.c | 185 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 156 insertions(+), 29 deletions(-) diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 28f6db57d5e..4c0b11d105a 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -671,11 +671,12 @@ int kvm_arch_destroy_vcpu(CPUState *cs) bool kvm_arm_reg_syncs_via_cpreg_list(uint64_t regidx) { /* Return true if the regidx is a register we should synchronize - * via the cpreg_tuples array (ie is not a core reg we sync by - * hand in kvm_arch_get/put_registers()) + * via the cpreg_tuples array (ie is not a core or sve reg that + * we sync by hand in kvm_arch_get/put_registers()) */ switch (regidx & KVM_REG_ARM_COPROC_MASK) { case KVM_REG_ARM_CORE: + case KVM_REG_ARM64_SVE: return false; default: return true; @@ -721,10 +722,8 @@ int kvm_arm_cpreg_level(uint64_t regidx) =20 static int kvm_arch_put_fpsimd(CPUState *cs) { - ARMCPU *cpu =3D ARM_CPU(cs); - CPUARMState *env =3D &cpu->env; + CPUARMState *env =3D &ARM_CPU(cs)->env; struct kvm_one_reg reg; - uint32_t fpr; int i, ret; =20 for (i =3D 0; i < 32; i++) { @@ -742,17 +741,73 @@ static int kvm_arch_put_fpsimd(CPUState *cs) } } =20 - reg.addr =3D (uintptr_t)(&fpr); - fpr =3D vfp_get_fpsr(env); - reg.id =3D AARCH64_SIMD_CTRL_REG(fp_regs.fpsr); - ret =3D kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); - if (ret) { - return ret; + return 0; +} + +/* + * SVE registers are encoded in KVM's memory in an endianness-invariant fo= rmat. + * The byte at offset i from the start of the in-memory representation con= tains + * the bits [(7 + 8 * i) : (8 * i)] of the register value. As this means t= he + * lowest offsets are stored in the lowest memory addresses, then that nea= rly + * matches QEMU's representation, which is to use an array of host-endian + * uint64_t's, where the lower offsets are at the lower indices. To comple= te + * the translation we just need to byte swap the uint64_t's on big-endian = hosts. + */ +static uint64_t *sve_bswap64(uint64_t *dst, uint64_t *src, int nr) +{ +#ifdef HOST_WORDS_BIGENDIAN + int i; + + for (i =3D 0; i < nr; ++i) { + dst[i] =3D bswap64(src[i]); } =20 - reg.addr =3D (uintptr_t)(&fpr); - fpr =3D vfp_get_fpcr(env); - reg.id =3D AARCH64_SIMD_CTRL_REG(fp_regs.fpcr); + return dst; +#else + return src; +#endif +} + +/* + * KVM SVE registers come in slices where ZREGs have a slice size of 2048 = bits + * and PREGS and the FFR have a slice size of 256 bits. However we simply = hard + * code the slice index to zero for now as it's unlikely we'll need more t= han + * one slice for quite some time. + */ +static int kvm_arch_put_sve(CPUState *cs) +{ + ARMCPU *cpu =3D ARM_CPU(cs); + CPUARMState *env =3D &cpu->env; + uint64_t tmp[ARM_MAX_VQ * 2]; + uint64_t *r; + struct kvm_one_reg reg; + int n, ret; + + for (n =3D 0; n < KVM_ARM64_SVE_NUM_ZREGS; ++n) { + r =3D sve_bswap64(tmp, &env->vfp.zregs[n].d[0], cpu->sve_max_vq * = 2); + reg.addr =3D (uintptr_t)r; + reg.id =3D KVM_REG_ARM64_SVE_ZREG(n, 0); + ret =3D kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + } + + for (n =3D 0; n < KVM_ARM64_SVE_NUM_PREGS; ++n) { + r =3D sve_bswap64(tmp, r =3D &env->vfp.pregs[n].p[0], + DIV_ROUND_UP(cpu->sve_max_vq * 2, 8)); + reg.addr =3D (uintptr_t)r; + reg.id =3D KVM_REG_ARM64_SVE_PREG(n, 0); + ret =3D kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + } + + r =3D sve_bswap64(tmp, &env->vfp.pregs[FFR_PRED_NUM].p[0], + DIV_ROUND_UP(cpu->sve_max_vq * 2, 8)); + reg.addr =3D (uintptr_t)r; + reg.id =3D KVM_REG_ARM64_SVE_FFR(0); ret =3D kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); if (ret) { return ret; @@ -765,6 +820,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) { struct kvm_one_reg reg; uint64_t val; + uint32_t fpr; int i, ret; unsigned int el; =20 @@ -855,7 +911,27 @@ int kvm_arch_put_registers(CPUState *cs, int level) } } =20 - ret =3D kvm_arch_put_fpsimd(cs); + if (cpu_isar_feature(aa64_sve, cpu)) { + ret =3D kvm_arch_put_sve(cs); + } else { + ret =3D kvm_arch_put_fpsimd(cs); + } + if (ret) { + return ret; + } + + reg.addr =3D (uintptr_t)(&fpr); + fpr =3D vfp_get_fpsr(env); + reg.id =3D AARCH64_SIMD_CTRL_REG(fp_regs.fpsr); + ret =3D kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + + reg.addr =3D (uintptr_t)(&fpr); + fpr =3D vfp_get_fpcr(env); + reg.id =3D AARCH64_SIMD_CTRL_REG(fp_regs.fpcr); + ret =3D kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); if (ret) { return ret; } @@ -878,10 +954,8 @@ int kvm_arch_put_registers(CPUState *cs, int level) =20 static int kvm_arch_get_fpsimd(CPUState *cs) { - ARMCPU *cpu =3D ARM_CPU(cs); - CPUARMState *env =3D &cpu->env; + CPUARMState *env =3D &ARM_CPU(cs)->env; struct kvm_one_reg reg; - uint32_t fpr; int i, ret; =20 for (i =3D 0; i < 32; i++) { @@ -899,21 +973,53 @@ static int kvm_arch_get_fpsimd(CPUState *cs) } } =20 - reg.addr =3D (uintptr_t)(&fpr); - reg.id =3D AARCH64_SIMD_CTRL_REG(fp_regs.fpsr); - ret =3D kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); - if (ret) { - return ret; - } - vfp_set_fpsr(env, fpr); + return 0; +} =20 - reg.addr =3D (uintptr_t)(&fpr); - reg.id =3D AARCH64_SIMD_CTRL_REG(fp_regs.fpcr); +/* + * KVM SVE registers come in slices where ZREGs have a slice size of 2048 = bits + * and PREGS and the FFR have a slice size of 256 bits. However we simply = hard + * code the slice index to zero for now as it's unlikely we'll need more t= han + * one slice for quite some time. + */ +static int kvm_arch_get_sve(CPUState *cs) +{ + ARMCPU *cpu =3D ARM_CPU(cs); + CPUARMState *env =3D &cpu->env; + struct kvm_one_reg reg; + uint64_t *r; + int n, ret; + + for (n =3D 0; n < KVM_ARM64_SVE_NUM_ZREGS; ++n) { + r =3D &env->vfp.zregs[n].d[0]; + reg.addr =3D (uintptr_t)r; + reg.id =3D KVM_REG_ARM64_SVE_ZREG(n, 0); + ret =3D kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + if (ret) { + return ret; + } + sve_bswap64(r, r, cpu->sve_max_vq * 2); + } + + for (n =3D 0; n < KVM_ARM64_SVE_NUM_PREGS; ++n) { + r =3D &env->vfp.pregs[n].p[0]; + reg.addr =3D (uintptr_t)r; + reg.id =3D KVM_REG_ARM64_SVE_PREG(n, 0); + ret =3D kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + if (ret) { + return ret; + } + sve_bswap64(r, r, DIV_ROUND_UP(cpu->sve_max_vq * 2, 8)); + } + + r =3D &env->vfp.pregs[FFR_PRED_NUM].p[0]; + reg.addr =3D (uintptr_t)r; + reg.id =3D KVM_REG_ARM64_SVE_FFR(0); ret =3D kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); if (ret) { return ret; } - vfp_set_fpcr(env, fpr); + sve_bswap64(r, r, DIV_ROUND_UP(cpu->sve_max_vq * 2, 8)); =20 return 0; } @@ -923,6 +1029,7 @@ int kvm_arch_get_registers(CPUState *cs) struct kvm_one_reg reg; uint64_t val; unsigned int el; + uint32_t fpr; int i, ret; =20 ARMCPU *cpu =3D ARM_CPU(cs); @@ -1012,11 +1119,31 @@ int kvm_arch_get_registers(CPUState *cs) env->spsr =3D env->banked_spsr[i]; } =20 - ret =3D kvm_arch_get_fpsimd(cs); + if (cpu_isar_feature(aa64_sve, cpu)) { + ret =3D kvm_arch_get_sve(cs); + } else { + ret =3D kvm_arch_get_fpsimd(cs); + } if (ret) { return ret; } =20 + reg.addr =3D (uintptr_t)(&fpr); + reg.id =3D AARCH64_SIMD_CTRL_REG(fp_regs.fpsr); + ret =3D kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + if (ret) { + return ret; + } + vfp_set_fpsr(env, fpr); + + reg.addr =3D (uintptr_t)(&fpr); + reg.id =3D AARCH64_SIMD_CTRL_REG(fp_regs.fpcr); + ret =3D kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + if (ret) { + return ret; + } + vfp_set_fpcr(env, fpr); + ret =3D kvm_get_vcpu_events(cpu); if (ret) { return ret; --=20 2.20.1 From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572598468; cv=none; d=zoho.com; s=zohoarc; b=V1kIdo/d1NqceIrtbIUL+g29SVQRZ3GOvUmOttaRKFw6UQveJUEwid5nbExZvGrXxNxGh3W/WISvI2Pyef+FZ/udjXIZVtW6Rjltdw2Yts18vpTA3D1C7zWmursiAFd/hTnKh0EYCI2JUbaMTH3uUyjOmBO+SA5OuNjOE4xGQQM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572598468; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=H7ILofrJ53o7sIXI9sIMKbof/7pxu+txIzjGatMT/v8=; b=XBpNBJLKbN0E2ItvK6tTFlW9s/K8rabKgt2Euwo6RM5ytuIHT7r8sQy3j2HbxnDR99n8ZM0VqLcHY3apNSuy8VGyxbk9mrxWE9Nl8UNXYOfqGKGrq/SuBvyrJzhu2yqWDZo8sgm1v39yj3RKak8HBwNd7LvR7eJs6AmHz8tbi8g= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1572598468146746.8645771058606; Fri, 1 Nov 2019 01:54:28 -0700 (PDT) Received: from localhost ([::1]:57502 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQShO-0003E2-PU for importer@patchew.org; Fri, 01 Nov 2019 04:54:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56542) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSey-0001An-HG for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSet-0000Gh-Un for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:55 -0400 Received: from mail-wm1-x32e.google.com ([2a00:1450:4864:20::32e]:52121) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSet-0000CD-O8 for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:51 -0400 Received: by mail-wm1-x32e.google.com with SMTP id q70so8591979wme.1 for ; Fri, 01 Nov 2019 01:51:51 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=H7ILofrJ53o7sIXI9sIMKbof/7pxu+txIzjGatMT/v8=; b=xdFZMrdfTOumkKySVLyCi0ZJ6S2aiMoPM/Rnn51f3jkOIDFIN1GeoEBp73X8/pYMp3 Rr1/mSwJguO5TxJ2JDkBtNUz28/BUAnxdJFzOEwZH9fY6jvefZsHRMAP7euwkoF0SnCa qJGSf3WEPbxXlh2rtIMeB+Z5seLhnPxKN3uEAzUXOeOfcmPB1JA1bYzJ1hzCIvWANN7p Ppg0GBXiFv3mkcC8ukwIhc2VE/u8LNeVZXQcy09qBaPD/8gkjPPkrM1hpGkdpCeHnBVF qJ4TF80GmTuKRs0P8lGPucUadRFh5piGFlgNHHAb8lu8BHDzem87cXDZjHh5UkRbg/qC OGNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=H7ILofrJ53o7sIXI9sIMKbof/7pxu+txIzjGatMT/v8=; b=RlRd/etbYqJxTchz/ybejT+wgGP8CITwBFDnhJuGeVuMMMAlN554SIDGxqkRcc8G+b kK/zuCrFZZaX7th5+rajTxULl3FOTyPeMsxhMaoItFUZZ7ihqwAEGavYhqK3Go6zs2EE 3S5dA9JWt8W+x2ouKW6do39tsPdOnNEC6tL379IC2f9KwygFhn/DoYN/vxBaw0yfKHZJ WlZv999R3s57sGpzSYGVhW0rKVyW2ah/7WfRaNFxw/5WntrXmvGuXhevsaGYzcQh66HS EPX0/w5NBUEQwveWNVa8/mUO+jADtUmiyV+ALQVcWtXrJQg2oJnJJFUPabMs0xUs2mSH aUVw== X-Gm-Message-State: APjAAAUkO04K7pdOHCoVCQLghtrNOgCS4IeA2XtwP48c4ao0ElunUwLp A27GcAj+CzEok1f1HRe6Z7qIS/rllxtNxz5g X-Google-Smtp-Source: APXvYqwS1+O5lTc6zWVNDDxJBvYjDYX/bcKJTDHr19WfPAGFazm8SNqRUX0pbyALDn/IxHKjd6GGUA== X-Received: by 2002:a1c:6a1a:: with SMTP id f26mr2271761wmc.19.1572598310410; Fri, 01 Nov 2019 01:51:50 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 06/11] target/arm/kvm64: max cpu: Enable SVE when available Date: Fri, 1 Nov 2019 08:51:35 +0000 Message-Id: <20191101085140.5205-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::32e X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" From: Andrew Jones Enable SVE in the KVM guest when the 'max' cpu type is configured and KVM supports it. KVM SVE requires use of the new finalize vcpu ioctl, so we add that now too. For starters SVE can only be turned on or off, getting all vector lengths the host CPU supports when on. We'll add the other SVE CPU properties in later patches. Signed-off-by: Andrew Jones Reviewed-by: Richard Henderson Reviewed-by: Eric Auger Tested-by: Masayoshi Mizuma Reviewed-by: Beata Michalska Message-id: 20191031142734.8590-7-drjones@redhat.com Signed-off-by: Peter Maydell --- target/arm/kvm_arm.h | 27 +++++++++++++++++++++++++++ target/arm/cpu64.c | 17 ++++++++++++++--- target/arm/kvm.c | 5 +++++ target/arm/kvm64.c | 20 +++++++++++++++++++- tests/arm-cpu-features.c | 4 ++++ 5 files changed, 69 insertions(+), 4 deletions(-) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index b4e19457a09..7c12f1501a8 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -27,6 +27,20 @@ */ int kvm_arm_vcpu_init(CPUState *cs); =20 +/** + * kvm_arm_vcpu_finalize + * @cs: CPUState + * @feature: int + * + * Finalizes the configuration of the specified VCPU feature by + * invoking the KVM_ARM_VCPU_FINALIZE ioctl. Features requiring + * this are documented in the "KVM_ARM_VCPU_FINALIZE" section of + * KVM's API documentation. + * + * Returns: 0 if success else < 0 error code + */ +int kvm_arm_vcpu_finalize(CPUState *cs, int feature); + /** * kvm_arm_register_device: * @mr: memory region for this device @@ -225,6 +239,14 @@ bool kvm_arm_aarch32_supported(CPUState *cs); */ bool kvm_arm_pmu_supported(CPUState *cs); =20 +/** + * bool kvm_arm_sve_supported: + * @cs: CPUState + * + * Returns true if the KVM VCPU can enable SVE and false otherwise. + */ +bool kvm_arm_sve_supported(CPUState *cs); + /** * kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the * IPA address space supported by KVM @@ -276,6 +298,11 @@ static inline bool kvm_arm_pmu_supported(CPUState *cs) return false; } =20 +static inline bool kvm_arm_sve_supported(CPUState *cs) +{ + return false; +} + static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms) { return -ENOENT; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 34b0ba2cf6f..a771a28daa5 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -493,6 +493,11 @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, c= onst char *name, return; } =20 + if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) { + error_setg(errp, "'sve' feature not supported by KVM on this host"= ); + return; + } + t =3D cpu->isar.id_aa64pfr0; t =3D FIELD_DP64(t, ID_AA64PFR0, SVE, value); cpu->isar.id_aa64pfr0 =3D t; @@ -507,11 +512,16 @@ static void aarch64_max_initfn(Object *obj) { ARMCPU *cpu =3D ARM_CPU(obj); uint32_t vq; + uint64_t t; =20 if (kvm_enabled()) { kvm_arm_set_cpu_features_from_host(cpu); + if (kvm_arm_sve_supported(CPU(cpu))) { + t =3D cpu->isar.id_aa64pfr0; + t =3D FIELD_DP64(t, ID_AA64PFR0, SVE, 1); + cpu->isar.id_aa64pfr0 =3D t; + } } else { - uint64_t t; uint32_t u; aarch64_a57_initfn(obj); =20 @@ -612,8 +622,6 @@ static void aarch64_max_initfn(Object *obj) =20 object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_m= ax_vq, cpu_max_set_sve_max_vq, NULL, NULL, &error_fat= al); - object_property_add(obj, "sve", "bool", cpu_arm_get_sve, - cpu_arm_set_sve, NULL, NULL, &error_fatal); =20 for (vq =3D 1; vq <=3D ARM_MAX_VQ; ++vq) { char name[8]; @@ -622,6 +630,9 @@ static void aarch64_max_initfn(Object *obj) cpu_arm_set_sve_vq, NULL, NULL, &error_fat= al); } } + + object_property_add(obj, "sve", "bool", cpu_arm_get_sve, + cpu_arm_set_sve, NULL, NULL, &error_fatal); } =20 struct ARMCPUInfo { diff --git a/target/arm/kvm.c b/target/arm/kvm.c index b473c63edb1..f07332bbda3 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -51,6 +51,11 @@ int kvm_arm_vcpu_init(CPUState *cs) return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); } =20 +int kvm_arm_vcpu_finalize(CPUState *cs, int feature) +{ + return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_FINALIZE, &feature); +} + void kvm_arm_init_serror_injection(CPUState *cs) { cap_has_inject_serror_esr =3D kvm_check_extension(cs->kvm_state, diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 4c0b11d105a..850da1b5e6a 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -602,6 +602,13 @@ bool kvm_arm_aarch32_supported(CPUState *cpu) return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT); } =20 +bool kvm_arm_sve_supported(CPUState *cpu) +{ + KVMState *s =3D KVM_STATE(current_machine->accelerator); + + return kvm_check_extension(s, KVM_CAP_ARM_SVE); +} + #define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5 =20 int kvm_arch_init_vcpu(CPUState *cs) @@ -630,13 +637,17 @@ int kvm_arch_init_vcpu(CPUState *cs) cpu->kvm_init_features[0] |=3D 1 << KVM_ARM_VCPU_EL1_32BIT; } if (!kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) { - cpu->has_pmu =3D false; + cpu->has_pmu =3D false; } if (cpu->has_pmu) { cpu->kvm_init_features[0] |=3D 1 << KVM_ARM_VCPU_PMU_V3; } else { unset_feature(&env->features, ARM_FEATURE_PMU); } + if (cpu_isar_feature(aa64_sve, cpu)) { + assert(kvm_arm_sve_supported(cs)); + cpu->kvm_init_features[0] |=3D 1 << KVM_ARM_VCPU_SVE; + } =20 /* Do KVM_ARM_VCPU_INIT ioctl */ ret =3D kvm_arm_vcpu_init(cs); @@ -644,6 +655,13 @@ int kvm_arch_init_vcpu(CPUState *cs) return ret; } =20 + if (cpu_isar_feature(aa64_sve, cpu)) { + ret =3D kvm_arm_vcpu_finalize(cs, KVM_ARM_VCPU_SVE); + if (ret) { + return ret; + } + } + /* * When KVM is in use, PSCI is emulated in-kernel and not by qemu. * Currently KVM has its own idea about MPIDR assignment, so we diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c index 7fd01f0ea3f..015b511c87e 100644 --- a/tests/arm-cpu-features.c +++ b/tests/arm-cpu-features.c @@ -417,12 +417,16 @@ static void test_query_cpu_model_expansion_kvm(const = void *data) assert_has_feature(qts, "host", "aarch64"); assert_has_feature(qts, "host", "pmu"); =20 + assert_has_feature(qts, "max", "sve"); + assert_error(qts, "cortex-a15", "We cannot guarantee the CPU type 'cortex-a15' works " "with KVM on this host", NULL); } else { assert_has_not_feature(qts, "host", "aarch64"); assert_has_not_feature(qts, "host", "pmu"); + + assert_has_not_feature(qts, "max", "sve"); } =20 qtest_quit(qts); --=20 2.20.1 From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572598672; cv=none; d=zoho.com; s=zohoarc; b=fS6eebL9Z8h7ribZwd4pNpU2lI+2aptKTIxuKui799JtbvgXchqrKqOBMddie/qRIXQ05f5VHAdSPaNIrxgELmH71zMEXC9TTNkKPzn4lSa1TSICyoLUBUi/SboJz4vvd/+PW/IBwZxzU2YMHAVBXEWG8o1qnhkw/jAfw+cvfw4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572598672; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=62TpCPLeToJz0pC4qYB0g1aPcp75KDGFrfBiQCUjf5E=; b=DbDCLYI5mMYHddH9n9jPVYltAEtRBiLBP99RmngztYvymFZEZfSj0V+6v8hnpTb8EfRfaMkxKgMRXVTPC6kyzdMLloDXbDdFUcyxPuE6U2WVCtjFNr5MxbtYAR7m3JKdwT36h5P+B5l497F80GPHE4UEBl2qTkjUFAGp+6zHCUE= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1572598672130731.7197346501611; Fri, 1 Nov 2019 01:57:52 -0700 (PDT) Received: from localhost ([::1]:57564 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSkd-0007BX-Ql for importer@patchew.org; Fri, 01 Nov 2019 04:57:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56535) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSf0-0001AC-4B for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:52:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSew-0000W6-PK for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:56 -0400 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]:54541) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSew-0000Ge-IW for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:54 -0400 Received: by mail-wm1-x336.google.com with SMTP id c12so4039918wml.4 for ; Fri, 01 Nov 2019 01:51:53 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=62TpCPLeToJz0pC4qYB0g1aPcp75KDGFrfBiQCUjf5E=; b=OyqCk5FHlgxu2t/T8mcCa0D9rXfQQyESK6j8dZu5gI7rHeKAZSjb7gvgzb4lY16vcp tOUd3gEVpDd8fjPZ6iPCVdOXNgyR2vHhwEBsslyqcPifV52+H3kahF63oM9kvm/NDrXO qmwXn28jVwPAECQPlNoeo2xbRNHBB7P+/424CzH10O9lHVXE6UNUbhkzECjqtqTmNF6y FlOkzIrNGcifiQVlGKkdYAwViB0cIM8yWSShruorhHqUuGihC50MNfsykXKCoBbs1G3m 0SLd4OU7TM3i7xYK0yVi77GY3Oj81KAmt9vwLx3COEFX0OKjtKI/xG8uWXBuwlxbUw14 xBOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=62TpCPLeToJz0pC4qYB0g1aPcp75KDGFrfBiQCUjf5E=; b=JneXSkzM9tTqkmJ6Ce4uODfWNwixEaom09neo1C2DnPs4OJjPCBpnoBVlWVWW/JjIC F4dGeS2aXEMPNqKCszg/zGwUWmT0utUdn4ijpHK47OZJgj1augwLLLMOTJ1sKrdUxKk9 0ZL65rTzg860YYYowSJspjoCCM560uVG3BLTfVjsYJrhY2qXNLgyZJrzN6WxXGPmcjHq ZGgd7ndNxoDFvOB5kaHjYfHNCV/vHfx50Q+pCrgYLAw4CbGoo6AHox6x3FL+dZrh/Tso qJD+ltlZqo/kOfpH4+UsPRDOussBR1eckULIYxk72mnnQ/luPn0Bon9oaz2JftlWjYBd NXWw== X-Gm-Message-State: APjAAAV0EfCjoK4x6/3nHsFgYrlYYwW6qJqhAaWDcKWo5C7gLqoK+pJX LQoiktXeoMfRdFhjWfgZW4yEiIkdJhPpVZI0 X-Google-Smtp-Source: APXvYqzRPCxQu90lty6bAbYVWChe/HbVLl4hLyZlWesx/t5ljE91z/51kLvRJi2b06Iy70HGFRZIpA== X-Received: by 2002:a05:600c:228b:: with SMTP id 11mr9375776wmf.112.1572598311316; Fri, 01 Nov 2019 01:51:51 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 07/11] target/arm/kvm: scratch vcpu: Preserve input kvm_vcpu_init features Date: Fri, 1 Nov 2019 08:51:36 +0000 Message-Id: <20191101085140.5205-8-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::336 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" From: Andrew Jones kvm_arm_create_scratch_host_vcpu() takes a struct kvm_vcpu_init parameter. Rather than just using it as an output parameter to pass back the preferred target, use it also as an input parameter, allowing a caller to pass a selected target if they wish and to also pass cpu features. If the caller doesn't want to select a target they can pass -1 for the target which indicates they want to use the preferred target and have it passed back like before. Signed-off-by: Andrew Jones Reviewed-by: Richard Henderson Reviewed-by: Eric Auger Tested-by: Masayoshi Mizuma Reviewed-by: Beata Michalska Message-id: 20191031142734.8590-8-drjones@redhat.com Signed-off-by: Peter Maydell --- target/arm/kvm.c | 20 +++++++++++++++----- target/arm/kvm32.c | 6 +++++- target/arm/kvm64.c | 6 +++++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index f07332bbda3..5b82cefef60 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -66,7 +66,7 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpu= s_to_try, int *fdarray, struct kvm_vcpu_init *init) { - int ret, kvmfd =3D -1, vmfd =3D -1, cpufd =3D -1; + int ret =3D 0, kvmfd =3D -1, vmfd =3D -1, cpufd =3D -1; =20 kvmfd =3D qemu_open("/dev/kvm", O_RDWR); if (kvmfd < 0) { @@ -86,7 +86,14 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cp= us_to_try, goto finish; } =20 - ret =3D ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, init); + if (init->target =3D=3D -1) { + struct kvm_vcpu_init preferred; + + ret =3D ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &preferred); + if (!ret) { + init->target =3D preferred.target; + } + } if (ret >=3D 0) { ret =3D ioctl(cpufd, KVM_ARM_VCPU_INIT, init); if (ret < 0) { @@ -98,10 +105,12 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *= cpus_to_try, * creating one kind of guest CPU which is its preferred * CPU type. */ + struct kvm_vcpu_init try; + while (*cpus_to_try !=3D QEMU_KVM_ARM_TARGET_NONE) { - init->target =3D *cpus_to_try++; - memset(init->features, 0, sizeof(init->features)); - ret =3D ioctl(cpufd, KVM_ARM_VCPU_INIT, init); + try.target =3D *cpus_to_try++; + memcpy(try.features, init->features, sizeof(init->features)); + ret =3D ioctl(cpufd, KVM_ARM_VCPU_INIT, &try); if (ret >=3D 0) { break; } @@ -109,6 +118,7 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *c= pus_to_try, if (ret < 0) { goto err; } + init->target =3D try.target; } else { /* Treat a NULL cpus_to_try argument the same as an empty * list, which means we will fail the call since this must diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c index 2451a2d4bbe..32bf8d6757c 100644 --- a/target/arm/kvm32.c +++ b/target/arm/kvm32.c @@ -53,7 +53,11 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *a= hcf) QEMU_KVM_ARM_TARGET_CORTEX_A15, QEMU_KVM_ARM_TARGET_NONE }; - struct kvm_vcpu_init init; + /* + * target =3D -1 informs kvm_arm_create_scratch_host_vcpu() + * to use the preferred target + */ + struct kvm_vcpu_init init =3D { .target =3D -1, }; =20 if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) { return false; diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 850da1b5e6a..c7ecefbed72 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -502,7 +502,11 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures = *ahcf) KVM_ARM_TARGET_CORTEX_A57, QEMU_KVM_ARM_TARGET_NONE }; - struct kvm_vcpu_init init; + /* + * target =3D -1 informs kvm_arm_create_scratch_host_vcpu() + * to use the preferred target + */ + struct kvm_vcpu_init init =3D { .target =3D -1, }; =20 if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) { return false; --=20 2.20.1 From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572599198; cv=none; d=zoho.com; s=zohoarc; b=g0fz5DwrShgbxKQjBQkZeZfFABibhDCrHfSOwaO+2GEIrjNstCzb90ELnIS7R9y8V5+9ZbyU0NFg2Jg9v3QHJfNw1d4TpgnRGJfm8AqyECbTeELpGS1tKVyMl2ndBDDg0E/0QLIeDf4J0wktmB81nkdxuzLLuZIgl9CXFgmTbJA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572599198; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Y+GRMSFiDaiBvXVxNY6UdIADt2KEyce4VeE8Ilngfns=; b=On2LyLNeR/BwoORtRE/HW7o8fnoL+bSm7++r1q2VZ75RpXlF4nGaQFN5+Ex7PWpOdnJkwcbc69snXpBXuB9GhBtsUNEjJfuMAazbvQ4pkNfqp8b7qXzTaOw7AtfJHxpydZ12Dr5pggMEKBokvIVwfJkc3+//WrScG241pykyLrI= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1572599198136473.26339565044157; Fri, 1 Nov 2019 02:06:38 -0700 (PDT) Received: from localhost ([::1]:33806 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQStA-0000al-Ab for importer@patchew.org; Fri, 01 Nov 2019 05:06:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56580) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSf3-0001Cq-SO for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:52:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSex-0000bY-UJ for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:58 -0400 Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]:32871) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSex-0000RW-KB for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:55 -0400 Received: by mail-wr1-x42a.google.com with SMTP id s1so8974927wro.0 for ; Fri, 01 Nov 2019 01:51:54 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Y+GRMSFiDaiBvXVxNY6UdIADt2KEyce4VeE8Ilngfns=; b=NTLlqjtpAvmetFTad/DR6wIFYWHyuYXDpElLotFd9UOoPL7h/Vqc+loQ6q+pNUIEIE O1nfueHQoaofXUddWSzF26wi2LU5ywSC5w+RWD4VnEb3CU4KnDTGliSXa0YbJTmEwpLz ihwOHN+DBSlzln4dZJB7o6yksfV3vVwp6ESetygTIernyth2uKqjmzp7st3ZRnGEN4us 1jQxKmGkkEvKsRMLWVg5HLZtwk8QVu2eqRQuDeZV1Xkvz+lnzAEULX0Bz0rw4EN1bVQV wvSIDRKql55JgsRyY8kSSkw1bXEI4AdQpay63SSE/4oNGdJ1JOgEyrW+JnYxVxVaNncU Kziw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Y+GRMSFiDaiBvXVxNY6UdIADt2KEyce4VeE8Ilngfns=; b=AxGEMWTIYlSzoJbJNVxcHVQ+2vkIrHKPeUJV9FaTB8gIQsoWNF9O4pY33fSlwrluCe Iu3ZGv8aV3+oocN6MuC0XJ9rhrJE7OXDJfg/jOSuLcuZEdKT979aD1CYFiThLKbi2lXb CWmzura3DLi1uf7/KivRlqnu4CHMhYrIagMQ3Hm9xCwubTqegFXX+KWpIHvGrKNyh0B8 WyJDnirsszDx3zFATLSCu5w2bSRPvfuMUQDZ0eLuFKEHNd6ILLynhmkZM2MdKnDdg5/M kDjTx1rrvRRgnFgHE/drUFrT7PBhxxHYsfGjY+2BGg0roveHtI5QAX09jDZGHMw9oRc0 ZaCA== X-Gm-Message-State: APjAAAXmsPGNJYZymF1hfnpyKQsJyjBJwm2pEPzZsdecCFZxvE7o0pgM QrIIG6ALQ2k9Oafvu1Q2OkOK4dJaWcotcguN X-Google-Smtp-Source: APXvYqyvCZJuQmFvH//f8XYqq82GxDyD0N5kxlQPJZ8rTC+FS6wuMTkWdMEunaSevlAENggrRnT5ew== X-Received: by 2002:adf:f945:: with SMTP id q5mr10229037wrr.33.1572598312694; Fri, 01 Nov 2019 01:51:52 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 08/11] target/arm/cpu64: max cpu: Support sve properties with KVM Date: Fri, 1 Nov 2019 08:51:37 +0000 Message-Id: <20191101085140.5205-9-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42a X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" From: Andrew Jones Extend the SVE vq map initialization and validation with KVM's supported vector lengths when KVM is enabled. In order to determine and select supported lengths we add two new KVM functions for getting and setting the KVM_REG_ARM64_SVE_VLS pseudo-register. This patch has been co-authored with Richard Henderson, who reworked the target/arm/cpu64.c changes in order to push all the validation and auto-enabling/disabling steps into the finalizer, resulting in a nice LOC reduction. Signed-off-by: Andrew Jones Reviewed-by: Eric Auger Reviewed-by: Richard Henderson Tested-by: Masayoshi Mizuma Message-id: 20191031142734.8590-9-drjones@redhat.com Signed-off-by: Peter Maydell --- target/arm/kvm_arm.h | 12 +++ target/arm/cpu64.c | 176 ++++++++++++++++++++++++++++---------- target/arm/kvm64.c | 100 +++++++++++++++++++++- tests/arm-cpu-features.c | 104 +++++++++++++++++++++- docs/arm-cpu-features.rst | 45 +++++++--- 5 files changed, 379 insertions(+), 58 deletions(-) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 7c12f1501a8..8e14d400e8a 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -212,6 +212,17 @@ typedef struct ARMHostCPUFeatures { */ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf); =20 +/** + * kvm_arm_sve_get_vls: + * @cs: CPUState + * @map: bitmap to fill in + * + * Get all the SVE vector lengths supported by the KVM host, setting + * the bits corresponding to their length in quadwords minus one + * (vq - 1) in @map up to ARM_MAX_VQ. + */ +void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map); + /** * kvm_arm_set_cpu_features_from_host: * @cpu: ARMCPU to set the features for @@ -316,6 +327,7 @@ static inline int kvm_arm_vgic_probe(void) static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq) {} static inline void kvm_arm_pmu_init(CPUState *cs) {} =20 +static inline void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map) {} #endif =20 static inline const char *gic_class_name(void) diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index a771a28daa5..c161a146ff0 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -273,9 +273,18 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) * any of the above. Finally, if SVE is not disabled, then at least o= ne * vector length must be enabled. */ + DECLARE_BITMAP(kvm_supported, ARM_MAX_VQ); DECLARE_BITMAP(tmp, ARM_MAX_VQ); uint32_t vq, max_vq =3D 0; =20 + /* Collect the set of vector lengths supported by KVM. */ + bitmap_zero(kvm_supported, ARM_MAX_VQ); + if (kvm_enabled() && kvm_arm_sve_supported(CPU(cpu))) { + kvm_arm_sve_get_vls(CPU(cpu), kvm_supported); + } else if (kvm_enabled()) { + assert(!cpu_isar_feature(aa64_sve, cpu)); + } + /* * Process explicit sve properties. * From the properties, sve_vq_map implies sve_vq_init. @@ -293,10 +302,19 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) return; } =20 - /* Propagate enabled bits down through required powers-of-two. */ - for (vq =3D pow2floor(max_vq); vq >=3D 1; vq >>=3D 1) { - if (!test_bit(vq - 1, cpu->sve_vq_init)) { - set_bit(vq - 1, cpu->sve_vq_map); + if (kvm_enabled()) { + /* + * For KVM we have to automatically enable all supported uniti= alized + * lengths, even when the smaller lengths are not all powers-o= f-two. + */ + bitmap_andnot(tmp, kvm_supported, cpu->sve_vq_init, max_vq); + bitmap_or(cpu->sve_vq_map, cpu->sve_vq_map, tmp, max_vq); + } else { + /* Propagate enabled bits down through required powers-of-two.= */ + for (vq =3D pow2floor(max_vq); vq >=3D 1; vq >>=3D 1) { + if (!test_bit(vq - 1, cpu->sve_vq_init)) { + set_bit(vq - 1, cpu->sve_vq_map); + } } } } else if (cpu->sve_max_vq =3D=3D 0) { @@ -308,23 +326,45 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) return; } =20 - /* Disabling a power-of-two disables all larger lengths. */ - if (test_bit(0, cpu->sve_vq_init)) { - error_setg(errp, "cannot disable sve128"); - error_append_hint(errp, "Disabling sve128 results in all vecto= r " - "lengths being disabled.\n"); - error_append_hint(errp, "With SVE enabled, at least one vector= " - "length must be enabled.\n"); - return; - } - for (vq =3D 2; vq <=3D ARM_MAX_VQ; vq <<=3D 1) { - if (test_bit(vq - 1, cpu->sve_vq_init)) { - break; + if (kvm_enabled()) { + /* Disabling a supported length disables all larger lengths. */ + for (vq =3D 1; vq <=3D ARM_MAX_VQ; ++vq) { + if (test_bit(vq - 1, cpu->sve_vq_init) && + test_bit(vq - 1, kvm_supported)) { + break; + } } + max_vq =3D vq <=3D ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ; + bitmap_andnot(cpu->sve_vq_map, kvm_supported, + cpu->sve_vq_init, max_vq); + if (max_vq =3D=3D 0 || bitmap_empty(cpu->sve_vq_map, max_vq)) { + error_setg(errp, "cannot disable sve%d", vq * 128); + error_append_hint(errp, "Disabling sve%d results in all " + "vector lengths being disabled.\n", + vq * 128); + error_append_hint(errp, "With SVE enabled, at least one " + "vector length must be enabled.\n"); + return; + } + } else { + /* Disabling a power-of-two disables all larger lengths. */ + if (test_bit(0, cpu->sve_vq_init)) { + error_setg(errp, "cannot disable sve128"); + error_append_hint(errp, "Disabling sve128 results in all " + "vector lengths being disabled.\n"); + error_append_hint(errp, "With SVE enabled, at least one " + "vector length must be enabled.\n"); + return; + } + for (vq =3D 2; vq <=3D ARM_MAX_VQ; vq <<=3D 1) { + if (test_bit(vq - 1, cpu->sve_vq_init)) { + break; + } + } + max_vq =3D vq <=3D ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ; + bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq); } - max_vq =3D vq <=3D ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ; =20 - bitmap_complement(cpu->sve_vq_map, cpu->sve_vq_init, max_vq); max_vq =3D find_last_bit(cpu->sve_vq_map, max_vq) + 1; } =20 @@ -358,16 +398,48 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) assert(max_vq !=3D 0); bitmap_clear(cpu->sve_vq_map, max_vq, ARM_MAX_VQ - max_vq); =20 - /* Ensure all required powers-of-two are enabled. */ - for (vq =3D pow2floor(max_vq); vq >=3D 1; vq >>=3D 1) { - if (!test_bit(vq - 1, cpu->sve_vq_map)) { - error_setg(errp, "cannot disable sve%d", vq * 128); - error_append_hint(errp, "sve%d is required as it " - "is a power-of-two length smaller than " - "the maximum, sve%d\n", - vq * 128, max_vq * 128); + if (kvm_enabled()) { + /* Ensure the set of lengths matches what KVM supports. */ + bitmap_xor(tmp, cpu->sve_vq_map, kvm_supported, max_vq); + if (!bitmap_empty(tmp, max_vq)) { + vq =3D find_last_bit(tmp, max_vq) + 1; + if (test_bit(vq - 1, cpu->sve_vq_map)) { + if (cpu->sve_max_vq) { + error_setg(errp, "cannot set sve-max-vq=3D%d", + cpu->sve_max_vq); + error_append_hint(errp, "This KVM host does not suppor= t " + "the vector length %d-bits.\n", + vq * 128); + error_append_hint(errp, "It may not be possible to use= " + "sve-max-vq with this KVM host. Try " + "using only sve properties.\n"); + } else { + error_setg(errp, "cannot enable sve%d", vq * 128); + error_append_hint(errp, "This KVM host does not suppor= t " + "the vector length %d-bits.\n", + vq * 128); + } + } else { + error_setg(errp, "cannot disable sve%d", vq * 128); + error_append_hint(errp, "The KVM host requires all " + "supported vector lengths smaller " + "than %d bits to also be enabled.\n", + max_vq * 128); + } return; } + } else { + /* Ensure all required powers-of-two are enabled. */ + for (vq =3D pow2floor(max_vq); vq >=3D 1; vq >>=3D 1) { + if (!test_bit(vq - 1, cpu->sve_vq_map)) { + error_setg(errp, "cannot disable sve%d", vq * 128); + error_append_hint(errp, "sve%d is required as it " + "is a power-of-two length smaller than " + "the maximum, sve%d\n", + vq * 128, max_vq * 128); + return; + } + } } =20 /* @@ -421,15 +493,28 @@ static void cpu_max_set_sve_max_vq(Object *obj, Visit= or *v, const char *name, { ARMCPU *cpu =3D ARM_CPU(obj); Error *err =3D NULL; + uint32_t max_vq; =20 - visit_type_uint32(v, name, &cpu->sve_max_vq, &err); - - if (!err && (cpu->sve_max_vq =3D=3D 0 || cpu->sve_max_vq > ARM_MAX_VQ)= ) { - error_setg(&err, "unsupported SVE vector length"); - error_append_hint(&err, "Valid sve-max-vq in range [1-%d]\n", - ARM_MAX_VQ); + visit_type_uint32(v, name, &max_vq, &err); + if (err) { + error_propagate(errp, err); + return; } - error_propagate(errp, err); + + if (kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) { + error_setg(errp, "cannot set sve-max-vq"); + error_append_hint(errp, "SVE not supported by KVM on this host\n"); + return; + } + + if (max_vq =3D=3D 0 || max_vq > ARM_MAX_VQ) { + error_setg(errp, "unsupported SVE vector length"); + error_append_hint(errp, "Valid sve-max-vq in range [1-%d]\n", + ARM_MAX_VQ); + return; + } + + cpu->sve_max_vq =3D max_vq; } =20 static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name, @@ -462,6 +547,12 @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v= , const char *name, return; } =20 + if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) { + error_setg(errp, "cannot enable %s", name); + error_append_hint(errp, "SVE not supported by KVM on this host\n"); + return; + } + if (value) { set_bit(vq - 1, cpu->sve_vq_map); } else { @@ -619,20 +710,19 @@ static void aarch64_max_initfn(Object *obj) cpu->ctr =3D 0x80038003; /* 32 byte I and D cacheline size, VIPT i= cache */ cpu->dcz_blocksize =3D 7; /* 512 bytes */ #endif - - object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_m= ax_vq, - cpu_max_set_sve_max_vq, NULL, NULL, &error_fat= al); - - for (vq =3D 1; vq <=3D ARM_MAX_VQ; ++vq) { - char name[8]; - sprintf(name, "sve%d", vq * 128); - object_property_add(obj, name, "bool", cpu_arm_get_sve_vq, - cpu_arm_set_sve_vq, NULL, NULL, &error_fat= al); - } } =20 object_property_add(obj, "sve", "bool", cpu_arm_get_sve, cpu_arm_set_sve, NULL, NULL, &error_fatal); + object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_v= q, + cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal); + + for (vq =3D 1; vq <=3D ARM_MAX_VQ; ++vq) { + char name[8]; + sprintf(name, "sve%d", vq * 128); + object_property_add(obj, name, "bool", cpu_arm_get_sve_vq, + cpu_arm_set_sve_vq, NULL, NULL, &error_fatal); + } } =20 struct ARMCPUInfo { diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index c7ecefbed72..c93bbee425a 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -613,6 +613,100 @@ bool kvm_arm_sve_supported(CPUState *cpu) return kvm_check_extension(s, KVM_CAP_ARM_SVE); } =20 +QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN !=3D 1); + +void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map) +{ + /* Only call this function if kvm_arm_sve_supported() returns true. */ + static uint64_t vls[KVM_ARM64_SVE_VLS_WORDS]; + static bool probed; + uint32_t vq =3D 0; + int i, j; + + bitmap_clear(map, 0, ARM_MAX_VQ); + + /* + * KVM ensures all host CPUs support the same set of vector lengths. + * So we only need to create the scratch VCPUs once and then cache + * the results. + */ + if (!probed) { + struct kvm_vcpu_init init =3D { + .target =3D -1, + .features[0] =3D (1 << KVM_ARM_VCPU_SVE), + }; + struct kvm_one_reg reg =3D { + .id =3D KVM_REG_ARM64_SVE_VLS, + .addr =3D (uint64_t)&vls[0], + }; + int fdarray[3], ret; + + probed =3D true; + + if (!kvm_arm_create_scratch_host_vcpu(NULL, fdarray, &init)) { + error_report("failed to create scratch VCPU with SVE enabled"); + abort(); + } + ret =3D ioctl(fdarray[2], KVM_GET_ONE_REG, ®); + kvm_arm_destroy_scratch_host_vcpu(fdarray); + if (ret) { + error_report("failed to get KVM_REG_ARM64_SVE_VLS: %s", + strerror(errno)); + abort(); + } + + for (i =3D KVM_ARM64_SVE_VLS_WORDS - 1; i >=3D 0; --i) { + if (vls[i]) { + vq =3D 64 - clz64(vls[i]) + i * 64; + break; + } + } + if (vq > ARM_MAX_VQ) { + warn_report("KVM supports vector lengths larger than " + "QEMU can enable"); + } + } + + for (i =3D 0; i < KVM_ARM64_SVE_VLS_WORDS; ++i) { + if (!vls[i]) { + continue; + } + for (j =3D 1; j <=3D 64; ++j) { + vq =3D j + i * 64; + if (vq > ARM_MAX_VQ) { + return; + } + if (vls[i] & (1UL << (j - 1))) { + set_bit(vq - 1, map); + } + } + } +} + +static int kvm_arm_sve_set_vls(CPUState *cs) +{ + uint64_t vls[KVM_ARM64_SVE_VLS_WORDS] =3D {0}; + struct kvm_one_reg reg =3D { + .id =3D KVM_REG_ARM64_SVE_VLS, + .addr =3D (uint64_t)&vls[0], + }; + ARMCPU *cpu =3D ARM_CPU(cs); + uint32_t vq; + int i, j; + + assert(cpu->sve_max_vq <=3D KVM_ARM64_SVE_VQ_MAX); + + for (vq =3D 1; vq <=3D cpu->sve_max_vq; ++vq) { + if (test_bit(vq - 1, cpu->sve_vq_map)) { + i =3D (vq - 1) / 64; + j =3D (vq - 1) % 64; + vls[i] |=3D 1UL << j; + } + } + + return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); +} + #define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5 =20 int kvm_arch_init_vcpu(CPUState *cs) @@ -624,7 +718,7 @@ int kvm_arch_init_vcpu(CPUState *cs) =20 if (cpu->kvm_target =3D=3D QEMU_KVM_ARM_TARGET_NONE || !object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) { - fprintf(stderr, "KVM is not supported for this guest CPU type\n"); + error_report("KVM is not supported for this guest CPU type"); return -EINVAL; } =20 @@ -660,6 +754,10 @@ int kvm_arch_init_vcpu(CPUState *cs) } =20 if (cpu_isar_feature(aa64_sve, cpu)) { + ret =3D kvm_arm_sve_set_vls(cs); + if (ret) { + return ret; + } ret =3D kvm_arm_vcpu_finalize(cs, KVM_ARM_VCPU_SVE); if (ret) { return ret; diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c index 015b511c87e..40d8395b7f7 100644 --- a/tests/arm-cpu-features.c +++ b/tests/arm-cpu-features.c @@ -130,6 +130,17 @@ static QDict *resp_get_props(QDict *resp) return qdict; } =20 +static bool resp_get_feature(QDict *resp, const char *feature) +{ + QDict *props; + + g_assert(resp); + g_assert(resp_has_props(resp)); + props =3D resp_get_props(resp); + g_assert(qdict_get(props, feature)); + return qdict_get_bool(props, feature); +} + #define assert_has_feature(qts, cpu_type, feature) \ ({ \ QDict *_resp =3D do_query_no_props(qts, cpu_type); \ @@ -359,6 +370,25 @@ static void sve_tests_sve_off(const void *data) qtest_quit(qts); } =20 +static void sve_tests_sve_off_kvm(const void *data) +{ + QTestState *qts; + + qts =3D qtest_init(MACHINE_KVM "-cpu max,sve=3Doff"); + + /* + * We don't know if this host supports SVE so we don't + * attempt to test enabling anything. We only test that + * everything is disabled (as it should be with sve=3Doff) + * and that using sve=3Doff to explicitly disable vector + * lengths is OK too. + */ + assert_sve_vls(qts, "max", 0, NULL); + assert_sve_vls(qts, "max", 0, "{ 'sve128': false }"); + + qtest_quit(qts); +} + static void test_query_cpu_model_expansion(const void *data) { QTestState *qts; @@ -414,14 +444,82 @@ static void test_query_cpu_model_expansion_kvm(const = void *data) } =20 if (g_str_equal(qtest_get_arch(), "aarch64")) { + bool kvm_supports_sve; + char max_name[8], name[8]; + uint32_t max_vq, vq; + uint64_t vls; + QDict *resp; + char *error; + assert_has_feature(qts, "host", "aarch64"); assert_has_feature(qts, "host", "pmu"); =20 - assert_has_feature(qts, "max", "sve"); - assert_error(qts, "cortex-a15", "We cannot guarantee the CPU type 'cortex-a15' works " "with KVM on this host", NULL); + + assert_has_feature(qts, "max", "sve"); + resp =3D do_query_no_props(qts, "max"); + kvm_supports_sve =3D resp_get_feature(resp, "sve"); + vls =3D resp_get_sve_vls(resp); + qobject_unref(resp); + + if (kvm_supports_sve) { + g_assert(vls !=3D 0); + max_vq =3D 64 - __builtin_clzll(vls); + sprintf(max_name, "sve%d", max_vq * 128); + + /* Enabling a supported length is of course fine. */ + assert_sve_vls(qts, "max", vls, "{ %s: true }", max_name); + + /* Get the next supported length smaller than max-vq. */ + vq =3D 64 - __builtin_clzll(vls & ~BIT_ULL(max_vq - 1)); + if (vq) { + /* + * We have at least one length smaller than max-vq, + * so we can disable max-vq. + */ + assert_sve_vls(qts, "max", (vls & ~BIT_ULL(max_vq - 1)), + "{ %s: false }", max_name); + + /* + * Smaller, supported vector lengths cannot be disabled + * unless all larger, supported vector lengths are also + * disabled. + */ + sprintf(name, "sve%d", vq * 128); + error =3D g_strdup_printf("cannot disable %s", name); + assert_error(qts, "max", error, + "{ %s: true, %s: false }", + max_name, name); + g_free(error); + } + + /* + * The smallest, supported vector length is required, because + * we need at least one vector length enabled. + */ + vq =3D __builtin_ffsll(vls); + sprintf(name, "sve%d", vq * 128); + error =3D g_strdup_printf("cannot disable %s", name); + assert_error(qts, "max", error, "{ %s: false }", name); + g_free(error); + + /* Get an unsupported length. */ + for (vq =3D 1; vq <=3D max_vq; ++vq) { + if (!(vls & BIT_ULL(vq - 1))) { + break; + } + } + if (vq <=3D SVE_MAX_VQ) { + sprintf(name, "sve%d", vq * 128); + error =3D g_strdup_printf("cannot enable %s", name); + assert_error(qts, "max", error, "{ %s: true }", name); + g_free(error); + } + } else { + g_assert(vls =3D=3D 0); + } } else { assert_has_not_feature(qts, "host", "aarch64"); assert_has_not_feature(qts, "host", "pmu"); @@ -446,6 +544,8 @@ int main(int argc, char **argv) NULL, sve_tests_sve_max_vq_8); qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off", NULL, sve_tests_sve_off); + qtest_add_data_func("/arm/kvm/query-cpu-model-expansion/sve-off", + NULL, sve_tests_sve_off_kvm); } =20 return g_test_run(); diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst index 2ea4d6e90c0..bed218d4461 100644 --- a/docs/arm-cpu-features.rst +++ b/docs/arm-cpu-features.rst @@ -191,10 +191,18 @@ SVE CPU Property Dependencies and Constraints =20 1) At least one vector length must be enabled when `sve` is enabled. =20 - 2) If a vector length `N` is enabled, then all power-of-two vector - lengths smaller than `N` must also be enabled. E.g. if `sve512` - is enabled, then the 128-bit and 256-bit vector lengths must also - be enabled. + 2) If a vector length `N` is enabled, then, when KVM is enabled, all + smaller, host supported vector lengths must also be enabled. If + KVM is not enabled, then only all the smaller, power-of-two vector + lengths must be enabled. E.g. with KVM if the host supports all + vector lengths up to 512-bits (128, 256, 384, 512), then if `sve512` + is enabled, the 128-bit vector length, 256-bit vector length, and + 384-bit vector length must also be enabled. Without KVM, the 384-bit + vector length would not be required. + + 3) If KVM is enabled then only vector lengths that the host CPU type + support may be enabled. If SVE is not supported by the host, then + no `sve*` properties may be enabled. =20 SVE CPU Property Parsing Semantics ---------------------------------- @@ -209,8 +217,10 @@ SVE CPU Property Parsing Semantics an error is generated. =20 2) If SVE is enabled (`sve=3Don`), but no `sve` CPU properties are - provided, then all supported vector lengths are enabled, including - the non-power-of-two lengths. + provided, then all supported vector lengths are enabled, which when + KVM is not in use means including the non-power-of-two lengths, and, + when KVM is in use, it means all vector lengths supported by the host + processor. =20 3) If SVE is enabled, then an error is generated when attempting to disable the last enabled vector length (see constraint (1) of "SVE @@ -221,20 +231,31 @@ SVE CPU Property Parsing Semantics has been explicitly disabled, then an error is generated (see constraint (2) of "SVE CPU Property Dependencies and Constraints"). =20 - 5) If one or more `sve` CPU properties are set `off`, but no `sve`, + 5) When KVM is enabled, if the host does not support SVE, then an error + is generated when attempting to enable any `sve*` properties (see + constraint (3) of "SVE CPU Property Dependencies and Constraints"). + + 6) When KVM is enabled, if the host does support SVE, then an error is + generated when attempting to enable any vector lengths not supported + by the host (see constraint (3) of "SVE CPU Property Dependencies and + Constraints"). + + 7) If one or more `sve` CPU properties are set `off`, but no `sve`, CPU properties are set `on`, then the specified vector lengths are disabled but the default for any unspecified lengths remains enabled. - Disabling a power-of-two vector length also disables all vector - lengths larger than the power-of-two length (see constraint (2) of - "SVE CPU Property Dependencies and Constraints"). + When KVM is not enabled, disabling a power-of-two vector length also + disables all vector lengths larger than the power-of-two length. + When KVM is enabled, then disabling any supported vector length also + disables all larger vector lengths (see constraint (2) of "SVE CPU + Property Dependencies and Constraints"). =20 - 6) If one or more `sve` CPU properties are set to `on`, then they + 8) If one or more `sve` CPU properties are set to `on`, then they are enabled and all unspecified lengths default to disabled, except for the required lengths per constraint (2) of "SVE CPU Property Dependencies and Constraints", which will even be auto-enabled if they were not explicitly enabled. =20 - 7) If SVE was disabled (`sve=3Doff`), allowing all vector lengths to be + 9) If SVE was disabled (`sve=3Doff`), allowing all vector lengths to be explicitly disabled (i.e. avoiding the error specified in (3) of "SVE CPU Property Parsing Semantics"), then if later an `sve=3Don` is provided an error will be generated. To avoid this error, one must --=20 2.20.1 From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572598675; cv=none; d=zoho.com; s=zohoarc; b=iu2TXgjLcQlXNH5OB4rJkXdxDoHQls/+Xe4SxhXb7gtTBnp7JLKL85z7OHL0rFObAC6tvcU/7hDV1dOQ3W4BPUY3Tof635LXBaRiQwDNm+GAjwyF7g0W1nqvngN+H+iHy2Z2uxUmKof1L7LQ/oa3ndIM+Q+MH9SWwDH+RXRCpdo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572598675; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=GsD3QQxbEUJRJc4Np7QQU7K8ZouwI6xXEaEwME4AcL8=; b=BFDON7P1iCDTkHn9B62An9RGWnTlQFR0q9cnvdKiglkI+LHmRDlSv9xbr9YbqsAZ87ccbPglWX3p0ON2PteZwFquYNqiVUX9Ezkwyyz4bPZCxg8DvHFXkP1bOIGhXBLjZKNFSK0LdeQrFsFhaORcKD99nc5X1oh3gvrwL7PS6GY= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1572598675744672.5732305695122; Fri, 1 Nov 2019 01:57:55 -0700 (PDT) Received: from localhost ([::1]:57560 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSkk-00071d-LL for importer@patchew.org; Fri, 01 Nov 2019 04:57:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56560) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSez-0001Bx-KN for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSex-0000YM-E0 for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:57 -0400 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]:52127) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSex-0000Ui-5t for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:55 -0400 Received: by mail-wm1-x334.google.com with SMTP id q70so8592108wme.1 for ; Fri, 01 Nov 2019 01:51:55 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=GsD3QQxbEUJRJc4Np7QQU7K8ZouwI6xXEaEwME4AcL8=; b=VViZHBHOAXkznGeBpvV3TrDjbhhWy6bTtz5Mto/Ho++Zs4qSI7y53ABT58xIgPUimJ 9yIYS54womdYT70Zhte3kFAhEdbm1yH3H02mviwQGgVNSAGH/4kvW9fRED9fYE14ZXOL M9xC9vNBv2I4sm8Mf/DDoBm2wCZAtWIwOzok/GzxqmY5+t5XWsUGUbcV1OLmk/K9gSvg ShaivVfhQ9K0NcWS9fJHOAKc7PQ6fjQB0gEPsK5Kf7M9J1D1HXwgLlKMhMgnG4KpyDsQ Kir9p/T7zKxwIpG9l6gJgoRB23fJnvm9b6m+Mz5JqNYa756ioxoxE+ba/pubUcKLHEw8 obkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=GsD3QQxbEUJRJc4Np7QQU7K8ZouwI6xXEaEwME4AcL8=; b=SqnT7r0oEOzdX22xht8Xlhbct6g8NuBYmmTuxb8joo9unjSx1/7gIIs2ZQtcM6c0IH bYwbbfxPRjMgT5DcV/SGT0ubnVwtElA/NbA6tM6nYchFZIR77uYgzyeSoYTIENm7o+RL UpcVZwYYMVYZ5ER9dQ4SWkBC9RrIXb18hMNBK3LMdABJcLuIEstVUZi61R1nAhLi8GmY dsIObVpoo5/MrlP8uxMsmFjobULvoGzP2hurV60kpLa+0Um/XbBvqXpoJQreQGwR9/GU IlDsXTz2MlNx5dX1JJfBxd744FqOx5DvXkpnXpesvj6ECmZjSNBfrckETh+sZubvDWjZ cGRg== X-Gm-Message-State: APjAAAV0L/QcoUwSCCtWvyxbzO1Ygd6Z59PrQiR7HKge6DflpD3oFEah l9NNTTWHDfRiQkLvcL8QZ1ABlUPNuEWCvP+c X-Google-Smtp-Source: APXvYqzCGTTRSRurd3h+rtwzzQmOKopoALJSeeoo6Tf0LUwwXTfoJhUp8UQyu0l20cZRd872dvcPcw== X-Received: by 2002:a05:600c:1150:: with SMTP id z16mr9541358wmz.153.1572598313714; Fri, 01 Nov 2019 01:51:53 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 09/11] target/arm/kvm: host cpu: Add support for sve properties Date: Fri, 1 Nov 2019 08:51:38 +0000 Message-Id: <20191101085140.5205-10-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::334 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" From: Andrew Jones Allow cpu 'host' to enable SVE when it's available, unless the user chooses to disable it with the added 'sve=3Doff' cpu property. Also give the user the ability to select vector lengths with the sve properties. We don't adopt 'max' cpu's other sve property, sve-max-vq, because that property is difficult to use with KVM. That property assumes all vector lengths in the range from 1 up to and including the specified maximum length are supported, but there may be optional lengths not supported by the host in that range. With KVM one must be more specific when enabling vector lengths. Signed-off-by: Andrew Jones Reviewed-by: Eric Auger Reviewed-by: Richard Henderson Tested-by: Masayoshi Mizuma Message-id: 20191031142734.8590-10-drjones@redhat.com Signed-off-by: Peter Maydell --- target/arm/cpu.h | 2 ++ target/arm/cpu.c | 3 +++ target/arm/cpu64.c | 33 +++++++++++++++++---------------- target/arm/kvm64.c | 14 +++++++++++++- tests/arm-cpu-features.c | 17 ++++++++--------- docs/arm-cpu-features.rst | 19 ++++++++++++------- 6 files changed, 55 insertions(+), 33 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index a044d6028b6..e1a66a2d1cc 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -977,11 +977,13 @@ int aarch64_cpu_gdb_write_register(CPUState *cpu, uin= t8_t *buf, int reg); void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq); void aarch64_sve_change_el(CPUARMState *env, int old_el, int new_el, bool el0_a64); +void aarch64_add_sve_properties(Object *obj); #else static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { } static inline void aarch64_sve_change_el(CPUARMState *env, int o, int n, bool a) { } +static inline void aarch64_add_sve_properties(Object *obj) { } #endif =20 #if !defined(CONFIG_TCG) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 17d1f2b2894..7a4ac9339bf 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2670,6 +2670,9 @@ static void arm_host_initfn(Object *obj) ARMCPU *cpu =3D ARM_CPU(obj); =20 kvm_arm_set_cpu_features_from_host(cpu); + if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { + aarch64_add_sve_properties(obj); + } arm_cpu_post_init(obj); } =20 diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index c161a146ff0..68baf0482ff 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -594,6 +594,21 @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, c= onst char *name, cpu->isar.id_aa64pfr0 =3D t; } =20 +void aarch64_add_sve_properties(Object *obj) +{ + uint32_t vq; + + object_property_add(obj, "sve", "bool", cpu_arm_get_sve, + cpu_arm_set_sve, NULL, NULL, &error_fatal); + + for (vq =3D 1; vq <=3D ARM_MAX_VQ; ++vq) { + char name[8]; + sprintf(name, "sve%d", vq * 128); + object_property_add(obj, name, "bool", cpu_arm_get_sve_vq, + cpu_arm_set_sve_vq, NULL, NULL, &error_fatal); + } +} + /* -cpu max: if KVM is enabled, like -cpu host (best possible with this ho= st); * otherwise, a CPU with as many features enabled as our emulation support= s. * The version of '-cpu max' for qemu-system-arm is defined in cpu.c; @@ -602,17 +617,11 @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, = const char *name, static void aarch64_max_initfn(Object *obj) { ARMCPU *cpu =3D ARM_CPU(obj); - uint32_t vq; - uint64_t t; =20 if (kvm_enabled()) { kvm_arm_set_cpu_features_from_host(cpu); - if (kvm_arm_sve_supported(CPU(cpu))) { - t =3D cpu->isar.id_aa64pfr0; - t =3D FIELD_DP64(t, ID_AA64PFR0, SVE, 1); - cpu->isar.id_aa64pfr0 =3D t; - } } else { + uint64_t t; uint32_t u; aarch64_a57_initfn(obj); =20 @@ -712,17 +721,9 @@ static void aarch64_max_initfn(Object *obj) #endif } =20 - object_property_add(obj, "sve", "bool", cpu_arm_get_sve, - cpu_arm_set_sve, NULL, NULL, &error_fatal); + aarch64_add_sve_properties(obj); object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_v= q, cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal); - - for (vq =3D 1; vq <=3D ARM_MAX_VQ; ++vq) { - char name[8]; - sprintf(name, "sve%d", vq * 128); - object_property_add(obj, name, "bool", cpu_arm_get_sve_vq, - cpu_arm_set_sve_vq, NULL, NULL, &error_fatal); - } } =20 struct ARMCPUInfo { diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index c93bbee425a..876184b8fe4 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -488,7 +488,9 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *= ahcf) * and then query that CPU for the relevant ID registers. */ int fdarray[3]; + bool sve_supported; uint64_t features =3D 0; + uint64_t t; int err; =20 /* Old kernels may not know about the PREFERRED_TARGET ioctl: however @@ -578,13 +580,23 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures= *ahcf) ARM64_SYS_REG(3, 0, 0, 3, 2)); } =20 + sve_supported =3D ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_S= VE) > 0; + kvm_arm_destroy_scratch_host_vcpu(fdarray); =20 if (err < 0) { return false; } =20 - /* We can assume any KVM supporting CPU is at least a v8 + /* Add feature bits that can't appear until after VCPU init. */ + if (sve_supported) { + t =3D ahcf->isar.id_aa64pfr0; + t =3D FIELD_DP64(t, ID_AA64PFR0, SVE, 1); + ahcf->isar.id_aa64pfr0 =3D t; + } + + /* + * We can assume any KVM supporting CPU is at least a v8 * with VFPv4+Neon; this in turn implies most of the other * feature bits. */ diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c index 40d8395b7f7..b132ed09806 100644 --- a/tests/arm-cpu-features.c +++ b/tests/arm-cpu-features.c @@ -458,8 +458,8 @@ static void test_query_cpu_model_expansion_kvm(const vo= id *data) "We cannot guarantee the CPU type 'cortex-a15' works " "with KVM on this host", NULL); =20 - assert_has_feature(qts, "max", "sve"); - resp =3D do_query_no_props(qts, "max"); + assert_has_feature(qts, "host", "sve"); + resp =3D do_query_no_props(qts, "host"); kvm_supports_sve =3D resp_get_feature(resp, "sve"); vls =3D resp_get_sve_vls(resp); qobject_unref(resp); @@ -470,7 +470,7 @@ static void test_query_cpu_model_expansion_kvm(const vo= id *data) sprintf(max_name, "sve%d", max_vq * 128); =20 /* Enabling a supported length is of course fine. */ - assert_sve_vls(qts, "max", vls, "{ %s: true }", max_name); + assert_sve_vls(qts, "host", vls, "{ %s: true }", max_name); =20 /* Get the next supported length smaller than max-vq. */ vq =3D 64 - __builtin_clzll(vls & ~BIT_ULL(max_vq - 1)); @@ -479,7 +479,7 @@ static void test_query_cpu_model_expansion_kvm(const vo= id *data) * We have at least one length smaller than max-vq, * so we can disable max-vq. */ - assert_sve_vls(qts, "max", (vls & ~BIT_ULL(max_vq - 1)), + assert_sve_vls(qts, "host", (vls & ~BIT_ULL(max_vq - 1)), "{ %s: false }", max_name); =20 /* @@ -489,7 +489,7 @@ static void test_query_cpu_model_expansion_kvm(const vo= id *data) */ sprintf(name, "sve%d", vq * 128); error =3D g_strdup_printf("cannot disable %s", name); - assert_error(qts, "max", error, + assert_error(qts, "host", error, "{ %s: true, %s: false }", max_name, name); g_free(error); @@ -502,7 +502,7 @@ static void test_query_cpu_model_expansion_kvm(const vo= id *data) vq =3D __builtin_ffsll(vls); sprintf(name, "sve%d", vq * 128); error =3D g_strdup_printf("cannot disable %s", name); - assert_error(qts, "max", error, "{ %s: false }", name); + assert_error(qts, "host", error, "{ %s: false }", name); g_free(error); =20 /* Get an unsupported length. */ @@ -514,7 +514,7 @@ static void test_query_cpu_model_expansion_kvm(const vo= id *data) if (vq <=3D SVE_MAX_VQ) { sprintf(name, "sve%d", vq * 128); error =3D g_strdup_printf("cannot enable %s", name); - assert_error(qts, "max", error, "{ %s: true }", name); + assert_error(qts, "host", error, "{ %s: true }", name); g_free(error); } } else { @@ -523,8 +523,7 @@ static void test_query_cpu_model_expansion_kvm(const vo= id *data) } else { assert_has_not_feature(qts, "host", "aarch64"); assert_has_not_feature(qts, "host", "pmu"); - - assert_has_not_feature(qts, "max", "sve"); + assert_has_not_feature(qts, "host", "sve"); } =20 qtest_quit(qts); diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst index bed218d4461..1b367e22e16 100644 --- a/docs/arm-cpu-features.rst +++ b/docs/arm-cpu-features.rst @@ -272,31 +272,36 @@ SVE CPU Property Examples =20 $ qemu-system-aarch64 -M virt -cpu max =20 - 3) Only enable the 128-bit vector length:: + 3) When KVM is enabled, implicitly enable all host CPU supported vector + lengths with the `host` CPU type:: + + $ qemu-system-aarch64 -M virt,accel=3Dkvm -cpu host + + 4) Only enable the 128-bit vector length:: =20 $ qemu-system-aarch64 -M virt -cpu max,sve128=3Don =20 - 4) Disable the 512-bit vector length and all larger vector lengths, + 5) Disable the 512-bit vector length and all larger vector lengths, since 512 is a power-of-two. This results in all the smaller, uninitialized lengths (128, 256, and 384) defaulting to enabled:: =20 $ qemu-system-aarch64 -M virt -cpu max,sve512=3Doff =20 - 5) Enable the 128-bit, 256-bit, and 512-bit vector lengths:: + 6) Enable the 128-bit, 256-bit, and 512-bit vector lengths:: =20 $ qemu-system-aarch64 -M virt -cpu max,sve128=3Don,sve256=3Don,sve512= =3Don =20 - 6) The same as (5), but since the 128-bit and 256-bit vector + 7) The same as (6), but since the 128-bit and 256-bit vector lengths are required for the 512-bit vector length to be enabled, then allow them to be auto-enabled:: =20 $ qemu-system-aarch64 -M virt -cpu max,sve512=3Don =20 - 7) Do the same as (6), but by first disabling SVE and then re-enabling i= t:: + 8) Do the same as (7), but by first disabling SVE and then re-enabling i= t:: =20 $ qemu-system-aarch64 -M virt -cpu max,sve=3Doff,sve512=3Don,sve=3Don =20 - 8) Force errors regarding the last vector length:: + 9) Force errors regarding the last vector length:: =20 $ qemu-system-aarch64 -M virt -cpu max,sve128=3Doff $ qemu-system-aarch64 -M virt -cpu max,sve=3Doff,sve128=3Doff,sve=3Don @@ -308,5 +313,5 @@ The examples in "SVE CPU Property Examples" exhibit man= y ways to select vector lengths which developers may find useful in order to avoid overly verbose command lines. However, the recommended way to select vector lengths is to explicitly enable each desired length. Therefore only -example's (1), (3), and (5) exhibit recommended uses of the properties. +example's (1), (4), and (6) exhibit recommended uses of the properties. =20 --=20 2.20.1 From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572599016; cv=none; d=zoho.com; s=zohoarc; b=F4pxCRs0CpEc8u5tOlp9c/ytfbii1VYIBCFdLaXU6xvILvMe/g7+EQYeZHyupFFiiNOm4EZG0WlsItPggKs672QPCD5KAE1MPNXPsTBIAwvg1dGmMjlQMgulBd59ApLYH0zNEmabnxd7X8ipgjlVvCYyrx2GykOTYW12QNUGsT8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572599016; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=rrO+qwPM4Kmir6VZyxAXUgGXFxnOGGraCt67S9SJoFU=; b=SKowJdVGc7gioN8mO7hKOx9M26JepxkH4BdEQM8pBkofaVM6hDq0RsDkJY1LvJ2twSw5QKHEXRdr9UtvgC87hE7bHjj9IXZbmhTqNmYoDBSGHrVetvj0m3hUDB4jrlElm+TPrNl5AOLuVI7a1iIkpU3FxKc//vnA7lv++wney6w= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1572599016460719.8916657266661; Fri, 1 Nov 2019 02:03:36 -0700 (PDT) Received: from localhost ([::1]:58918 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSqF-00050s-3C for importer@patchew.org; Fri, 01 Nov 2019 05:03:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56555) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSez-0001BZ-AU for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSey-0000cW-7Z for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:57 -0400 Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]:34564) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSey-0000YI-1U for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:56 -0400 Received: by mail-wr1-x42d.google.com with SMTP id e6so7115071wrw.1 for ; Fri, 01 Nov 2019 01:51:55 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=rrO+qwPM4Kmir6VZyxAXUgGXFxnOGGraCt67S9SJoFU=; b=j0tRb9cYn0tON9ckOzHCr5Ts/qCfHuQDrbSQ+54FfC2KjXdrQAfyjZJPdXoWPDBVOC uSRshks7jQNS9WqrhPbWGfxOaTSwCx7KRrrlKOMHb41WLfh0e31Y1hGmcJ6g6DLOtM5B /bqnZyyj6kvY/UPqt4JHwl8GfDR01RlmKRAeT8xbR1qTsbwrMdhqvkVhSJZGNx3s3y2q twEyPw7+yBv90QJl7JMnSfpJ2wlIIzDQbvL76og+s0rVTEjKcJGgjQmQOMnmNDmf5dxi Qgi3PCqk5FVt7pz3xFxi9BpnlS4EfvcLpVXaWcxVtl2lqUZXsvnVU867iVlFZyj8Eiy3 LngQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rrO+qwPM4Kmir6VZyxAXUgGXFxnOGGraCt67S9SJoFU=; b=RIJdYeJB5/HbTWT+xF/xC67V4GoSk+1ITVUdyqwGajSseYZId6+RHfQOIm3rXSnm13 iAeA5tP21MsWp7FsEERwGUeRB325en4GcT2f/s+1ACMlCu7mdoCmhgbODd97GwEe8pE+ sVEyx7IZzEvvUwV4W6Qtz23WmDSNcqTYXUPdAMGMLVhtm3ilRu747c69cg+eATKICu81 q6sauiIZQS17P7FwhTRkwDFLKn/rvvfCi66cZw+C1z/gMK5GGKgMJDy29R4mDdlDHi4a i5lJ2gS7GTMXSx4kGA7ivW6Frc4SWvnxoEltKzDBOTz6Vb5FsvBMgSPE19+UJCWYTqGr CtwQ== X-Gm-Message-State: APjAAAXMDAw6iV32LqooNDUZ+MpJ6D7/Q67bGIAh54PRRGyimrQEyeJS z0TlkDMVKxOAMTiqe6OPugb8fnPvRj02hSLD X-Google-Smtp-Source: APXvYqyqsqAOnRR4X+DdEQqZjgbkMzsM31C8nQvGGSwkwDv3x2CozhGP9xrbYwVIkbkXT3VUj44JuQ== X-Received: by 2002:adf:ff81:: with SMTP id j1mr607945wrr.98.1572598314758; Fri, 01 Nov 2019 01:51:54 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 10/11] hw/arm/boot: Rebuild hflags when modifying CPUState at boot Date: Fri, 1 Nov 2019 08:51:39 +0000 Message-Id: <20191101085140.5205-11-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42d X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) From: "Edgar E. Iglesias" Rebuild hflags when modifying CPUState at boot. Fixes: e979972a6a Signed-off-by: Edgar E. Iglesias Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Alex Benn=C3=A9e Reviewed-by: Luc Michel Message-id: 20191031040830.18800-2-edgar.iglesias@xilinx.com Signed-off-by: Peter Maydell --- hw/arm/boot.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index c264864c11d..ef6724960c0 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -786,6 +786,7 @@ static void do_cpu_reset(void *opaque) info->secondary_cpu_reset_hook(cpu, info); } } + arm_rebuild_hflags(env); } } =20 --=20 2.20.1 From nobody Sat May 4 06:21:52 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1572598820; cv=none; d=zoho.com; s=zohoarc; b=WkZ5V22GM5Fz2XYOnHjw4/7o+uek/6kCHgRufpbiu6Mgp7JYi3GfqX6obY3/1LNpxep/tTR1f6w0dybwpl9AQPZLS1TJ5/hjYkI2XDW1bOq09cf8X4U84Gw4HsO59D43lBXFxf+6BJadlmvNCBgY/ZIIs0DoXnS02amuk8d0nnc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1572598820; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Wh/QH/3UtP8gd1jgQHJ/Qv7q+ZrFPgvBOyLNaqirHw4=; b=XiiPVyAHQQxO0o+TGZ6Mqc4cZBEyQbMHKUSlVTuzRIuhe9PFep+NEaifh+WWm+fSGyvoyge6OmhN4PjF4qXHtfH8IICseE7fYJc59+voAK5E2vpRmeb0a9wvpF1oyNFpaC0FvnJkZFiePKPAEXYCEbQi/gId/PPvIjtRRmFWuJ8= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1572598820613232.73702706962524; Fri, 1 Nov 2019 02:00:20 -0700 (PDT) Received: from localhost ([::1]:57626 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSn5-0001j3-Cd for importer@patchew.org; Fri, 01 Nov 2019 05:00:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56599) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iQSf3-0001EE-42 for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:52:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iQSf1-0000qx-3H for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:52:00 -0400 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:37136) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iQSf0-0000d0-TO for qemu-devel@nongnu.org; Fri, 01 Nov 2019 04:51:59 -0400 Received: by mail-wm1-x341.google.com with SMTP id q130so8376472wme.2 for ; Fri, 01 Nov 2019 01:51:56 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id d20sm8818922wra.4.2019.11.01.01.51.54 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Nov 2019 01:51:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Wh/QH/3UtP8gd1jgQHJ/Qv7q+ZrFPgvBOyLNaqirHw4=; b=PcWRJD+2t9c1RwGAyxjqMq/hHwGAencq1Rz+H1oWSHpe2aBI2Vv49/EhUt7sNMkTBu qrYeScn/sm7js4jf2JgWznQgI6ryoC8oULJeyH/keLkFYXO9g5S6mqOy6mBAFlzTr2J9 w2P7Q/JhgVhBUAXovmGrTAgpCIcpFpUPFCY0XpaL91xzXZjSsC2zcGPe4VedocwrczGj rc7hVBddwVuTHiFpI0paq/weOCjLPfRh8U5ALb4UzF12OOUKJFWqDvP+2IayzVQAj8y4 RdO47tGe+BTakUoK0Twh1PGV38pOEI05+Zu92knMLm6uzyqRZ+bpTUtL923A06kySGLf xg8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Wh/QH/3UtP8gd1jgQHJ/Qv7q+ZrFPgvBOyLNaqirHw4=; b=OtQQ8iU/Mk0G5NZ9M5ahFw7T4WxilEdCpIHffsuWDgQ+MlpeMXGIjBEqJHXlHZQ7CG AmpG03hSBEm056QODIGT1gRDbeJyFsNJJisu/MdERaSfk4LW28J9yqBu5uiJ6z3n1QBY xOw1A7gq824Vf+p9SfkYVv57N02RXIcr06qtAERVd/YHbwQKgS48IiC4TkD+R3plf78q PdUQPBwBeFawt93Zc6fe6J+OUa97WE/cj0GmPHjBlG6y4J1nznbHcA6lxFzhx2doSi3B oTjzTghcZ1BT2+NlpCT9jbNztb5yZKY1r2RgjeHdYu5FUlgt1t1hbNFVzhs+uftHOVCc FUrg== X-Gm-Message-State: APjAAAUi9IAp4/pCzMakRQtkn8xAcYqfgSMP2xqD3VMY/88aaLOGmpnA /f1BGJuIZHXsG4Kozg85oA9pj2DD1NCUEc8Z X-Google-Smtp-Source: APXvYqzIRzau0TZnveTb+rU2IukXzB95XIe4M6w5yQzD89o0iqjdtt+U7CpRjhcMF7ctIWB6MMlPLA== X-Received: by 2002:a7b:ce0c:: with SMTP id m12mr9325256wmc.38.1572598315697; Fri, 01 Nov 2019 01:51:55 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Subject: [PULL 11/11] target/arm: Allow reading flags from FPSCR for M-profile Date: Fri, 1 Nov 2019 08:51:40 +0000 Message-Id: <20191101085140.5205-12-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191101085140.5205-1-peter.maydell@linaro.org> References: <20191101085140.5205-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::341 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" From: Christophe Lyon rt=3D=3D15 is a special case when reading the flags: it means the destination is APSR. This patch avoids rejecting vmrs apsr_nzcv, fpscr as illegal instruction. Cc: qemu-stable@nongnu.org Signed-off-by: Christophe Lyon Message-id: 20191025095711.10853-1-christophe.lyon@linaro.org [PMM: updated the comment] Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/translate-vfp.inc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c index 9ae980bef63..85c5ef897be 100644 --- a/target/arm/translate-vfp.inc.c +++ b/target/arm/translate-vfp.inc.c @@ -703,9 +703,10 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_= VMRS *a) if (arm_dc_feature(s, ARM_FEATURE_M)) { /* * The only M-profile VFP vmrs/vmsr sysreg is FPSCR. - * Writes to R15 are UNPREDICTABLE; we choose to undef. + * Accesses to R15 are UNPREDICTABLE; we choose to undef. + * (FPSCR -> r15 is a special case which writes to the PSR flags.) */ - if (a->rt =3D=3D 15 || a->reg !=3D ARM_VFP_FPSCR) { + if (a->rt =3D=3D 15 && (!a->l || a->reg !=3D ARM_VFP_FPSCR)) { return false; } } --=20 2.20.1