From nobody Fri Oct 2 07:45:28 2026 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 240C051FCAD; Wed, 30 Sep 2026 21:48:57 +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=1790804939; cv=none; b=WILXX4PMBzCPEuvKZXRDvbsLBF8qE9bpizaK3kY4vbz4wZdf7Y4YQu617OaNwGKZo79WS7EQrn9Zf/G9cdV+LT+gPr5ADpFwuHTwaUIsxNBggsloBdcVDbfOQaShn67iBD1EhHEm31BFTWnytouBB+6PBLwaKkP50tyTfj1xKAk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804939; c=relaxed/simple; bh=X1FgS+kMZP9ukBUAVhzrOqr7yryrwOBh9nVXlOvtkDc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=c3FCL+bCQtd3bpWyoibI/OYDnT8RrILe2jbVj0L2P6ulUld0ukQAP1191bT9eq6+RL44GY9YYiQj316MrMWymvBVv7BLd0hNXIeT7F9CRmHnVCqyNXTcd268bYTVQzAmJkOmzRN+Ef/eR6wUpOVTe03dYDi6NSAPOmrEZPhsGJY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=E9AZvKsA; 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="E9AZvKsA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 46BE41F00899; Wed, 30 Sep 2026 21:48:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804937; bh=6AoNn9IrRf6+2TK5gl+pKg760w1DAC/vdj1nXqae1ME=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=E9AZvKsAKLNfMfxPf9Zy/5oBN2eggb1IM4PHjQv6fNe/uPCOmvKsdE4fZjIK+nSwp VbFtaRYkHSPZsxLmL4sW7Fz739D/vnuraykqz2GebS2jtnZScf8E+6fpNQgSy+CWJN Eb7T+gWoM2Fa8OYpl8/h5q5VPqDmtLkmA31rCd+CHtlFSa3mYvO4h5rPyiBSmi/7R0 Nw84k74TePaqhCzj+gp9bZxfSiNG+HvAqQWOug2yoObrmpWjFTO9WUABRgXSKZCjPd BhnvkET0SDdKnAk8eplNTflbcfdbj5uDFNWbycXxpWCSDGbgaFR3QxQf/OsY98PbtA WfLFaATgFc/ag== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:11 +0100 Subject: [PATCH v21 01/15] arm64/gcs: Ensure FGTs for EL1 GCS instructions are disabled 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-1-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown , "Lorenzo Stoakes (ARM)" X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1006; i=broonie@kernel.org; h=from:subject:message-id; bh=X1FgS+kMZP9ukBUAVhzrOqr7yryrwOBh9nVXlOvtkDc=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO07YPOw7wKvBJdXdYYLORf4er5mAip1k2qT +5jJaeLhbmJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DtAAKCRAk1otyXVSH 0DwiB/0ec0wcYBdfjSINE9IKRpKNZ9OV/BS1v23AxKqTWwrunVfLuoRMx+jCLv/TY0e5TGlGAyK TPE9tF5BcmYAm11arvJ9Ar7BEuSJ089xAiS8uK+GVKmQPzWLJZzs9j56S+PAgswBOanvstwpPYq 1PtCA/EydqKaGul6afJo6+T3zY+2NFtTEAavaC8Zxe3h169bb86RvEt4PtUs6XKjmyupcHSJkwF II6MZlPGOuKaoRQCvSsV7ph/Z+otkwaZ9v5XtgAwSdIUTRCIJOBlMNkvqTMJpqvKeq1rj2CMdH9 OpE4b8tEmWW+9REjiE4ScnTXWBWEJ3CacDa82zRTB/gNOjVo X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB The initial EL2 setup for GCS did not include disabling of EL1 usage of GCS instructions, also disable these traps. Fixes: ff5181d8a2a8 ("arm64/gcs: Provide basic EL2 setup to allow GCS usage= at EL0 and EL1") Reviewed-by: Leonardo Bras Reviewed-by: Lorenzo Stoakes (ARM) Signed-off-by: Mark Brown --- arch/arm64/include/asm/el2_setup.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el= 2_setup.h index aa8ec9df8024..d308c6e6757d 100644 --- a/arch/arm64/include/asm/el2_setup.h +++ b/arch/arm64/include/asm/el2_setup.h @@ -393,6 +393,11 @@ orr x0, x0, #HFGRTR_EL2_nGCS_EL1_MASK orr x0, x0, #HFGRTR_EL2_nGCS_EL0_MASK =20 + /* Disable traps of GCS instructions at EL1 */ + orr x2, x2, #HFGITR_EL2_nGCSEPP_MASK + orr x2, x2, #HFGITR_EL2_nGCSSTR_EL1_MASK + orr x2, x2, #HFGITR_EL2_nGCSPUSHM_EL1_MASK + .Lskip_gce_fgt_\@: =20 .Lset_fgt_\@: --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 02EC84CDDF8; Wed, 30 Sep 2026 21:49:01 +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=1790804943; cv=none; b=HwM46OxEcNEjYiJlTABDjxbmYH7j2vMo5+fs8YxFtX62XWYDBmF1zUiZAu6hi50nWRcEBmBaSYycHwJN84IFa/1wRnIMOEc9QevQtcywkCHmj2gyVujoaxZrEbNwr1SZLoafPdrzmh68TNYzCzvOy8nPB4yQDUK7GJuQbdNRyHE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804943; c=relaxed/simple; bh=DwBoYQFaczmEOWbnV9xSdDgF3MgqEmjOd72qq7R27xE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dL0LUtE5mQo6fJ0+8sOnt+mYD/VQn/Wse5K4wS5YPSrx/7RxgBWyzXEzlTICsWSwIQuvu6J8mQK5oVVG/D1gRqOcHPkZ15YqMykGpbyku1kpEyzpRZdzSaEmnqBWIw49Gp8f/p1+0tuOUeRlq69BLe5Aj9vtEJ30Ppf5iVXeAnA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KHDNb2F2; 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="KHDNb2F2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 27CB11F000FF; Wed, 30 Sep 2026 21:48:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804941; bh=OmI43dNjbW9ipLj+uvJbJhfjBFlJUEORAc9xQbdzhRk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=KHDNb2F21R1I7bXqmNAaWpXeQK9EChJqU9dgmuyRYicKt+bU8w88DAkJodincfhKo BhvuBd4C2JLEEfBM7ZtIqgVtWY3vda9VqSGoQaP6/J/DzUVtmcrxVhmCtnSKdcyQmr oAfhT0yZdeBUba2gyrT0OrDSBd43d30Tna3bo9boYT6qqYAhW9cj2KodZHPtf5UrYw ssU8VcREWum3Lvd5ZW0zfk4gTxRGOIVF+9LTP7iwPYZJhf4HCuHD68bfl6PyixnbmM VulLoPou/Vd90vkJln6yqTYCnL/PLyGkNdZCwSz6iklV6ckhbJgggTIqXiqPJF+doW J6X6oYtTYPl3w== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:12 +0100 Subject: [PATCH v21 02/15] KVM: arm64: Refuse to start a guest with S1PIE or S1POE but not TCR2 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-2-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=2332; i=broonie@kernel.org; h=from:subject:message-id; bh=DwBoYQFaczmEOWbnV9xSdDgF3MgqEmjOd72qq7R27xE=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO1hbtlerL9S2qZZZLtlBkEy8ZCDKCCOwfKK CCEvCtnPHqJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DtQAKCRAk1otyXVSH 0IdcB/9X5ZZqHN11AV843Dho/QJXH3M8htRierETr6LGsfAgsUbLAaCXasBSRLg5jWHlN1MovSI sLP1OcVZAifIMlKimYLc4cCOfcbBEnV+s5hp59y6+tpr69dTeKFsHf7WOr/Ya4Eux7yVeU/Lum4 q+8MSU4D2RaW/QgDSzv8byA/ntbYKtT5CttovlDl5yyIsPiGPMdCPhBAXuCqZkxBJBIWUwiL0EN JCY+7jtbPqzw1xEwzRy2+RTizp2VjO3rrOYnKGaQQvaSb1FkLMFWWa4QbOeewctPziXA7WKW/2+ TeYk+aoHFvXDS6opSBe7JpxqvQxGFBF1ZEKsylTiITrJsDRe X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Since there is an architectural dependency between the features as an optimisation we only context switch guest registers for FEAT_S1PIE and FEAT_S1POE if the guest also has FEAT_TCR2. We do not, however, enforce this as a requirement when starting a guest and only configure the traps for accessing the registers based on their individual features. This means that a VMM can configure a guest which can read and write the system registers for FEAT_S1PIE and FEAT_S1POE without the hypervisor updating the values of these registers for the guest. Avoid this by refusing to create a guest with an affected configuration. Rather than doing something data driven we open code the checks, I started doing something data driven but it was very clear that such code should be shared with the host kernel cpufeature code. Refactoring for that seemed like disproportionate effort and invasiveness for the context so is deferred for followup work. Fixes: 663abf04ee4d ("KVM: arm64: Make PIR{,E0}_EL1 save/restore conditiona= l on FEAT_TCRX") Signed-off-by: Mark Brown Reviewed-by: Lorenzo Stoakes (ARM) --- arch/arm64/kvm/sys_regs.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 44aae52c473d..3ae293798b27 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -5860,6 +5860,24 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu) mutex_unlock(&kvm->arch.config_lock); } =20 +/* + * Some optimisations in fast paths would be broken by architecturally + * invalid feature combinations, reject those. + * + * This should share code with the host kernel cpufeature code, and + * make use of the MRS to generate dependencies. + */ +static bool kvm_validate_id_regs(struct kvm *kvm) +{ + if (kvm_has_s1pie(kvm) && !kvm_has_tcr2(kvm)) + return false; + + if (kvm_has_s1poe(kvm) && !kvm_has_tcr2(kvm)) + return false; + + return true; +} + /* * Perform last adjustments to the ID registers that are implied by the * configuration outside of the ID regs themselves, as well as any @@ -5928,6 +5946,9 @@ int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu) kvm_vgic_finalize_idregs(kvm); } =20 + if (!kvm_validate_id_regs(vcpu->kvm)) + return -EINVAL; + return 0; } =20 --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 C0735527585; Wed, 30 Sep 2026 21:49:05 +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=1790804947; cv=none; b=MtJWGm8W+fJpNfgk7a98/9PiwGGwKt8lFsKSRfDhxvrrwPz+rw6tpJTtvnYE+xrLDDZ3qogR/QY51jNjCgxot5UuQ45kZP8l9Iz0u0yU4Vap7EVBILxz83E0zTDwqA0Xs7dATB2TT1e1oJIRmThdmQejB3h1R+SUqMaDYANHrc8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804947; c=relaxed/simple; bh=24gu3tTEXMr5y5OE4USskH8btbov3m5C1nWmYIFvex4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dphEt0WU3zmsaXG05gAnSpQCvHvcTGdp8KsUeDLPjFuCObe1w+bTyeoLOKsk6uYUNz2BVrIVL8ADLQ4OAXC3KgMFv3Su4ixGi5198wDtayH8jwlapwA1Psh9LbSRK1ZiCc/xqs368j1gBbx9IJbikpuUram95mBGtii1xuefhZQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kx6nmrJz; 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="kx6nmrJz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 10EBF1F00898; Wed, 30 Sep 2026 21:49:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804945; bh=H3DzGsLbDGjNxEYy8GnqLtLvo0/BnHUHE2QIhe2sQRc=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=kx6nmrJzHCTCKJiQGYx9TToLe7NCmBn40D6jSc3rHrhlva/HoRfC6U54BB0mGFAQb CyyLHJLui/bimQ0kUBPM8vS9mqTkeXQldgcQteR5x0crQKAtvfsoiyC5N5RPUuK3Oh /ojzVfugQGjgvkgHgtrEEsQEcIjQ7eNCijPdx5lzD1YRtCHyfgyU5lkQt6ZxiYypLA Geoy5VcvE6hoJXCi8JzlFstuEpv/zayb+eONr9jgE72z/gQFODNyWWq846wHssfiSU KY4ErteYLmmeyq7DEFDlrnK0k1e2rLhhwKX653LQYVAbpyBjDwk0iwIrKBRCL6D954 Wqih6QVkWdpew== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:13 +0100 Subject: [PATCH v21 03/15] KVM: arm64: Manage GCS access and registers for guests 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-3-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=13224; i=broonie@kernel.org; h=from:subject:message-id; bh=24gu3tTEXMr5y5OE4USskH8btbov3m5C1nWmYIFvex4=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO1yRQ/8v3RmfQJFGea8sWt3yTnNsD3rRDTq FosG7vRlKeJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DtQAKCRAk1otyXVSH 0HfZB/90mKWgmZ5TqEfoEPafYwUODFAOMMnkwJ1EDa/UZJ2EuQD5MKKMxLLsCj61aMxkTw0b/w8 yJyBTNA2J/jiKHe0TNd0ROpc7bRtgViPiNZGTpiyvSdxnm2/OwgYr58MmVKHIg8f19xzmI3sK1o HxN2ZJiEZPNpHjUl2Rq9HT9iRwYP6beRetUjJeMxm5fBrbkWYq+wEq/JS1mN0IFxYhJNzWJR2ln YNy7D7ygEeyEU0L8DExWw7dmEJ4tTWFwhwvlVIMEVekGq0FF6tb44KhIGvaEAKWruEKjpKAKjA1 OSONS2NVqKzPh1Q0PXxl44O4XcVXGKROo/VC3hcr5ZE7B37Z X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB GCS introduces a number of system registers, on systems with GCS we need to context switch them and expose them to VMMs to allow guests to use GCS. In order to allow guests to use GCS we also need to configure HCRX_EL2.GCSEn, if this is not set GCS instructions will be noops and CHKFEAT will report GCS as disabled. Reviewed-by: Leonardo Bras Signed-off-by: Mark Brown Reviewed-by: Lorenzo Stoakes (ARM) --- arch/arm64/include/asm/kvm_emulate.h | 3 ++ arch/arm64/include/asm/kvm_host.h | 14 ++++++++++ arch/arm64/include/asm/vncr_mapping.h | 2 ++ arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 27 ++++++++++++++++++ arch/arm64/kvm/hyp/vhe/sysreg-sr.c | 10 +++++++ arch/arm64/kvm/sys_regs.c | 45 ++++++++++++++++++++++++++= ++++ 6 files changed, 101 insertions(+) diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/= kvm_emulate.h index a3c1928bdf74..0cd91b3d6c82 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -712,6 +712,9 @@ static inline void vcpu_set_hcrx(struct kvm_vcpu *vcpu) if (kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_V)) vcpu->arch.hcrx_el2 |=3D HCRX_EL2_EnASR; =20 + if (kvm_has_gcs(kvm)) + vcpu->arch.hcrx_el2 |=3D HCRX_EL2_GCSEn; + /* * NV3 is a host-specific extension, and we always use * it when present and that the guest uses NV. It may diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 27fe0cd5b2d7..6aba1bcb8ee7 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -500,6 +500,10 @@ enum vcpu_sysreg { =20 POR_EL0, /* Permission Overlay Register 0 (EL0) */ =20 + /* Guarded Control Stack registers */ + GCSCRE0_EL1, /* Guarded Control Stack Control (EL0) */ + GCSPR_EL0, /* Guarded Control Stack Pointer (EL0) */ + /* FP/SIMD/SVE */ SVCR, FPMR, @@ -520,6 +524,8 @@ enum vcpu_sysreg { PIRE0_EL2, /* Permission Indirection Register 0 (EL2) */ PIR_EL2, /* Permission Indirection Register 1 (EL2) */ POR_EL2, /* Permission Overlay Register 2 (EL2) */ + GCSCR_EL2, /* Guarded Control Stack Control Register (EL2) */ + GCSPR_EL2, /* Guarded Control Stack Pointer Register (EL2) */ SPSR_EL2, /* EL2 saved program status register */ ELR_EL2, /* EL2 exception link register */ AFSR0_EL2, /* Auxiliary Fault Status Register 0 (EL2) */ @@ -592,6 +598,10 @@ enum vcpu_sysreg { VNCR(VDISR_EL2), VNCR(VSESR_EL2), =20 + /* Guarded Control Stack registers */ + VNCR(GCSPR_EL1), /* Guarded Control Stack Pointer (EL1) */ + VNCR(GCSCR_EL1), /* Guarded Control Stack Control (EL1) */ + VNCR(HFGRTR_EL2), VNCR(HFGWTR_EL2), VNCR(HFGITR_EL2), @@ -1654,6 +1664,10 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64= val); #define kvm_has_sctlr2(k) \ (kvm_has_feat((k), ID_AA64MMFR3_EL1, SCTLRX, IMP)) =20 +#define kvm_has_gcs(k) \ + (system_supports_gcs() && \ + kvm_has_feat((k), ID_AA64PFR1_EL1, GCS, IMP)) + static inline bool kvm_arch_has_irq_bypass(void) { return true; diff --git a/arch/arm64/include/asm/vncr_mapping.h b/arch/arm64/include/asm= /vncr_mapping.h index 9e8a49fa8b63..e589adccc2f3 100644 --- a/arch/arm64/include/asm/vncr_mapping.h +++ b/arch/arm64/include/asm/vncr_mapping.h @@ -97,6 +97,8 @@ #define VNCR_PMSNEVFR_EL1 0x850 #define VNCR_PMSDSFR_EL1 0x858 #define VNCR_TRFCR_EL1 0x880 +#define VNCR_GCSPR_EL1 0x8C0 +#define VNCR_GCSCR_EL1 0x8D0 #define VNCR_MPAM1_EL1 0x900 #define VNCR_MPAMHCR_EL2 0x930 #define VNCR_MPAMVPMV_EL2 0x938 diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hy= p/include/hyp/sysreg-sr.h index c382848d3194..2bb319240563 100644 --- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h @@ -17,6 +17,7 @@ #include =20 static inline bool ctxt_has_s1poe(struct kvm_cpu_context *ctxt); +static inline bool ctxt_has_gcs(struct kvm_cpu_context *ctxt); =20 static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt) { @@ -67,6 +68,11 @@ static inline void __sysreg_save_user_state(struct kvm_c= pu_context *ctxt) { ctxt_sys_reg(ctxt, TPIDR_EL0) =3D read_sysreg(tpidr_el0); ctxt_sys_reg(ctxt, TPIDRRO_EL0) =3D read_sysreg(tpidrro_el0); + + if (ctxt_has_gcs(ctxt)) { + ctxt_sys_reg(ctxt, GCSPR_EL0) =3D read_sysreg_s(SYS_GCSPR_EL0); + ctxt_sys_reg(ctxt, GCSCRE0_EL1) =3D read_sysreg_s(SYS_GCSCRE0_EL1); + } } =20 static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt) @@ -131,6 +137,13 @@ static inline bool ctxt_has_sctlr2(struct kvm_cpu_cont= ext *ctxt) return kvm_has_sctlr2(kern_hyp_va(vcpu->kvm)); } =20 +static inline bool ctxt_has_gcs(struct kvm_cpu_context *ctxt) +{ + struct kvm_vcpu *vcpu =3D ctxt_to_vcpu(ctxt); + + return kvm_has_gcs(kern_hyp_va(vcpu->kvm)); +} + static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) { ctxt_sys_reg(ctxt, SCTLR_EL1) =3D read_sysreg_el1(SYS_SCTLR); @@ -144,6 +157,10 @@ static inline void __sysreg_save_el1_state(struct kvm_= cpu_context *ctxt) if (ctxt_has_s1pie(ctxt)) { ctxt_sys_reg(ctxt, PIR_EL1) =3D read_sysreg_el1(SYS_PIR); ctxt_sys_reg(ctxt, PIRE0_EL1) =3D read_sysreg_el1(SYS_PIRE0); + if (ctxt_has_gcs(ctxt)) { + ctxt_sys_reg(ctxt, GCSPR_EL1) =3D read_sysreg_el1(SYS_GCSPR); + ctxt_sys_reg(ctxt, GCSCR_EL1) =3D read_sysreg_el1(SYS_GCSCR); + } } =20 if (ctxt_has_s1poe(ctxt)) @@ -210,6 +227,11 @@ static inline void __sysreg_restore_user_state(struct = kvm_cpu_context *ctxt) { write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL0), tpidr_el0); write_sysreg(ctxt_sys_reg(ctxt, TPIDRRO_EL0), tpidrro_el0); + if (ctxt_has_gcs(ctxt)) { + write_sysreg_s(ctxt_sys_reg(ctxt, GCSPR_EL0), SYS_GCSPR_EL0); + write_sysreg_s(ctxt_sys_reg(ctxt, GCSCRE0_EL1), + SYS_GCSCRE0_EL1); + } } =20 static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt, @@ -243,6 +265,11 @@ static inline void __sysreg_restore_el1_state(struct k= vm_cpu_context *ctxt, if (ctxt_has_s1pie(ctxt)) { write_sysreg_el1(ctxt_sys_reg(ctxt, PIR_EL1), SYS_PIR); write_sysreg_el1(ctxt_sys_reg(ctxt, PIRE0_EL1), SYS_PIRE0); + + if (ctxt_has_gcs(ctxt)) { + write_sysreg_el1(ctxt_sys_reg(ctxt, GCSPR_EL1), SYS_GCSPR); + write_sysreg_el1(ctxt_sys_reg(ctxt, GCSCR_EL1), SYS_GCSCR); + } } =20 if (ctxt_has_s1poe(ctxt)) diff --git a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c b/arch/arm64/kvm/hyp/vhe/sy= sreg-sr.c index 0c4ef1ce32ae..95c4f5229978 100644 --- a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c +++ b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c @@ -59,6 +59,9 @@ static void __sysreg_save_vel2_state(struct kvm_vcpu *vcp= u) if (ctxt_has_s1pie(&vcpu->arch.ctxt)) { __vcpu_assign_sys_reg(vcpu, PIRE0_EL2, read_sysreg_el1(SYS_PIRE0)); __vcpu_assign_sys_reg(vcpu, PIR_EL2, read_sysreg_el1(SYS_PIR)); + + if (ctxt_has_gcs(&vcpu->arch.ctxt)) + __vcpu_assign_sys_reg(vcpu, GCSCR_EL2, read_sysreg_el1(SYS_GCSCR)); } =20 if (ctxt_has_s1poe(&vcpu->arch.ctxt)) @@ -86,6 +89,8 @@ static void __sysreg_save_vel2_state(struct kvm_vcpu *vcp= u) __vcpu_assign_sys_reg(vcpu, SP_EL2, read_sysreg(sp_el1)); __vcpu_assign_sys_reg(vcpu, ELR_EL2, read_sysreg_el1(SYS_ELR)); __vcpu_assign_sys_reg(vcpu, SPSR_EL2, read_sysreg_el1(SYS_SPSR)); + if (ctxt_has_gcs(&vcpu->arch.ctxt)) + __vcpu_assign_sys_reg(vcpu, GCSPR_EL2, read_sysreg_el1(SYS_GCSPR)); =20 if (ctxt_has_sctlr2(&vcpu->arch.ctxt)) __vcpu_assign_sys_reg(vcpu, SCTLR2_EL2, read_sysreg_el1(SYS_SCTLR2)); @@ -138,6 +143,11 @@ static void __sysreg_restore_vel2_state(struct kvm_vcp= u *vcpu) if (ctxt_has_s1pie(&vcpu->arch.ctxt)) { write_sysreg_el1(__vcpu_sys_reg(vcpu, PIR_EL2), SYS_PIR); write_sysreg_el1(__vcpu_sys_reg(vcpu, PIRE0_EL2), SYS_PIRE0); + + if (ctxt_has_gcs(&vcpu->arch.ctxt)) { + write_sysreg_el1(__vcpu_sys_reg(vcpu, GCSCR_EL2), SYS_GCSCR); + write_sysreg_el1(__vcpu_sys_reg(vcpu, GCSPR_EL2), SYS_GCSPR); + } } =20 if (ctxt_has_s1poe(&vcpu->arch.ctxt)) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 3ae293798b27..823460106de8 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -109,6 +109,8 @@ static enum sr_loc_attr locate_direct_register(const st= ruct kvm_vcpu *vcpu, case PIR_EL1: case PIRE0_EL1: case POR_EL1: + case GCSCR_EL1: + case GCSPR_EL1: case ESR_EL1: case AFSR0_EL1: case AFSR1_EL1: @@ -135,6 +137,8 @@ static enum sr_loc_attr locate_direct_register(const st= ruct kvm_vcpu *vcpu, case DACR32_EL2: case IFSR32_EL2: case DBGVCR32_EL2: + case GCSCRE0_EL1: + case GCSPR_EL0: /* These registers are always loaded, no matter what */ return SR_LOC_LOADED; =20 @@ -198,6 +202,8 @@ static void locate_register(const struct kvm_vcpu *vcpu= , enum vcpu_sysreg reg, MAPPED_EL2_SYSREG(PIR_EL2, PIR_EL1, NULL ); MAPPED_EL2_SYSREG(PIRE0_EL2, PIRE0_EL1, NULL ); MAPPED_EL2_SYSREG(POR_EL2, POR_EL1, NULL ); + MAPPED_EL2_SYSREG(GCSCR_EL2, GCSCR_EL1, NULL ); + MAPPED_EL2_SYSREG(GCSPR_EL2, GCSPR_EL1, NULL ); MAPPED_EL2_SYSREG(AMAIR_EL2, AMAIR_EL1, NULL ); MAPPED_EL2_SYSREG(ELR_EL2, ELR_EL1, NULL ); MAPPED_EL2_SYSREG(SPSR_EL2, SPSR_EL1, NULL ); @@ -253,6 +259,10 @@ static u64 read_sr_from_cpu(enum vcpu_sysreg reg) case TCR2_EL1: val =3D read_sysreg_s(SYS_TCR2_EL12); break; case PIR_EL1: val =3D read_sysreg_s(SYS_PIR_EL12); break; case PIRE0_EL1: val =3D read_sysreg_s(SYS_PIRE0_EL12); break; + case GCSPR_EL0: val =3D read_sysreg_s(SYS_GCSPR_EL0); break; + case GCSCRE0_EL1: val =3D read_sysreg_s(SYS_GCSCRE0_EL1); break; + case GCSCR_EL1: val =3D read_sysreg_s(SYS_GCSCR_EL12); break; + case GCSPR_EL1: val =3D read_sysreg_s(SYS_GCSPR_EL12); break; case POR_EL1: val =3D read_sysreg_s(SYS_POR_EL12); break; case ESR_EL1: val =3D read_sysreg_s(SYS_ESR_EL12); break; case AFSR0_EL1: val =3D read_sysreg_s(SYS_AFSR0_EL12); break; @@ -293,6 +303,10 @@ static void write_sr_to_cpu(enum vcpu_sysreg reg, u64 = val) case PIR_EL1: write_sysreg_s(val, SYS_PIR_EL12); break; case PIRE0_EL1: write_sysreg_s(val, SYS_PIRE0_EL12); break; case POR_EL1: write_sysreg_s(val, SYS_POR_EL12); break; + case GCSCRE0_EL1: write_sysreg_s(val, SYS_GCSCRE0_EL1); break; + case GCSPR_EL0: write_sysreg_s(val, SYS_GCSPR_EL0); break; + case GCSCR_EL1: write_sysreg_s(val, SYS_GCSCR_EL12); break; + case GCSPR_EL1: write_sysreg_s(val, SYS_GCSPR_EL12); break; case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); break; case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); break; case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); break; @@ -3089,6 +3103,21 @@ static unsigned int cnthv_visibility(const struct kv= m_vcpu *vcpu, return REG_HIDDEN; } =20 +static unsigned int gcs_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + if (kvm_has_gcs(vcpu->kvm)) + return 0; + + return REG_HIDDEN; +} + +static unsigned int gcs_el2_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd) +{ + return __el2_visibility(vcpu, rd, gcs_visibility); +} + static bool access_mdcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) @@ -3493,6 +3522,13 @@ static const struct sys_reg_desc sys_reg_descs[] =3D= { PTRAUTH_KEY(APDB), PTRAUTH_KEY(APGA), =20 + { SYS_DESC(SYS_GCSCR_EL1), NULL, reset_val, GCSCR_EL1, 0, + .visibility =3D gcs_visibility }, + { SYS_DESC(SYS_GCSPR_EL1), NULL, reset_unknown, GCSPR_EL1, + .visibility =3D gcs_visibility }, + { SYS_DESC(SYS_GCSCRE0_EL1), NULL, reset_val, GCSCRE0_EL1, 0, + .visibility =3D gcs_visibility }, + { SYS_DESC(SYS_SPSR_EL1), access_spsr}, { SYS_DESC(SYS_ELR_EL1), access_elr}, =20 @@ -3618,6 +3654,8 @@ static const struct sys_reg_desc sys_reg_descs[] =3D { CTR_EL0_DminLine_MASK | CTR_EL0_L1Ip_MASK | CTR_EL0_IminLine_MASK), + { SYS_DESC(SYS_GCSPR_EL0), NULL, reset_unknown, GCSPR_EL0, + .visibility =3D gcs_visibility }, { SYS_DESC(SYS_SVCR), undef_access, reset_val, SVCR, 0, .visibility =3D s= me_visibility }, { SYS_DESC(SYS_FPMR), undef_access, reset_val, FPMR, 0, .visibility =3D f= p8_visibility }, =20 @@ -3861,6 +3899,10 @@ static const struct sys_reg_desc sys_reg_descs[] =3D= { EL2_REG_FILTERED(VNCR_EL2, bad_vncr_trap, reset_val, 0, vncr_el2_visibility), =20 + EL2_REG_FILTERED(GCSCR_EL2, access_rw, reset_val, 0, + gcs_el2_visibility), + EL2_REG_FILTERED(GCSPR_EL2, access_rw, reset_val, 0, + gcs_el2_visibility), { SYS_DESC(SYS_DACR32_EL2), undef_access, reset_unknown, DACR32_EL2 }, EL2_REG_VNCR_FILT(HDFGRTR2_EL2, fgt2_visibility), EL2_REG_VNCR_FILT(HDFGWTR2_EL2, fgt2_visibility), @@ -5875,6 +5917,9 @@ static bool kvm_validate_id_regs(struct kvm *kvm) if (kvm_has_s1poe(kvm) && !kvm_has_tcr2(kvm)) return false; =20 + if (kvm_has_gcs(kvm) && !kvm_has_s1pie(kvm)) + return false; + return true; } =20 --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 8D1994CDDF8; Wed, 30 Sep 2026 21:49:09 +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=1790804950; cv=none; b=MLwJ7FnSMzPkQvrkSV0ohsnG7lwIbYa0KKbHqszLZyoQz04VZ/HVUHiLUf9KGn54YTnMtSnNkNzs0bSS5cSbVTsQT2gyArBr0B/Rl1qB/XZA0zScxJHIWd2lf1JrKNqabEMDclc1k6V2PoJ2WUbpBgmFxZVXlekxuumstquDsY8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804950; c=relaxed/simple; bh=8EKdi1Ug7yuFBXk2To/23syHRc/c4ByaL1DAe9/Ky+E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bCZZRyjDKfrVlzTfH8A7W2twW24uzIjK8pNZymlLDX61ZG8ailhByw9DLtlyELHgVnsWIoSDt9WAqseD5PhF3Zzk5qmpKsVZUxWGd8sXlDf+FJ34Nu4y1LoQWu+Kxk/0nhCgFtwHyHMoPd8MdLoU1Q2i58o2AE9pnteeJgMLb0g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NeCMipxc; 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="NeCMipxc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C5B0D1F0089A; Wed, 30 Sep 2026 21:49:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804949; bh=MQINmNITbwk/CNSnjNxxkSOViUDJsfxpMIuvPsY7vAk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=NeCMipxcwj6LMsiGcZqIR0a563XhN3JS4r38Ol+Wts9EONy/7E5yQTTnueHeoba7U j89ptbpxprPB2FzoL8/eZJNIEm7C2qJ8XJwYJVCqoXc6ivo1bf3Wu5o7CEfxakUB9Q Qd6RNhlNnL/ORdeEs7x3CtI+8Qc8m28nsr66vSttsFe3UFOY2LoUIZqQQ4WaEB99aM ZNeoqMwX2GAcpBvF5EtYECuvvu2j+1mAJzNBcNQOzz4KGmgO6yGBXzjZI0uw7a9E3A hUGHSPAUIiDpdU8XtlIhXn+KmASrJSuT3XIOkseqkGpmzGMbIEdZS62OaWxiU10AJh d2L6PjeGDLK2Q== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:14 +0100 Subject: [PATCH v21 04/15] KVM: arm64: Ensure GCS memory effects are visible 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-4-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown , "Lorenzo Stoakes (ARM)" X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1978; i=broonie@kernel.org; h=from:subject:message-id; bh=8EKdi1Ug7yuFBXk2To/23syHRc/c4ByaL1DAe9/Ky+E=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO2lipkyHOAo94DBt+ulXEk70NYLNaxmaxSl 7R8oCTkCCmJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DtgAKCRAk1otyXVSH 0J3fB/44lYnNfRDOffasRnt5hOdIs89T8XJhvgnEQHSoFjXZrw9IM+hhtpww/uwBZJ0i0IA1IV+ MG4rLX+1/47Kh5xncPILkT/oiLmyAmOrYDBB6zW7c+YTMhPBKUF46VwkCO7A6duNPyQxW+o3tR/ i3M1aqDfaOcK59K3IvKp2aOBzgQmVIwhg+k8hRez08dlaTdRSMxS+wJPyzsGPtWa827cbiXlTy6 0Oc8pV47WgzJmQTGIOIaKLlUSnWLDACXEo06GBjvTY/BOqDaFizcSjRoSxF0KgzQgjvn8B+yjTD GmRHEMXpNu2Ibol12loW2NLG1ZbkD9hQ3ewAUP5zfC9k7DxX X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB In order to allow efficient implementation of GCS implementations are permitted to do GCS specific caching, with barriers implicit in stack switch operations and GCSB DSYNC as an explicit barrier. Since we do not use GCS in the hypervisor or host kernel the hypervisor cannot rely on any barriers being present in vCPU context switches other than those it explicitly inserts. Add explicit barriers when loading and saving vCPU state. Reviewed-by: Yuan Yao Reviewed-by: Leonardo Bras Reviewed-by: Lorenzo Stoakes (ARM) Signed-off-by: Mark Brown --- arch/arm64/kvm/arm.c | 7 +++++++ arch/arm64/kvm/hyp/nvhe/hyp-main.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 8b080804bc90..52f53f682e6a 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -755,6 +755,13 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) vcpu_set_flag(vcpu, PKVM_HOST_STATE_DIRTY); } =20 + /* + * Ensure any GCS memory effects from the outgoing vCPU are + * visible elsewhere. + */ + if (kvm_has_gcs(vcpu->kvm)) + gcsb_dsync(); + kvm_vcpu_put_debug(vcpu); kvm_arch_vcpu_put_fp(vcpu); if (has_vhe()) diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 9a3b92e626ad..534db037c5f6 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -261,6 +261,13 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vc= pu) fpsimd_sve_sync(&hyp_vcpu->vcpu); sync_debug_state(hyp_vcpu); =20 + /* + * Ensure any GCS memory effects from the outgoing vCPU are + * visible elsewhere even if the host skips syncing. + */ + if (kvm_has_gcs(hyp_vcpu->vcpu.kvm)) + gcsb_dsync(); + if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) { host_vcpu->arch.ctxt =3D hyp_vcpu->vcpu.arch.ctxt; } else { --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 5EBA452E04E; Wed, 30 Sep 2026 21:49:13 +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=1790804954; cv=none; b=It1sjcdjm0z/mJqoUse50niNlHtYAyUE4E/6IWHzSxJBRUoi4asl0bxoRpG5ysGnrOSCLc3UlNIfYKFWFMmi9vSaYlOHMykaDWt42msbkFf0VoB5YemugcvNyJlfrmZaSta2S84qcK49dfcUJUa04EVCnaKoVcygjTsgDraj5zE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804954; c=relaxed/simple; bh=aNoJ3V8nZd2+GGpGyDVqbDlbmnpADLGv/VzgqgiASdI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=s8t5QVxr+rQ2DFW6AgSSjgZ1jsdaxdtjVwFfhoSs+KMP7KuZv24Zo4WW7JsxOcaS44oblrs7tYOm6g6wBsqse9PGcE1CC1oENg+ubZPpNJTh8Wv0m8XIIfAY0GpsZ+objbsnPVC4AchEivF8wsbp/zVzTotWWy11mAIgqJQ9ka0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=V4RynEcj; 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="V4RynEcj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A3E091F000FF; Wed, 30 Sep 2026 21:49:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804952; bh=dFLnt75MTV/WN//EyOWGqDTK+6P19LegSAMQd0i6wA0=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=V4RynEcj1NgscFf1Rmry4WY+8F+TmzdpbxNgnCVPngptpncfalTSgs2rWPYlHupox XrAu28S9nGwLAOQX/DK1V8417eNPdZzFypD2XMUXQrgYFwnCBlgkeD8FwJE1vUwy2H GJzZueBmQb2oUmTIXJ9K2TB8+S/n45m+fFhfq7uGPVLn5lZzcRKmhV4FREQ2iplTlb tChlv2GcALcEaHW21fN3Q5EEl3ubIREJKWQmOrlL9EPSu4bc6LCUeFKK6j68CjjnV5 8JlNdrM8sjf7M47oZSzCnKGIVR2BDhm/515dTYOVSTlK1P8fm8JdaFlU2OtcyNKBBn pCSpjlbWeN87Q== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:15 +0100 Subject: [PATCH v21 05/15] KVM: arm64: Set PSTATE.EXLOCK when entering an exception 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-5-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=2795; i=broonie@kernel.org; h=from:subject:message-id; bh=aNoJ3V8nZd2+GGpGyDVqbDlbmnpADLGv/VzgqgiASdI=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO3BxMtZg6CNKL6cawCHZ4SM+hDNUqT1FuaX +YU+cxcc36JATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DtwAKCRAk1otyXVSH 0JVLB/wJXVZCHypd/SUA/b8N6mo1O143FlQqywKn9p/iLfCyUgNap6EJOFkMcXEzrxJToKzZO/z 8wZjUoMpmSEFpJLVzZD45NFQT03xyXjUJXYXLrphq8ptEI0C5BzLhWErc9qs6vETUs+3+Qkn8s7 AMbd6NMTu9V8x9bKqUCrbEbBOC17Pny7Lipidd9NX+wnl5CSISVfw4ijwZi49JgAMuEELpA4Vb9 Vi1QORQM60PHSqnJvU7TJDKpfUyG98GgiZ9sCbEX8HwohL9YUVs5APP10AFRVpN1LX9cgulP0Ol 38wEuhoR/6tTOsbb0qrnO8CzYMTYztpgQNVpw/e0umjj6U0/ X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB As per DDI 0487 R_WTXBY we need to manage PSTATE.EXLOCK when entering an exception, when the exception is entered from a lower EL the bit is cleared while if entering from the same EL it is set to GCSCR_ELx.EXLOCKEN. Implement this behaviour in enter_exception64(). Reviewed-by: Yuan Yao Reviewed-by: Leonardo Bras Signed-off-by: Mark Brown Reviewed-by: Lorenzo Stoakes (ARM) --- arch/arm64/include/uapi/asm/ptrace.h | 1 + arch/arm64/kvm/hyp/exception.c | 37 ++++++++++++++++++++++++++++++++= ++++ 2 files changed, 38 insertions(+) diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi= /asm/ptrace.h index 15649a253a57..eed7f1226be6 100644 --- a/arch/arm64/include/uapi/asm/ptrace.h +++ b/arch/arm64/include/uapi/asm/ptrace.h @@ -56,6 +56,7 @@ #define PSR_C_BIT 0x20000000 #define PSR_Z_BIT 0x40000000 #define PSR_N_BIT 0x80000000 +#define PSR_EXLOCK_BIT 0x400000000 =20 #define PSR_BTYPE_SHIFT 10 =20 diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c index 754e2dc1df54..820849631df9 100644 --- a/arch/arm64/kvm/hyp/exception.c +++ b/arch/arm64/kvm/hyp/exception.c @@ -49,6 +49,37 @@ static void __vcpu_write_spsr_und(struct kvm_vcpu *vcpu,= u64 val) vcpu->arch.ctxt.spsr_und =3D val; } =20 +static bool set_exlock(struct kvm_vcpu *vcpu, unsigned long mode, + unsigned long target_mode) +{ + u64 gcscr; + + if (!kvm_has_gcs(kern_hyp_va(vcpu->kvm))) + return false; + + /* GCS can't be enabled for 32 bit */ + if (mode & PSR_MODE32_BIT) + return false; + + /* When taking an exception to a higher EL EXLOCK is cleared. */ + if ((mode | PSR_MODE_THREAD_BIT) !=3D target_mode) + return false; + + /* + * When taking an exception to the same EL EXLOCK is set to + * the effective value of GCSCR_ELx.EXLOCKEN. + */ + if (is_hyp_ctxt(vcpu)) + gcscr =3D vcpu_read_sys_reg(vcpu, GCSCR_EL2); + else + gcscr =3D vcpu_read_sys_reg(vcpu, GCSCR_EL1); + + if (gcscr & GCSCR_ELx_EXLOCKEN) + return true; + + return false; +} + /* * This performs the exception entry at a given EL (@target_mode), stashin= g PC * and PSTATE into ELR and SPSR respectively, and compute the new PC/PSTAT= E. @@ -138,6 +169,12 @@ static void enter_exception64(struct kvm_vcpu *vcpu, u= nsigned long target_mode, // PSTATE.BTYPE is set to zero upon any exception to AArch64 // See ARM DDI 0487E.a, pages D1-2293 to D1-2294. =20 + // PSTATE.EXLOCK is set to 0 upon any exception to a higher + // EL, or to GCSCR_ELx.EXLOCKEN for an exception to the same + // exception level. See ARM DDI 0487 R_WTXBY. + if (set_exlock(vcpu, mode, target_mode)) + new |=3D PSR_EXLOCK_BIT; + new |=3D PSR_D_BIT; new |=3D PSR_A_BIT; new |=3D PSR_I_BIT; --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 B64F252CCC6; Wed, 30 Sep 2026 21:49:16 +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=1790804958; cv=none; b=Dld1h9Q0YUGg+2JtwjxTleQ+5gruuPFyJsqg8szrAe6P9MeMCkyK48yPh8exYTVS438Ucb7ZG0TLCG/eV/QoXr6i2Ips8MOBESS46vqHfgKl8qKQucxD78m18sZrnIK6GNDb+5Twtx2vZdj90pakOawsO4pZxvZ4V6JaAa9ua7c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804958; c=relaxed/simple; bh=bBnQDLmdMm1YnC+rDRboHwuSsLquBFG/4uNykMXfTLU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gA9xreFbCOTP+SS3q4DQ4WB+g4gSinP3hDsrz/H+VzUfuFSkRBkG+uJmEJssCrWUj7sdVIL/7N5Fl85JGRxqZwW0AV1tp2Gx11W6NY3ZAx7n0K9+dW79xT4PHrK6IrY/LifgcniSInjXYVWUC2vR35DVBJY4P0W6incJh4axG6E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZD/bGzTd; 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="ZD/bGzTd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 58BE31F00898; Wed, 30 Sep 2026 21:49:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804956; bh=0RFak+FihnONiTiEOAUxLCIOKirVYlhzx9YeUDFVJDk=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=ZD/bGzTdv6v1PNnNdFQSLCKIKGjX3DYJnaE9iFCxT2nnwmPFcTrxwTqCxtegvIr5e A04E6WWP8DAOKxGRBHsz664uDYFutOcb/b6Al2KCfaVxKY9PPUmlscFx04XPmwMpQw EG0yXIGgg9x4LB++okGpiYzpJ0oGCtwszIOJyp8m+PRyb0nBUWbcQ6dbtbdgYZJU4l ZrVRYTnaRQlXANish8rhMRRj40Hiczq6pt9Fa7Bte4kwNvXNcxLESOSFxYWCaSxp/C 0FXgSMN/FWcPObu5DTxbZWZe7C3hNNDF4u7mSSI9oZiqgQMC1/QekyEbph55z6g9Wk p+9Q9NXoIPVdA== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:16 +0100 Subject: [PATCH v21 06/15] KVM: arm64: Validate GCS exception lock when emulating ERET 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-6-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=3854; i=broonie@kernel.org; h=from:subject:message-id; bh=bBnQDLmdMm1YnC+rDRboHwuSsLquBFG/4uNykMXfTLU=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO4BhrNor4NfGVDZghSRfCcwZSvFZk+reGqp fL8NgZ41iSJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DuAAKCRAk1otyXVSH 0AF/B/0TgqsSBrk0vQJPq3g1ZMqss1vydZqimIRNMTu3o5sZFfy+KdQVwHVja5gnDplQX6cSw6y QawHZwWv21+fBfbw3khP02m4eirPe/IZ7q0SpZpXG5PmwORLdlxbsbb2TWVdfo2LfWjxg33fJ9d sbTskoGsl2nbKk5OzgUzxth/2FZfZOGEaqz1H9c4oUqGfW40WCPmIcUoIIh41gLUtFhUA1xKnxi k12APuqVzfX0Kf6XGu0aWQTsJgf0Zmffuubfdp/SYsfQocwqBaywj0to8rVLnaavMn0KFUskFDI T+QWTD0SOxsZiM10z3ncs6mTb8G2SkCStJ2v2Szmf2L5hi7o X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB As per DDI0487 R_TYTWB GCS adds an additional case where an illegal exception return can be generated. If all of: - PSTATE.EXLOCK is 0. - The EL is not being changed by the ERET. - GCSCR_ELx.EXLOCKEN is 1. are true then the return is illegal. Emulate this behaviour when emulating ERET for nested guests, while we're at it using the symbolic definition for EXLOCK in SPSR. Reviewed-by: Leonardo Bras Signed-off-by: Mark Brown Reviewed-by: Lorenzo Stoakes (ARM) --- arch/arm64/include/asm/kvm_nested.h | 32 ++++++++++++++++++++++++++++++++ arch/arm64/kvm/emulate-nested.c | 5 ++++- arch/arm64/kvm/hyp/vhe/switch.c | 4 ++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/k= vm_nested.h index 1ed708335809..9e595e8e7642 100644 --- a/arch/arm64/include/asm/kvm_nested.h +++ b/arch/arm64/include/asm/kvm_nested.h @@ -240,6 +240,38 @@ static inline bool kvm_auth_eretax(struct kvm_vcpu *vc= pu, u64 *elr) } #endif =20 +#ifdef CONFIG_ARM64_GCS +/* See IllegalExceptionReturn() pseudocode */ +static inline bool kvm_check_illegal_exlock_return(struct kvm_vcpu *vcpu, + u64 spsr) +{ + u64 pstate, cur_mode, target_mode; + + if (!kvm_has_gcs(vcpu->kvm)) + return false; + + if (vcpu->arch.ctxt.regs.pstate & PSR_EXLOCK_BIT) + return false; + + /* Check the EL only, ignore thread mode */ + pstate =3D vcpu->arch.ctxt.regs.pstate; + cur_mode =3D (pstate & PSR_MODE_MASK) | PSR_MODE_THREAD_BIT; + target_mode =3D (spsr & PSR_MODE_MASK) | PSR_MODE_THREAD_BIT; + + if (cur_mode !=3D target_mode) + return false; + + return vcpu_read_sys_reg(vcpu, GCSCR_EL2) & GCSCR_ELx_EXLOCKEN; +} + +#else +static inline bool kvm_check_illegal_exlock_return(struct kvm_vcpu *vcpu, + u64 spsr) +{ + return false; +} +#endif + #define KVM_NV_GUEST_MAP_SZ (KVM_PGTABLE_PROT_SW1 | KVM_PGTABLE_PROT_SW0) =20 static inline u64 kvm_encode_nested_level(struct kvm_s2_trans *trans) diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-neste= d.c index 625604019fb3..5aa26384720a 100644 --- a/arch/arm64/kvm/emulate-nested.c +++ b/arch/arm64/kvm/emulate-nested.c @@ -2748,10 +2748,13 @@ static u64 kvm_check_illegal_exception_return(struc= t kvm_vcpu *vcpu, u64 spsr) * - trying to return to an illegal M value * - trying to return to a 32bit EL * - trying to return to EL1 with HCR_EL2.TGE set + * - GCSCR_ELx.EXLOCKEN is 1 and PSTATE.EXLOCK is 0 when attempting + * to return from ELx the same EL. */ if (mode =3D=3D PSR_MODE_EL3t || mode =3D=3D PSR_MODE_EL3h || mode =3D=3D 0b00001 || (mode & BIT(1)) || (spsr & PSR_MODE32_BIT) || + kvm_check_illegal_exlock_return(vcpu, spsr) || (vcpu_el2_tge_is_set(vcpu) && (mode =3D=3D PSR_MODE_EL1t || mode =3D=3D PSR_MODE_EL1h))) { u64 mask; @@ -2778,7 +2781,7 @@ static u64 kvm_check_illegal_exception_return(struct = kvm_vcpu *vcpu, u64 spsr) =20 mask =3D PSR_MODE_MASK | PSR_MODE32_BIT; if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, GCS, IMP)) - mask |=3D BIT_ULL(34); /* PSTATE.EXLOCK */ + mask |=3D PSR_EXLOCK_BIT; =20 spsr |=3D *vcpu_cpsr(vcpu) & mask; spsr |=3D PSR_IL_BIT; diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switc= h.c index 7875911c0506..af59d1bf51ad 100644 --- a/arch/arm64/kvm/hyp/vhe/switch.c +++ b/arch/arm64/kvm/hyp/vhe/switch.c @@ -383,6 +383,10 @@ static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu,= u64 *exit_code) return false; } =20 + /* Push GCS exception lock failures into the slow path */ + if (kvm_check_illegal_exlock_return(vcpu, spsr)) + return false; + /* If ERETAx fails, take the slow path */ if (esr_iss_is_eretax(esr)) { if (!(vcpu_has_ptrauth(vcpu) && kvm_auth_eretax(vcpu, &elr))) --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 A0E9452189B; Wed, 30 Sep 2026 21:49:20 +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=1790804961; cv=none; b=lWXa82QvSiMO/JdKUgF415dUuLLOkV7zx1hoIu3DxMsCFSONuhuTzHTy8X4HKjF24aXB9ouzHfBI323wpxWpnEiRsHuokmZw0UoKLucQizdPZaU9syab0XW7DdcqdYGllfCK34MwgJCbyfv4HT+ATvlXU9powXIg/rzmSMrGA8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804961; c=relaxed/simple; bh=kVbReCZrKoi+cVaC6OJWcE+twh1TXQHikn7eWoOdtvk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AHILXvAdJEQhWiBMGL/zRyIF9buklTOi4PcFa+E2cT0TdSM0E2+ZcxY67I6SU1T7oMGeHC69uDM1FrQrgXWSKnCwQv3H/q2a/MsJggP2Zk4RrTY3CViyCiSXt1+gy4aqymm6EaetMcgwB3lCYBsikygQEL/uW6Sh8BefEzMrGfI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ts8bHGm2; 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="Ts8bHGm2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0C94C1F000FF; Wed, 30 Sep 2026 21:49:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804960; bh=ETO//ZHEIrAWcvZFpQcrmAKGm+pliNn3pzbd4bW/wbA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Ts8bHGm29D1eMA1ta/GX1aqLyyVAi8ruqECban51kmGbRcRgDMsWBcCDAl0t2f3Jh Q/jLdqjBnV+OEHiSbInjqDYJW3odZYvT11P1QpbunBu4HFg50GGd3PsnO/OJfHwjv1 cyr+X5i7pYq83Sj6UiV09wpQGnCKVhSv/jpvOH2KXXxkPqugXlyJtbHWmiA1YUapYd C2EPaZNy7XsHTcCZ3Oox0e1+FjyzInMk0f1opkKPGNIiXuqHaBK2Tqu1IibKtTBVaX 9XAlCbwpAzGbtk85ULfPQlGSBOguDVYMq/Be6o9croqMZ800dQpGmf9w//yIU3XOy9 3b9kjxhA7fITg== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:17 +0100 Subject: [PATCH v21 07/15] KVM: arm64: Forward GCS exceptions to nested guests 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-7-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1333; i=broonie@kernel.org; h=from:subject:message-id; bh=kVbReCZrKoi+cVaC6OJWcE+twh1TXQHikn7eWoOdtvk=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO4QbfvLeVqTJpjsPJjc0EbJR8LurVnuvWMa bAxPXZiG5WJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DuAAKCRAk1otyXVSH 0EzLB/0X4o5J+Ob3x2kpC8lQ8ERNBXCpJ05jLcfpiazZPwXlKoGWfNoYBN6W1t/+QdQX/pWmMvF 4/9rpQcNiHT8J3tHlFJ0/BsGvEmP3SdsYdVt12wgekEypSAgwPZ72VrzfW/nJlE+yhMTP2xP0o8 oXzZxyDkTKHz7fihVqNfygtcv1cRcJvyq8c68xHosJaj+3rBUjswzk1DzJ4NHXa6MxNq8PhySPa UAJx7D4ehMg6Rbwgp723DbbbjdIBKGqwnkv6JtNYCGl5oyDvLaBUEWRM83zap9K9hxNsmoTc48p 0/+lkUNYaRVU7dj9yWoo1LGKSQPHFWoTouPxFugwWMtXMgZm X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB For nested guests where HFGITR_EL2.nGCSSTR_EL1 is clear or when there are L2 GCS data check exceptions we need to forward the exception to the guest. Add handling to do so. Reviewed-by: Leonardo Bras Signed-off-by: Mark Brown Reviewed-by: Lorenzo Stoakes (ARM) --- arch/arm64/kvm/handle_exit.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index db37678dcb05..a8198e96fcb4 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -304,12 +304,24 @@ static int handle_svc(struct kvm_vcpu *vcpu) return 1; } =20 +/* + * We might get GCS exceptions that need to be forwarded to the + * hypervisor when a nested guest has HFGITR_EL2.nGCSSTR_EL1 clear, or + * for a GCS data check exception for a L2 guest. + */ static int kvm_handle_gcs(struct kvm_vcpu *vcpu) { - /* We don't expect GCS, so treat it with contempt */ - if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, GCS, IMP)) - WARN_ON_ONCE(1); + if (!kvm_has_gcs(vcpu->kvm)) { + kvm_inject_undefined(vcpu); + return 1; + } =20 + if (vcpu_has_nv(vcpu)) { + kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu)); + return 1; + } + + WARN_ON_ONCE(1); kvm_inject_undefined(vcpu); return 1; } --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 77D91530DF0; Wed, 30 Sep 2026 21:49:24 +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=1790804965; cv=none; b=oHgQc7vuw3KkGPZwzWpgqrsRep0UzL8QTLzjt60SlDL7Me1kNf//qm4GaDVfssXr+o5mK21N1mfhld9dqEbfY7P/7FG/6wEjCJCVnlUAOdX2nXwdkFdoS+N7KPNkh28kgwzQ9VtUdH7SbFSmFhdak1PwYk5yn6mxuo8rGP5B1qU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804965; c=relaxed/simple; bh=p2SMLjfEfZRBygQRA7fMdB/WEVVEAeNCJ7sGMUq/zOk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tueTaPLpJf3KWydXyThec05QtAzzZDcsP0OvRX73QKkvnAN7JlGV9WUJMQTpw6j8U3sZmDWLi5kI/2QJdgKrHkYhFyEiQr1W+/D5Szr0ulrKP9JEpg+ssPsNc2NbxUxUSV3HnTgQM0b4crJfONIM4tN1+Cg/tfO9tyDTL/blUV8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PoekURoQ; 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="PoekURoQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B70611F00898; Wed, 30 Sep 2026 21:49:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804964; bh=Zd/+Jyw6bZX7UUcetdB7IGFu9m8nLhB6L7sX9bIi7t8=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=PoekURoQSMZiBIMi64huDTrJ8XyurMMyps4PwgX8Jhpg3Qox/1FqQldgWy/SBpDAy w/bVQNh9+cQ4vXg9WaBkr0bguVRE0vfQB5UUsbfh8yHjFDDUnyFKo9Vmr8M4MDPyUA anEC/wJx4K5PkR3bxoxobqenQV3dhJR58/TwMYrUony8jbyiVOBYm+psCYp+AIK2tX K+lVvMqQa8jZNBDCEXiBZ/ih2nPLB2bE88W8zQtlbe3U0DoxP37ZSEv8jGNDIjZMph BoDNpkcAYNLYclqMV6lWdYdWd/79chIw7twTJBXctKXCMyGv14EFnGD5Yhsgt+UK4U ++dttQ7HbmyQQ== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:18 +0100 Subject: [PATCH v21 08/15] KVM: arm64: Enforce EXLOCK for SPSR and ELR 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-8-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=3057; i=broonie@kernel.org; h=from:subject:message-id; bh=p2SMLjfEfZRBygQRA7fMdB/WEVVEAeNCJ7sGMUq/zOk=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO52fYAk0djW5voyppA7cUSGG3uVSRxOiiRx JhEDbivJR2JATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DuQAKCRAk1otyXVSH 0A47B/9vXV2XCZ6uLeUIFTwXHKySyUmCeMIABlrqUbh0HBy2DSdhuNhtCUJKVT+x5TEVGqHJZGz L12rQ9zN7WuGhDxeCCCC9mRC6Dwwuf3tBCd0w8JACxqvsnWKlOW5fPlyHfDfFxBRgeydVOc5dN0 aZcsRdyj1mmww5kjbPCXanopo0fgnvnEI1ktiHCJaa4HZvU74IfpUMP8PL4DhaO2R6/0kyT1D2s q29bZa69GL7Bya0uou1HKWKGm86gASDjo6aydBCBNLs26KAOnkO0uN1j4qtkfkm2EqsqYPn4IvU g9TD4cUe+5McxzCFL56ctMFXmnZYHub5lDZpCB+1oep2x4Je X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB As per I_CFFNS and the pseudocode for the SPSR_ELx and ELR_ELx registers a GCS exception with ExType 1 is generated for attempts to write to those registers when both GCSCR_ELx.EXLOCKEN and PSTATE.EXLOCK are set. Ensure that this is enforced for guests if access to these registers from the guest is handled by the hypervisor. Reviewed-by: Leonardo Bras Signed-off-by: Mark Brown --- arch/arm64/include/asm/kvm_emulate.h | 8 +++++++ arch/arm64/kvm/sys_regs.c | 42 ++++++++++++++++++++++++++++++++= ---- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/= kvm_emulate.h index 0cd91b3d6c82..e47ab38327de 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -81,6 +81,14 @@ int kvm_inject_nested_irq(struct kvm_vcpu *vcpu); int kvm_inject_nested_sea(struct kvm_vcpu *vcpu, bool iabt, u64 addr); int kvm_inject_nested_serror(struct kvm_vcpu *vcpu, u64 esr); =20 +static inline void kvm_inject_exlock(struct kvm_vcpu *vcpu) +{ + u64 esr =3D FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_GCS) | ESR_ELx_IL | + FIELD_PREP(ESR_ELx_ExType_MASK, ESR_ELx_ExType_EXLOCK); + + kvm_inject_sync(vcpu, esr); +} + static inline void kvm_inject_nested_sve_trap(struct kvm_vcpu *vcpu) { u64 esr =3D FIELD_PREP(ESR_ELx_EC_MASK, ESR_ELx_EC_SVE) | diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 823460106de8..faecf4657ec5 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -2866,14 +2866,42 @@ static bool access_sp_el1(struct kvm_vcpu *vcpu, return true; } =20 +static inline bool sysregs_exlocked(struct kvm_vcpu *vcpu) +{ + u64 gcscr; + + if (!kvm_has_gcs(vcpu->kvm)) + return false; + + if (!(vcpu->arch.ctxt.regs.pstate & PSR_EXLOCK_BIT)) + return false; + + /* + * Note that the EXLOCKEN for the running EL is checked + * regardless of the register written to. + */ + if (is_hyp_ctxt(vcpu)) + gcscr =3D vcpu_read_sys_reg(vcpu, GCSCR_EL2); + else + gcscr =3D vcpu_read_sys_reg(vcpu, GCSCR_EL1); + + return gcscr & GCSCR_ELx_EXLOCKEN; +} + static bool access_elr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - if (p->is_write) + if (p->is_write) { + if (sysregs_exlocked(vcpu)) { + kvm_inject_exlock(vcpu); + return false; + } + vcpu_write_sys_reg(vcpu, p->regval, ELR_EL1); - else + } else { p->regval =3D vcpu_read_sys_reg(vcpu, ELR_EL1); + } =20 return true; } @@ -2882,10 +2910,16 @@ static bool access_spsr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { - if (p->is_write) + if (p->is_write) { + if (sysregs_exlocked(vcpu)) { + kvm_inject_exlock(vcpu); + return false; + } + __vcpu_assign_sys_reg(vcpu, SPSR_EL1, p->regval); - else + } else { p->regval =3D __vcpu_sys_reg(vcpu, SPSR_EL1); + } =20 return true; } --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 1083053160C; Wed, 30 Sep 2026 21:49:27 +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=1790804969; cv=none; b=U/nv5z0hlUEZKFlrUtBBIQCZt2Aqyf8DITpj+d4gHZi+VG6bMBcyqai77G5wGVtgpr28foHbvn+1GRLYnKFnMG2ZsS49qF5lvGNrShgZ0V73PYOq1R/n6debZnGFP1SO7KY3MMrmBQF8/GjSX1kAdrbFGypjR5dMuP6Wttbtcvw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804969; c=relaxed/simple; bh=cxKp4O4LsyzanVWYD2N6RiRBPKov/JqWLVenhRBtLog=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pTi3BcDfgDLUaOHZJsWWR6kBXPogQB8A6n9fr+ULf35YkYF1tYZtwY/MRGEm8ON7ydYYNPmM+1B3W0q/Nnch0wmHIQuNWPdTq2G9rcyJEBmxJmvEnITCwnoQ64mg54VxGM3NKrNznD3JZFXHbZ/zuzUjDXZax5xFXNx134xkLBs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Dx0DIGYH; 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="Dx0DIGYH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 682BE1F0089C; Wed, 30 Sep 2026 21:49:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804967; bh=Xaz3/wrMiOTvQ7QsDHrniOTAXkJk6SVO21zvEdLnW0w=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=Dx0DIGYHPOdAtusPWS4FBsCBp6nY9oJ88O/CumZSKDpPF6NEhxcvtyRyN3LKoGEii 69myaNErotNg/Bm3bc0mVoosPIXtQb1nVlf09Y5dDceBbdAp4K6zm5pQ4MeQBezf7q KvWFjvP7xUbAZ6WrDYlKdz1toLMcAuIoee7dUi9mOXOriWeP1TdYQ2XoUeZsBn5MxD Qb1Qu+E87xD3yFg4or2Ttn8FeuWVCpXRDQrShhVZzmYgn6I/5KKd/T83dWqIUMKio9 L3hhtHxztxbHnnFWUbp9gfuMKFsI71yGvvl6yl04OVNQyqSlas/Q1EgHqHFsDX2Bpe va8eYv6lmV4yg== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:19 +0100 Subject: [PATCH v21 09/15] KVM: arm64: Allow GCS to be enabled for guests 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-9-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1994; i=broonie@kernel.org; h=from:subject:message-id; bh=cxKp4O4LsyzanVWYD2N6RiRBPKov/JqWLVenhRBtLog=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO63IkXqiM/IhBYdRfO72ei7V5hYPpACCZEa fR+7tMCUmuJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DugAKCRAk1otyXVSH 0CfMB/9rJWt2FEC2Wgl6uPd/R/OwAnUa9YAFAEzvxGfIpus/WSp7NVVDOIpRPLbxlYT3No3biSp A7pbNnOkQ6EyOZkvkGWeDcG4LPsWobB8uIHQRNEllwcMqRHvwRczEPouhH0dv+VwRwf26XhBmj8 nn9+3wFsL5PyUqtTDhvji/YRAXCBEGfc7J18UC9m1mHdcBiLUbA/MQzr1EWu1rXDs1TfF7p+8HV 5Rv1oqAsVnC06TzHg75xh0few7IZxo1+PaxoQXkx0+M0gPDnof1+/k8JTDHs5Hf8qRTrmruKgTJ p9NXWzdxHSjPDkGrXoYkZlFxGo8gfWGUKJR6soO/iM3WKTvr X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Now that required functionality for GCS is in place expose ID_AA64PFR1_EL1.GCS, allowing guests to be given the feature. Reviewed-by: Leonardo Bras Signed-off-by: Mark Brown Reviewed-by: Lorenzo Stoakes (ARM) --- arch/arm64/kvm/nested.c | 3 +-- arch/arm64/kvm/sys_regs.c | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c index 3c4fc566eafc..f62d9ab7f31c 100644 --- a/arch/arm64/kvm/nested.c +++ b/arch/arm64/kvm/nested.c @@ -1702,11 +1702,10 @@ u64 limit_nv_id_reg(struct kvm *kvm, u32 reg, u64 v= al) break; =20 case SYS_ID_AA64PFR1_EL1: - /* Only support BTI, SSBS, CSV2_frac */ + /* Only support GCS, BTI, SSBS, CSV2_frac */ val &=3D ~(ID_AA64PFR1_EL1_PFAR | ID_AA64PFR1_EL1_MTEX | ID_AA64PFR1_EL1_THE | - ID_AA64PFR1_EL1_GCS | ID_AA64PFR1_EL1_MTE_frac | ID_AA64PFR1_EL1_NMI | ID_AA64PFR1_EL1_SME | diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index faecf4657ec5..5de4ba1bef6b 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -2193,10 +2193,12 @@ static u64 sanitise_id_aa64pfr1_el1(const struct kv= m_vcpu *vcpu, u64 val) SYS_FIELD_GET(ID_AA64PFR0_EL1, RAS, pfr0) =3D=3D ID_AA64PFR0_EL1_RA= S_IMP)) val &=3D ~ID_AA64PFR1_EL1_RAS_frac; =20 + if (!system_supports_gcs()) + val &=3D ~ID_AA64PFR1_EL1_GCS; + val &=3D ~ID_AA64PFR1_EL1_SME; val &=3D ~ID_AA64PFR1_EL1_RNDR_trap; val &=3D ~ID_AA64PFR1_EL1_NMI; - val &=3D ~ID_AA64PFR1_EL1_GCS; val &=3D ~ID_AA64PFR1_EL1_THE; val &=3D ~ID_AA64PFR1_EL1_MTEX; val &=3D ~ID_AA64PFR1_EL1_PFAR; @@ -3444,7 +3446,6 @@ static const struct sys_reg_desc sys_reg_descs[] =3D { ~(ID_AA64PFR1_EL1_PFAR | ID_AA64PFR1_EL1_MTEX | ID_AA64PFR1_EL1_THE | - ID_AA64PFR1_EL1_GCS | ID_AA64PFR1_EL1_MTE_frac | ID_AA64PFR1_EL1_NMI | ID_AA64PFR1_EL1_RNDR_trap | --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 E5F3B5221E4; Wed, 30 Sep 2026 21:49:31 +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=1790804973; cv=none; b=dR0/EyMGEugn1B5ujiQflMw3PsqqzxSEvePDRc/DuK9yl0PxlU/hLTpY2hgodO7HVZVnv61eTl0B+Ve25Q8kqVuAO0r9rhyhDzkCDUm8AOegspPKaxDSSBe0OKKW2U9zJwGkIZyU8CwAetnvuGw6UJRjIfW1uJClugj2R+dJVYI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804973; c=relaxed/simple; bh=JTor9Lxzhm4h9y/I5pbwM1ZZXnzU52yIxfAOX8qz2wc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LIYSfzdRhNlM79NfhV3pEUn7XhhCqLIQdhs/wsgv3d9I7r7mmiBrY21Z8JdAdSxzHOqkOsQwC6SSEsQvxnER95PRgLoXNHYCq9+pU3t5OqfPWfKsIhtUVktv/f6gggEJ9i0FvfHcnLXpWazAFwo3GglNYdR+H7wn08j9Joii8/U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iZ3HjDFv; 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="iZ3HjDFv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1C3B11F000FF; Wed, 30 Sep 2026 21:49:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804971; bh=QZ28KimG+sA29Zf5pARwG9R82neiorcaxW5Meg8/n6A=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=iZ3HjDFvbFex5g9q2a64XEmyyZs8RonDRPy7eQrkr0ybOz9oNP1NuT6W3tUo5W4L/ RtV3UiznAnNy7mhQb7hncDpOhYyZSSe0SHsw7JC/tlSSPxlF3nmMjmxToEOv+XmnPo tq+dT9CR5t+TW2lEXd28UP7DfoMJaj6peKd2Eho7Tvfv0sA/iqCpOypA/2OKepxuyE UEHXsvq0f9tJPAcV3yO198ns5zpQD2fvZYBZ6QUfxgvR+IfZJK4CYUvkI93tNPfcSY e08jvZqsksoe2RAfSmVRDnw4YlzbOJbxvYqYRDUWunh39dEjZUYO2/CcLafu7KGYwx H8Wr2aoCeQaoQ== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:20 +0100 Subject: [PATCH v21 10/15] KVM: selftests: arm64: Check that invalid feature combinations are rejected 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-10-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=3874; i=broonie@kernel.org; h=from:subject:message-id; bh=JTor9Lxzhm4h9y/I5pbwM1ZZXnzU52yIxfAOX8qz2wc=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO7wjG6Z2GuPWofP8i6Mr/VAYJ98hn1t+mMe QZkuQqpusaJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DuwAKCRAk1otyXVSH 0Ei6B/kBZ+dbCyKYXXnJ07EhGQ2MhZ2QjSZwNUd0X0zZn9h+bU/e5VRXIFLM2zwY2bPaTFuei+U AMcV36X/9auPS3zXxFoMuUhCtZAMCg/3gE9fuw8CzdT+LynwVnZA0tn/CLGCfBPyb0AGZsJOaGP ZywZHYhBbjhaH4k+SN5NOxfiYzK41phINfkd2S0J0/1B+06O3w8k1pLbYKnflaPWDXGd0TivscS t5w+9GicbfU63jdVIicSOrmzR9a2O7jN89BcoUZCoqDBoMga6TpYowNc/QDi13X45bLvuKBhGbx KOppyt7+0hMUoFmPYZJU+dcW/vrLKw+T+ImsLbfvsWPF1ZwV X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB In order to optimise fast paths KVM explicitly rejects configurations with S1PIE or S1POE but not TCR2, add coverage of this in the set_id_regs test. We have a list of invalid configurations, for each of them we try to run a VM and fail the test if it succeeds. We do feature detection by validating that we can write the fields with failing values. Since this misfiring can disrupt some of the other tests due to the kernel refusing to start guests we run the new tests first, improving diagnostics in the failing case. Signed-off-by: Mark Brown Acked-by: Lorenzo Stoakes (ARM) --- tools/testing/selftests/kvm/arm64/set_id_regs.c | 87 +++++++++++++++++++++= ++++ 1 file changed, 87 insertions(+) diff --git a/tools/testing/selftests/kvm/arm64/set_id_regs.c b/tools/testin= g/selftests/kvm/arm64/set_id_regs.c index 7429a1055df5..cb5e6358c59c 100644 --- a/tools/testing/selftests/kvm/arm64/set_id_regs.c +++ b/tools/testing/selftests/kvm/arm64/set_id_regs.c @@ -803,6 +803,89 @@ static void test_reset_preserves_id_regs(struct kvm_vc= pu *vcpu) ksft_test_result_pass("%s\n", __func__); } =20 +struct reg_ftr_val { + u64 reg; + u64 mask; + u64 val; +}; + +#define REG_FTR_VAL(r, f, v) \ + { .reg =3D ARM64_SYS_REG(sys_reg_Op0(SYS_ ## r), \ + sys_reg_Op1(SYS_ ## r), \ + sys_reg_CRn(SYS_ ## r), \ + sys_reg_CRm(SYS_ ## r), \ + sys_reg_Op2(SYS_ ## r)), \ + .mask =3D r ## _ ## f ## _MASK, \ + .val =3D (r ## _ ## f ## _ ## v << r ## _ ## f ## _SHIFT) } + +static const struct reg_ftr_val s1pie_no_tcr2[] =3D { + REG_FTR_VAL(ID_AA64MMFR3_EL1, TCRX, NI), + REG_FTR_VAL(ID_AA64MMFR3_EL1, S1PIE, IMP), + { } +}; + +static const struct reg_ftr_val s1poe_no_tcr2[] =3D { + REG_FTR_VAL(ID_AA64MMFR3_EL1, TCRX, NI), + REG_FTR_VAL(ID_AA64MMFR3_EL1, S1POE, IMP), + { } +}; + +struct ftr_config { + const char *name; + const struct reg_ftr_val *regs; +}; + +static const struct ftr_config invalid_configs[] =3D { + { .name =3D "S1PIE without TCRX", .regs =3D s1pie_no_tcr2 }, + { .name =3D "S1POE without TCRX", .regs =3D s1poe_no_tcr2 }, +}; + +static void test_invalid_config(const struct ftr_config *config) +{ + struct kvm_vcpu *vcpu; + struct kvm_vm *vm; + const struct reg_ftr_val *field; + u64 val; + int ret; + + vm =3D vm_create(1); + vm_enable_cap(vm, KVM_CAP_ARM_WRITABLE_IMP_ID_REGS, 0); + vcpu =3D vm_vcpu_add(vm, 0, guest_code); + kvm_arch_vm_finalize_vcpus(vm); + + /* + * If we don't manage to set any of the fields assume the + * system does not support the feature and skip the test. + */ + for (field =3D config->regs; field->reg; field++) { + val =3D vcpu_get_reg(vcpu, field->reg); + val &=3D ~field->mask; + val |=3D field->val; + __vcpu_set_reg(vcpu, field->reg, val); + + if (vcpu_get_reg(vcpu, field->reg) !=3D val) { + ksft_print_msg("Test setup not supported\n"); + ksft_test_result_skip("refuse %s\n", config->name); + goto out; + } + } + + ret =3D _vcpu_run(vcpu); + ksft_test_result(ret < 0 && errno =3D=3D EINVAL, "refuse %s\n", + config->name); +out: + kvm_vm_free(vm); +} + +static void test_invalid_configs(void) +{ + int i; + + for (i =3D 0; i < ARRAY_SIZE(invalid_configs); i++) { + test_invalid_config(&invalid_configs[i]); + } +} + int main(void) { struct kvm_vcpu *vcpu; @@ -829,12 +912,16 @@ int main(void) ksft_print_header(); =20 test_cnt =3D 3 + MPAM_IDREG_TEST + MTE_IDREG_TEST; + test_cnt +=3D ARRAY_SIZE(invalid_configs); for (i =3D 0; i < ARRAY_SIZE(test_regs); i++) for (j =3D 0; test_regs[i].ftr_bits[j].type !=3D FTR_END; j++) test_cnt++; =20 ksft_set_plan(test_cnt); =20 + /* Do this first in case a break interferes with other tests */ + test_invalid_configs(); + test_vm_ftr_id_regs(vcpu, aarch64_only); test_vcpu_ftr_id_regs(vcpu); test_vcpu_non_ftr_id_regs(vcpu); --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 7204F53160C; Wed, 30 Sep 2026 21:49:35 +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=1790804977; cv=none; b=FDYSt5DagjQIR/GTE6cOHx5127B4l45C86qZnqo24l740CpFMditnlPD10rBt5RpOVye4lvl/G1SpbTRSBQwbnkQgsZO+uc4j+iqI1mVdcvYXW6qyDm1tGw0Slowv/UxAzsxuPIAv6V/aTH+wzo64kTlUbcu2e9jdTk+3KwMguk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804977; c=relaxed/simple; bh=72ACJI/cJk1wqzghWVp8GJhHfQXGaj1gc2q43XRzx90=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H/zaflNdvNa02pfP8C28818ge8t/DSVHiAJ6uklMMUWP7E4G30dR5s9uoBLtd67s5v1l8wlgzMnq7M2rv2AMvqcTJ40QZl+cABw23HXg8uyGcgX2MlcQdnLXHKj5oBJ5WLX7L3BNra4x4BAre6I2jaBh5J7TK9qQM1tqiTMwIwA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=C2pFgqxr; 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="C2pFgqxr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C96771F00898; Wed, 30 Sep 2026 21:49:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804975; bh=NDDm+a34EvcRId8lWDE4aHYbVSzH6REPnYRckEl93Ck=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=C2pFgqxrKa6EaED+HUjuk1CfGE7aanUWw7cRzx7JtgwVkd6AKu5IKzTK6W1DMZ9ty BAMZCTPiCZKQIKGgoK8vcbm4f1KnD2CaJ27Cxqw/m/74pxgak++v4jHVJ9DCdn6LxE aR5f9Jl15zV6yXkZONFKUcnQWX1qAeovLcMLrNJFMnuQHQCO0UgRe6H7AoJyz7Slcw TYhHWV5oCbcjMnDsDy7mg4V9KO7HSMBqpH1rBTnHSEPDQTsLbsqv0xTbOUL2u9Yp6z i1Rgo0FKUDM2N3nMl/lbNo9zWptd6gWTi4J78diwyTv/3Qd28SqvwrATb8aslnDS+5 z8CW7ZK2jzPCA== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:21 +0100 Subject: [PATCH v21 11/15] KVM: selftests: arm64: Add GCS registers to get-reg-list 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-11-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown , Thiago Jung Bauermann X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=2412; i=broonie@kernel.org; h=from:subject:message-id; bh=72ACJI/cJk1wqzghWVp8GJhHfQXGaj1gc2q43XRzx90=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO8zdfdjgisAjpwzhRQStgXuo4X2zVSo+4tL 889ySYMMKmJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DvAAKCRAk1otyXVSH 0Kl4B/4yq1siA8k8JbouKK1Q3ZhTDAE1elUgMuFxC2MOs3Ql20vli7wPsgRftQ9LjpNZk3T2yN8 umyuArJUwy620EfsG1E3kQjk4xtI0s8uDtQDu8jWf2BJ8uLQjvcCoTAm4gfJi/zf/OQ2KlF8pwq 71nVllCsd6dXttzyHGpfDz1d4h72noQRYm629RLbIa3rhHl+0PWKh/1w9CHNwCGxJiYgeTQpz01 RJ5D1zejGqMAp8LG+fz9Q+RaHgmjhYgqu/sqDINPKJNnM46vxnwi7J69+B3JP9cPOYp2bbZFm+x LO2wOYWGZaHz7Xib7aoA3KX3ksYSuvlBA1XHpP3JFYb+8iG0 X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB GCS adds new registers GCSCR_ELx, GCSCRE0_EL1 and GCSPR_ELx. Add these to those validated by get-reg-list. Reviewed-by: Thiago Jung Bauermann Signed-off-by: Mark Brown Reviewed-by: Lorenzo Stoakes (ARM) --- tools/testing/selftests/kvm/arm64/get-reg-list.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/testing/selftests/kvm/arm64/get-reg-list.c b/tools/testi= ng/selftests/kvm/arm64/get-reg-list.c index 533994687b5d..b895d2ba387d 100644 --- a/tools/testing/selftests/kvm/arm64/get-reg-list.c +++ b/tools/testing/selftests/kvm/arm64/get-reg-list.c @@ -42,6 +42,12 @@ struct feature_id_reg { static struct feature_id_reg feat_id_regs[] =3D { REG_FEAT(TCR2_EL1, ID_AA64MMFR3_EL1, TCRX, IMP), REG_FEAT(TCR2_EL2, ID_AA64MMFR3_EL1, TCRX, IMP), + REG_FEAT(GCSPR_EL0, ID_AA64PFR1_EL1, GCS, IMP), + REG_FEAT(GCSPR_EL1, ID_AA64PFR1_EL1, GCS, IMP), + REG_FEAT(GCSPR_EL2, ID_AA64PFR1_EL1, GCS, IMP), + REG_FEAT(GCSCRE0_EL1, ID_AA64PFR1_EL1, GCS, IMP), + REG_FEAT(GCSCR_EL1, ID_AA64PFR1_EL1, GCS, IMP), + REG_FEAT(GCSCR_EL2, ID_AA64PFR1_EL1, GCS, IMP), REG_FEAT(PIRE0_EL1, ID_AA64MMFR3_EL1, S1PIE, IMP), REG_FEAT(PIRE0_EL2, ID_AA64MMFR3_EL1, S1PIE, IMP), REG_FEAT(PIR_EL1, ID_AA64MMFR3_EL1, S1PIE, IMP), @@ -503,6 +509,9 @@ static __u64 base_regs[] =3D { ARM64_SYS_REG(3, 0, 2, 0, 1), /* TTBR1_EL1 */ ARM64_SYS_REG(3, 0, 2, 0, 2), /* TCR_EL1 */ ARM64_SYS_REG(3, 0, 2, 0, 3), /* TCR2_EL1 */ + ARM64_SYS_REG(3, 0, 2, 5, 0), /* GCSCR_EL1 */ + ARM64_SYS_REG(3, 0, 2, 5, 1), /* GCSPR_EL1 */ + ARM64_SYS_REG(3, 0, 2, 5, 2), /* GCSCRE0_EL1 */ ARM64_SYS_REG(3, 0, 5, 1, 0), /* AFSR0_EL1 */ ARM64_SYS_REG(3, 0, 5, 1, 1), /* AFSR1_EL1 */ ARM64_SYS_REG(3, 0, 5, 2, 0), /* ESR_EL1 */ @@ -519,6 +528,7 @@ static __u64 base_regs[] =3D { ARM64_SYS_REG(3, 0, 13, 0, 4), /* TPIDR_EL1 */ ARM64_SYS_REG(3, 0, 14, 1, 0), /* CNTKCTL_EL1 */ ARM64_SYS_REG(3, 2, 0, 0, 0), /* CSSELR_EL1 */ + ARM64_SYS_REG(3, 3, 2, 5, 1), /* GCSPR_EL0 */ ARM64_SYS_REG(3, 3, 10, 2, 4), /* POR_EL0 */ ARM64_SYS_REG(3, 3, 13, 0, 2), /* TPIDR_EL0 */ ARM64_SYS_REG(3, 3, 13, 0, 3), /* TPIDRRO_EL0 */ @@ -740,6 +750,8 @@ static __u64 el2_regs[] =3D { SYS_REG(VTTBR_EL2), SYS_REG(VTCR_EL2), SYS_REG(VNCR_EL2), + SYS_REG(GCSCR_EL2), + SYS_REG(GCSPR_EL2), SYS_REG(HDFGRTR2_EL2), SYS_REG(HDFGWTR2_EL2), SYS_REG(HFGRTR2_EL2), --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 4D358522F0A; Wed, 30 Sep 2026 21:49:39 +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=1790804980; cv=none; b=IHWH+KvAAIIaDbODVp9jnwJsj46ov7HlvMWeMcTn/GFVrTPJ9lhdUOefKRULW4sgrD80Hk4dQwWbuEl4k9+yQeTEMeWjWAQiliXSUT7/V6CX4ofTzXTlMRNTRk0BjLT74bypzBnM7iC1k0YG0B7VuE+bKdO9BRhB2NmdaxDc7Xs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804980; c=relaxed/simple; bh=Tfjwe96+Pus/NcQqd0MtFJGHAujN/0M7VQnvCDfTPfo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=chAfE2FrVM1ZtalfR8GY9zd8TXxzvvEV/VDNHjIZ7Qihb9tIM6knVivkwPYpW87nEIxwAKSzPZbg0tujsPNX+JyPaQVb1hcaR6WXBm2J0VNU7pGd2DYFgAHHB+c5LUpynV50QBIuRk3j0T1n/z1Vd5DjpREfbFlS8yjeh2fvQuk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hdJfM4Qh; 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="hdJfM4Qh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A5E491F000FF; Wed, 30 Sep 2026 21:49:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804978; bh=Wy0+k1InAjyE26lqhC7MpFZWdvI+C7jRsbn8a+z/FAQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=hdJfM4QhYbEs4brp34H1ssEHtyAj+BaeyqPWhk1zU+UMRak1YVElJXBGViX1yVEij 6vl+a/SuEC47wcnrxV/sE3AeT92FiFZunGWVBUJYZxolTzbsqhKyVPeLqgLWGhaolr rijx3XZ67wI4Fm0hWlT5nJ6XJKAG84QX4pEv/hGxKmz6FVdHIp//yCr2LGQpRbWw0b zrzQmJ3A64rhHIrNbbEabYttriptehg2NxQCRj0ZK4Hd1wZBOCmcK2mHwJ8sED8kLF PvRYIh+44QPRnBCCg2dPaf4c76RTU0bBpEAHdRrlFkzKqZwDGeiaAsllmpEZgBaGo/ /dFzcuUTuDShA== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:22 +0100 Subject: [PATCH v21 12/15] KVM: selftests: arm64: Add GCS to set_id_regs 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-12-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1732; i=broonie@kernel.org; h=from:subject:message-id; bh=Tfjwe96+Pus/NcQqd0MtFJGHAujN/0M7VQnvCDfTPfo=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO89S6s1s3YTYvEi7Pe2YG5B+wlge3CrvcBq G8G8N0HucyJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DvAAKCRAk1otyXVSH 0AoAB/9GISjeiauUt6+C48J60uI4rxisvx5a6uEGeIbh3HehLpPkwEqujVDEk7TtxMtRTR0+REF LuAD3f9u9Kxujl0hWnkk3ezyvSfE8WHAh+1htRmFRkIEOXcc305kIA0NGko3ICGJj2Ih/UlSJU5 XutnQeCpTwy43JlqFbVJ3KQ0vqoxcTeIaY2WfdolxBJUL2IZkXJmw4srDog2tW/RLE1T5BDNo69 rYnIdR8DgaQKHl5FLdsVmRQsUTFsd14z5LYEWPI5p7n9t/OifwTNxCmWgzf9PGbgUZWE5KakCqh M7gKuWU98E5VW4zMbuQBCVQ7eDYx/3/1BWJdKp0aXRiVT98Q X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Now that GCS is configurable via the ID registers update set_id_regs to cover ID_AA64PFR1_EL1.GCS. Signed-off-by: Mark Brown Reviewed-by: Lorenzo Stoakes (ARM) --- tools/testing/selftests/kvm/arm64/set_id_regs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/testing/selftests/kvm/arm64/set_id_regs.c b/tools/testin= g/selftests/kvm/arm64/set_id_regs.c index cb5e6358c59c..9db8516748cc 100644 --- a/tools/testing/selftests/kvm/arm64/set_id_regs.c +++ b/tools/testing/selftests/kvm/arm64/set_id_regs.c @@ -154,6 +154,7 @@ static const struct reg_ftr_bits ftr_id_aa64pfr0_el1[] = =3D { =20 static const struct reg_ftr_bits ftr_id_aa64pfr1_el1[] =3D { REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, DF2, 0), + REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, GCS, 0), REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, CSV2_frac, 0), REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, SSBS, ID_AA64PFR1_EL1_SSBS_= NI), REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR1_EL1, BT, 0), @@ -818,6 +819,12 @@ struct reg_ftr_val { .mask =3D r ## _ ## f ## _MASK, \ .val =3D (r ## _ ## f ## _ ## v << r ## _ ## f ## _SHIFT) } =20 +static const struct reg_ftr_val gcs_no_s1pie[] =3D { + REG_FTR_VAL(ID_AA64PFR1_EL1, GCS, IMP), + REG_FTR_VAL(ID_AA64MMFR3_EL1, S1PIE, NI), + { } +}; + static const struct reg_ftr_val s1pie_no_tcr2[] =3D { REG_FTR_VAL(ID_AA64MMFR3_EL1, TCRX, NI), REG_FTR_VAL(ID_AA64MMFR3_EL1, S1PIE, IMP), @@ -836,6 +843,7 @@ struct ftr_config { }; =20 static const struct ftr_config invalid_configs[] =3D { + { .name =3D "GCS without S1PIE", .regs =3D gcs_no_s1pie }, { .name =3D "S1PIE without TCRX", .regs =3D s1pie_no_tcr2 }, { .name =3D "S1POE without TCRX", .regs =3D s1poe_no_tcr2 }, }; --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 BD8775335BA; Wed, 30 Sep 2026 21:49:42 +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=1790804983; cv=none; b=CLj4zPMpHSE8BcTc+DH1EY9SsFWBdRh5+a3xJVHD1Xwsa2bO7fVcvMu0+dSjevsIgQl+YkGq9iW5CUrqE1En4b+VkeIb3Dkr2whWoB7EtKFG+qTWk1af53uK/V1RQsce5DYGTMDdrRU9EckNnzW9lW1dMVra9XQdK2W7mliYprQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804983; c=relaxed/simple; bh=XOq2i2Akpnkmw/R7Jj1JMRk+55dESJrYh85L+sVQnck=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Hf/XTS0v/OxE95Tckvi8t40YRMfLjyFzHRXmB24pFY4IpCArRfeEJCCUFKTy6mEDgLnAgfeNTeYHpcKom+m0lOV1EBJWSU/o2OFhKtoW5yQ8B3/Pb1lyBlHxDd7OKbXKLtvJeW2ZwhR95OEAjldVcZSWtSN19yV+ZbP+HrqzIeo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IXmbG6jJ; 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="IXmbG6jJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5D21C1F00898; Wed, 30 Sep 2026 21:49:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804982; bh=h3lrCthLI1PC2iGCSfULUwv97R+6R+4yOlZN59Nt/3c=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=IXmbG6jJCbw7N0HXXWrLm91tO1wVlO/YgTjjksE//WqUgUk85PZeLOx56ZdgkhvZW kN38rytbTvvFhhACOaLkNIy+LnaK+ku7ED0MMt1Vl4wUtvJZR6ZY7Iw5Fj7DpcUKl5 arm5DBOgjlgtPn91kOu3eXYeazZNau9NEYvznm75YJ/cgSeEs6GYlTRUFwe/qFp/3a j8km+JMykjbQnC39jJUZcNP8blqFbWwie+/AM07g5n+cfbmsysw88KcdbEUyG+osav cmHY0IMIy+bln5/RCSCXqPMZh5MShXQt8bxen/tZ+3vshUTN5DKgjrID6fGFrdFp5Q 2DW5+jKmUpXCw== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:23 +0100 Subject: [PATCH v21 13/15] KVM: selftests: arm64: Only restore SPSR_EL1 and ELR_EL1 if they change 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-13-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=1555; i=broonie@kernel.org; h=from:subject:message-id; bh=XOq2i2Akpnkmw/R7Jj1JMRk+55dESJrYh85L+sVQnck=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO9JuUHyRVDEv1xhfnkijFI8FEvAQ0AbR/91 YqKDLaXw32JATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DvQAKCRAk1otyXVSH 0Bm3B/0eoqlFUjRCKbK69n2bBkysp01U/eJf6B/+ofQ4MTse0MTyJPLrjZH5mp4lYvI6L6f0P+2 DpDfyXhk+62t5VKZRXG0Swn1jB2wp836Nk1PgaeAiEa8WYrLgiSmM2cNzdamMl/AfrMb3YjeR5G 0PIo1cSr8MwraP7Yf8IKPX0AbUNFjkNErvOzBReB4mdbiE60MdVR87gHnzz5DCIFrm8N1uYCnXn QCO9hlGLYLkqb1cnG2W4bgj+ueD/RceHYVTkFTLWo43S80fbCKYIanRtks8oIPZAFa4U+tL+iG7 ub9FCQrBG4UR5jMjN/eJQX9kqqM5IEOzeohlQh2nXCoyiP58 X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB When EXLOCK is enabled for ELx writes to SPSR_ELx and ELR_ELx generate GCS exceptions. Currently the selftest helpers unconditionally reload the saved values for these registers regardless of if the handler didn't change them. This gets in the way of EXLOCK testing, making it hard to generate contexts which will generate an invalid ERET since we never get as far as doing an exception return while EXLOCK is enabled. In order to facilitate testing of nested virtualisation emulation of EXLOCK change our reloads into read/modify/write cycles, suppressing the writes when they would not change the value in the register. Reviewed-by: Leonardo Bras Signed-off-by: Mark Brown Reviewed-by: Lorenzo Stoakes (ARM) --- tools/testing/selftests/kvm/lib/arm64/handlers.S | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/testing/selftests/kvm/lib/arm64/handlers.S b/tools/testi= ng/selftests/kvm/lib/arm64/handlers.S index 0e443eadfac6..367c22d61cba 100644 --- a/tools/testing/selftests/kvm/lib/arm64/handlers.S +++ b/tools/testing/selftests/kvm/lib/arm64/handlers.S @@ -33,8 +33,18 @@ =20 .macro restore_registers ldp x1, x2, [sp, #16 * 16] /* PC, PSTATE */ + + /* Suppress redundant writes to support GCS exception lock testing */ + mrs x3, elr_el1 + cmp x1, x3 + beq .Lskip_elr_\@ msr elr_el1, x1 +.Lskip_elr_\@: + mrs x3, spsr_el1 + cmp x2, x3 + beq .Lskip_spsr_\@ msr spsr_el1, x2 +.Lskip_spsr_\@: =20 /* sp is not restored */ ldp x30, xzr, [sp, #16 * 15] /* x30, SP */ --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 6ED5A3DFC8F; Wed, 30 Sep 2026 21:49:46 +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=1790804987; cv=none; b=M5yaRo87TKKiFICQyxg4JHqqR1pmeftVvk0bofa8ottwn0U2q4OxC3ZMuK+vQAunxck05g3cqwuUydL4qdIcaWPdz7oMPEP2PuImev6YtsmTbrO0nW1dcDfiPQ3Znozwl317VBp5uwe4iaSSbLjmHNcBc079Qe0vOttk4Kn/HQ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804987; c=relaxed/simple; bh=jOjbheMvQ2oaiZTFNxEcabEupt1ryfHHOU/dZyrsMYg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rcN6uy5scrL775GWNUAFWJAZZnbtegcMPN//Q66yeAZ4f7UDdac7rDIX9XG9awPk/4WieBtvyJGMgUIgypKA2xKwJ0DgPQwnzzk4VH5z+0gNtjOmNTSg/7D/x1kIxRYlITeoxz1chz7M/5G7KBlLe/wpcXeVSBWEbpHEapOrfvg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WzU1Gddb; 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="WzU1Gddb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 14AE71F000FF; Wed, 30 Sep 2026 21:49:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804986; bh=C2a3aKAOAWCQvHPMfzvxGHSX9GtshWwwpXGCiSwIczA=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=WzU1GddbjGM7swVSQkhFafBDdOITmXPNaZdy67ofXsd4NJDdZZYHCAfEK52xy8rZ3 RCIzcuTG2eL5ihVSZ+v9S0IQ7n0Gthb0wcuiQnz1vXx2iFuhY0u3yuhhJNl5Va8cZ3 jztHOvaGmeKutPS0AQgHqVtRvUOm0w5cZ0AB2KkbeSiO08z8kCPcyOaZ5aw/Ny8lZb mOmZ4eSZxDCOLePvz/9buUz1/eP9DiWqap7VQwDpn5H28hBPWJbFoeF6rBxwM0kQWH qCFM1lG1tPGRDfNVm8RRgU6WMCzLtiKYzgrf9FTDWdT9J71dS53aTYHJ6fuCWxOruY X6YQSiCgcr/iQ== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:24 +0100 Subject: [PATCH v21 14/15] tools: Synchronise the kernel esr.h 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-14-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=7228; i=broonie@kernel.org; h=from:subject:message-id; bh=jOjbheMvQ2oaiZTFNxEcabEupt1ryfHHOU/dZyrsMYg=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO+PNwvuwtOgqKb1SLmqd/GgYUJkrZPsLYrL 2lZe0r5DmKJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DvgAKCRAk1otyXVSH 0EMYB/9rMvSHV7saPUZOt8G7n3A+cchdJZJs5kVWKk/Rhd1Qo1khx9owVuGtnqa3L5kXaa9ys8F w9zxo3Y0hQTIbQp5DDTwYmrQy/LwPv2eDCIHGin81IFqRpxoKCygRzifPNt3CxDiE5iPtulOMbE LCpJyCIeF1P7gV62nK5H+ixOwPlIQ+w+0OfoZDyeJN6G3UM0pa2/5uB0iHrJ5rem9Hu9gfzAGgB wGB8BRd+iHrJ5oPG8eXHoH016ODC/2U+dt4KuWZJIGv6ROCz12UEi+ckxJ2PsqGpTOGqTh+X9dx JjIPvUa9FcOKcujb/YCDUA/TGWdCxhgdBLAD5Gv5Qv3R6b6V X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB To pick up definitions for GCS. Reviewed-by: Leonardo Bras Signed-off-by: Mark Brown --- tools/arch/arm64/include/asm/esr.h | 113 +++++++++++++++++++++++++++++++++= ---- 1 file changed, 102 insertions(+), 11 deletions(-) diff --git a/tools/arch/arm64/include/asm/esr.h b/tools/arch/arm64/include/= asm/esr.h index f3c6403e5ef2..24c6ebe3fd41 100644 --- a/tools/arch/arm64/include/asm/esr.h +++ b/tools/arch/arm64/include/asm/esr.h @@ -19,7 +19,8 @@ #define ESR_ELx_EC_FP_ASIMD UL(0x07) #define ESR_ELx_EC_CP10_ID UL(0x08) /* EL2 only */ #define ESR_ELx_EC_PAC UL(0x09) /* EL2 and above */ -/* Unallocated EC: 0x0A - 0x0B */ +#define ESR_ELx_EC_OTHER UL(0x0A) +/* Unallocated EC: 0x0B */ #define ESR_ELx_EC_CP14_64 UL(0x0C) #define ESR_ELx_EC_BTI UL(0x0D) #define ESR_ELx_EC_ILL UL(0x0E) @@ -50,7 +51,8 @@ #define ESR_ELx_EC_FP_EXC32 UL(0x28) /* Unallocated EC: 0x29 - 0x2B */ #define ESR_ELx_EC_FP_EXC64 UL(0x2C) -/* Unallocated EC: 0x2D - 0x2E */ +#define ESR_ELx_EC_GCS UL(0x2D) +/* Unallocated EC: 0x2E */ #define ESR_ELx_EC_SERROR UL(0x2F) #define ESR_ELx_EC_BREAKPT_LOW UL(0x30) #define ESR_ELx_EC_BREAKPT_CUR UL(0x31) @@ -97,6 +99,8 @@ #define ESR_ELx_AET_CE (UL(6) << ESR_ELx_AET_SHIFT) =20 /* Shared ISS field definitions for Data/Instruction aborts */ +#define ESR_ELx_VNCR_SHIFT (13) +#define ESR_ELx_VNCR (UL(1) << ESR_ELx_VNCR_SHIFT) #define ESR_ELx_SET_SHIFT (11) #define ESR_ELx_SET_MASK (UL(3) << ESR_ELx_SET_SHIFT) #define ESR_ELx_FnV_SHIFT (10) @@ -119,6 +123,16 @@ #define ESR_ELx_FSC_SEA_TTW(n) (0x14 + (n)) #define ESR_ELx_FSC_SECC (0x18) #define ESR_ELx_FSC_SECC_TTW(n) (0x1c + (n)) +#define ESR_ELx_FSC_EXCL_ATOMIC (0x35) +#define ESR_ELx_FSC_ADDRSZ (0x00) + +/* + * Annoyingly, the negative levels for Address size faults aren't laid out + * contiguously (or in the desired order) + */ +#define ESR_ELx_FSC_ADDRSZ_nL(n) ((n) =3D=3D -1 ? 0x25 : 0x2C) +#define ESR_ELx_FSC_ADDRSZ_L(n) ((n) < 0 ? ESR_ELx_FSC_ADDRSZ_nL(n) : \ + (ESR_ELx_FSC_ADDRSZ + (n))) =20 /* Status codes for individual page table levels */ #define ESR_ELx_FSC_ACCESS_L(n) (ESR_ELx_FSC_ACCESS + (n)) @@ -141,12 +155,12 @@ #define ESR_ELx_SF (UL(1) << ESR_ELx_SF_SHIFT) #define ESR_ELx_AR_SHIFT (14) #define ESR_ELx_AR (UL(1) << ESR_ELx_AR_SHIFT) -#define ESR_ELx_VNCR_SHIFT (13) -#define ESR_ELx_VNCR (UL(1) << ESR_ELx_VNCR_SHIFT) #define ESR_ELx_CM_SHIFT (8) #define ESR_ELx_CM (UL(1) << ESR_ELx_CM_SHIFT) =20 /* ISS2 field definitions for Data Aborts */ +#define ESR_ELx_HDBSSF_SHIFT (11) +#define ESR_ELx_HDBSSF (UL(1) << ESR_ELx_HDBSSF_SHIFT) #define ESR_ELx_TnD_SHIFT (10) #define ESR_ELx_TnD (UL(1) << ESR_ELx_TnD_SHIFT) #define ESR_ELx_TagAccess_SHIFT (9) @@ -161,8 +175,6 @@ #define ESR_ELx_Xs_MASK (GENMASK_ULL(4, 0)) =20 /* ISS field definitions for exceptions taken in to Hyp */ -#define ESR_ELx_FSC_ADDRSZ (0x00) -#define ESR_ELx_FSC_ADDRSZ_L(n) (ESR_ELx_FSC_ADDRSZ + (n)) #define ESR_ELx_CV (UL(1) << 24) #define ESR_ELx_COND_SHIFT (20) #define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT) @@ -174,6 +186,13 @@ #define ESR_ELx_WFx_ISS_WFE (UL(1) << 0) #define ESR_ELx_xVC_IMM_MASK ((UL(1) << 16) - 1) =20 +/* ISS definitions for LD64B/ST64B/{T,P}SBCSYNC instructions */ +#define ESR_ELx_ISS_OTHER_ST64BV (0) +#define ESR_ELx_ISS_OTHER_ST64BV0 (1) +#define ESR_ELx_ISS_OTHER_LDST64B (2) +#define ESR_ELx_ISS_OTHER_TSBCSYNC (3) +#define ESR_ELx_ISS_OTHER_PSBCSYNC (4) + #define DISR_EL1_IDS (UL(1) << 24) /* * DISR_EL1 and ESR_ELx share the bottom 13 bits, but the RES0 bits may me= an @@ -371,12 +390,14 @@ /* * ISS values for SME traps */ +#define ESR_ELx_SME_ISS_SMTC_MASK GENMASK(2, 0) +#define ESR_ELx_SME_ISS_SMTC(esr) ((esr) & ESR_ELx_SME_ISS_SMTC_MASK) =20 -#define ESR_ELx_SME_ISS_SME_DISABLED 0 -#define ESR_ELx_SME_ISS_ILL 1 -#define ESR_ELx_SME_ISS_SM_DISABLED 2 -#define ESR_ELx_SME_ISS_ZA_DISABLED 3 -#define ESR_ELx_SME_ISS_ZT_DISABLED 4 +#define ESR_ELx_SME_ISS_SMTC_SME_DISABLED 0 +#define ESR_ELx_SME_ISS_SMTC_ILL 1 +#define ESR_ELx_SME_ISS_SMTC_SM_DISABLED 2 +#define ESR_ELx_SME_ISS_SMTC_ZA_DISABLED 3 +#define ESR_ELx_SME_ISS_SMTC_ZT_DISABLED 4 =20 /* ISS field definitions for MOPS exceptions */ #define ESR_ELx_MOPS_ISS_MEM_INST (UL(1) << 24) @@ -387,6 +408,31 @@ #define ESR_ELx_MOPS_ISS_SRCREG(esr) (((esr) & (UL(0x1f) << 5)) >> 5) #define ESR_ELx_MOPS_ISS_SIZEREG(esr) (((esr) & (UL(0x1f) << 0)) >> 0) =20 +/* ISS field definitions for GCS */ +#define ESR_ELx_ExType_SHIFT (20) +#define ESR_ELx_ExType_MASK GENMASK(23, 20) +#define ESR_ELx_Raddr_SHIFT (10) +#define ESR_ELx_Raddr_MASK GENMASK(14, 10) +#define ESR_ELx_Rn_SHIFT (5) +#define ESR_ELx_Rn_MASK GENMASK(9, 5) +#define ESR_ELx_Rvalue_SHIFT 5 +#define ESR_ELx_Rvalue_MASK GENMASK(9, 5) +#define ESR_ELx_IT_SHIFT (0) +#define ESR_ELx_IT_MASK GENMASK(4, 0) + +#define ESR_ELx_ExType_DATA_CHECK 0 +#define ESR_ELx_ExType_EXLOCK 1 +#define ESR_ELx_ExType_STR 2 + +#define ESR_ELx_IT_RET 0 +#define ESR_ELx_IT_GCSPOPM 1 +#define ESR_ELx_IT_RET_KEYA 2 +#define ESR_ELx_IT_RET_KEYB 3 +#define ESR_ELx_IT_GCSSS1 4 +#define ESR_ELx_IT_GCSSS2 5 +#define ESR_ELx_IT_GCSPOPCX 6 +#define ESR_ELx_IT_GCSPOPX 7 + #ifndef __ASSEMBLER__ #include =20 @@ -408,6 +454,11 @@ static inline bool esr_is_cfi_brk(unsigned long esr) (esr_brk_comment(esr) & ~CFI_BRK_IMM_MASK) =3D=3D CFI_BRK_IMM_BASE; } =20 +static inline bool esr_is_ubsan_brk(unsigned long esr) +{ + return (esr_brk_comment(esr) & ~UBSAN_BRK_MASK) =3D=3D UBSAN_BRK_IMM; +} + static inline bool esr_fsc_is_translation_fault(unsigned long esr) { esr =3D esr & ESR_ELx_FSC; @@ -439,6 +490,46 @@ static inline bool esr_fsc_is_access_flag_fault(unsign= ed long esr) (esr =3D=3D ESR_ELx_FSC_ACCESS_L(0)); } =20 +static inline bool esr_fsc_is_excl_atomic_fault(unsigned long esr) +{ + esr =3D esr & ESR_ELx_FSC; + + return esr =3D=3D ESR_ELx_FSC_EXCL_ATOMIC; +} + +static inline bool esr_fsc_is_addr_sz_fault(unsigned long esr) +{ + esr &=3D ESR_ELx_FSC; + + return (esr =3D=3D ESR_ELx_FSC_ADDRSZ_L(3)) || + (esr =3D=3D ESR_ELx_FSC_ADDRSZ_L(2)) || + (esr =3D=3D ESR_ELx_FSC_ADDRSZ_L(1)) || + (esr =3D=3D ESR_ELx_FSC_ADDRSZ_L(0)) || + (esr =3D=3D ESR_ELx_FSC_ADDRSZ_L(-1)); +} + +static inline bool esr_fsc_is_sea_ttw(unsigned long esr) +{ + esr =3D esr & ESR_ELx_FSC; + + return (esr =3D=3D ESR_ELx_FSC_SEA_TTW(3)) || + (esr =3D=3D ESR_ELx_FSC_SEA_TTW(2)) || + (esr =3D=3D ESR_ELx_FSC_SEA_TTW(1)) || + (esr =3D=3D ESR_ELx_FSC_SEA_TTW(0)) || + (esr =3D=3D ESR_ELx_FSC_SEA_TTW(-1)); +} + +static inline bool esr_fsc_is_secc_ttw(unsigned long esr) +{ + esr =3D esr & ESR_ELx_FSC; + + return (esr =3D=3D ESR_ELx_FSC_SECC_TTW(3)) || + (esr =3D=3D ESR_ELx_FSC_SECC_TTW(2)) || + (esr =3D=3D ESR_ELx_FSC_SECC_TTW(1)) || + (esr =3D=3D ESR_ELx_FSC_SECC_TTW(0)) || + (esr =3D=3D ESR_ELx_FSC_SECC_TTW(-1)); +} + /* Indicate whether ESR.EC=3D=3D0x1A is for an ERETAx instruction */ static inline bool esr_iss_is_eretax(unsigned long esr) { --=20 2.47.3 From nobody Fri Oct 2 07:45:28 2026 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 64F9F524B0A; Wed, 30 Sep 2026 21:49: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=1790804991; cv=none; b=AvdJ2EpUGxQOnN7o2pkXW8IbIFfwdk0HajiZIES88+Tt8VVVItVVWxKfkRAl2vaeIS3bYOwc4Keg7n722LA9JCPpI40zrWojTAmVYAipyESl8z3FpUi8FiV42acSf38AqQJ6x3SRgC06hMuXvPHOerRaX/gq7jKQ/yF2pSiv4SA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790804991; c=relaxed/simple; bh=Ap5WYMP/jFZxgMJJY0WLriB9g9iNEKwHzXZCFBgXX8g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tDuZfodBB/hM9Yl9anXVApKqkMliXAPSl2Sc/xgYDBpvY+WOC9FkxpEDWIvitjtzGxAc+AFqwbToJoyIyNwsXrgmMlHaebmLDjcQ6ibIkgVH0qiuHB/MdFSKmmc1cDvZ30O75yCJdZ3x5jcOWQhVlylD+Bfjr4bjkEShKIn9fUQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OwGs2+Qt; 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="OwGs2+Qt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BEF691F00898; Wed, 30 Sep 2026 21:49:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790804990; bh=gbRjCKyJEsfaoYs0uz6FNo90W1JB3dsyqZL+XpcN78I=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=OwGs2+Qte/WJVkJC7eXFmL3seluTWGH9nBh5a9LwiH5jB0L6/5phQIHqvo8Bpb+82 AXE4zlkxy8GLprGm0rF7mKD38zv9G2T90yn12m6pIRAP5wd7COEEuZLuOJWgFSiKtw dyuBTnGbEJ2nIidwJYnfyt4YGbS+UmO86TsepFPkOKfZzRabgodN/R/zYUbHnY4y4u 8SGhQHp2VfCJuyALo0cBMT/LF1sANXa3yvOz0n15RFOKsemD8CYPnW3bURv3da5IaX fGog4zVAlx5x0D9nbqL81KTrx9bXrTjmzUDUeil/UA1sbsPraUAJV9m+6kG/OPZifM M/ZzIUWybsvow== From: Mark Brown Date: Wed, 30 Sep 2026 22:48:25 +0100 Subject: [PATCH v21 15/15] KVM: selftests: arm64: Add GCS EXLOCK exception emulation test 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: quoted-printable Message-Id: <20260930-arm64-gcs-v21-15-3556644cd927@kernel.org> References: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> In-Reply-To: <20260930-arm64-gcs-v21-0-3556644cd927@kernel.org> To: Catalin Marinas , Will Deacon , Marc Zyngier , Joey Gouly , Suzuki K Poulose , Shuah Khan , Oliver Upton , Fuad Tabba Cc: Peter Maydell , Leonardo Bras , Wei-Lin Chang , Yao Yuan , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Mark Brown X-Mailer: b4 0.17-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=11623; i=broonie@kernel.org; h=from:subject:message-id; bh=Ap5WYMP/jFZxgMJJY0WLriB9g9iNEKwHzXZCFBgXX8g=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBqvYO/DYTBT/N2pQqG7Bv+IyjaOkfEiUG/sCG5L 7fcU9ofqfeJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCar2DvwAKCRAk1otyXVSH 0JsXCACFAaYDC8+8EAqUWrRXksRRQB75PpQu1oB5tCF0YP5tiZQ/ba7op4SbpKXQLXuwUDt8dE4 hckx9kLXtI2gM9d6Pd1z09PL3QpogQixNANCGXJDcHRdgdX6zr2aZPtYoZs1ueNYwOW8k3b6d86 hlCQ6qwAqGdMU1hxWy/+yfGZsNWArzHU8ce29zej5938WR8FWR6Nop0C3Qn1NAN3YLk3U4GR0YO hRIfmOewl63cPW373CJRv4Lg+dA7hVlFyVP5MmZ1in+hXrzqnpIm2EfBbOGcYXNzwZQFTJb2YV6 vPRSLAG7qyyXiENYkZD8/tLL5VeML75QEq7At1rX3nyyuBfc X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB When running in vEL2 ERET is emulated, this means that we must emulate the behaviour of GCSCR_EL2.EXLOCKEN. Add a test that validates the behaviour. As per DDI0487 R_WTXBY PSTATE.EXLOCK is set to the value of GCSCR_ELx.EXLOCKEN when taking an exception to the same exception level. As per DDI0487 R_TYTWB if on exception return to the same EL GCSCR_ELx.EXLOCKEN is 1 and PSTATE.EXLOCK is not 1 then the exception return is illegal. We nest handling of two UDFs to allow us to both observe and modify PSTATE.EXLOCK, checking that expected exceptions are generated for ERET. We also repeat the UDF tests having enabled fine grained traps for ERET to try to ensure that the slow paths are taken. We also attempt to write to both SPSR_ELx and ELR_ELx, again using a UDF handler to control PSTATE.EXLOCK. We do all this both with and without having enabled EXLOCKEN, though only for code running at EL2 due to framework limitations. For completeness we also inject a data abort from EL0 to EL2 with GCSCR_EL2.EXLOCKEN set, ensuring that PSTATE.EXLOCK is not set. Signed-off-by: Mark Brown Reviewed-by: Leonardo Bras --- tools/testing/selftests/kvm/Makefile.kvm | 1 + tools/testing/selftests/kvm/arm64/gcs_exceptions.c | 336 +++++++++++++++++= ++++ 2 files changed, 337 insertions(+) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index 96bab7002d39..0286453ab223 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -179,6 +179,7 @@ TEST_GEN_PROGS_arm64 +=3D arm64/hello_el2 TEST_GEN_PROGS_arm64 +=3D arm64/host_sve TEST_GEN_PROGS_arm64 +=3D arm64/hypercalls TEST_GEN_PROGS_arm64 +=3D arm64/external_aborts +TEST_GEN_PROGS_arm64 +=3D arm64/gcs_exceptions TEST_GEN_PROGS_arm64 +=3D arm64/mmio_sign_ext TEST_GEN_PROGS_arm64 +=3D arm64/page_fault_test TEST_GEN_PROGS_arm64 +=3D arm64/psci_test diff --git a/tools/testing/selftests/kvm/arm64/gcs_exceptions.c b/tools/tes= ting/selftests/kvm/arm64/gcs_exceptions.c new file mode 100644 index 000000000000..c127904108e1 --- /dev/null +++ b/tools/testing/selftests/kvm/arm64/gcs_exceptions.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Test KVM's handling of Guarded Control Stack exception state. + */ + +#include "kvm_util.h" +#include "processor.h" +#include "test_util.h" +#include "ucall.h" + +#include +#include + +#define PSTATE_IL_BIT BIT(20) + +static void require_guest_gcs(struct kvm_vcpu *vcpu) +{ + u64 pfr1 =3D vcpu_get_reg(vcpu, + KVM_ARM64_SYS_REG(SYS_ID_AA64PFR1_EL1)); + + TEST_REQUIRE(SYS_FIELD_GET(ID_AA64PFR1_EL1, GCS, pfr1) >=3D + ID_AA64PFR1_EL1_GCS_IMP); +} + +static bool expect_exlock; +static unsigned int undef_count; +static unsigned int illegal_count; +static unsigned int gcs_count; +static u64 handler_pstate; +static u64 illegal_pstate; + +static u64 expected_illegal_pc; +static enum udf_mode { + UDF_COLLECT, /* Initial UDF we collect PSTATE from */ + UDF_VALIDATE, /* Secondary UDF that collects and validates */ + UDF_REPAIR, /* UDF to clear EXLOCK */ + UDF_ELR_EL1, /* Write to ELR_EL1 with EXLOCK */ + UDF_ELR_EL2, /* Write to ELR_EL2 with EXLOCK */ + UDF_SPSR_EL1, /* Write to SPSR_EL1 with EXLOCK */ + UDF_SPSR_EL2, /* Write to SPSR_EL2 with EXLOCK */ +} udf_mode; + +static void guest_undef_handler(struct ex_regs *regs) +{ + u64 esr =3D read_sysreg(esr_el2); + u64 val; + + undef_count++; + + /* Just skip the instruction either way. */ + GUEST_ASSERT_EQ(esr, ESR_ELx_IL); + regs->pc +=3D 4; + + switch (udf_mode) { + case UDF_COLLECT: + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN, + expect_exlock ? GCSCR_ELx_EXLOCKEN : 0); + + /* + * If we want the nested exception handler to change + * PSTATE it can't have EXLOCK set. + */ + write_sysreg_s(0, SYS_GCSCR_EL2); + isb(); + + /* + * Take another exception without returning so we can + * collect the EXLOCK state we're seeing here and make + * our return illegal. + */ + expected_illegal_pc =3D regs->pc; + udf_mode =3D UDF_VALIDATE; + asm volatile("udf #0" ::: "memory"); + + /* Reenable so PSTATE.EXLOCK is checked */ + write_sysreg_s(expect_exlock ? GCSCR_ELx_EXLOCKEN : 0, + SYS_GCSCR_EL2); + isb(); + break; + + case UDF_VALIDATE: + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN, + 0); + + /* Validate the EXLOCK of the original exception. */ + handler_pstate =3D regs->pstate; + GUEST_ASSERT_EQ(!!(regs->pstate & PSR_EXLOCK_BIT), + expect_exlock); + + /* Clearing PSTATE.EXLOCK triggers an illegal ERET. */ + regs->pstate &=3D ~PSR_EXLOCK_BIT; + break; + + case UDF_REPAIR: + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN, + 0); + + /* Disable EXLOCK for the requesting context */ + regs->pstate &=3D ~PSR_EXLOCK_BIT; + break; + + case UDF_ELR_EL1: + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN, + expect_exlock ? GCSCR_ELx_EXLOCKEN : 0); + + asm volatile("mrs %0, elr_el1 \n\ + msr elr_el1, %0" + : "=3Dr"(val) :: "memory"); + break; + + case UDF_ELR_EL2: + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN, + expect_exlock ? GCSCR_ELx_EXLOCKEN : 0); + + asm volatile("mrs %0, elr_el2 \n\ + msr elr_el2, %0" + : "=3Dr"(val) :: "memory"); + break; + + case UDF_SPSR_EL1: + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN, + expect_exlock ? GCSCR_ELx_EXLOCKEN : 0); + + asm volatile("mrs %0, spsr_el1 \n\ + msr spsr_el1, %0" + : "=3Dr"(val) :: "memory"); + break; + + case UDF_SPSR_EL2: + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN, + expect_exlock ? GCSCR_ELx_EXLOCKEN : 0); + + asm volatile("mrs %0, spsr_el2 \n\ + msr spsr_el2, %0" + : "=3Dr"(val) :: "memory"); + break; + + default: + GUEST_FAIL("Invalid udf_mode"); + } +} + +static void guest_illegal_handler(struct ex_regs *regs) +{ + u64 esr =3D read_sysreg(esr_el2); + + illegal_count++; + illegal_pstate =3D regs->pstate; + + GUEST_ASSERT_EQ(ESR_ELx_EC(esr), ESR_ELx_EC_ILL); + GUEST_ASSERT(esr & ESR_ELx_IL); + GUEST_ASSERT(regs->pstate & PSTATE_IL_BIT); + GUEST_ASSERT(!(regs->pstate & PSR_EXLOCK_BIT)); + GUEST_ASSERT_EQ(regs->pc, expected_illegal_pc); + + /* Disable exception locking so we can repair the return state. */ + write_sysreg_s(0, SYS_GCSCR_EL2); + isb(); + + /* We need our own EXLOCK clearing so we can repair the original */ + udf_mode =3D UDF_REPAIR; + asm volatile("udf #0" ::: "memory"); + + /* Disable EXLOCK for the generating context, making things legal */ + regs->pstate &=3D ~(PSTATE_IL_BIT | PSR_EXLOCK_BIT); +} + +static void guest_gcs_handler(struct ex_regs *regs) +{ + u64 esr =3D read_sysreg(esr_el2); + + gcs_count++; + + GUEST_ASSERT_EQ(ESR_ELx_EC(esr), ESR_ELx_EC_GCS); + GUEST_ASSERT_EQ(FIELD_GET(ESR_ELx_ExType_MASK, esr), + ESR_ELx_ExType_EXLOCK); + + /* Disabling EXLOCKEN makes sysreg writes legal. */ + write_sysreg_s(0, SYS_GCSCR_EL2); + isb(); +} + +static noinline void test_udf_exception(bool enable_exlock) +{ + unsigned int initial_undef =3D undef_count; + unsigned int initial_illegal =3D illegal_count; + unsigned int initial_gcs =3D gcs_count; + + expect_exlock =3D enable_exlock; + write_sysreg_s(enable_exlock ? GCSCR_ELx_EXLOCKEN : 0, + SYS_GCSCR_EL2); + isb(); + + udf_mode =3D UDF_COLLECT; + asm volatile("udf #0" ::: "memory"); + + /* Leave GCS disabled even if a broken ERET skipped the ILL handler. */ + write_sysreg_s(0, SYS_GCSCR_EL2); + isb(); + + GUEST_ASSERT_EQ(undef_count, initial_undef + 2 + enable_exlock); + GUEST_ASSERT_EQ(illegal_count, initial_illegal + enable_exlock); + GUEST_ASSERT_EQ(!!(handler_pstate & PSR_EXLOCK_BIT), enable_exlock); + if (enable_exlock) + GUEST_ASSERT(illegal_pstate & PSTATE_IL_BIT); + GUEST_ASSERT_EQ(initial_gcs, gcs_count); +} + +static noinline void test_sysreg(enum udf_mode reg, bool enable_exlock) +{ + unsigned int initial_undef =3D undef_count; + unsigned int initial_gcs =3D gcs_count; + + expect_exlock =3D enable_exlock; + + write_sysreg_s(enable_exlock ? GCSCR_ELx_EXLOCKEN : 0, + SYS_GCSCR_EL2); + isb(); + + udf_mode =3D reg; + asm volatile("udf #0" ::: "memory"); + + /* Ensure EXLOCK is disabled */ + write_sysreg_s(0, SYS_GCSCR_EL2); + isb(); + + GUEST_ASSERT_EQ(gcs_count, initial_gcs + expect_exlock); + GUEST_ASSERT_EQ(undef_count, initial_undef + 1); +} + +static void guest_code(void) +{ + GUEST_ASSERT_EQ(get_current_el(), 2); + + /* + * Try straightforwardly generating an exception without and + * with EXLOCK. + */ + test_udf_exception(false); + test_sysreg(UDF_ELR_EL1, false); + test_sysreg(UDF_ELR_EL2, false); + test_sysreg(UDF_SPSR_EL1, false); + test_sysreg(UDF_SPSR_EL2, false); + + test_udf_exception(true); + test_sysreg(UDF_ELR_EL1, true); + test_sysreg(UDF_ELR_EL2, true); + test_sysreg(UDF_SPSR_EL1, true); + test_sysreg(UDF_SPSR_EL2, true); + + GUEST_DONE(); +} + +static void test_exception_from_same_el(void) +{ + struct kvm_vcpu_init init; + struct kvm_vcpu *vcpu; + struct kvm_vm *vm; + struct ucall uc; + + vm =3D vm_create(1); + kvm_get_default_vcpu_target(vm, &init); + init.features[0] |=3D BIT(KVM_ARM_VCPU_HAS_EL2); + vcpu =3D aarch64_vcpu_add(vm, 0, &init, guest_code); + require_guest_gcs(vcpu); + + vm_init_descriptor_tables(vm); + vcpu_init_descriptor_tables(vcpu); + vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT, + ESR_ELx_EC_UNKNOWN, guest_undef_handler); + vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT, + ESR_ELx_EC_ILL, guest_illegal_handler); + vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT, + ESR_ELx_EC_GCS, guest_gcs_handler); + kvm_arch_vm_finalize_vcpus(vm); + + vcpu_run(vcpu); + switch (get_ucall(vcpu, &uc)) { + case UCALL_DONE: + break; + case UCALL_ABORT: + REPORT_GUEST_ASSERT(uc); + break; + default: + TEST_FAIL("Unhandled ucall: %ld", uc.cmd); + } + + kvm_vm_free(vm); +} + +static void test_exception_from_lower_el(void) +{ + struct kvm_vcpu_events events =3D {}; + struct kvm_vcpu_init init; + struct kvm_vcpu *vcpu; + struct kvm_vm *vm; + u64 pstate; + + vm =3D vm_create(1); + kvm_get_default_vcpu_target(vm, &init); + init.features[0] |=3D BIT(KVM_ARM_VCPU_HAS_EL2); + vcpu =3D aarch64_vcpu_add(vm, 0, &init, NULL); + require_guest_gcs(vcpu); + kvm_arch_vm_finalize_vcpus(vm); + + /* + * Inject an EL0 data abort to vEL2 with EXLOCK enabled for + * vEL2. + */ + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_HCR_EL2), + vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_HCR_EL2)) | + HCR_EL2_TGE); + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_GCSCR_EL2), + GCSCR_ELx_EXLOCKEN); + vcpu_set_reg(vcpu, ARM64_CORE_REG(regs.pstate), + PSR_MODE_EL0t | PSR_EXLOCK_BIT); + + events.exception.ext_dabt_pending =3D true; + vcpu_events_set(vcpu, &events); + + pstate =3D vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pstate)); + TEST_ASSERT_EQ(pstate & PSR_MODE_MASK, PSR_MODE_EL2h); + TEST_ASSERT(!(pstate & PSR_EXLOCK_BIT), + "EXLOCK set on exception from a lower EL"); + + kvm_vm_free(vm); +} + +int main(void) +{ + TEST_REQUIRE(kvm_check_cap(KVM_CAP_ARM_EL2)); + test_exception_from_same_el(); + test_exception_from_lower_el(); + + return 0; +} --=20 2.47.3