From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 54DFFC43458 for ; Thu, 9 Jul 2026 00:53:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=qVJP9IC6O5+JtqSVBZPIwZ7OSRal3lx5jLwdPPRuuXw=; b=ADYmWD1HL6jG6Novg8s0iotMO3 u/jy/YAAhx72612bgXRBWKwxOx+DBR9nAu0toQBstKuBBwuIU8iReatRq9QTtJvn4Z7Lfu56FfHck R+eNWibgLgeqhxUvHzppsqCqcht8pv43IeSnOKkO7AhfUWwPn1xHXUXqq1fxUjRnTWix522ROBZCQ fZ2gXTzMXXCOqpBhSLFFlh8Lk+E5FnOG2KLu0qxtCSI40nnG/pV21INecui/wO72jKfAcTB4rYD0X oM9f8SZkui12hRWotS989tl2uNj/gXiuUbhKyDSP8/1bgvJoShwSIkG1dYZVTnRNeXNcWj1h/zJzq QYEip8AA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1whd1D-00000000h75-1sp7; Thu, 09 Jul 2026 00:53:35 +0000 Received: from sea.source.kernel.org ([172.234.252.31]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1whd1C-00000000h5y-2zoC for linux-arm-kernel@lists.infradead.org; Thu, 09 Jul 2026 00:53:34 +0000 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 735694365A; Thu, 9 Jul 2026 00:53:34 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 64D3C1F00A3A; Thu, 9 Jul 2026 00:53:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1783558414; bh=qVJP9IC6O5+JtqSVBZPIwZ7OSRal3lx5jLwdPPRuuXw=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=I3rt2SspEDV+dBv+fFbYuIuSLTyYrcnbGkMO3VK6nWrkt5lPmMiHej1NFznLJ/Ymd UtDp+SwvKkZdvCeWecV5RJOj6/Y2UVQ1I+tnzC4RAyr70gqJr6Dh7B1H4SfXoRdZRe cCuoHLqg3kh3/fX6eVZMwRtleCQDAVOQSJut+kg/owKPa6Wh8XqMEYRVqMqAVWhXgS GBUt6d/iefcAbty7pK4xlYqQrH2StL6l7NF2FVBB+P1ULL7ucMyTm7Qi2OsW08OTGH pQ52icd28LXIrFkb3i8LfrylS2b6QqzUzLdVNoNPq+noQJ4LyH/x7ZKwhFpzxDaHde mLEO4u+4B50mg== From: Mark Brown Date: Thu, 09 Jul 2026 01:51:50 +0100 Subject: [PATCH v11 13/29] KVM: arm64: Document the KVM ABI for SME MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260709-kvm-arm64-sme-v11-13-32799f66db9d@kernel.org> References: <20260709-kvm-arm64-sme-v11-0-32799f66db9d@kernel.org> In-Reply-To: <20260709-kvm-arm64-sme-v11-0-32799f66db9d@kernel.org> To: Marc Zyngier , Joey Gouly , Catalin Marinas , Suzuki K Poulose , Will Deacon , Paolo Bonzini , Jonathan Corbet , Shuah Khan , Oliver Upton Cc: Dave Martin , Fuad Tabba , Mark Rutland , Ben Horgan , Jean-Philippe Brucker , linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Peter Maydell , Eric Auger , Mark Brown X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=12406; i=broonie@kernel.org; h=from:subject:message-id; bh=ehgZkteamEO7lsn/YovoqQS1aFysUSpw5kKyZXzrBKw=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqTvDEXrjNUoWaosqWt7h9Y9Abl8oKqwfJvB4Ko weJREhoFEOJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCak7wxAAKCRAk1otyXVSH 0Ok5B/4q5n+tgLPHRhkJqB+c/iOwlFryNHjOCDDJkL3oeEo83EPGOWT2EbpJF6vutnWPD1AyFGV fi97CmxxMk/bfb7JdW1JM1F0o0F70X1M2P7ZFJBZluSlZGJ+iE6BND1kr7GPu8Lqp43hFjQevSn +pvTKLvZWH43pTJjTLE2B584WqvREHI2MGG/7uo0D/jjI/vg6YdSbAPasr8Yxj66vNMZlpg/wn0 +QTvOb0qG7o0XMZ3XihLG2FqVRJyv+JdljwFOfQ+zaB7eFbvhJiDMrp+cMQOoX39gTSAGE0OJbc p+0MToO/kDbQgieJeWTCqZbQF2JrjNCVabfg9kK7YHlRyPPn X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org SME, the Scalable Matrix Extension, is an arm64 extension which adds support for matrix operations, with core concepts patterned after SVE. SVE introduced some complication in the ABI since it adds new vector floating point registers with runtime configurable size, the size being controlled by a parameter called the vector length (VL). To provide control of this to VMMs we offer two phase configuration of SVE, SVE must first be enabled for the vCPU with KVM_ARM_VCPU_INIT(KVM_ARM_VCPU_SVE), after which vector length may then be configured but the configurably sized floating point registers are inaccessible until finalized with a call to KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE) after which the configurably sized registers can be accessed. SME introduces an additional independent configurable vector length which as well as controlling the size of the new ZA register also provides an alternative view of the configurably sized SVE registers (known as streaming mode) with the guest able to switch between the two modes as it pleases. There is also a fixed sized register ZT0 introduced in SME2. As well as streaming mode the guest may enable and disable ZA and (where SME2 is available) ZT0 dynamically independently of streaming mode. These modes are controlled via the system register SVCR. We handle the configuration of the vector length for SME in a similar manner to SVE, requiring initialization and finalization of the feature with a pseudo register controlling the available SME vector lengths as for SVE. Further, if the guest has both SVE and SME then finalizing one prevents further configuration of the vector length for the other. Where both SVE and SME are configured for the guest we present the SVE registers to userspace as having the maximum vector length of the currently active vector type as configured via SVCR.SM, imposing an ordering requirement on userspace. Userspace access to ZA and (if configured) ZT0 is only available when SVCR.ZA is 1. Reviewed-by: Fuad Tabba Signed-off-by: Mark Brown --- Documentation/virt/kvm/api.rst | 124 +++++++++++++++++++++++++++++------------ 1 file changed, 88 insertions(+), 36 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index a5f9ee92f43e..64f482c9f6a9 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -406,7 +406,7 @@ Errors: instructions from device memory (arm64) ENOSYS data abort outside memslots with no syndrome info and KVM_CAP_ARM_NISV_TO_USER not enabled (arm64) - EPERM SVE feature set but not finalized (arm64) + EPERM SVE or SME feature set but not finalized (arm64) ======= ============================================================== This ioctl is used to run a guest virtual cpu. While there are no @@ -2607,11 +2607,11 @@ Specifically: ======================= ========= ===== ======================================= .. [1] These encodings are not accepted for SVE-enabled vcpus. See - :ref:`KVM_ARM_VCPU_INIT`. + :ref:`KVM_ARM_VCPU_INIT`. They are also not accepted when SME is + enabled without SVE and the vcpu is in streaming mode. The equivalent register content can be accessed via bits [127:0] of - the corresponding SVE Zn registers instead for vcpus that have SVE - enabled (see below). + the corresponding SVE Zn registers in these cases (see below). arm64 CCSIDR registers are demultiplexed by CSSELR value:: @@ -2642,24 +2642,38 @@ arm64 SVE registers have the following bit patterns:: 0x6050 0000 0015 060 FFR bits[256*slice + 255 : 256*slice] 0x6060 0000 0015 ffff KVM_REG_ARM64_SVE_VLS pseudo-register -Access to register IDs where 2048 * slice >= 128 * max_vq will fail with -ENOENT. max_vq is the vcpu's maximum supported vector length in 128-bit -quadwords: see [2]_ below. +arm64 SME registers have the following bit patterns:: -These registers are only accessible on vcpus for which SVE is enabled. -See KVM_ARM_VCPU_INIT for details. + 0x6080 0000 0017 ZA[n] bits[2048*slice + 2047 : 2048*slice] + 0x6060 0000 0017 0600 ZT0 + 0x6060 0000 0017 fffe KVM_REG_ARM64_SME_VLS pseudo-register -In addition, except for KVM_REG_ARM64_SVE_VLS, these registers are not -accessible until the vcpu's SVE configuration has been finalized -using KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE). See KVM_ARM_VCPU_INIT -and KVM_ARM_VCPU_FINALIZE for more information about this procedure. +Access to Z, P, FFR or ZA register IDs where 2048 * slice >= 128 * +max_vq will fail with ENOENT. max_vq is the vcpu's current maximum +supported vector length in 128-bit quadwords: see [2]_ below. -KVM_REG_ARM64_SVE_VLS is a pseudo-register that allows the set of vector -lengths supported by the vcpu to be discovered and configured by -userspace. When transferred to or from user memory via KVM_GET_ONE_REG -or KVM_SET_ONE_REG, the value of this register is of type -__u64[KVM_ARM64_SVE_VLS_WORDS], and encodes the set of vector lengths as -follows:: +Changing the value of SVCR.SM will result in the contents of registers +that are architecturally reset by entering or exiting streaming mode +being reset. When restoring the values of these registers for a VM +with SME support it is important that SVCR.SM be configured first. + +Access to the ZA and ZT0 registers is only available if SVCR.ZA is set +to 1. These registers are only accessible on vcpus for which SME is +enabled. See KVM_ARM_VCPU_INIT for details. + +In addition, except for KVM_REG_ARM64_SVE_VLS and +KVM_REG_ARM64_SME_VLS, these registers are not accessible until the +vcpu's SVE and SME configuration has been finalized using +KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC). See KVM_ARM_VCPU_INIT and +KVM_ARM_VCPU_FINALIZE for more information about this procedure. + +KVM_REG_ARM64_SVE_VLS and KVM_REG_ARM64_SME_VLS are +pseudo-registers that allows the set of vector lengths supported by +the vcpu to be discovered and configured by userspace. When +transferred to or from user memory via KVM_GET_ONE_REG or +KVM_SET_ONE_REG, the value of this register is of type +__u64[KVM_ARM64_SVE_VLS_WORDS], and encodes the set of vector lengths +as follows:: __u64 vector_lengths[KVM_ARM64_SVE_VLS_WORDS]; @@ -2671,19 +2685,25 @@ follows:: /* Vector length vq * 16 bytes not supported */ .. [2] The maximum value vq for which the above condition is true is - max_vq. This is the maximum vector length available to the guest on - this vcpu, and determines which register slices are visible through - this ioctl interface. + max_vq. This is the maximum vector length currently available to + the guest on this vcpu, and determines which register slices are + visible through this ioctl interface. Note that these slices + should not be confused with the architectural "ZA tile slice". + + If SME is supported and SVCR.SM is 1, then the max_vq used for the + Z and P registers is the maximum SME vector length. Otherwise + it is the maximum SVE vector length. (See Documentation/arch/arm64/sve.rst for an explanation of the "vq" nomenclature.) -KVM_REG_ARM64_SVE_VLS is only accessible after KVM_ARM_VCPU_INIT. -KVM_ARM_VCPU_INIT initialises it to the best set of vector lengths that -the host supports. +KVM_REG_ARM64_SVE_VLS and KVM_REG_ARM64_SME_VLS are only accessible +after KVM_ARM_VCPU_INIT. KVM_ARM_VCPU_INIT initialises them to the +best set of vector lengths that the host supports. -Userspace may subsequently modify it if desired until the vcpu's SVE -configuration is finalized using KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE). +Userspace may subsequently modify these registers if desired until the +vcpu's SVE and SME configuration is finalized using +KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC). Apart from simply removing all vector lengths from the host set that exceed some value, support for arbitrarily chosen sets of vector lengths @@ -2691,8 +2711,8 @@ is hardware-dependent and may not be available. Attempting to configure an invalid set of vector lengths via KVM_SET_ONE_REG will fail with EINVAL. -After the vcpu's SVE configuration is finalized, further attempts to -write this register will fail with EPERM. +After the vcpu's SVE or SME configuration is finalized, further +attempts to write these registers will fail with EPERM. arm64 bitmap feature firmware pseudo-registers have the following bit pattern:: @@ -3491,6 +3511,7 @@ The initial values are defined as: - General Purpose registers, including PC and SP: set to 0 - FPSIMD/NEON registers: set to 0 - SVE registers: set to 0 + - SME registers: set to 0 - System registers: Reset to their architecturally defined values as for a warm reset to EL1 (resp. SVC) or EL2 (in the case of EL2 being enabled). @@ -3534,7 +3555,7 @@ Possible features: - KVM_ARM_VCPU_SVE: Enables SVE for the CPU (arm64 only). Depends on KVM_CAP_ARM_SVE. - Requires KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE): + Requires KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC): * After KVM_ARM_VCPU_INIT: @@ -3542,7 +3563,7 @@ Possible features: initial value of this pseudo-register indicates the best set of vector lengths possible for a vcpu on this host. - * Before KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE): + * Before KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC): - KVM_RUN and KVM_GET_REG_LIST are not available; @@ -3555,11 +3576,41 @@ Possible features: KVM_SET_ONE_REG, to modify the set of vector lengths available for the vcpu. - * After KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE): + * After KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC): - the KVM_REG_ARM64_SVE_VLS pseudo-register is immutable, and can no longer be written using KVM_SET_ONE_REG. + - KVM_ARM_VCPU_SME: Enables SME for the CPU (arm64 only). + Depends on KVM_CAP_ARM_SME. + Requires KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC): + + * After KVM_ARM_VCPU_INIT: + + - KVM_REG_ARM64_SME_VLS may be read using KVM_GET_ONE_REG: the + initial value of this pseudo-register indicates the best set of + vector lengths possible for a vcpu on this host. + + * Before KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC): + + - KVM_RUN and KVM_GET_REG_LIST are not available; + + - KVM_GET_ONE_REG and KVM_SET_ONE_REG cannot be used to access + the scalable architectural SVE registers + KVM_REG_ARM64_SVE_ZREG(), KVM_REG_ARM64_SVE_PREG() or + KVM_REG_ARM64_SVE_FFR, the matrix register + KVM_REG_ARM64_SME_ZAHREG() or the LUT register + KVM_REG_ARM64_SME_ZTREG(); + + - KVM_REG_ARM64_SME_VLS may optionally be written using + KVM_SET_ONE_REG, to modify the set of vector lengths available + for the vcpu. + + * After KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_VEC): + + - the KVM_REG_ARM64_SME_VLS pseudo-register is immutable, and can + no longer be written using KVM_SET_ONE_REG. + - KVM_ARM_VCPU_HAS_EL2: Enable Nested Virtualisation support, booting the guest from EL2 instead of EL1. Depends on KVM_CAP_ARM_EL2. @@ -5156,11 +5207,12 @@ Errors: Recognised values for feature: - ===== =========================================== - arm64 KVM_ARM_VCPU_SVE (requires KVM_CAP_ARM_SVE) - ===== =========================================== + ===== ============================================================== + arm64 KVM_ARM_VCPU_VEC (requires KVM_CAP_ARM_SVE or KVM_CAP_ARM_SME) + arm64 KVM_ARM_VCPU_SVE (alias for KVM_ARM_VCPU_VEC) + ===== ============================================================== -Finalizes the configuration of the specified vcpu feature. +Finalizes the configuration of the specified vcpu features. The vcpu must already have been initialised, enabling the affected feature, by means of a successful :ref:`KVM_ARM_VCPU_INIT ` call with the -- 2.47.3