From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 41362381B15; Sun, 19 Jul 2026 23:11:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784502711; cv=none; b=K6UDE1nZ72+90WvZxyzdiSyk9oC8go83+AHMfG+ifs3r4paQIJN+U3IbFNO+hr3o4Xcti60LLtGjfh6erg6RtQIk7HpZN2TRh7dIo9S4MnRwJHqZvxnwIlSJDX6kEVST+XjV6ZlH5lT0MrYMPzXSDus4FiIwJ7+LEedMwsANvPk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784502711; c=relaxed/simple; bh=/V2DHbBTPReofZe1HQ+FEeJ8vnQLj7k1VzICcoZuutU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=B9U6hm6K0AI+q7CktDS7HdsDKOJ50DS+Lei211epEhP4RYNYn1SKxDsiZ8jXCDinRt1rVcbHRgSwte5ZbQLl3D9pCRsyvgopHSBDo7vXzp3InOy/NUJHBYxzlKQzjZNOT84ORdL/rpLMBHZoUoMq4W83x9SlokCYiVdkGxfs/eo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=U2TZN9Yk; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="U2TZN9Yk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3E0601F000E9; Sun, 19 Jul 2026 23:11:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1784502710; bh=b7MommBkO+e3Lshh90ju5gAfW2OCnzsFwyfx+L/ofMI=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=U2TZN9YkXy8tKubch5qFJVPAWb135k2i3Uk3/V9Igt8PoOMx6A9100yn+vu4sBwqc 9OnmgiIcpNnb0ovUhaDUJwZb5uekMaeb7Scxxxz3JJ6Qncf/omfJ6mMhZRg2UkyaNQ CXTArejgni+1UFl4u52MXXuiBLLxMYhCh6FSUAhNQvd8xX+4JcpiEjPKSJbaijuQTB Rk3T0+vejePDnXImj3hjZdzj692Go7J+nJbuvzEMhLseRi+SggFVVjGLuEpojgbrhW o0HlKP4MOGseBMAC4qstLWlfEX5w/oJXxKzLDh5uXzsLO8rXbUbgoDxsD3HDX0E/um cTEU8bg0ae69A== From: Mark Brown Date: Mon, 20 Jul 2026 00:07:53 +0100 Subject: [PATCH v13 26/32] KVM: arm64: Handle SME exceptions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260720-kvm-arm64-sme-v13-26-d9abd3ffa245@kernel.org> References: <20260720-kvm-arm64-sme-v13-0-d9abd3ffa245@kernel.org> In-Reply-To: <20260720-kvm-arm64-sme-v13-0-d9abd3ffa245@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=4959; i=broonie@kernel.org; h=from:subject:message-id; bh=/V2DHbBTPReofZe1HQ+FEeJ8vnQLj7k1VzICcoZuutU=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqXVk7tA4g1AXbw5CzGAwC7Hipu/k89oJfl38ov 7bfv1y9k8CJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCal1ZOwAKCRAk1otyXVSH 0HsPB/97fDqYBSjKxZ3dd6l/czkSqcfOtuqMqV84Pua1+3sq79ziwQ2/FlswJEih2N8gdt0UvPS 3v45ijuSoj2K9TlFnMwt0dbDNSKsN1mIUQ3kDEnmrc/eYUYjVS/at79Xq135+abrKmyIbZ8D3wI 55ekkcfAF8or6x2nhWV+WSjyBwEBGeBx075eoR87WK8aFzXb9wsuvXLIUVAjK0A3Phu/Rkmk3vE i/4PVKthQTuYtR+MVAggDcYKvEC4hw7+63zcLj9fWAk8/Vg60bx3aT2ZZHWRfZhfO8bMgwf5YuI 6eD8M79dNqGaC8yMhd51DJXXcLMnNkUyRJNWv4w04Nd+qfT0 X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB The access control for SME follows the same structure as for the base FP and SVE extensions, with control being via CPACR_ELx.SMEN and CPTR_EL2.TSM mirroring the equivalent FPSIMD and SVE controls in those registers. Add handling for these controls and exceptions mirroring the existing handling for FPSIMD and SVE, plus handling for emulation of SMCR_EL2.EZT0. Signed-off-by: Mark Brown --- arch/arm64/kvm/handle_exit.c | 19 +++++++++++++++++++ arch/arm64/kvm/hyp/include/hyp/switch.h | 11 ++++++----- arch/arm64/kvm/hyp/nvhe/switch.c | 2 ++ arch/arm64/kvm/hyp/vhe/switch.c | 1 + 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index f674cd25d894..24d54e977a31 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -233,6 +233,24 @@ static int handle_sve(struct kvm_vcpu *vcpu) return 1; } +static int handle_sme(struct kvm_vcpu *vcpu) +{ + u64 esr = kvm_vcpu_get_esr(vcpu); + + if (guest_hyp_sme_traps_enabled(vcpu)) + return kvm_inject_nested_sync(vcpu, esr); + + /* Reinject SME EZT0 traps that were enabled by the guest. */ + if (vcpu_has_sme2(vcpu) && + ESR_ELx_EC(esr) == ESR_ELx_EC_SME && + ESR_ELx_SME_ISS_SMTC(esr) == ESR_ELx_SME_ISS_SMTC_ZT_DISABLED && + !(__vcpu_sys_reg(vcpu, SMCR_EL2) & SMCR_ELx_EZT0)) + return kvm_inject_nested_sync(vcpu, esr); + + kvm_inject_undefined(vcpu); + return 1; +} + /* * Two possibilities to handle a trapping ptrauth instruction: * @@ -386,6 +404,7 @@ static exit_handle_fn arm_exit_handlers[] = { [ESR_ELx_EC_SVC64] = handle_svc, [ESR_ELx_EC_SYS64] = kvm_handle_sys_reg, [ESR_ELx_EC_SVE] = handle_sve, + [ESR_ELx_EC_SME] = handle_sme, [ESR_ELx_EC_ERET] = kvm_handle_eret, [ESR_ELx_EC_IABT_LOW] = kvm_handle_guest_abort, [ESR_ELx_EC_DABT_LOW] = kvm_handle_guest_abort, diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index 2eabffb640e9..5987b550ad34 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -67,11 +67,8 @@ static inline void __activate_cptr_traps_nvhe(struct kvm_vcpu *vcpu) { u64 val = CPTR_NVHE_EL2_RES1 | CPTR_EL2_TAM | CPTR_EL2_TTA; - /* - * Always trap SME since it's not supported in KVM. - * TSM is RES1 if SME isn't implemented. - */ - val |= CPTR_EL2_TSM; + if (!vcpu_has_sme(vcpu) || !guest_owns_fp_regs()) + val |= CPTR_EL2_TSM; if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs()) val |= CPTR_EL2_TZ; @@ -99,6 +96,8 @@ static inline void __activate_cptr_traps_vhe(struct kvm_vcpu *vcpu) val |= CPACR_EL1_FPEN; if (vcpu_has_sve(vcpu)) val |= CPACR_EL1_ZEN; + if (vcpu_has_sme(vcpu)) + val |= CPACR_EL1_SMEN; } if (!vcpu_has_nv(vcpu)) @@ -140,6 +139,8 @@ static inline void __activate_cptr_traps_vhe(struct kvm_vcpu *vcpu) val &= ~CPACR_EL1_FPEN; if (!(SYS_FIELD_GET(CPACR_EL1, ZEN, cptr) & BIT(0))) val &= ~CPACR_EL1_ZEN; + if (!(SYS_FIELD_GET(CPACR_EL1, SMEN, cptr) & BIT(0))) + val &= ~CPACR_EL1_SMEN; if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1POE, IMP)) val |= cptr & CPACR_EL1_E0POE; diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 7318e3e6a5f3..2d5029dbfb00 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -196,6 +196,7 @@ static const exit_handler_fn hyp_exit_handlers[] = { [ESR_ELx_EC_CP15_32] = kvm_hyp_handle_cp15_32, [ESR_ELx_EC_SYS64] = kvm_hyp_handle_sysreg, [ESR_ELx_EC_SVE] = kvm_hyp_handle_fpsimd, + [ESR_ELx_EC_SME] = kvm_hyp_handle_fpsimd, [ESR_ELx_EC_FP_ASIMD] = kvm_hyp_handle_fpsimd, [ESR_ELx_EC_IABT_LOW] = kvm_hyp_handle_iabt_low, [ESR_ELx_EC_DABT_LOW] = kvm_hyp_handle_dabt_low, @@ -208,6 +209,7 @@ static const exit_handler_fn pvm_exit_handlers[] = { [ESR_ELx_EC_HVC64] = kvm_handle_pvm_hvc64, [ESR_ELx_EC_SYS64] = kvm_handle_pvm_sys64, [ESR_ELx_EC_SVE] = kvm_handle_pvm_restricted, + [ESR_ELx_EC_SME] = kvm_handle_pvm_restricted, [ESR_ELx_EC_FP_ASIMD] = kvm_hyp_handle_fpsimd, [ESR_ELx_EC_IABT_LOW] = kvm_hyp_handle_iabt_low, [ESR_ELx_EC_DABT_LOW] = kvm_hyp_handle_dabt_low, diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c index 625fe81a20b1..2931a1a1fe90 100644 --- a/arch/arm64/kvm/hyp/vhe/switch.c +++ b/arch/arm64/kvm/hyp/vhe/switch.c @@ -495,6 +495,7 @@ static const exit_handler_fn hyp_exit_handlers[] = { [0 ... ESR_ELx_EC_MAX] = NULL, [ESR_ELx_EC_CP15_32] = kvm_hyp_handle_cp15_32, [ESR_ELx_EC_SYS64] = kvm_hyp_handle_sysreg_vhe, + [ESR_ELx_EC_SME] = kvm_hyp_handle_fpsimd, [ESR_ELx_EC_SVE] = kvm_hyp_handle_fpsimd, [ESR_ELx_EC_FP_ASIMD] = kvm_hyp_handle_fpsimd, [ESR_ELx_EC_IABT_LOW] = kvm_hyp_handle_iabt_low, -- 2.47.3