From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 0EA4C42188B; Fri, 29 May 2026 15:56:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070209; cv=none; b=be+EBhTbaXgLyVNr/V1qAVKVJbF9HZ+9/1QfXjyNUxmWFUMcuh+r9SL9gpDVMHXxhKTPWz+jmikhNv2bRGDFHKosa16wFLIQPm5md9phjl5XmHaK9TqUEYeawcF5ZmdKZGczAOEDHl7FwZCrRfPD3Y5RtL/o/sm5EUSxivyPUpA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070209; c=relaxed/simple; bh=jRjbqJyRqBwC5B2OUsOJnMBk6r+2yw1RyoyjJ22uZyM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IxOS4mi112FpWy/ijwNU3fTLZwaCWWukCF+gmjmtSm31WdXhY5VjIIEJuhpWiC33Blp7YWw1CXei+jpkajMqwj3J6c5q0Skc0slCOLuQGJwxHqBwxSSBCxijmefJ1p37/KPWeZFegahJKCg4sLIYuN5WH2bji4YjvYc8RqT+2M4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=KDxRUAlP; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="KDxRUAlP" Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFFnLY1467851; Fri, 29 May 2026 15:56:12 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=X0+Z7dbvpvWAPkUoS 6IVhDw51hFtW/9CwXUKchMioEc=; b=KDxRUAlPx7Yjqz/LDTEZStq8jsvSrmdpH Vtr5xYC1WZEewf6Wchl3YE7yMg0M0dhMVvjGZQVBhw7w8UFemqLy5p+WluNFIQnU lfjbhGdfTeGRtS/YKVMh9HPkNd72oetlcXG/0Bslw0/5mNsunrNg46qmGSmZJxnT +XELCyG9llzU8TTfvCF6ejLLGBLviAOGTLXdPWtR65rN7bSf+E6WDUYXLlKm/EGv TRnUFh1jAFNL/vMugUdqLM4dFd8Ld0YzttX8J4qJWKAHoXPtngfApq86l8gnQzKE 8Iv8m8dLPzr3xkB5HMhBbwT48sVve/4jA5eHpK6ihAip3WmqP6BQA== Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee886mgew-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:11 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs56R016943; Fri, 29 May 2026 15:56:10 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgjn5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:10 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay07.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu2An50594186 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:02 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B3A7B20040; Fri, 29 May 2026 15:56:02 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 58E922004D; Fri, 29 May 2026 15:56:02 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:02 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 01/26] KVM: arm64: Extract some feature related changes to kvm_feature.h Date: Fri, 29 May 2026 17:55:34 +0200 Message-ID: <20260529155601.2927240-2-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: LLZt6BPdI1g8_R9pvTBACHosjuOMXjhE X-Authority-Analysis: v=2.4 cv=Z8Dc2nRA c=1 sm=1 tr=0 ts=6a19b71b cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=WW8djTQXebi2HcFpRRMA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX4Nw4TEKeU5LR KBe06HG4BiiVlWSlLIDC+aYTlG2OBA/SKAoKYlPYUbOo0cGzx95oNuh4xJ5XVoU2hQCoqaP/Yjm mX+sjQKI+B0c1xn7ZfU/3kDJXo5C64712dNzYfzTQd9H6MrkpMirSET4yQOxAF8MMp4D40QoSCT 5tfPfWN4KvJnUuGAdNfqwm520QUWS4GLnFxMJBz/K7bK5S5F3ciHrtvTw4N8BVg3g+xerRoaHm4 Sjb6CwQVrdIRO3mH5t8XjC0AghZ5JzStpbSVI7b+YmE68hvPTsm7xYJ9eckwvhC9Jfd/vN6XPKL t0SfcMNdc8I5hCqYGTZKvb3b2ALwQt8qNqK/3QthYTFMagxWDIBoNhUMSoS4KuqHPQZq0BJX6XL yPCiWczFI7NWs4yfdlkvDFLVW8L8ZZHKikttR53U4UkvPd+iw8WRa3jqcfVbQ8hvGYhNpPoQWFq aReOYhaP0HDBMCViSkQ== X-Proofpoint-ORIG-GUID: LLZt6BPdI1g8_R9pvTBACHosjuOMXjhE X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 bulkscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 phishscore=0 suspectscore=0 adultscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Move definitions related to kvm feature handling to a separate header. Add flexibility through separation of concerns and allow sharing those definitions in the future. Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_emulate.h | 1 + arch/arm64/include/asm/kvm_feature.h | 93 ++++++++++++++++++++++ arch/arm64/include/asm/kvm_host.h | 84 ------------------- arch/arm64/include/asm/kvm_nested.h | 1 + arch/arm64/kvm/at.c | 1 + arch/arm64/kvm/config.c | 1 + arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 1 + arch/arm64/kvm/hyp/nvhe/hyp-main.c | 1 + arch/arm64/kvm/hyp/nvhe/sys_regs.c | 1 + arch/arm64/kvm/vgic/vgic.h | 1 + 10 files changed, 101 insertions(+), 84 deletions(-) create mode 100644 arch/arm64/include/asm/kvm_feature.h diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/= kvm_emulate.h index 41eac2b5de14..2cb8511baddc 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -16,6 +16,7 @@ =20 #include #include +#include #include #include #include diff --git a/arch/arm64/include/asm/kvm_feature.h b/arch/arm64/include/asm/= kvm_feature.h new file mode 100644 index 000000000000..8d0c65246aa0 --- /dev/null +++ b/arch/arm64/include/asm/kvm_feature.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ARM64_KVM_FEATURE_H__ +#define __ARM64_KVM_FEATURE_H__ + +#include +#include +#include + +#define __expand_field_sign_unsigned(id, fld, val) \ + ((u64)SYS_FIELD_VALUE(id, fld, val)) + +#define __expand_field_sign_signed(id, fld, val) \ + ({ \ + u64 __val =3D SYS_FIELD_VALUE(id, fld, val); \ + sign_extend64(__val, id##_##fld##_WIDTH - 1); \ + }) + +#define get_idreg_field_unsigned(kvm, id, fld) \ + ({ \ + u64 __val =3D kvm_read_vm_id_reg((kvm), SYS_##id); \ + FIELD_GET(id##_##fld##_MASK, __val); \ + }) + +#define get_idreg_field_signed(kvm, id, fld) \ + ({ \ + u64 __val =3D get_idreg_field_unsigned(kvm, id, fld); \ + sign_extend64(__val, id##_##fld##_WIDTH - 1); \ + }) + +#define get_idreg_field_enum(kvm, id, fld) \ + get_idreg_field_unsigned(kvm, id, fld) + +#define kvm_cmp_feat_signed(kvm, id, fld, op, limit) \ + (get_idreg_field_signed((kvm), id, fld) op __expand_field_sign_signed(id,= fld, limit)) + +#define kvm_cmp_feat_unsigned(kvm, id, fld, op, limit) \ + (get_idreg_field_unsigned((kvm), id, fld) op __expand_field_sign_unsigned= (id, fld, limit)) + +#define kvm_cmp_feat(kvm, id, fld, op, limit) \ + (id##_##fld##_SIGNED ? \ + kvm_cmp_feat_signed(kvm, id, fld, op, limit) : \ + kvm_cmp_feat_unsigned(kvm, id, fld, op, limit)) + +#define __kvm_has_feat(kvm, id, fld, limit) \ + kvm_cmp_feat(kvm, id, fld, >=3D, limit) + +#define kvm_has_feat(kvm, ...) __kvm_has_feat(kvm, __VA_ARGS__) + +#define __kvm_has_feat_enum(kvm, id, fld, val) \ + kvm_cmp_feat_unsigned(kvm, id, fld, =3D=3D, val) + +#define kvm_has_feat_enum(kvm, ...) __kvm_has_feat_enum(kvm, __VA_ARGS__) + +#define kvm_has_feat_range(kvm, id, fld, min, max) \ + (kvm_cmp_feat(kvm, id, fld, >=3D, min) && \ + kvm_cmp_feat(kvm, id, fld, <=3D, max)) + +/* Check for a given level of PAuth support */ +#define kvm_has_pauth(k, l) \ + ({ \ + bool pa, pi, pa3; \ + \ + pa =3D kvm_has_feat((k), ID_AA64ISAR1_EL1, APA, l); \ + pa &=3D kvm_has_feat((k), ID_AA64ISAR1_EL1, GPA, IMP); \ + pi =3D kvm_has_feat((k), ID_AA64ISAR1_EL1, API, l); \ + pi &=3D kvm_has_feat((k), ID_AA64ISAR1_EL1, GPI, IMP); \ + pa3 =3D kvm_has_feat((k), ID_AA64ISAR2_EL1, APA3, l); \ + pa3 &=3D kvm_has_feat((k), ID_AA64ISAR2_EL1, GPA3, IMP); \ + \ + (pa + pi + pa3) =3D=3D 1; \ + }) + +#define kvm_has_fpmr(k) \ + (system_supports_fpmr() && \ + kvm_has_feat((k), ID_AA64PFR2_EL1, FPMR, IMP)) + +#define kvm_has_tcr2(k) \ + (kvm_has_feat((k), ID_AA64MMFR3_EL1, TCRX, IMP)) + +#define kvm_has_s1pie(k) \ + (kvm_has_feat((k), ID_AA64MMFR3_EL1, S1PIE, IMP)) + +#define kvm_has_s1poe(k) \ + (system_supports_poe() && \ + kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP)) + +#define kvm_has_ras(k) \ + (kvm_has_feat((k), ID_AA64PFR0_EL1, RAS, IMP)) + +#define kvm_has_sctlr2(k) \ + (kvm_has_feat((k), ID_AA64MMFR3_EL1, SCTLRX, IMP)) + +#endif /* __ARM64_KVM_FEATURE_H__*/ diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 2db51746b4d8..4c2c62b8b506 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -1423,90 +1423,6 @@ static inline u64 *__vm_id_reg(struct kvm_arch *ka, = u32 reg) =20 void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); =20 -#define __expand_field_sign_unsigned(id, fld, val) \ - ((u64)SYS_FIELD_VALUE(id, fld, val)) - -#define __expand_field_sign_signed(id, fld, val) \ - ({ \ - u64 __val =3D SYS_FIELD_VALUE(id, fld, val); \ - sign_extend64(__val, id##_##fld##_WIDTH - 1); \ - }) - -#define get_idreg_field_unsigned(kvm, id, fld) \ - ({ \ - u64 __val =3D kvm_read_vm_id_reg((kvm), SYS_##id); \ - FIELD_GET(id##_##fld##_MASK, __val); \ - }) - -#define get_idreg_field_signed(kvm, id, fld) \ - ({ \ - u64 __val =3D get_idreg_field_unsigned(kvm, id, fld); \ - sign_extend64(__val, id##_##fld##_WIDTH - 1); \ - }) - -#define get_idreg_field_enum(kvm, id, fld) \ - get_idreg_field_unsigned(kvm, id, fld) - -#define kvm_cmp_feat_signed(kvm, id, fld, op, limit) \ - (get_idreg_field_signed((kvm), id, fld) op __expand_field_sign_signed(id,= fld, limit)) - -#define kvm_cmp_feat_unsigned(kvm, id, fld, op, limit) \ - (get_idreg_field_unsigned((kvm), id, fld) op __expand_field_sign_unsigned= (id, fld, limit)) - -#define kvm_cmp_feat(kvm, id, fld, op, limit) \ - (id##_##fld##_SIGNED ? \ - kvm_cmp_feat_signed(kvm, id, fld, op, limit) : \ - kvm_cmp_feat_unsigned(kvm, id, fld, op, limit)) - -#define __kvm_has_feat(kvm, id, fld, limit) \ - kvm_cmp_feat(kvm, id, fld, >=3D, limit) - -#define kvm_has_feat(kvm, ...) __kvm_has_feat(kvm, __VA_ARGS__) - -#define __kvm_has_feat_enum(kvm, id, fld, val) \ - kvm_cmp_feat_unsigned(kvm, id, fld, =3D=3D, val) - -#define kvm_has_feat_enum(kvm, ...) __kvm_has_feat_enum(kvm, __VA_ARGS__) - -#define kvm_has_feat_range(kvm, id, fld, min, max) \ - (kvm_cmp_feat(kvm, id, fld, >=3D, min) && \ - kvm_cmp_feat(kvm, id, fld, <=3D, max)) - -/* Check for a given level of PAuth support */ -#define kvm_has_pauth(k, l) \ - ({ \ - bool pa, pi, pa3; \ - \ - pa =3D kvm_has_feat((k), ID_AA64ISAR1_EL1, APA, l); \ - pa &=3D kvm_has_feat((k), ID_AA64ISAR1_EL1, GPA, IMP); \ - pi =3D kvm_has_feat((k), ID_AA64ISAR1_EL1, API, l); \ - pi &=3D kvm_has_feat((k), ID_AA64ISAR1_EL1, GPI, IMP); \ - pa3 =3D kvm_has_feat((k), ID_AA64ISAR2_EL1, APA3, l); \ - pa3 &=3D kvm_has_feat((k), ID_AA64ISAR2_EL1, GPA3, IMP); \ - \ - (pa + pi + pa3) =3D=3D 1; \ - }) - -#define kvm_has_fpmr(k) \ - (system_supports_fpmr() && \ - kvm_has_feat((k), ID_AA64PFR2_EL1, FPMR, IMP)) - -#define kvm_has_tcr2(k) \ - (kvm_has_feat((k), ID_AA64MMFR3_EL1, TCRX, IMP)) - -#define kvm_has_s1pie(k) \ - (kvm_has_feat((k), ID_AA64MMFR3_EL1, S1PIE, IMP)) - -#define kvm_has_s1poe(k) \ - (system_supports_poe() && \ - kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP)) - -#define kvm_has_ras(k) \ - (kvm_has_feat((k), ID_AA64PFR0_EL1, RAS, IMP)) - -#define kvm_has_sctlr2(k) \ - (kvm_has_feat((k), ID_AA64MMFR3_EL1, SCTLRX, IMP)) - static inline bool kvm_arch_has_irq_bypass(void) { return true; diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/k= vm_nested.h index dc2957662ff2..5da9ffae4f73 100644 --- a/arch/arm64/include/asm/kvm_nested.h +++ b/arch/arm64/include/asm/kvm_nested.h @@ -5,6 +5,7 @@ #include #include #include +#include #include =20 static inline bool vcpu_has_nv(const struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c index 9f8f0ae8e86e..ae91734dde37 100644 --- a/arch/arm64/kvm/at.c +++ b/arch/arm64/kvm/at.c @@ -7,6 +7,7 @@ #include =20 #include +#include #include #include #include diff --git a/arch/arm64/kvm/config.c b/arch/arm64/kvm/config.c index 0622162b089e..014fe04daabf 100644 --- a/arch/arm64/kvm/config.c +++ b/arch/arm64/kvm/config.c @@ -6,6 +6,7 @@ =20 #include #include +#include #include #include =20 diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hy= p/include/hyp/sysreg-sr.h index a17cbe7582de..dd824096dfc1 100644 --- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include =20 diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 06db299c37a8..3e5c9107d78f 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/s= ys_regs.c index 8c3fbb413a06..b5a0de84ce01 100644 --- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c @@ -7,6 +7,7 @@ #include =20 #include +#include #include =20 #include diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index 9d941241c8a2..b275d3cabe21 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -6,6 +6,7 @@ #define __KVM_ARM_VGIC_NEW_H__ =20 #include +#include #include =20 #define PRODUCT_ID_KVM 0x4b /* ASCII code K */ --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 33BD43F9276; Fri, 29 May 2026 15:56:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070190; cv=none; b=dL9pNymZKHMV/Jni5V2vfgUCuS040TcAzgOw5qE8RUjr8xoCWsxXQ1uCXbfpGA04Hx0X3AfnBmxYUCuOD0/fR1R81xeLz5Ra+295l7CPGB+NY//HcWetZBLlmhlgO5sfIOQ/HbKDYlF2wleGCjdqpwF30wPi6tp4rME6I1VaUX0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070190; c=relaxed/simple; bh=tjuJSvy87A6cVWbudTYOVPxNt1QdD+XhxSPmslH9XQk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MKCPiHrnx9XmQnG+KKnmAnBlVqxbYc7g9YB14Q3e36YWhn2jmxDa9vNjgZ8PnGJKjK6lPtLPKXuS8o103973WcNJMFpNlU4NQASVzTEyW8ywAL4nI8geHT43MxVQWQWu8vKy+Lz8E2I4Gx/ceM78FXVGZQAKAewZaqGHJZBdOsc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=AXNGdUch; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="AXNGdUch" Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFZ5hW1684858; Fri, 29 May 2026 15:56:10 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=7WJoSNxNCqAD1yMb5 BggkCxNMBPVI9mELDSocM+HPU8=; b=AXNGdUchGt+EKII8ibBc0IXKzgVrMYHGu 15IpxwrKwCf73UDiZulwisrnJGqJEQ/+cocWakBSIScC6qHRvYKEND9H0v6odc0/ u4/Ax25rM0CkYYdx994iBFfG3r8vykVl3gneL7cTCq7dztU6gvrXtnn9NL3pm9Ku lRhfXngAmVhhe9RxsWKMBPChiz6ggz9ue2IKplQzAl1KM30baWoLyOUYZaKoQjvk InXRhsKdHimdbEHHveqAT/dkYSqt7gp1iaKvlVxQSDbjy1d5+c6tKSqJFuUHJuLd v7mAfTWw5r1xwGhiMaSw6kchafITj1AecWmM5FImUVpjDTfT0cKOA== Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884mh3w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:10 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs9LN029222; Fri, 29 May 2026 15:56:09 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgkns-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu3aN41877916 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:03 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1577620040; Fri, 29 May 2026 15:56:03 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BD2D42004B; Fri, 29 May 2026 15:56:02 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:02 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 02/26] KVM: arm64: Remove __expand_field_sign_(un)signed Date: Fri, 29 May 2026 17:55:35 +0200 Message-ID: <20260529155601.2927240-3-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=fIYJG5ae c=1 sm=1 tr=0 ts=6a19b71a cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=8GpaujLIwWfsa4wt0MAA:9 X-Proofpoint-ORIG-GUID: 3I44r_DIBytvrXZTWkT_uTU1h5rmPzRk X-Proofpoint-GUID: 3I44r_DIBytvrXZTWkT_uTU1h5rmPzRk X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX1KhKBwY2gvl2 t/NYK0TgB5NS37wysRV+k4on33aX+pB9kji43Wr2RbAdV+dEY4lg8OVfgh5sqk34D5bmE/7eo68 ssrMD5nl0twm65zxGLHszNqeJbkaaqSQYcPL5k7HejuWlwXyG3zZ7VWNdzp2OLDsZhP9QZHYC52 LlS7c7Ap/6+BsoJkCd/ANZtIc4Sos3OvsffJGAw2GlTpchRWJGMGwqiIBCFCiFSH0ejKv+hcQcy Kq3md6GF8P7vtn/MQLlqeN/IaaJV0dquFRGNzmiCbNiJwj24Ccpi5CWprxlr866Gw5w50wIY2XX BGP2MQ1iNEKiyXaSlRbYcxS2LYH0Ao+cuJwlNNty/lTgGY4WscfyZyObXAfEyLAGdspfHTDInCS rYpQluYFQuXbiM2XEgjK5SGvmzBjb9LWLvd9GfWoxrCckucTQyxIut3Lo1RKA9N4tFMyvCth9xP Q0/bzea+peapDHh2IKg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 adultscore=0 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" __expand_field_sign_unsigned is a very small abstraction that makes it harder to see what's happening when looking at the caller. Just inline it. Create a macro S64_SYS_FIELD_VALUE that is a sign extended SYS_FIELD_VALUE. Then also get rid of __expand_field_sign_signed. Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_feature.h | 13 ++----------- include/arch/arm64/asm/sysreg-defs.h | 8 ++++++++ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/arch/arm64/include/asm/kvm_feature.h b/arch/arm64/include/asm/= kvm_feature.h index 8d0c65246aa0..d580f4ffab34 100644 --- a/arch/arm64/include/asm/kvm_feature.h +++ b/arch/arm64/include/asm/kvm_feature.h @@ -6,15 +6,6 @@ #include #include =20 -#define __expand_field_sign_unsigned(id, fld, val) \ - ((u64)SYS_FIELD_VALUE(id, fld, val)) - -#define __expand_field_sign_signed(id, fld, val) \ - ({ \ - u64 __val =3D SYS_FIELD_VALUE(id, fld, val); \ - sign_extend64(__val, id##_##fld##_WIDTH - 1); \ - }) - #define get_idreg_field_unsigned(kvm, id, fld) \ ({ \ u64 __val =3D kvm_read_vm_id_reg((kvm), SYS_##id); \ @@ -31,10 +22,10 @@ get_idreg_field_unsigned(kvm, id, fld) =20 #define kvm_cmp_feat_signed(kvm, id, fld, op, limit) \ - (get_idreg_field_signed((kvm), id, fld) op __expand_field_sign_signed(id,= fld, limit)) + (get_idreg_field_signed((kvm), id, fld) op S64_SYS_FIELD_VALUE(id, fld, l= imit)) =20 #define kvm_cmp_feat_unsigned(kvm, id, fld, op, limit) \ - (get_idreg_field_unsigned((kvm), id, fld) op __expand_field_sign_unsigned= (id, fld, limit)) + (get_idreg_field_unsigned((kvm), id, fld) op (u64)SYS_FIELD_VALUE(id, fld= , limit)) =20 #define kvm_cmp_feat(kvm, id, fld, op, limit) \ (id##_##fld##_SIGNED ? \ diff --git a/include/arch/arm64/asm/sysreg-defs.h b/include/arch/arm64/asm/= sysreg-defs.h index 27646c91e15c..3e280d4156ce 100644 --- a/include/arch/arm64/asm/sysreg-defs.h +++ b/include/arch/arm64/asm/sysreg-defs.h @@ -998,9 +998,17 @@ =20 #ifndef __ASSEMBLER__ #include +#include +#include =20 #define SYS_FIELD_VALUE(reg, field, val) reg##_##field##_##val =20 +#define S64_SYS_FIELD_VALUE(id, fld, val) \ + ({ \ + u64 __val =3D SYS_FIELD_VALUE(id, fld, val); \ + sign_extend64(__val, id##_##fld##_WIDTH - 1); \ + }) + #define SYS_FIELD_GET(reg, field, val) \ FIELD_GET(reg##_##field##_MASK, val) =20 --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 179003FB07F; Fri, 29 May 2026 15:56:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070194; cv=none; b=TcgDdimXZ9DlSqx3oHMh5SNyJgMG5mwjbWy0Pr6i25638wQliAD3qbRqjv/dO0zpsJ2wCE2upfozR05Kjt4Y2t0Jr9K2Dvfa0Zcxmg8ySXLFRANQt6iW4KD+h8+/5+SIsFcrf0juTZhTJlniBkroITy8o1JJGEFH1SV5cBkQJsA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070194; c=relaxed/simple; bh=Qi+J57+Zfp1XErQQdrCLh3UBuVWDZKgF4zxzj0KQAxQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fBMA8tJTMz4vE/duMSNXDkiWMATMJJ+ORo4tnPzSshCuRWy1+QpmqKks7qe/K2948lWvBEMR9UUCtSgqcPZUn9iGVxpst9zfOs02sQWDLRwJ79q+wO9gwHNJAoOzCARX5o+c1fd8D0WZ2U+l1PMjB8+EktYYcmzmc8V2wyGAeLk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=g6b1nInc; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="g6b1nInc" Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TF5i9E2418034; Fri, 29 May 2026 15:56:11 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=ZtdNOjsS5e1+chG/S OEjXZHnwNU0fc8NOy7/AKFWsBU=; b=g6b1nIncytF7I5499HWr1yrq1R/EY6xyr TpedGbyJUFiQuSiP5dHBcTGVkd2NTw0gC1p9DisYRdfu0ZIeaHZ3GcBZaxE5oB0e pJSgUV2YjM/XhEc9/2f4qIk1Go/6oV2DIasxS5xEw/TCF7WpHDUmggpcmHYdHlOR cCfC4rSh6pi1VhhDK9daGQVM8QZkD6WJsiX7qDnf56S2PBPigi60gYxGjkAF6aWl 9CBbAlmdURPPpo8/WmXDqpo6z2N/gs+sZMRwE2JoPrs9QI3iWyXg9hyASMgpnhYD 0wxREnxZGzLUcP/WOvTbs7B7tO8OT7kEmYM5vdGD1UTelTZD7xyiw== Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884vkmn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:10 +0000 (GMT) Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs5Dd003155; Fri, 29 May 2026 15:56:09 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgm7r-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu3Dc41877920 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:03 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6A71F20040; Fri, 29 May 2026 15:56:03 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1E7BE2004D; Fri, 29 May 2026 15:56:03 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:03 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 03/26] KVM: arm64: Generalize get_idreg_field_*() Date: Fri, 29 May 2026 17:55:36 +0200 Message-ID: <20260529155601.2927240-4-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=L4MtheT8 c=1 sm=1 tr=0 ts=6a19b71a cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=VnNF1IyMAAAA:8 a=Qz9-bC73Ewa-9BkP4PUA:9 X-Proofpoint-ORIG-GUID: Y8uUbAKDXN_ID0QggIym4anEE5667k0U X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfXyDiYpjBYGR3M 8DzHC0YkcfkpvmaUG1sT7vzwzaTmojweT/MfINdf7VZOBWRVmf/u5NKJP8eytk1Ik4rkGaB4gjO bHT1XNig42Hc3gdqFs3u/2vz9VjmRurEOyBE1DHvrQI7pgS/6joLKTF0hfjUtpvgu16YoUqS4Vy vjPGySXjkiE1po+O9TKyfJcaylw8f3fpskeXclADc7fZfElKxbWvSaN5V2decooYIDkgccuwOp6 KJu3KTwBlx2igMhoxqWhP3N/mxU5IKEffO04xfPzRUAYd2auxb7/pUqdCAjb1CJAZNDwFMROLT/ AN/JvehoyYHHXM01P5J06qKaAnQUEO0LBT/cdpXvudkrOGB3xzglfZyh0peYG14wB2WftzuZ0KJ cEHw+PwrIH1xIYEF93C9EUF48stwT2sLAtENSqXkdxN0MwWKh0YjbW9uuwWw/i8BP2WMaMup+A5 dXrgRLxIFCCVavQW2XA== X-Proofpoint-GUID: Y8uUbAKDXN_ID0QggIym4anEE5667k0U X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 clxscore=1015 malwarescore=0 bulkscore=0 impostorscore=0 adultscore=0 priorityscore=1501 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Introduce intermediate macros that extract the value from a passed parameter instead of reading the VM's ID register. Allow using other sources of ID register values, i.e. read directly from the hardware or during a sequence of sanitization steps. Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_feature.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/kvm_feature.h b/arch/arm64/include/asm/= kvm_feature.h index d580f4ffab34..067550d5b208 100644 --- a/arch/arm64/include/asm/kvm_feature.h +++ b/arch/arm64/include/asm/kvm_feature.h @@ -6,20 +6,23 @@ #include #include =20 -#define get_idreg_field_unsigned(kvm, id, fld) \ - ({ \ - u64 __val =3D kvm_read_vm_id_reg((kvm), SYS_##id); \ - FIELD_GET(id##_##fld##_MASK, __val); \ - }) +#define extract_id_field_unsigned(val, id, fld) \ + (FIELD_GET(id##_##fld##_MASK, (val))) =20 -#define get_idreg_field_signed(kvm, id, fld) \ +#define extract_id_field_signed(val, id, fld) \ ({ \ - u64 __val =3D get_idreg_field_unsigned(kvm, id, fld); \ + u64 __val =3D extract_id_field_unsigned((val), id, fld); \ sign_extend64(__val, id##_##fld##_WIDTH - 1); \ }) =20 +#define get_idreg_field_unsigned(kvm, id, fld) \ + extract_id_field_unsigned(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld) + +#define get_idreg_field_signed(kvm, id, fld) \ + extract_id_field_signed(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld) + #define get_idreg_field_enum(kvm, id, fld) \ - get_idreg_field_unsigned(kvm, id, fld) + extract_id_field_unsigned(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld) =20 #define kvm_cmp_feat_signed(kvm, id, fld, op, limit) \ (get_idreg_field_signed((kvm), id, fld) op S64_SYS_FIELD_VALUE(id, fld, l= imit)) --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 0350E3FF884; Fri, 29 May 2026 15:56:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070200; cv=none; b=R3UKQOrwOXT1wZ5fP2mz3+tqLFWJWKfYWsrXQrVt46yzBFPYCwUWD/HaPpqXm+Q8WLhqaVAyKWxofJwXPgXoR5h+YNHtrOwMu3xu2pBm9wztKnggOBmqMqm7QPkg2Q/97acJ0hk1nj3FUQLKMD4GxD06Z0CuvyBoZDevtN11sNU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070200; c=relaxed/simple; bh=tDUPaKRpTyz68q1SoICI7EnRFiMWtlFnRYt/3QcOi/Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hvsurbAwFO8hPFfO8hY+1lBcd0xqTTRRCaSuH2sH0KcOrV391J7NW3hAu8G78MPXDa9GhikadSu+fyGp1Jr5SDMRS3beZndUYxqd7ICy36ALDM0ooa3040LjjefoBsHonLo4zypTlaDsWUl4xL5yTUEDvICmT/HHVJMveB/AKVs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=aBTU/fwY; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="aBTU/fwY" Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFDvEC1684674; Fri, 29 May 2026 15:56:12 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=o53yR+CaUtzV3aGfV +UvVE5sv2cSNRU3xdbCbsPiryg=; b=aBTU/fwYfHFuJOD9btnZkqgs2CiCERqAO HC53TWBgkABRCRPjBuIkMQwijjNSuZGPef6WuebDm+o7NYPYlwhOgWe6THlxpUK8 swF7xL7ZeBxdYsteAInsFl7MtWF94QSrT2Za9kgq7xWcxPIB2V52c+g9Rh4VQP+2 tFSxSGfTKtinj7aW/1XVUiVu9POtEU2gIQdXIn/4UPfUfMPO+bHHCi/1LZrCOUg5 uzXM6+rd8SmK982SbVh5P1NV7IZBX3RNXAb4sl6+KRRpNoiONL/pw4vh2hdvu3Pl o7e0BSYtYh2j2X3PxVJ0zpz4oNIK5jtVGqfNcbWvKet025amyZFlA== Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884mh52-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:12 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs5HY016958; Fri, 29 May 2026 15:56:11 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgjng-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:11 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu3YE41877922 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:04 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C409C20040; Fri, 29 May 2026 15:56:03 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 77A822004B; Fri, 29 May 2026 15:56:03 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:03 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 04/26] KVM: arm64: Generalize kvm_cmp_feat_*() Date: Fri, 29 May 2026 17:55:37 +0200 Message-ID: <20260529155601.2927240-5-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=fIYJG5ae c=1 sm=1 tr=0 ts=6a19b71c cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=_j3w4fkP5V9tGIP_pu8A:9 X-Proofpoint-ORIG-GUID: LwKL746gUuzqFOb_cvnxjsPLxtZNxuA6 X-Proofpoint-GUID: LwKL746gUuzqFOb_cvnxjsPLxtZNxuA6 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfXx7ll/KPOg9Zh qKwcPJ1vxRGBqw1V7I37q1tG2FZG8gbYHjnuMPcnybFBgttruvnxyEsvrccF5xa3gDCVEpzKDad 55gUaOlL65YNEL4ub+66bU1in1bNGLrYm7l/RczFcAd1vWyIbiuYHWTXwo5a5YKyhuv6qfH9TgV w3THlYphBhrh2fI56cPnquEZrG9LaGqeMDrumy6JuLZWdMH7pbdAqyVwDlPhrACnkeKUbhc4AKp XE+zQ8kWDJZrr6+poTo00g+mDG6NsDWwdeU2jQIbGyHSbdnjwCZcAV8cU4RImS/FzKYf6Wsn0Nr XTM1XFlnVPxpXIT+ayCRoTUVz6lXydeFi9lwnsiOmBZszVyz+lxUdyzoAWNpey6HX1AGJS4N7Ys ruW0A+B9k9Bmcygj305loQh7W0y4GTZvfsMmWmLTu9ZjKn4bwyil5fxeq32bhnwiUup2nC9xPD5 UcXXS9n1Ps/YV0wzDSQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 adultscore=0 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Introduce an intermediate macro that extracts the value from a passed parameter instead of reading the VM's ID register. Allow using other sources of ID register values, i.e. read directly from the hardware or during a sequence of sanitization steps. Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_feature.h | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kvm_feature.h b/arch/arm64/include/asm/= kvm_feature.h index 067550d5b208..6dd7b4a4929c 100644 --- a/arch/arm64/include/asm/kvm_feature.h +++ b/arch/arm64/include/asm/kvm_feature.h @@ -15,6 +15,17 @@ sign_extend64(__val, id##_##fld##_WIDTH - 1); \ }) =20 +#define cmp_id_feat_signed(val, id, fld, op, limit) \ + (extract_id_field_signed((val), id, fld) op S64_SYS_FIELD_VALUE(id, fld, = limit)) + +#define cmp_id_feat_unsigned(val, id, fld, op, limit) \ + (extract_id_field_unsigned((val), id, fld) op (u64)SYS_FIELD_VALUE(id, fl= d, limit)) + +#define cmp_id_feat(val, id, fld, op, limit) \ + (id##_##fld##_SIGNED ? \ + cmp_id_feat_signed(val, id, fld, op, limit) : \ + cmp_id_feat_unsigned(val, id, fld, op, limit)) + #define get_idreg_field_unsigned(kvm, id, fld) \ extract_id_field_unsigned(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld) =20 @@ -25,15 +36,13 @@ extract_id_field_unsigned(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld) =20 #define kvm_cmp_feat_signed(kvm, id, fld, op, limit) \ - (get_idreg_field_signed((kvm), id, fld) op S64_SYS_FIELD_VALUE(id, fld, l= imit)) + cmp_id_feat_signed(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, op, limi= t) =20 #define kvm_cmp_feat_unsigned(kvm, id, fld, op, limit) \ - (get_idreg_field_unsigned((kvm), id, fld) op (u64)SYS_FIELD_VALUE(id, fld= , limit)) + cmp_id_feat_unsigned(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, op, li= mit) =20 #define kvm_cmp_feat(kvm, id, fld, op, limit) \ - (id##_##fld##_SIGNED ? \ - kvm_cmp_feat_signed(kvm, id, fld, op, limit) : \ - kvm_cmp_feat_unsigned(kvm, id, fld, op, limit)) + cmp_id_feat(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, op, limit) =20 #define __kvm_has_feat(kvm, id, fld, limit) \ kvm_cmp_feat(kvm, id, fld, >=3D, limit) --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 A0858406278; Fri, 29 May 2026 15:56:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070205; cv=none; b=WRY1CkE7f8ENhqyYLPtdzqLfiNKkHazA9erYKb/nLyraGtcmkzFTjA073yUzCcG0fZErLYxC28xFTmoUXYuE9WcQq+QaspuwfEqM3iYySmwydeCC0SeXObWEzm+C/d7SWpB0V+d4IQL+11XHMrn9rSvRZu2vBQHeKlTapQni/pc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070205; c=relaxed/simple; bh=HDAWQbPbqsKVts76IWz2G5ZvfWRnka9qLwysJOQbLQ4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Kedeffzm2+vsTieOmDv3oYsNg6hvdkn0trJy0MEwSuVsmAf0P86uWet/9wM3rB5Jnm3mmS+/b2B5Afx7AqogLSfd4uXSC9fR3eX/QPvlgxu7G4l7lb06rVIdHuKBX/oURcANtlmI/bNDSBpFQ3ptSc4lcWgjMTvdyR+B4buLMe8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=UpzwAVFB; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="UpzwAVFB" Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TF6ZrS2133949; Fri, 29 May 2026 15:56:14 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=ljBGB7KNBcV4js4AR cAzKk20xu/gcYobP0fAzwBLxO4=; b=UpzwAVFBQLF+gdifZpeiTX/DHEiNgtZqo kyqKhAwAxggW851r5n6xNQyE82hvmfM0NLx1TRsffeCO/JD7TyB9/wBmS0kSNaMA KNODtAcHgMVzC9ZRxJNmKW9UsvYm6604U18KqSW/7op+Bln/aMWUzTgv78fimYge UqVe0QQoY+jwrNm1p62zL6yMuOS73Wpq771rTFIOb1jqqgocBZxQmfC3+nSeBsMB cJKaagda22ZAHMeY8Pj/X9MIf4lSbFfDQftkk+bNhr8e0s07tSpVMWzWO83f2spe Vu2XuNLxquPHoee/3Aoh99tIaavIB9c5yr8FWLi/wQGpBu3DFMPBQ== Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee887v3v6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:14 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs7n3023023; Fri, 29 May 2026 15:56:14 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrc0k29-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu4qw16187694 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:04 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 259A920040; Fri, 29 May 2026 15:56:04 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CE58D2004D; Fri, 29 May 2026 15:56:03 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:03 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 05/26] KVM: arm64: Generalize kvm_has_feat_* Date: Fri, 29 May 2026 17:55:38 +0200 Message-ID: <20260529155601.2927240-6-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=QLJYgALL c=1 sm=1 tr=0 ts=6a19b71e cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=_j3w4fkP5V9tGIP_pu8A:9 X-Proofpoint-GUID: pjTP7KJw7SCX0_U55yppFHYCNLoNtDUQ X-Proofpoint-ORIG-GUID: pjTP7KJw7SCX0_U55yppFHYCNLoNtDUQ X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX6V5nzLMy5oqZ givv/kpikfps64HDzkuYJMwm24WuhYZrue3RNXGoYhzBUU5Iyj9hR5SM3uOzxDf1V+rwIOEiv5b EgVPvjOgEdWVMFy/bawWtKBfmXpjEYRZhhAshn080uNe3rb71JfAuXe4F/qgWdTK3xPxjUwYUJt NbvBEfm0jhFYtZ9l9cyEhujKJEkAQHCuF40uilN7TOEehuStJ49rnx7pi/k/f3b+jHeRQZekGIn 9zvCu2/Jo8X+m3gS/inHV3951jbha/CFy6boFTXzbyiqJshNRdbSpzEJybPBJ1K8QYRqoSKwNrm v833snpklKzJtDu3NqEAKF1MwMelE0AdPvt8K+VFKHCBaDNVY0xgLUiD6VEP+LDTjeA7dpvIUr9 +pVJVvfpYuYrhFMnIWOST2OmDuh3bTSa7094eOP9oRgVzdDvO+f4DrBxAbhOZkZk/tLiMLDqXeV SELU6JrsMU8t+s3YTJg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 impostorscore=0 malwarescore=0 adultscore=0 lowpriorityscore=0 phishscore=0 clxscore=1015 priorityscore=1501 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Introduce an intermediate macro that extracts the value from a passed parameter instead of reading the VM's ID register. Allow using other sources of ID register values, i.e. read directly from the hardware or during a sequence of sanitization steps. Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_feature.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/kvm_feature.h b/arch/arm64/include/asm/= kvm_feature.h index 6dd7b4a4929c..b627696ac648 100644 --- a/arch/arm64/include/asm/kvm_feature.h +++ b/arch/arm64/include/asm/kvm_feature.h @@ -26,6 +26,16 @@ cmp_id_feat_signed(val, id, fld, op, limit) : \ cmp_id_feat_unsigned(val, id, fld, op, limit)) =20 +#define id_has_feat(val, id, fld, limit) \ + cmp_id_feat(val, id, fld, >=3D, limit) + +#define id_has_feat_enum(val, id, fld, variant) \ + cmp_id_feat_unsigned(val, id, fld, =3D=3D, variant) + +#define id_has_feat_range(val, id, fld, min, max) \ + (cmp_id_feat(val, id, fld, >=3D, min) && \ + cmp_id_feat(val, id, fld, <=3D, max)) + #define get_idreg_field_unsigned(kvm, id, fld) \ extract_id_field_unsigned(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld) =20 @@ -45,18 +55,17 @@ cmp_id_feat(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, op, limit) =20 #define __kvm_has_feat(kvm, id, fld, limit) \ - kvm_cmp_feat(kvm, id, fld, >=3D, limit) + id_has_feat(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, limit) =20 #define kvm_has_feat(kvm, ...) __kvm_has_feat(kvm, __VA_ARGS__) =20 #define __kvm_has_feat_enum(kvm, id, fld, val) \ - kvm_cmp_feat_unsigned(kvm, id, fld, =3D=3D, val) + id_has_feat_enum(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, val) =20 #define kvm_has_feat_enum(kvm, ...) __kvm_has_feat_enum(kvm, __VA_ARGS__) =20 #define kvm_has_feat_range(kvm, id, fld, min, max) \ - (kvm_cmp_feat(kvm, id, fld, >=3D, min) && \ - kvm_cmp_feat(kvm, id, fld, <=3D, max)) + id_has_feat_range(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, min, max) =20 /* Check for a given level of PAuth support */ #define kvm_has_pauth(k, l) \ --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 26DB53FE358; Fri, 29 May 2026 15:56:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070198; cv=none; b=uB5D02o7IrqNugDAeawy/v8wMpPioT2cOicZTpGMLBGE9g7N/gUZn2GZBotlShl+9Fsbl5A3T4PlScXi/tUyIDqee/Aiu9zqqMLKTd+ax4kccweWR0HXdXtGE8CZnQfORkuDNdaC1x47cpeMG8YPHT5Fjys1GbEmT0jx5aMt1CQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070198; c=relaxed/simple; bh=duGQu2jfwKrEz5AtUFtktTOtLQqDhLn3V4YShFyx0n4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cp9IO1+bTaPa4bSkbd2ffas214NWSUtccEUsjF/3H/GT94lehFJZBcErrHVqjy1nrrgs4O22RmxrWRqjbIKcuyismJujNzi/dvspmZyKnKHVRltp1dSyO/+Gi2AaASttoxBhhU61EpKTv6mbvopHdi7OH16pf1FWSGFqhof/Bv0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=KX60PrKQ; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="KX60PrKQ" Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFBnER3215536; Fri, 29 May 2026 15:56:13 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=oli/0CpBrVw+C5kY4 hqojKRn9iZuZzYeBdWYURH49v0=; b=KX60PrKQ5W35puNXp8vVvBbLSC7fXlmGQ FRn7kFmMzyJBNmu3QXMv/Xb41RhcumsNLWsYWYLLdpADKT3R6UpTnHQy292ZV+df e6ImxcYcNUI4B/0eDd8c9U+sDmo/BH+/UWLSgEP0OgPiQZaYC3vdPHX3s5BboJOM ApZxSX61t6Acjh4H14Zc8NRch9zLsiNqLhKbvkObsxEmfpl8Y5qQdw2jmzehGAnA iGw21qI+bt10JZcedrXW3DsuNRiCmmcbkWOBMNJknLiuqL+7Hjb8E0/pBe8tzx5H omA/YyU0uZfF1llKmM6a27b7vhG6PUGjt/mEgEWg9Gt5rCJKg69Aw== Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee88bm2jn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:12 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs7LM009663; Fri, 29 May 2026 15:56:11 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgku1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:11 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu4rl16187696 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:04 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7B89820040; Fri, 29 May 2026 15:56:04 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2F6B02004B; Fri, 29 May 2026 15:56:04 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:04 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 06/26] KVM: arm64: Remove get_idreg_field_*() and kvm_cmp_feat_*() Date: Fri, 29 May 2026 17:55:39 +0200 Message-ID: <20260529155601.2927240-7-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX4MxL7Si8G3/U uLpH/XYmYvlUN4YzqxTSQaONYql/vI9JWZZbGBCBXvlYEkosDq5+S2+5N9rgwEr4DyJAJbOXxAV 5H21vjYL7wglHa2JYkKBIJDONSiIsKCVdGCgYMWWD910BC3MNRoEaO+F2B18SbOCBpaD2a6CKfy s2McYX2VWlzfGn+YLIx3+wm3cC/y7kGluAvoi6MjaxvB5f4aWcrBBKJJ5D+Mm1LB/XL1sQNwqU8 u3pWGkEcyI4Ys8BP4fa/fannc4HSMjBIJdlwelpsv6covbNhF5odajk7KHenoq6pTXHQAQYKdCm j0nTD9ZNIaFRgv3BwK9fcxz1xpSOA3v1zJd+5g9wrbtd0oksxOONzKATKQv6gz+U/+3B2mE7j4y ri5s5UpgjUq3CXGPv6HIdzCxEgte4Ksp/N9EHPxM2rsVJkP5aS96ZlJXJ5SXWLHfbTacynQIT9K M2/MMCGMFqlr7LNsFrw== X-Proofpoint-ORIG-GUID: gGyF-Vy7Mge0ZWxA2eii8UEGfWLcKPST X-Authority-Analysis: v=2.4 cv=IJEyzAvG c=1 sm=1 tr=0 ts=6a19b71c cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=h1Z8OaWvIKWV_s2n3WQA:9 X-Proofpoint-GUID: gGyF-Vy7Mge0ZWxA2eii8UEGfWLcKPST X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 phishscore=0 clxscore=1015 spamscore=0 bulkscore=0 adultscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" These macros are now unused after generalizing the feature detection code in the parent commit. The functionality is preserved through the new generalized macros that operate on register values directly. Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_feature.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/arch/arm64/include/asm/kvm_feature.h b/arch/arm64/include/asm/= kvm_feature.h index b627696ac648..da9ba5041f44 100644 --- a/arch/arm64/include/asm/kvm_feature.h +++ b/arch/arm64/include/asm/kvm_feature.h @@ -36,24 +36,6 @@ (cmp_id_feat(val, id, fld, >=3D, min) && \ cmp_id_feat(val, id, fld, <=3D, max)) =20 -#define get_idreg_field_unsigned(kvm, id, fld) \ - extract_id_field_unsigned(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld) - -#define get_idreg_field_signed(kvm, id, fld) \ - extract_id_field_signed(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld) - -#define get_idreg_field_enum(kvm, id, fld) \ - extract_id_field_unsigned(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld) - -#define kvm_cmp_feat_signed(kvm, id, fld, op, limit) \ - cmp_id_feat_signed(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, op, limi= t) - -#define kvm_cmp_feat_unsigned(kvm, id, fld, op, limit) \ - cmp_id_feat_unsigned(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, op, li= mit) - -#define kvm_cmp_feat(kvm, id, fld, op, limit) \ - cmp_id_feat(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, op, limit) - #define __kvm_has_feat(kvm, id, fld, limit) \ id_has_feat(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, limit) =20 --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 A954D3FB040; Fri, 29 May 2026 15:56:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070193; cv=none; b=TfO5+gk+/OgL/jksTIayeqcoLU1N+WdCZzIkiRLAOKrmWElMD7vxd/ZZYgrZArHr4CJ42o/Nhi+/4jO2HFt6FZylGdvIO+I7XtXODE8FT9CZOz/Ou6/3cL4BQgJTeo6pyVjXR+GKFOv12+E8633R+tm5ynNoLlsD/i5F1/GKX+U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070193; c=relaxed/simple; bh=86J4c4IDhkXcD+sXUJ3szi39ltTyhiRUK+PG6XXZDcc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dnqRGpy5juLM6J81WxVYQXqsAG4wKKQgyav/EUudytz3hHYQjkzYqDifVpPX+1TKKKF6XS8DQ3ag1UD9idAuxlxW3il3wrQaNO+fAScQCF5IBV93ZtnOvvRVQFdWV7lohUIKk/tEW3NL0NdKq6usVMRQPlmtgItqMi9TVf9vmac= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=V34lUfcp; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="V34lUfcp" Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFAXSC2419213; Fri, 29 May 2026 15:56:12 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=3/FkRX+SkHZmJLVfE SRkOboCdzcmTpr5KGDuU5B1jY4=; b=V34lUfcpaRVZPqVpvVs+sLOJLgO7gfRJ+ kLjFvhE+ysG946P89jOQOn+qoddOadzUGpB3v3/IDkrYxGjGcSW3JbO8ZFRp7M1U AbpK0G2b84n4SpJSGrkCioEo2Zi8hoQSuoLROclb7ft/mjNGDcqmWBWm1VH56nEz 4xQhC/YnXvSKQmMjjk7YwSeAtmDB4kYoPGJmN/edDOMCnrju08jfQa300PMKk3It 6hBxZbZ4g5tlOfXx0da5DWQdxVAI9xCwtPFyzxfR+wMlu5aS0pswlaE8z9mhEetX SvJeJsX5AJUTEuXpl84JK4wlY4XDpIur99sLkht/KLCtQTFFhgwTQ== Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884vknk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:12 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs814023079; Fri, 29 May 2026 15:56:11 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrc0k1r-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:11 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu4t616187700 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:05 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D1F6120040; Fri, 29 May 2026 15:56:04 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 865482004D; Fri, 29 May 2026 15:56:04 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:04 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 07/26] KVM: arm64: Remove kvm_has_feat_range Date: Fri, 29 May 2026 17:55:40 +0200 Message-ID: <20260529155601.2927240-8-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=L4MtheT8 c=1 sm=1 tr=0 ts=6a19b71c cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=VnNF1IyMAAAA:8 a=3-yqm4NPzKxgNXSuSH0A:9 X-Proofpoint-ORIG-GUID: iRKEu5XZGYdTQl1aubAOq9aFT057y5V6 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX8mTz7O9VCZFE R0XL99rl7E3yEfO2jUkeFCw65+CjRp4OtiyuZQ1D5P2YKaZ5EPpZvFlCGZr+o/HVLxaELK6D7Ze M0AtUF8VESpOJGbVIVny3zPZGSxbHohy/2AWVERM3iaFZoKVPDad7OUka8DmDmbvwXrteTCsGyf MQOx0qVS16L7/aughYsjRWDyG658HCwKaMl/024pux99SZ3aZoTC7E7tQFMCKdvdHnbvqy4JCdg NtzHTu32KWRqIwB9lvmn6xo7XXgoLSBDInAdOHbivz2jvi6Mv2hOqkcZ55OAUERGvQGQqiYA+Nb a/cia20Md2aMzdbkM62zv9QzcFe3OOFHP3WjG+f4ClqvLCHvZt5qE2ldnWJpd4oOC6d/1RH+wJ8 3BczdDf9r4VraVSDORZon4KkHF3EPgCb5J1zZNGEKxQJl1sMH9iptxmZXjV1sD4k7XdcMsrS3d1 swNwplc0CQkEp1ZfrCA== X-Proofpoint-GUID: iRKEu5XZGYdTQl1aubAOq9aFT057y5V6 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 clxscore=1015 malwarescore=0 bulkscore=0 impostorscore=0 adultscore=0 priorityscore=1501 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" It is (and has been) unused. Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_feature.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_feature.h b/arch/arm64/include/asm/= kvm_feature.h index da9ba5041f44..27a472d2343e 100644 --- a/arch/arm64/include/asm/kvm_feature.h +++ b/arch/arm64/include/asm/kvm_feature.h @@ -46,8 +46,6 @@ =20 #define kvm_has_feat_enum(kvm, ...) __kvm_has_feat_enum(kvm, __VA_ARGS__) =20 -#define kvm_has_feat_range(kvm, id, fld, min, max) \ - id_has_feat_range(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, min, max) =20 /* Check for a given level of PAuth support */ #define kvm_has_pauth(k, l) \ --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 CC41C3FDC18; Fri, 29 May 2026 15:56:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070198; cv=none; b=RFcQBfarH9g6ZWtDXmw90rlFjaQKC2C9saDlZJkL2UUw3pZsFP/ksENpC3MmkNHK7q3QZ3tdIIbfd7qZBrN7PJlTHnvuMXtfVYE9U2LQwZc8I9zV3KMHHsqQT8ctGTrBNKHFL6ZHkXBB830Ev98l6QNYFEbfMHQartDQfA52hTM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070198; c=relaxed/simple; bh=baq4cRKR9673AaG4M+ydRFk7OMtBI4huA/q4jzTaWRY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GQtGm8P9gTz5Eg1P0jXQY13vMLE8xZCB+ibcjj8yELghipXEAWbUuZ+N+a5Chh6vbzWkP7hyBzSoNNVUEn+PtEXD6kSrKIIR5XitnmPdpsEhXqhT0tyQ6O6HO3Pf5W+lmtQLNNWeT2wq3CdA1XnRE4Mz5kwbN+SogxcQ6nMORtM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=dLD7BOjw; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="dLD7BOjw" Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFHRqk3217155; Fri, 29 May 2026 15:56:13 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=jAH55rZkTvViU7aHU 2ThlI/tFiC7U75l7lFJ0ODKt4U=; b=dLD7BOjwsNSwrTXxjLa+wXYbOoDnsCowh gwhdgkAFxeOL1Zs01rCC/JCEeDBOd3hKT/Kuj8pdKLTFf562oHpga5DJvTXm/CJV 28hojkLH26TjDFFx050TXWHN5a047qjXabwmBaA5Ntyi9+Nt3DOvQDwfPEcgnQZL nsUT+daKGNpPoLQreYfjFHJZheR8mETgxQXh4in8Hb+//pPv2m5DocUTMHPowk/9 x2/u9967xkTL9sJYqS+oIIAdgo8pn5e8MNN8W1tEKfaFlhYTloNuOqgQWD5vz/uZ +ERPJzukHyV+PI+1eUIyxShLjGGnksRacyG56sWSt883f9u/B4+CQ== Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee88bm2jt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:12 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs7ah009677; Fri, 29 May 2026 15:56:12 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgkua-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:11 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu58142205502 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:05 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3E3DD20040; Fri, 29 May 2026 15:56:05 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DBC372004B; Fri, 29 May 2026 15:56:04 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:04 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 08/26] KVM: arm64: Split up feature sysreg sanitisation Date: Fri, 29 May 2026 17:55:41 +0200 Message-ID: <20260529155601.2927240-9-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX2dMs4exigRHo h1N3uP2ic/tjvpD55Tuk34/BiQEu2cXz6QYNyT8goHv5c+iBM0N+xrLr66gt30+wnpJ5AqoWAWA 56xSJDB0D+km5gnSbGm2raeLrWngmw/FF2fiMcX72OtQZpqX3Pe07EAFFD3qdPWJMpNl7mMBSxM SJNEtb5jSvArye7Lupc9zmWd/cMoDztiNXDTAI8dXhWdb4qHES8eBEb/koZQipxLXJu4Jy8zy17 GMyEP//LH4UpoI0WzOXFH4AXXs6//o+e9z9quiJtc+qS2VY4kNS7g2bwHOzI24YGzrh+aKCuJtH IqRYUJBrmbTMghz5FyX9RoVDERY8ZxJ+musOXu0/3+5cQ68ZQkntF46TAF2KuP5w01W6gpfGl+K xaX+eo7m12TiTZYe1jeu27ctFNGfEzdgW26qXpEEjJh0rz+IgLj8K6LL430LipdWnlcdiykL+MV FUeeGdqhNHS20qaAY+Q== X-Proofpoint-ORIG-GUID: wFvicD_RSdqEi-rRAAIp92c4cgx5IjOR X-Authority-Analysis: v=2.4 cv=IJEyzAvG c=1 sm=1 tr=0 ts=6a19b71c cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=r_tBfuKwx9rY2nSX5wQA:9 X-Proofpoint-GUID: wFvicD_RSdqEi-rRAAIp92c4cgx5IjOR X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 phishscore=0 clxscore=1015 spamscore=0 bulkscore=0 adultscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Split ID register sanitisation into distinct stages: 1) static KVM limits (kvm_max_possible_guest_ftr_reg) 2) host-specific (kvm_sanitised_host_ftr_reg) 3) per-vcpu configuration (kvm_sanitise_vcpu_ftr_reg) This refactoring improves code organization by separating concerns. Static limits apply regardless of host or guest configuration. Host capability checks handle features like GIC, GCIE, and Spectre mitigations. Per-vcpu feature configuration manages SVE, MTE, PMU, and similar guest-specific features. Additionally, this enables other architectures to add different host-implementation-based sanitisation in the future. Remove helper functions sanitise_id_aa64{pfr0,pfr1,dfr0}_el1 in favor of organized logic. Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- arch/arm64/kvm/sys_regs.c | 291 ++++++++++++++++++++------------------ 1 file changed, 153 insertions(+), 138 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 2434bcc2d50d..b9aa892616ab 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1841,54 +1841,86 @@ static u8 pmuver_to_perfmon(u8 pmuver) } } =20 -static u64 sanitise_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu, u64 val); -static u64 sanitise_id_aa64pfr1_el1(const struct kvm_vcpu *vcpu, u64 val); -static u64 sanitise_id_aa64pfr2_el1(const struct kvm_vcpu *vcpu, u64 val); -static u64 sanitise_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val); - -/* Read a sanitised cpufeature ID register by sys_reg_desc */ -static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) +/* + * Sanitise based on the host implementation. + */ +static u64 kvm_sanitised_host_ftr_reg(u32 id) { - u32 id =3D reg_to_encoding(r); - u64 val; - - if (sysreg_visible_as_raz(vcpu, r)) - return 0; - - val =3D read_sanitised_ftr_reg(id); + u64 val =3D read_sanitised_ftr_reg(id); =20 switch (id) { - case SYS_ID_AA64DFR0_EL1: - val =3D sanitise_id_aa64dfr0_el1(vcpu, val); + case SYS_ID_AA64ISAR2_EL1: + if (!cpus_have_final_cap(ARM64_HAS_WFXT) || + has_broken_cntvoff()) + val &=3D ~ID_AA64ISAR2_EL1_WFxT; break; case SYS_ID_AA64PFR0_EL1: - val =3D sanitise_id_aa64pfr0_el1(vcpu, val); + /* + * The default is to expose CSV2 =3D=3D 1 if the HW isn't affected. + * Although this is a per-CPU feature, we make it global because + * asymmetric systems are just a nuisance. + * + * Userspace can override this as long as it doesn't promise + * the impossible. + */ + if (arm64_get_spectre_v2_state() =3D=3D SPECTRE_UNAFFECTED) { + val &=3D ~ID_AA64PFR0_EL1_CSV2_MASK; + val |=3D SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, CSV2, IMP); + } + if (arm64_get_meltdown_state() =3D=3D SPECTRE_UNAFFECTED) { + val &=3D ~ID_AA64PFR0_EL1_CSV3_MASK; + val |=3D SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, CSV3, IMP); + } + if (vgic_host_has_gicv3()) { + val &=3D ~ID_AA64PFR0_EL1_GIC_MASK; + val |=3D SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, GIC, IMP); + } break; - case SYS_ID_AA64PFR1_EL1: - val =3D sanitise_id_aa64pfr1_el1(vcpu, val); + case SYS_ID_AA64PFR1_EL1: { + u64 pfr0_host =3D read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1); + + if (!(cpus_have_final_cap(ARM64_HAS_RASV1P1_EXTN) && + SYS_FIELD_GET(ID_AA64PFR0_EL1, RAS, pfr0_host) =3D=3D ID_AA64PFR0_= EL1_RAS_IMP)) + val &=3D ~ID_AA64PFR1_EL1_RAS_frac; break; + } case SYS_ID_AA64PFR2_EL1: - val =3D sanitise_id_aa64pfr2_el1(vcpu, val); + if (vgic_host_has_gicv5()) + val |=3D SYS_FIELD_PREP_ENUM(ID_AA64PFR2_EL1, GCIE, IMP); break; - case SYS_ID_AA64ISAR1_EL1: - if (!vcpu_has_ptrauth(vcpu)) - val &=3D ~(ID_AA64ISAR1_EL1_APA | - ID_AA64ISAR1_EL1_API | - ID_AA64ISAR1_EL1_GPA | - ID_AA64ISAR1_EL1_GPI); + case SYS_ID_AA64MMFR3_EL1: + if (!system_supports_poe()) + val &=3D ~ID_AA64MMFR3_EL1_S1POE; + break; + } + + return val; +} + +/* + * Statically sanitise the host's feature register, independent of the gue= st's + * configuration and host implementation. + */ +static u64 kvm_max_possible_guest_ftr_reg(u32 id, u64 val) +{ + switch (id) { + case SYS_ID_AA64DFR0_EL1: + val =3D ID_REG_LIMIT_FIELD_ENUM(val, ID_AA64DFR0_EL1, DebugVer, V8P8); + + /* Hide SPE from guests */ + val &=3D ~ID_AA64DFR0_EL1_PMSVer_MASK; + + /* Hide BRBE from guests */ + val &=3D ~ID_AA64DFR0_EL1_BRBE_MASK; break; case SYS_ID_AA64ISAR2_EL1: - if (!vcpu_has_ptrauth(vcpu)) - val &=3D ~(ID_AA64ISAR2_EL1_APA3 | - ID_AA64ISAR2_EL1_GPA3); - if (!cpus_have_final_cap(ARM64_HAS_WFXT) || - has_broken_cntvoff()) + /* Mask WFxT field unless *both* WFET & WFIT are present. */ + if (!id_has_feat(val, ID_AA64ISAR2_EL1, WFxT, IMP)) val &=3D ~ID_AA64ISAR2_EL1_WFxT; break; case SYS_ID_AA64ISAR3_EL1: val &=3D ID_AA64ISAR3_EL1_FPRCVT | ID_AA64ISAR3_EL1_LSFE | - ID_AA64ISAR3_EL1_FAMINMAX | ID_AA64ISAR3_EL1_LSUI; + ID_AA64ISAR3_EL1_FAMINMAX | ID_AA64ISAR3_EL1_LSUI; break; case SYS_ID_AA64MMFR2_EL1: val &=3D ~ID_AA64MMFR2_EL1_CCIDX_MASK; @@ -1899,13 +1931,81 @@ static u64 __kvm_read_sanitised_id_reg(const struct= kvm_vcpu *vcpu, ID_AA64MMFR3_EL1_SCTLRX | ID_AA64MMFR3_EL1_S1POE | ID_AA64MMFR3_EL1_S1PIE; - - if (!system_supports_poe()) - val &=3D ~ID_AA64MMFR3_EL1_S1POE; break; case SYS_ID_MMFR4_EL1: val &=3D ~ID_MMFR4_EL1_CCIDX; break; + case SYS_ID_AA64PFR0_EL1: + val &=3D ~ID_AA64PFR0_EL1_AMU_MASK; + /* + * MPAM is disabled by default as KVM also needs a set of PARTID to + * program the MPAMVPMx_EL2 PARTID remapping registers with. But some + * older kernels let the guest see the ID bit. + */ + val &=3D ~ID_AA64PFR0_EL1_MPAM_MASK; + break; + case SYS_ID_AA64PFR1_EL1: + 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; + val &=3D ~ID_AA64PFR1_EL1_MPAM_frac; + break; + case SYS_ID_AA64PFR2_EL1: + val &=3D ID_AA64PFR2_EL1_FPMR | + ID_AA64PFR2_EL1_MTEFAR | + ID_AA64PFR2_EL1_MTESTOREONLY; + break; + } + + return val; +} + +/* + * Sanitise based on vCPU configuration. + */ +static u64 kvm_sanitise_vcpu_ftr_reg(const struct kvm_vcpu *vcpu, u32 id, = u64 val) +{ + switch (id) { + case SYS_ID_AA64DFR0_EL1: + /* + * Only initialize the PMU version if the vCPU was configured with one. + */ + val &=3D ~ID_AA64DFR0_EL1_PMUVer_MASK; + if (kvm_vcpu_has_pmu(vcpu)) + val |=3D SYS_FIELD_PREP(ID_AA64DFR0_EL1, PMUVer, + kvm_arm_pmu_get_pmuver_limit()); + break; + case SYS_ID_AA64PFR0_EL1: + if (!vcpu_has_sve(vcpu)) + val &=3D ~ID_AA64PFR0_EL1_SVE_MASK; + break; + case SYS_ID_AA64PFR1_EL1: + if (!kvm_has_mte(vcpu->kvm)) { + val &=3D ~ID_AA64PFR1_EL1_MTE; + val &=3D ~ID_AA64PFR1_EL1_MTE_frac; + } + break; + case SYS_ID_AA64PFR2_EL1: + if (!kvm_has_mte(vcpu->kvm)) { + val &=3D ~ID_AA64PFR2_EL1_MTEFAR; + val &=3D ~ID_AA64PFR2_EL1_MTESTOREONLY; + } + break; + case SYS_ID_AA64ISAR1_EL1: + if (!vcpu_has_ptrauth(vcpu)) + val &=3D ~(ID_AA64ISAR1_EL1_APA | + ID_AA64ISAR1_EL1_API | + ID_AA64ISAR1_EL1_GPA | + ID_AA64ISAR1_EL1_GPI); + break; + case SYS_ID_AA64ISAR2_EL1: + if (!vcpu_has_ptrauth(vcpu)) + val &=3D ~(ID_AA64ISAR2_EL1_APA3 | + ID_AA64ISAR2_EL1_GPA3); } =20 if (vcpu_has_nv(vcpu)) @@ -1914,6 +2014,23 @@ static u64 __kvm_read_sanitised_id_reg(const struct = kvm_vcpu *vcpu, return val; } =20 +/* Read a sanitised cpufeature ID register by sys_reg_desc */ +static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + u32 id =3D reg_to_encoding(r); + u64 val; + + if (sysreg_visible_as_raz(vcpu, r)) + return 0; + + val =3D kvm_sanitised_host_ftr_reg(id); + val =3D kvm_max_possible_guest_ftr_reg(id, val); + val =3D kvm_sanitise_vcpu_ftr_reg(vcpu, id, val); + + return val; +} + static u64 kvm_read_sanitised_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { @@ -2046,108 +2163,6 @@ static unsigned int fp8_visibility(const struct kvm= _vcpu *vcpu, return REG_HIDDEN; } =20 -static u64 sanitise_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu, u64 val) -{ - if (!vcpu_has_sve(vcpu)) - val &=3D ~ID_AA64PFR0_EL1_SVE_MASK; - - /* - * The default is to expose CSV2 =3D=3D 1 if the HW isn't affected. - * Although this is a per-CPU feature, we make it global because - * asymmetric systems are just a nuisance. - * - * Userspace can override this as long as it doesn't promise - * the impossible. - */ - if (arm64_get_spectre_v2_state() =3D=3D SPECTRE_UNAFFECTED) { - val &=3D ~ID_AA64PFR0_EL1_CSV2_MASK; - val |=3D SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, CSV2, IMP); - } - if (arm64_get_meltdown_state() =3D=3D SPECTRE_UNAFFECTED) { - val &=3D ~ID_AA64PFR0_EL1_CSV3_MASK; - val |=3D SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, CSV3, IMP); - } - - if (vgic_host_has_gicv3()) { - val &=3D ~ID_AA64PFR0_EL1_GIC_MASK; - val |=3D SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, GIC, IMP); - } - - val &=3D ~ID_AA64PFR0_EL1_AMU_MASK; - - /* - * MPAM is disabled by default as KVM also needs a set of PARTID to - * program the MPAMVPMx_EL2 PARTID remapping registers with. But some - * older kernels let the guest see the ID bit. - */ - val &=3D ~ID_AA64PFR0_EL1_MPAM_MASK; - - return val; -} - -static u64 sanitise_id_aa64pfr1_el1(const struct kvm_vcpu *vcpu, u64 val) -{ - u64 pfr0 =3D read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1); - - if (!kvm_has_mte(vcpu->kvm)) { - val &=3D ~ID_AA64PFR1_EL1_MTE; - val &=3D ~ID_AA64PFR1_EL1_MTE_frac; - } - - if (!(cpus_have_final_cap(ARM64_HAS_RASV1P1_EXTN) && - SYS_FIELD_GET(ID_AA64PFR0_EL1, RAS, pfr0) =3D=3D ID_AA64PFR0_EL1_RA= S_IMP)) - val &=3D ~ID_AA64PFR1_EL1_RAS_frac; - - 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; - val &=3D ~ID_AA64PFR1_EL1_MPAM_frac; - - return val; -} - -static u64 sanitise_id_aa64pfr2_el1(const struct kvm_vcpu *vcpu, u64 val) -{ - val &=3D ID_AA64PFR2_EL1_FPMR | - ID_AA64PFR2_EL1_MTEFAR | - ID_AA64PFR2_EL1_MTESTOREONLY; - - if (!kvm_has_mte(vcpu->kvm)) { - val &=3D ~ID_AA64PFR2_EL1_MTEFAR; - val &=3D ~ID_AA64PFR2_EL1_MTESTOREONLY; - } - - if (vgic_host_has_gicv5()) - val |=3D SYS_FIELD_PREP_ENUM(ID_AA64PFR2_EL1, GCIE, IMP); - - return val; -} - -static u64 sanitise_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val) -{ - val =3D ID_REG_LIMIT_FIELD_ENUM(val, ID_AA64DFR0_EL1, DebugVer, V8P8); - - /* - * Only initialize the PMU version if the vCPU was configured with one. - */ - val &=3D ~ID_AA64DFR0_EL1_PMUVer_MASK; - if (kvm_vcpu_has_pmu(vcpu)) - val |=3D SYS_FIELD_PREP(ID_AA64DFR0_EL1, PMUVer, - kvm_arm_pmu_get_pmuver_limit()); - - /* Hide SPE from guests */ - val &=3D ~ID_AA64DFR0_EL1_PMSVer_MASK; - - /* Hide BRBE from guests */ - val &=3D ~ID_AA64DFR0_EL1_BRBE_MASK; - - return val; -} - /* * Older versions of KVM erroneously claim support for FEAT_DoubleLock with * NV-enabled VMs on unsupporting hardware. Silently ignore the incorrect --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 56F39400E16; Fri, 29 May 2026 15:56:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070203; cv=none; b=nGY30a7eZVJIN7WcSp6gxFCYqTvppk1JNxSbzG5rS8nzR5yUcVji3xAjeKxgcV/xedefvaWQSGWknM3xl1wJFxP5M53SDEfc3V8VJ6Qk9vCFzY9dfjVq7pwp7/q1A40DQs6eyx6iRepYwlmp26gzCAgPlRAp87M+rlGVd6DKpbQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070203; c=relaxed/simple; bh=GrNLXw87enQ8YyFIlPyIRnw07HBNMRfIhPiPbWEOzLM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u7MgaEQXz+FZf6QPq8qJokmc1Y6MvHOf5fakKwXFueTKl1qDhThG0ABdPYW2ngulHIP3NW/99BbNYphsMfCxk7ijjxwPRsRlrdcwx4c3FuVfZdia6gx9XyMl8DeSvXpoqHo0Aolk5zSPoVv2jQ2YBfMzXRKnOPqgiqerXXCEf+Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=Evhp8Xjg; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="Evhp8Xjg" Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFFon92418293; Fri, 29 May 2026 15:56:14 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=dqKCCofcz0Zv74DPH irPfzI3TpUJzfAENQhUkMK1kvo=; b=Evhp8XjgdpMwTUdSePXiqx8k31I/ekiRG 7mdbZwIjQAoQozZjlWvK4P7mSpYl8pBBUOmE5vDlUnpokXCPhghZV9M9H42BZldV 3VVS/qa19kj7EgEIUWExZCx4G+X1IAyp6i76u791S0qx6F0SJTwEPwUDui3a04Xw /sNxOhUiu/CoIyny3AV7RV6Rv1UtJ+E0+OiYpZ1ZZVsi9IdK1rmm0PDayN5sVT5s R16Qq4+XS1YCBl5KkKt//dgKnX5R0PkIjnN0IMV8SAKqXIo6J9a44c5ucaXu0Gj+ dSS+zaC9KAw37LHv9O56GImmqTAtFQ/cw5VlsgcAUTUD8cbAe2MrA== Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884vkpj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:14 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs8Dx027824; Fri, 29 May 2026 15:56:13 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrc8jmf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:13 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu5VT42205508 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:05 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A0A1920040; Fri, 29 May 2026 15:56:05 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4AC132004D; Fri, 29 May 2026 15:56:05 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:05 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 09/26] KVM: arm64: Refactor idreg caching into dedicated structure Date: Fri, 29 May 2026 17:55:42 +0200 Message-ID: <20260529155601.2927240-10-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=L4MtheT8 c=1 sm=1 tr=0 ts=6a19b71e cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=VnNF1IyMAAAA:8 a=ltnAkj20NlQT-AaSmW0A:9 X-Proofpoint-ORIG-GUID: v-ZUWhFCxXBMvxuhjxXM0qLXz25xPYX1 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX0iwO/qKPo8HI EsmFXXeoaO6BoC57iqvezPM1uhFuhPoC+50C6SIL4NgZnyFHBltBqcd3fhpS5L/vp5Rp+8CxlHE 1zlUXAj6rb6gc7zmzaw/x9WSNNizz5GosWm7rGpKYxy1lywT5myMVBcE1JBOFsZKllYcy1GDa+y zAbl65QxnoAU/l1Ch/Pg8G6/5xm9yp8IxksBt/+dE1mRiIRytX0SYuZ3TPzsptyFGqOmjIkVlfE Bv8IIGogt2Vm7i0wBJAlcfCPPA8f0gjlbKPwM9KVdU08SgJDuqiXbdwrfLen06qI59A/6Eu82nD i6w/D6Vl8XzCAds5Yo316fqM4P1aw3J9/4Am5/u1jVRKcazRmVg0ZwNKkADg8rxeJsplFX5lY6h uoghT3iFZbj5PqYZtSDvtS9J0saERKDsw76IeE2N8VL3FRr5XRsQVmpdTspo/CZ/QpYmBt/tP6w ftoVeK6dxi6SWAMnUVA== X-Proofpoint-GUID: v-ZUWhFCxXBMvxuhjxXM0qLXz25xPYX1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 clxscore=1015 malwarescore=0 bulkscore=0 impostorscore=0 adultscore=0 priorityscore=1501 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Move VM-wide ID register emulation fields from struct kvm_arch into a new struct kvm_vm_id_regs to prepare future sharing of these fields and functions using them. Update all users to use the new structure. No functional changes. Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_host.h | 50 ++++++++++++++++-------------- arch/arm64/kvm/config.c | 2 +- arch/arm64/kvm/hyp/nvhe/pkvm.c | 7 +++-- arch/arm64/kvm/hyp/nvhe/sys_regs.c | 4 +-- arch/arm64/kvm/sys_regs.c | 2 +- 5 files changed, 35 insertions(+), 30 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 4c2c62b8b506..a8efff6ea01d 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -352,22 +352,7 @@ struct kvm_arch { struct kvm_smccc_features smccc_feat; struct maple_tree smccc_filter; =20 - /* - * Emulated CPU ID registers per VM - * (Op0, Op1, CRn, CRm, Op2) of the ID registers to be saved in it - * is (3, 0, 0, crm, op2), where 1<=3Dcrm<8, 0<=3Dop2<8. - * - * These emulated idregs are VM-wide, but accessed from the context of a = vCPU. - * Atomic access to multiple idregs are guarded by kvm_arch.config_lock. - */ -#define IDREG_IDX(id) (((sys_reg_CRm(id) - 1) << 3) | sys_reg_Op2(id)) -#define KVM_ARM_ID_REG_NUM (IDREG_IDX(sys_reg(3, 0, 0, 7, 7)) + 1) - u64 id_regs[KVM_ARM_ID_REG_NUM]; - - u64 midr_el1; - u64 revidr_el1; - u64 aidr_el1; - u64 ctr_el0; + struct kvm_vm_id_regs id_regs; =20 /* Masks for VNCR-backed and general EL2 sysregs */ struct kvm_sysreg_masks *sysreg_masks; @@ -1399,19 +1384,38 @@ static inline void kvm_hyp_reserve(void) { } void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu); bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu); =20 -static inline u64 *__vm_id_reg(struct kvm_arch *ka, u32 reg) +struct kvm_vm_id_regs { + /* + * Emulated CPU ID registers per VM + * (Op0, Op1, CRn, CRm, Op2) of the ID registers to be saved in it + * is (3, 0, 0, crm, op2), where 1<=3Dcrm<8, 0<=3Dop2<8. + * + * These emulated idregs are VM-wide, but accessed from the context of a = vCPU. + * Atomic access to multiple idregs are guarded by kvm_arch.config_lock. + */ +#define IDREG_IDX(id) (((sys_reg_CRm(id) - 1) << 3) | sys_reg_Op2(id)) +#define KVM_ARM_ID_REG_NUM (IDREG_IDX(sys_reg(3, 0, 0, 7, 7)) + 1) + u64 normal[KVM_ARM_ID_REG_NUM]; + + u64 midr_el1; + u64 revidr_el1; + u64 aidr_el1; + u64 ctr_el0; +}; + +static inline u64 *__vm_id_reg(struct kvm_vm_id_regs *id_regs, u32 reg) { switch (reg) { case sys_reg(3, 0, 0, 1, 0) ... sys_reg(3, 0, 0, 7, 7): - return &ka->id_regs[IDREG_IDX(reg)]; + return &id_regs->normal[IDREG_IDX(reg)]; case SYS_CTR_EL0: - return &ka->ctr_el0; + return &id_regs->ctr_el0; case SYS_MIDR_EL1: - return &ka->midr_el1; + return &id_regs->midr_el1; case SYS_REVIDR_EL1: - return &ka->revidr_el1; + return &id_regs->revidr_el1; case SYS_AIDR_EL1: - return &ka->aidr_el1; + return &id_regs->aidr_el1; default: WARN_ON_ONCE(1); return NULL; @@ -1419,7 +1423,7 @@ static inline u64 *__vm_id_reg(struct kvm_arch *ka, u= 32 reg) } =20 #define kvm_read_vm_id_reg(kvm, reg) \ - ({ u64 __val =3D *__vm_id_reg(&(kvm)->arch, reg); __val; }) + ({ u64 __val =3D *__vm_id_reg(&(kvm)->arch.id_regs, reg); __val; }) =20 void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); =20 diff --git a/arch/arm64/kvm/config.c b/arch/arm64/kvm/config.c index 014fe04daabf..58a439c3ab9c 100644 --- a/arch/arm64/kvm/config.c +++ b/arch/arm64/kvm/config.c @@ -1398,7 +1398,7 @@ void __init check_feature_map(void) =20 static bool idreg_feat_match(struct kvm *kvm, const struct reg_bits_to_fea= t_map *map) { - u64 regval =3D kvm->arch.id_regs[map->regidx]; + u64 regval =3D kvm->arch.id_regs.normal[map->regidx]; u64 regfld =3D (regval >> map->shift) & GENMASK(map->width - 1, 0); =20 if (map->sign) { diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index eb1c10120f9f..94620f142f42 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -343,7 +343,7 @@ static void pkvm_init_features_from_host(struct pkvm_hy= p_vm *hyp_vm, const struc DECLARE_BITMAP(allowed_features, KVM_VCPU_MAX_FEATURES); =20 /* CTR_EL0 is always under host control, even for protected VMs. */ - hyp_vm->kvm.arch.ctr_el0 =3D host_kvm->arch.ctr_el0; + hyp_vm->kvm.arch.id_regs.ctr_el0 =3D host_kvm->arch.id_regs.ctr_el0; =20 /* Preserve the vgic model so that GICv3 emulation works */ hyp_vm->kvm.arch.vgic.vgic_model =3D host_kvm->arch.vgic.vgic_model; @@ -358,7 +358,7 @@ static void pkvm_init_features_from_host(struct pkvm_hy= p_vm *hyp_vm, const struc KVM_VCPU_MAX_FEATURES); =20 if (test_bit(KVM_ARCH_FLAG_WRITABLE_IMP_ID_REGS, &host_arch_flags)) - hyp_vm->kvm.arch.midr_el1 =3D host_kvm->arch.midr_el1; + hyp_vm->kvm.arch.id_regs.midr_el1 =3D host_kvm->arch.id_regs.midr_el1; =20 return; } @@ -493,7 +493,8 @@ static int vm_copy_id_regs(struct pkvm_hyp_vcpu *hyp_vc= pu) if (test_and_set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags)) return 0; =20 - memcpy(kvm->arch.id_regs, host_kvm->arch.id_regs, sizeof(kvm->arch.id_reg= s)); + memcpy(kvm->arch.id_regs.normal, host_kvm->arch.id_regs.normal, + sizeof(kvm->arch.id_regs.normal)); =20 return 0; } diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/s= ys_regs.c index b5a0de84ce01..e8d773d38905 100644 --- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c @@ -292,7 +292,7 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, return 0; =20 if (reg >=3D sys_reg(3, 0, 0, 1, 0) && reg <=3D sys_reg(3, 0, 0, 7, 7)) - return kvm->arch.id_regs[IDREG_IDX(reg)]; + return kvm->arch.id_regs.normal[IDREG_IDX(reg)]; =20 return 0; } @@ -543,7 +543,7 @@ void kvm_init_pvm_id_regs(struct kvm_vcpu *vcpu) * for protected VMs. */ for (r =3D sys_reg(3, 0, 0, 4, 0); r <=3D sys_reg(3, 0, 0, 7, 7); r +=3D = sys_reg(0, 0, 0, 0, 1)) - ka->id_regs[IDREG_IDX(r)] =3D pvm_calc_id_reg(vcpu, r); + ka->id_regs.normal[IDREG_IDX(r)] =3D pvm_calc_id_reg(vcpu, r); =20 set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags); } diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index b9aa892616ab..195ecdac7bd6 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -2477,7 +2477,7 @@ static int set_id_reg(struct kvm_vcpu *vcpu, const st= ruct sys_reg_desc *rd, =20 void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val) { - u64 *p =3D __vm_id_reg(&kvm->arch, reg); + u64 *p =3D __vm_id_reg(&kvm->arch.id_regs, reg); =20 lockdep_assert_held(&kvm->arch.config_lock); =20 --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 03DCD428822; Fri, 29 May 2026 15:56:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070212; cv=none; b=qPFS+HhNuKMiUT2YuXZohS2AvWTV+ePRwLMxbLE6TZUhn8BKKZHgtBTiLCrVRU+/vXSVO2jubAduKZ8UsX9QP554kYkLgPGpidmiQzKXvw5yL/BqFb+98zzkrpBGXw/nAaNb/5/PJAxyqZwYq/4Hs0hjpXQ25jDutigT4T31VtY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070212; c=relaxed/simple; bh=VdJ5D4pWhUMZiuLwpLwV45/dxvUbNQ3/d1sL6gUAPCo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jWjfA71Wsz/3cOZEr+6f8bnEKTF6Nh5Gl9XokJ93gRS4pLs9zB+1mAUwSrX4KaHgYkJr5eyCImPC0D+NqQbKYAA5+1B1RcFQh5bndbE0OFwd3YE5WCPlp16Ihee6l7lgxsSRrfCchjGqSx/Qnt4ZH0/cumMiphcY7++gn+mO4nk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=ahvt5PEK; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="ahvt5PEK" Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFKGCK1685956; Fri, 29 May 2026 15:56:17 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=OB54e0sJf0qPl31od E4TOuJ++EZKctY7iEXbx4L5EuE=; b=ahvt5PEK3ue2LKPLeYZ0iiHkL/ub/q50A xss/LlZNhg0Oclokhxgcab+IqqPYeYnkfi0VJtlmn8hUvz4A2xo5g2cyO5EDRt7c Rv3qcSf6olqpanSAEsPiZ9s6g+egE1QtVmxtEYPq7bz8eG5vCrGoC1avcCdQrRbB a4V19WHkkNHVGMRttXRnDAhGq11xAICMnfa2o4imN2w9Jep9zNfD/0605OmKkTbL M96SV0ZtUrq/PPS535IygkfW5b/+qWjBZRsVXzz3cCDUaRBNdmgb1fiLzS02DQK1 +KwUBX92IfoDLobvr1G/z5tJ9TzoL6UL52ymzFeaemSG9WLxI42Xg== Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884mh75-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:15 +0000 (GMT) Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs5GF003169; Fri, 29 May 2026 15:56:14 GMT Received: from smtprelay02.fra02v.mail.ibm.com ([9.218.2.226]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgm8v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay02.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu6ac36700644 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:06 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0617F20040; Fri, 29 May 2026 15:56:06 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id ACE432004B; Fri, 29 May 2026 15:56:05 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:05 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 10/26] KVM: arm64: Fix set_oslsr_el1 to write to OSLAR_EL1 Date: Fri, 29 May 2026 17:55:43 +0200 Message-ID: <20260529155601.2927240-11-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=fIYJG5ae c=1 sm=1 tr=0 ts=6a19b71f cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=5EGiLxFwAr7VIT5rVV0A:9 X-Proofpoint-ORIG-GUID: Wgd_CA6F3seeTvf6_fbULAQn4h0wRnvg X-Proofpoint-GUID: Wgd_CA6F3seeTvf6_fbULAQn4h0wRnvg X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX7ZbACSDx4jlO UQ8aei+lNfw7u4H6u/iIeB1Xy96QCrJaCbwREAu9McKDcUINIf2UmHhnI5TuAAiumMN8Y9/w1GX Hk/qtUUhPSeT9jfgzKJQtAfnoLpEsvsLLd+NBPP96SLXAcQ2jj+AhzNDaNNX293Lo8Tthn517BQ F8ZWheskkNTW7Q+Z95kYw2Y+5Nr+it4XHSoSiF33H/vMPe7vPY+1efXtvR+TEDxiYp94lO/yUEn ULyQ6JcxM6SfSfTg+kiieT00cw8rVAvCkR5CTo70JwqjEHmUpoyL+6/XnuPxBPaNbuK62tXj6JC bTZIAfV8hKU1jOCmsxcTbRZtdqKOOpmaWSH/3OavNWDMtp7K6Ow4raap6+9SGxG+V9E4gzZTl59 f/fjIlkJxC599mmR8W1vXsEy5OiOiA1C3t3Qs14ahjvtPxsmBX8Kh+h36X745+1KZ0CmOqthDW9 ErfRFOZ5KsbMvdeBpow== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 adultscore=0 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" From: Andreas Grapentin The set_oslsr_el1() function was incorrectly writing directly to the OSLSR_EL1 register, which is architecturally a read-only status register that reflects the state of the OS Lock. Fix this by extracting the OSLK bit from the user-provided value and writing it to OSLAR_EL1 (OS Lock Access Register) instead, which is the proper control register for managing the OS Lock state. OSLSR_EL1 will then reflect this state when read. This ensures the implementation follows the ARM architecture specification where OSLAR_EL1 controls the lock and OSLSR_EL1 provides status information. Signed-off-by: Andreas Grapentin Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/kvm/sys_regs.c | 10 +++++++++- include/arch/arm64/asm/sysreg-defs.h | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index a8efff6ea01d..5734e93cad57 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -408,6 +408,7 @@ enum vcpu_sysreg { PAR_EL1, /* Physical Address Register */ MDCCINT_EL1, /* Monitor Debug Comms Channel Interrupt Enable Reg */ OSLSR_EL1, /* OS Lock Status Register */ + OSLAR_EL1, /* OS Lock Access Register */ DISR_EL1, /* Deferred Interrupt Status Register */ =20 /* Performance Monitors Registers */ diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 195ecdac7bd6..6522f9302967 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -822,6 +822,8 @@ static bool trap_oslsr_el1(struct kvm_vcpu *vcpu, static int set_oslsr_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc = *rd, u64 val) { + u64 oslk; + /* * The only modifiable bit is the OSLK bit. Refuse the write if * userspace attempts to change any other bit in the register. @@ -829,7 +831,13 @@ static int set_oslsr_el1(struct kvm_vcpu *vcpu, const = struct sys_reg_desc *rd, if ((val ^ rd->val) & ~OSLSR_EL1_OSLK) return -EINVAL; =20 - __vcpu_assign_sys_reg(vcpu, rd->reg, val); + /* + * Redirect the write to the proper control register. + * OSLSR is read-only + */ + oslk =3D SYS_FIELD_GET(OSLSR_EL1, OSLK, val); + __vcpu_assign_sys_reg(vcpu, OSLAR_EL1, + SYS_FIELD_PREP(OSLAR_EL1, OSLK, oslk)); return 0; } =20 diff --git a/include/arch/arm64/asm/sysreg-defs.h b/include/arch/arm64/asm/= sysreg-defs.h index 3e280d4156ce..c6bdb0f11e1b 100644 --- a/include/arch/arm64/asm/sysreg-defs.h +++ b/include/arch/arm64/asm/sysreg-defs.h @@ -129,6 +129,7 @@ #define OSLSR_EL1_OSLM_NI 0 #define OSLSR_EL1_OSLM_IMPLEMENTED BIT(3) #define OSLSR_EL1_OSLK BIT(1) +#define OSLSR_EL1_OSLK_MASK BIT(1) =20 #define SYS_OSDLR_EL1 sys_reg(2, 0, 1, 3, 4) #define SYS_DBGPRCR_EL1 sys_reg(2, 0, 1, 4, 4) --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 E9FEA3F7891; Fri, 29 May 2026 16:01:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070516; cv=none; b=LB+a4sgqIwxU4zUvaoByC7H3bVbpmGRwZgPE/bH4GSIaGVWPA7ldcjxXg2HOpX9w/AHkH7j+Of1sUHEUdFTT4kPuMLafq0NBOx8EYuqF3o7sitPTHA+2b3Ag0SDFWUOkJP11sGAcsXi0jBxK1z4NR100N5nmy1SWSuwNgoQvHfw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070516; c=relaxed/simple; bh=2DnL581tiMP0xz3bQis3dMPdfTPq2gIL8VpTvpHoZ7s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CFoFwsXLcemLG6lWKYuOf6F0LzyufQoB1nenoz2SyU+oyprTPWCZ9eUWBamVTJWrSXWYmBCrsuRe8tZSlXgXnfa/5L11q8vuDZXjzDUjL7L5QZiqIo4E7vycWe5Y5ZBa0CC9AOjMVdDNZyHylTrT+bM0dFKjS+ixl8NIUE94In4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=kL1F6keG; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="kL1F6keG" Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFDh9g1467773; Fri, 29 May 2026 15:56:14 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=J4lB+fU5DdjjQ/QpM hV9CNZD0t3w/aRQR+zfaUlpeSE=; b=kL1F6keG/qqmfuhVM3ACxkRQ6/oAiceJA usauQSDAeEvlYyJPXNOB9tq83YKMRAepuwx45XfYOHesOqkaduurvCnQ68Rm6p/o Pmh4XrNhIr7prw8pkUaStUIP+PszaRgGorGNaaKz/yOAmXf1tYM3IiDp/veCKoWx NDrOQAjC40HYlNKcqnojiRrI8CLR3wxFJV5cbn+/9nr38jcc2IL2r3xuRV42uv7x B7f/Ii9I63US33AwVqNGbmNxgA7hpJhqIQflO+97uKcXzKlB2d/8qEqvyg/U7YA9 /deYZAC6GjNjYXnnQiixx8X4ttPoUI/8BtO+lTCwRnPOgiu2CStqw== Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee886mgg0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:13 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs7To027773; Fri, 29 May 2026 15:56:12 GMT Received: from smtprelay02.fra02v.mail.ibm.com ([9.218.2.226]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrc8jmd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:12 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay02.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu6gp36700646 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:06 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5DBF120040; Fri, 29 May 2026 15:56:06 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 115E92004D; Fri, 29 May 2026 15:56:06 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:06 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 11/26] KVM: arm64: Move definitions from sys_regs.c to sys_regs.h Date: Fri, 29 May 2026 17:55:44 +0200 Message-ID: <20260529155601.2927240-12-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: UC2v4yac9XJv9onHFWDc9OYBfj2NePhe X-Authority-Analysis: v=2.4 cv=Z8Dc2nRA c=1 sm=1 tr=0 ts=6a19b71d cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=zJUOOSkNxElFdCtx_FUA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX8/oZd7tugLX4 VT1BjfXkRoZiX97FWd9xENgoBEOimXfjRSHnS4ASmTMGMpGduJ/02jpXxbpeEFwee07o2moF7s/ 72lctKgbrzKFtic0CA7WNwrweU9zW+jO8B8kX8expd9rO6WoAANeefTVv67e9M7MnYTS3h0VRsQ RQE+HcfA1XHoInM25N7I4WEtz3MwMX8xnUzVF2AtdDSXE29RGOiob5glD3ByDwGAPwc9c/Ci5KK sJcJegVKO6vPsppxdRK6lzdVcZ0wcXLGleifHxJUS1DnRFMTiwQf/nIHxcmQbjrITwVrhNdEJLv XGu923W7/zKh6xVsNwn6dAt18w8VSyKWakOjgRUt8hAghGrzlHg4GftQiyb12Rf/l101U5ISOhi NxbmGF+asOiPRKI9ZTU8n9+ahODDZpICEDMKcEih6N212FCAm+z3qY9mPdRVyd3BrHY96fUEblZ jnObIFztGgWVZjFwmIw== X-Proofpoint-ORIG-GUID: UC2v4yac9XJv9onHFWDc9OYBfj2NePhe X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 bulkscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 phishscore=0 suspectscore=0 adultscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Make kvm_sanitised_host_ftr_reg() and kvm_read_sanitised_id_reg() available to enable code sharing with s390. Move some helper and ID register macro definitions to the header file. No functional changes. Signed-off-by: Steffen Eiden --- arch/arm64/kvm/sys_regs.c | 12 ++---- arch/arm64/kvm/sys_regs.h | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 6522f9302967..46b24529ec70 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1852,7 +1852,7 @@ static u8 pmuver_to_perfmon(u8 pmuver) /* * Sanitise based on the host implementation. */ -static u64 kvm_sanitised_host_ftr_reg(u32 id) +u64 kvm_sanitised_host_ftr_reg(u32 id) { u64 val =3D read_sanitised_ftr_reg(id); =20 @@ -2039,8 +2039,8 @@ static u64 __kvm_read_sanitised_id_reg(const struct k= vm_vcpu *vcpu, return val; } =20 -static u64 kvm_read_sanitised_id_reg(struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) +u64 kvm_read_sanitised_id_reg(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) { return __kvm_read_sanitised_id_reg(vcpu, r); } @@ -2123,12 +2123,6 @@ static unsigned int aa32_id_visibility(const struct = kvm_vcpu *vcpu, return id_visibility(vcpu, r); } =20 -static unsigned int raz_visibility(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - return REG_RAZ; -} - /* cpufeature ID register access trap handlers */ =20 static bool access_id_reg(struct kvm_vcpu *vcpu, diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h index 2a983664220c..75d581050b09 100644 --- a/arch/arm64/kvm/sys_regs.h +++ b/arch/arm64/kvm/sys_regs.h @@ -108,6 +108,12 @@ struct sys_reg_desc { #define REG_RAZ (1 << 1) /* RAZ from userspace and guest */ #define REG_USER_WI (1 << 2) /* WI from userspace only */ =20 +static inline unsigned int raz_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + return REG_RAZ; +} + static __printf(2, 3) inline void print_sys_reg_msg(const struct sys_reg_params *p, char *fmt, ...) @@ -237,6 +243,12 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr= _index); =20 int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu); =20 +u64 kvm_read_sanitised_id_reg(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r); + +/* Implemented by each architecture */ +u64 kvm_sanitised_host_ftr_reg(u32 id); + #define AA32(_x) .aarch32_map =3D AA32_##_x #define Op0(_x) .Op0 =3D _x #define Op1(_x) .Op1 =3D _x @@ -257,6 +269,81 @@ int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu); CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)), \ Op2(sys_reg_Op2(reg)) =20 +/* + * Since reset() callback and field val are not used for idregs, they will= be + * used for specific purposes for idregs. + * The reset() would return KVM sanitised register value. The value would = be the + * same as the host kernel sanitised value if there is no KVM sanitisation. + * The val would be used as a mask indicating writable fields for the idre= g. + * Only bits with 1 are writable from userspace. This mask might not be + * necessary in the future whenever all ID registers are enabled as writab= le + * from userspace. + */ + +#define ID_DESC_DEFAULT_CALLBACKS \ + .access =3D access_id_reg, \ + .get_user =3D get_id_reg, \ + .set_user =3D set_id_reg, \ + .visibility =3D id_visibility, \ + .reset =3D kvm_read_sanitised_id_reg + +#define ID_DESC(name) \ + SYS_DESC(SYS_##name), \ + ID_DESC_DEFAULT_CALLBACKS + +/* sys_reg_desc initialiser for known cpufeature ID registers */ +#define ID_SANITISED(name) { \ + ID_DESC(name), \ + .val =3D 0, \ +} + +/* sys_reg_desc initialiser for writable ID registers */ +#define ID_WRITABLE(name, mask) { \ + ID_DESC(name), \ + .val =3D mask, \ +} + +/* + * 32bit ID regs are fully writable when the guest is 32bit + * capable. Nothing in the KVM code should rely on 32bit features + * anyway, only 64bit, so let the VMM do its worse. + */ +#define AA32_ID_WRITABLE(name) { \ + ID_DESC(name), \ + .visibility =3D aa32_id_visibility, \ + .val =3D GENMASK(31, 0), \ +} + +/* sys_reg_desc initialiser for cpufeature ID registers that need filterin= g */ +#define ID_FILTERED(sysreg, name, mask) { \ + ID_DESC(sysreg), \ + .set_user =3D set_##name, \ + .val =3D (mask), \ +} + +/* + * sys_reg_desc initialiser for architecturally unallocated cpufeature ID + * register with encoding Op0=3D3, Op1=3D0, CRn=3D0, CRm=3Dcrm, Op2=3Dop2 + * (1 <=3D crm < 8, 0 <=3D Op2 < 8). + */ +#define ID_UNALLOCATED(crm, op2) { \ + .name =3D "S3_0_0_" #crm "_" #op2, \ + Op0(3), Op1(0), CRn(0), CRm(crm), Op2(op2), \ + ID_DESC_DEFAULT_CALLBACKS, \ + .visibility =3D raz_visibility, \ + .val =3D 0, \ +} + +/* + * sys_reg_desc initialiser for known ID registers that we hide from guest= s. + * For now, these are exposed just like unallocated ID regs: they appear + * RAZ for the guest. + */ +#define ID_HIDDEN(name) { \ + ID_DESC(name), \ + .visibility =3D raz_visibility, \ + .val =3D 0, \ +} #define ID_REG_LIMIT_FIELD_ENUM(val, reg, field, limit) \ ({ \ u64 __f_val =3D FIELD_GET(reg##_##field##_MASK, val); \ --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 F1BE74028F5; Fri, 29 May 2026 15:56:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070204; cv=none; b=uSyoIv77jzHuypXHQhFpDFYRhrWmuT4r+rR0ZkKUG9yRWDhjW+O7+A51pUK/5O07uHBFxSEhNyaKgK7yD5GliJVzbgblR7it6ZOPi0kD2geWhgRoComw/biBRwiDAIp69T1eSFpQdA0eGIQPeeDB31LagbiaG8+8wUFpcXqPOdk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070204; c=relaxed/simple; bh=O3yu8MIlfw8EI726kjrzX9JIr7MY1HrswifaiXGWrAo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Z+kQTuwH/KF3nVQEnW3eTruO79q/cImzLXuuYxD7CySS8u7dF8TPqfFi+/jTJhbFpFPOEMVPkC9tHVnf3Ztc4WtzE4ZK7LBNgESBbL6NPf5cgrEdbB9yFpyOjbNXhpjg/n5203rjRqvjrp2Kivv/43iG6XQqZgxG/jA34XtZ8OM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=MQJ+nAtm; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="MQJ+nAtm" Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TF7d2Z2776538; Fri, 29 May 2026 15:56:15 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=IdSp5Vw7z+HR0yKWR iC1T9INgcuPtWfpi9peZITRCZA=; b=MQJ+nAtm4uZZGXJsd46G+Kf+G/EjsLawB OcDKG8qkZ+uIWALCdbhnTzXAlgJ1ih9HPkzQEgo+JWn/r5xbGolBrvsY2ZvxNw/n VZ5e0mucOYOLQ6SROg5ySM09EvT7W8cCSLuIlFrdKSUSJpmC5e5ub2JEAWJg0+GA qV7zp0exmd0tDgvpWvC2++HZ0jPOgo/f9wRaXnwnWuS1gHvZAio/Vf/zFSRaIZiV B5x/YqmRX+FNDKzKIZhgm8ySAmRHBsYWllg+fSOw15W86tLMJPNwzwtOVA9QvojJ Nlc4byPx4uJ/mWSFcH+SSbzPBxLyOBxJh7WxI0wi+ZJ/JmfbvSU+w== Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee889m2bq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:15 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs5pn016946; Fri, 29 May 2026 15:56:14 GMT Received: from smtprelay02.fra02v.mail.ibm.com ([9.218.2.226]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgjpd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay02.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu66P36700652 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:06 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B274A2004D; Fri, 29 May 2026 15:56:06 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 655E82004B; Fri, 29 May 2026 15:56:06 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:06 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 12/26] KVM: arm64: Add PVM_ prefix to avoid name collisions Date: Fri, 29 May 2026 17:55:45 +0200 Message-ID: <20260529155601.2927240-13-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: 7ACddOjvFerXD0E0lV_VSanFeKdPoAcn X-Proofpoint-GUID: 7ACddOjvFerXD0E0lV_VSanFeKdPoAcn X-Authority-Analysis: v=2.4 cv=XqfK/1F9 c=1 sm=1 tr=0 ts=6a19b71f cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=UoxKMzVWMJxMEg80A50A:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX9wuS4D1QB6x1 kp1RpIFloqV+maUup3QiOVHUJTBohYC9JyukqiAlpFwt2M80rGHWPKEGm2hIJ5toBChgl0ZG0dv OAkDND3dzxNORV4cj1txC4BXdwhR9whZ/VBcKf8FcLV0YJUUmfi3OgUZV1VNYhIB6iB2HnB7/J8 qtfwsAUkp7VAbkayOY6l+Yij/UKTuulsSTLeWEei59fRB2u9z3jIn5eX0QKMVeqUEo6fBaLlXJX SE8Xbgsy3Nh5KKG2QJ4hdnK+9+g/RI42QavKBZzKJleoC6637LUPAxn1wGGl5N1wfrOEAEC+LbV NAElljrdJHiYCsyIhvfJqoYFT1f0uazED/Bk4lFIXfQTkYVzyrXQHlztZOWzR77+FgbrOQ8WcBR jw+J5J2MNda9llPb4Ecg0yQ7GwWFwax4w80a17pkucClopxVXnEqH/umBTqRSjt0jZmAYA4Uksu eOsRi8bItdyq2i7Ckgg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 impostorscore=0 adultscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 bulkscore=0 suspectscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Rename ID_UNALLOCATED to PVM_ID_UNALLOCATED and read_id_reg to pvm_read_id_reg to prevent future name collisions with other subsystems. While at it, fix whitespace issues in the macro invocations Signed-off-by: Steffen Eiden --- arch/arm64/kvm/hyp/nvhe/sys_regs.c | 48 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/s= ys_regs.c index e8d773d38905..08b14053568b 100644 --- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c @@ -282,8 +282,8 @@ static void inject_undef64(struct kvm_vcpu *vcpu) inject_sync64(vcpu, (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT)); } =20 -static u64 read_id_reg(const struct kvm_vcpu *vcpu, - struct sys_reg_desc const *r) +static u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, + struct sys_reg_desc const *r) { struct kvm *kvm =3D vcpu->kvm; u32 reg =3D reg_to_encoding(r); @@ -341,7 +341,7 @@ static bool pvm_access_id_aarch64(struct kvm_vcpu *vcpu, return false; } =20 - p->regval =3D read_id_reg(vcpu, r); + p->regval =3D pvm_read_id_reg(vcpu, r); return true; } =20 @@ -379,7 +379,7 @@ static bool pvm_idst_access(struct kvm_vcpu *vcpu, * register with encoding Op0=3D3, Op1=3D0, CRn=3D0, CRm=3Dcrm, Op2=3Dop2 * (1 <=3D crm < 8, 0 <=3D Op2 < 8). */ -#define ID_UNALLOCATED(crm, op2) { \ +#define PVM_ID_UNALLOCATED(crm, op2) { \ Op0(3), Op1(0), CRn(0), CRm(crm), Op2(op2), \ .access =3D pvm_access_id_aarch64, \ } @@ -438,46 +438,46 @@ static const struct sys_reg_desc pvm_sys_reg_descs[] = =3D { AARCH32(SYS_MVFR0_EL1), AARCH32(SYS_MVFR1_EL1), AARCH32(SYS_MVFR2_EL1), - ID_UNALLOCATED(3,3), + PVM_ID_UNALLOCATED(3, 3), AARCH32(SYS_ID_PFR2_EL1), AARCH32(SYS_ID_DFR1_EL1), AARCH32(SYS_ID_MMFR5_EL1), - ID_UNALLOCATED(3,7), + PVM_ID_UNALLOCATED(3, 7), =20 /* AArch64 ID registers */ /* CRm=3D4 */ AARCH64(SYS_ID_AA64PFR0_EL1), AARCH64(SYS_ID_AA64PFR1_EL1), AARCH64(SYS_ID_AA64PFR2_EL1), - ID_UNALLOCATED(4,3), + PVM_ID_UNALLOCATED(4, 3), AARCH64(SYS_ID_AA64ZFR0_EL1), - ID_UNALLOCATED(4,5), - ID_UNALLOCATED(4,6), - ID_UNALLOCATED(4,7), + PVM_ID_UNALLOCATED(4, 5), + PVM_ID_UNALLOCATED(4, 6), + PVM_ID_UNALLOCATED(4, 7), AARCH64(SYS_ID_AA64DFR0_EL1), AARCH64(SYS_ID_AA64DFR1_EL1), - ID_UNALLOCATED(5,2), - ID_UNALLOCATED(5,3), + PVM_ID_UNALLOCATED(5, 2), + PVM_ID_UNALLOCATED(5, 3), AARCH64(SYS_ID_AA64AFR0_EL1), AARCH64(SYS_ID_AA64AFR1_EL1), - ID_UNALLOCATED(5,6), - ID_UNALLOCATED(5,7), + PVM_ID_UNALLOCATED(5, 6), + PVM_ID_UNALLOCATED(5, 7), AARCH64(SYS_ID_AA64ISAR0_EL1), AARCH64(SYS_ID_AA64ISAR1_EL1), AARCH64(SYS_ID_AA64ISAR2_EL1), - ID_UNALLOCATED(6,3), - ID_UNALLOCATED(6,4), - ID_UNALLOCATED(6,5), - ID_UNALLOCATED(6,6), - ID_UNALLOCATED(6,7), + PVM_ID_UNALLOCATED(6, 3), + PVM_ID_UNALLOCATED(6, 4), + PVM_ID_UNALLOCATED(6, 5), + PVM_ID_UNALLOCATED(6, 6), + PVM_ID_UNALLOCATED(6, 7), AARCH64(SYS_ID_AA64MMFR0_EL1), AARCH64(SYS_ID_AA64MMFR1_EL1), AARCH64(SYS_ID_AA64MMFR2_EL1), - ID_UNALLOCATED(7,3), - ID_UNALLOCATED(7,4), - ID_UNALLOCATED(7,5), - ID_UNALLOCATED(7,6), - ID_UNALLOCATED(7,7), + PVM_ID_UNALLOCATED(7, 3), + PVM_ID_UNALLOCATED(7, 4), + PVM_ID_UNALLOCATED(7, 5), + PVM_ID_UNALLOCATED(7, 6), + PVM_ID_UNALLOCATED(7, 7), =20 /* Scalable Vector Registers are restricted. */ =20 --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 409403FE674; Fri, 29 May 2026 15:56:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070200; cv=none; b=r6X8YHr7CCPCARouJaDLD4te9+hJrRM56QSyPkuqnZ6mmWa0QYZoagJxQEY24DjzaVXxmgpW5jCSQR2rDKMouhajLyfyVqgJ0JkdWzBM02jdFqE+6iPS3FfRuiLCNEqZuWhm0/k4kv7T+ocImNQxuvcAD7jormlGYj5Q901uGDo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070200; c=relaxed/simple; bh=U1dkFh5tJ6ZwojqCHKxfmLBh/yZMgZ9RKDQJgDpgC7w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oUGhjQHxlxKQt2wU/jjY4lLUJh8oD3hYuHgV4w/6khk5z7dAx3WAQL7gzyCcvFlhrVGHGUxvAQKSsg7zIeIcNw2NiexqE3L027s8ZBpk6QMjvLW8fMYQIIstp4otLmq/xDmBcSDEyoGTAdb6H+/DIvWhn6dm3/H5xsA2kvNuwvk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=h3Ro1jA7; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="h3Ro1jA7" Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFg2LN2776549; Fri, 29 May 2026 15:56:14 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=WnQHAGFKd6DchrlP6 Ju4P8YPOX1SBDsgwJ6yTF6AD1E=; b=h3Ro1jA76JxVqbaXxvN/d730zt/FvXxUZ uZlQD5UmaK9LrRFXBt60ZkjvDjmWOYQ33xtPfmgBrppsD8CxLCayRuzznQqs4cY9 cc/GMc8rbCSyQzBUgk3ndsTqXO4cc1aTFKZdCpcHb3MYtqVQocsatGznf/dl5wjM UCt+bvTF6hw/WudSF8ePa1RP4+qBzqlQnGo3cdMRziz+qUrzqKWBRss6YBZs52LP nPpLEpFigApiZRI7xZSgy1nfesB9KFo0i8PWedHKW0t0gh+Q7WRFMA6Qh6CqqFDa BL7PcLHYVroCzYPso9ZjDHAMbszZnaF5/EHW+Ide2hOM+4twRxhog== Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee889m2ba-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:14 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs816023079; Fri, 29 May 2026 15:56:13 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrc0k2m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:13 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu78p50004432 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:07 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1B17E20040; Fri, 29 May 2026 15:56:07 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BDFB22004E; Fri, 29 May 2026 15:56:06 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:06 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 13/26] s390: Introduce read/write ARM sysreg instructions Date: Fri, 29 May 2026 17:55:46 +0200 Message-ID: <20260529155601.2927240-14-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: NYwQLjch8AAYoUDuGJ9-iOYn8u_3SwZM X-Proofpoint-GUID: NYwQLjch8AAYoUDuGJ9-iOYn8u_3SwZM X-Authority-Analysis: v=2.4 cv=XqfK/1F9 c=1 sm=1 tr=0 ts=6a19b71e cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=GoOEIcCEF_BdVuQDi_EA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX9/++cki3jljI f83bnBX/m3d72SamK5XaOFICAAVHg5ycoBac3FAfpNjOFDMmV674fElxYVUFLpx23BtZMlsWxP0 6zkbWx8mQAxfV+k/By+++ntdMPv7vtX5jUVvhk5rnY9jvcn0jxkHrY0mxho3Vj+P4WOWIWRi51o IQtwLfLWQ0C9OC8pF6IyzP+jLn7tP/JlByrzPy5nu3yt1on1JHFpQurpnvVtugEi3KSWKiNpBlQ 897F5BnM2AgEuTFwn8wAcYMpvy6rDEiXwkhrqLE9CXIrLOVX8OzhKzCdCvTriJ7yuSxVmfZ6amz FrDugEah/QsgKKzTRAQ5t6jfGd8LFXQNALEkjClfjFctL2JzGfnMjYjAWs6iZvQ/rLKRS8E6/X3 7HlSf/X7U39wNRNXxaJR/QFb1l3EspxXDNipGX4hapcr1xnEb4T+cbVfXyLxk6ACX/Iwby4Cdmb S2SMQ5fI0prTSW41Yiw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 impostorscore=0 adultscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 bulkscore=0 suspectscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Introduce Extract Arm System Register and Store Arm System Register to enable s390 hosts to read and write system registers for arm64 guests. The new instructions use the new RIE_H instruction format. Add assembler macros to create instructions in RIE_H format manually. Add Support for disassembling the new instructions. Co-developed-by: Andreas Grapentin Signed-off-by: Andreas Grapentin Signed-off-by: Steffen Eiden --- arch/s390/include/asm/sae-asm.h | 48 +++++++++++++++++++++++++++ arch/s390/include/asm/sae.h | 58 +++++++++++++++++++++++++++++++++ arch/s390/kernel/dis.c | 1 + arch/s390/tools/opcodes.txt | 2 ++ 4 files changed, 109 insertions(+) create mode 100644 arch/s390/include/asm/sae-asm.h diff --git a/arch/s390/include/asm/sae-asm.h b/arch/s390/include/asm/sae-as= m.h new file mode 100644 index 000000000000..d81ed89eb4ed --- /dev/null +++ b/arch/s390/include/asm/sae-asm.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_S390_SAE_ASM_H +#define __ASM_S390_SAE_ASM_H + +#ifdef __ASSEMBLER__ + +.macro GPR_NUM opd gr + \opd =3D 255 + .irp rs,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + .ifc \gr,%r\rs + \opd =3D \rs + .endif + .endr + .if \opd =3D=3D 255 + \opd =3D \gr + .endif +.endm + +/* + * RIE_H - RIE-h instruction format + * + * RIE-h format: R1, R3, I2, M4 + * +--------+----+----+----+-----------------+----+--------+ + * | OpCode | R1 |////| R3 | I2 | M4 | Opcode | + * +--------+----+----+----+-----------------+----+--------+ + * 0 8 12 16 20 36 40 47 + */ +.macro RIE_H opc, gr1, gr3, imm2, m4 + GPR_NUM r1, \gr1 + GPR_NUM r3, \gr3 + .byte (\opc & 0xff00) >> 8 + .byte r1 << 4 + .byte (r3 << 4) | ((\imm2 & 0xf000) >> 12) + .byte ((\imm2 & 0x0ff0) >> 4) + .byte ((\imm2 & 0x000f) << 4) | (\m4 & 0xf) + .byte \opc & 0xff +.endm + +.macro SASR r1, r3, i2, m4 + RIE_H 0xed99, \r1, \r3, \i2, \m4, +.endm + +.macro EASR r1, r3, i2, m4 + RIE_H 0xed9b, \r1, \r3, \i2, \m4, +.endm + +#endif /* __ASSEMBLER__ */ +#endif /* __ASM_S390_SAE_ASM_H */ diff --git a/arch/s390/include/asm/sae.h b/arch/s390/include/asm/sae.h index fe010a1a7729..1d9a16b91b23 100644 --- a/arch/s390/include/asm/sae.h +++ b/arch/s390/include/asm/sae.h @@ -4,6 +4,7 @@ =20 #include "linux/linkage.h" #include +#include =20 /* defined in arch/s390/kernel/entry.S */ asmlinkage int __sae64a(phys_addr_t sae_block_phys); @@ -12,6 +13,12 @@ asmlinkage int __sae64a(phys_addr_t sae_block_phys); #include #include =20 +asm(".include \"asm/sae-asm.h\"\n"); + +#define _SAE_ASR_REG_SHIFT 5 +#define SASR_FLAG_INITIALIZED 0x8 +#define EASR_FLAG_SA 0x8 + /** * __sae64a() - Start Arm Execution */ @@ -20,6 +27,57 @@ static inline void sae64a(struct kvm_sae_block *sae_bloc= k) __sae64a(virt_to_phys(sae_block)); } =20 +/** + * sasr() - Set Arm System Register + * @arm_reg: ARM system register identifier; compile-time constant + * @val: Value to set + * @save_area: Pointer to SAE save area + * @flags: Operation flags; compile-time constant + * + * Sets an ARM system register value. + */ +static __always_inline void sasr(unsigned int arm_reg, u64 val, + struct kvm_sae_save_area *save_area, + u64 flags) +{ + struct kvm_sae_save_area *sdo =3D (void *)save_area->sdo; + u16 reg =3D arm_reg >> _SAE_ASR_REG_SHIFT; + + asm volatile ( + " SASR %[r1],%[r3],%[i2],%[m4]\n" + : "+m" (*save_area), "+m" (*sdo) + : [r1] "d" (val), + [r3] "a" (save_area), [i2] "K" (reg), [m4] "I" (flags) + ); +} + +/** + * easr() - Extract Arm System Register + * @arm_reg: ARM system register identifier; compile-time constant + * @save_area: Pointer to SAE save area + * @flags: Operation flags; compile-time constant + * + * Reads an ARM system register value. + * + * Return: Register value + */ +static __always_inline u64 easr(unsigned int arm_reg, + const struct kvm_sae_save_area *save_area, + u64 flags) +{ + struct kvm_sae_save_area *sdo =3D (void *)save_area->sdo; + u16 reg =3D arm_reg >> _SAE_ASR_REG_SHIFT; + u64 val; + + asm volatile( + " EASR %[r1],%[r3],%[i2],%[m4]\n" + : [r1] "=3Dd"(val) + : "m"(*save_area), + "m"(*sdo), [r3] "a"(save_area), [i2] "K"(reg), [m4] "I"(flags) + ); + return val; +} + /** * stiasrm() - STore and Invalidate Arm System Register Multiple * @save_area: Pointer to SAE save area diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index 1cec93895b3a..6ff8fd09d5bc 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c @@ -208,6 +208,7 @@ static const unsigned char formats[][6] =3D { [INSTR_RIE_RUI0] =3D { R_8, I16_16, U4_12, 0, 0, 0 }, [INSTR_RIE_RUPI] =3D { R_8, I8_32, U4_12, J16_16, 0, 0 }, [INSTR_RIE_RUPU] =3D { R_8, U8_32, U4_12, J16_16, 0, 0 }, + [INSTR_RIE_R0RIU] =3D { R_8, R_16, U16_20, U4_36, 0, 0 }, [INSTR_RIL_RI] =3D { R_8, I32_16, 0, 0, 0, 0 }, [INSTR_RIL_RP] =3D { R_8, J32_16, 0, 0, 0, 0 }, [INSTR_RIL_RU] =3D { R_8, U32_16, 0, 0, 0, 0 }, diff --git a/arch/s390/tools/opcodes.txt b/arch/s390/tools/opcodes.txt index 0e4773c94af0..18af14071290 100644 --- a/arch/s390/tools/opcodes.txt +++ b/arch/s390/tools/opcodes.txt @@ -1255,6 +1255,8 @@ ed64 ley RXY_FRRD ed65 ldy RXY_FRRD ed66 stey RXY_FRRD ed67 stdy RXY_FRRD +ed99 sasr RIE_R0RIU +ed9b easr RIE_R0RIU eda8 czdt RSL_LRDFU eda9 czxt RSL_LRDFU edaa cdzt RSL_LRDFU --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 E71B53F0A99; Fri, 29 May 2026 16:01:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070497; cv=none; b=e3B5YAwMw2G/p8bFWnFesPh/avLg5S6ptfAf4Hn2/HKIFuq5DSwoKBrRo2RKhzuJFNNMuBmCUoZsnAH1Nf1LZG+FGubRG036OMYl0zdniCHXMRVvUPQlwB72jIj+OAkEqrVS6fvC2rwQookfYe9XVGWneRt4B/eWmjxxBgEA1Ss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070497; c=relaxed/simple; bh=BUzPlyqZ+pCOIzcOrqzch+Yiqb3DVpTAJdRTlrJ/f8U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KLmFo7ddO4NcgbS18Lgz6qCJDaUQ7j1qrWzIU2MtdRfWraae21RismfGb5653pp0gxCHOeqcuc2qA0vx46XHRbgCHanXUxhA9vh+Mwy8oNcXcBvd0n4P/a7U6W7rMkoaTneB712gODkYv5YvutsiDJTqtZk/83QAQewHhNYwheE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=f3P5V3HD; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="f3P5V3HD" Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFpqUf1684655; Fri, 29 May 2026 15:56:16 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=nZmkXK6RhtIK2VMR3 5jlDZhLRNQF6Fzob0wRyeJApKE=; b=f3P5V3HDDWbD8YOo37yqTZgPwMeHBfyBk bkbXxPHB7QJkIrrh+3IpMJaBDQVulMbtKO2lXaLuBtCBVkxbrRT4ph2Hx4Sk0Tv4 v+qzpHnWZUF7pbVg/deiMxcnzrIZhhB9UpX3SkBQn1sAXzZSFJz1Uy2bh+fJFmp8 rpweYI79ZyEZesqVeMsgXbleuvIVUSPCXCf/887nU20HNreZaiJJfbfYedWe1syz Wny3OSTKChksKCzCu3krHD9GzkpRPPNj5FjBOQUTXZvo8drx3eiRmpP2MF1ikt0H g3VwrAQH+xePQObYvwf7Qq1uNH6dh+f1D8AiFRGiYN2q7WFBtnrvA== Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884mh79-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:16 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs8E1027824; Fri, 29 May 2026 15:56:15 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrc8jn5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu7md50004436 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:07 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 82D7720040; Fri, 29 May 2026 15:56:07 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 25E252004D; Fri, 29 May 2026 15:56:07 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:07 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 14/26] s390: Introduce Query Available Arm features Date: Fri, 29 May 2026 17:55:47 +0200 Message-ID: <20260529155601.2927240-15-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=fIYJG5ae c=1 sm=1 tr=0 ts=6a19b720 cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=NGOT3fJOeBrWVEuXvOwA:9 X-Proofpoint-ORIG-GUID: jzBUttBrMfErQZAvtecOHuga00WuxSdG X-Proofpoint-GUID: jzBUttBrMfErQZAvtecOHuga00WuxSdG X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX5TlCfP8BYm0D Yv+5UkhhFObBpmGBqaURexhgYjVtr1f9moA+q0LcdHuUlnD0zu5neiTCRRO7cfO71HIu4gMt2QP 5CQqU+OgXvlg2awgv8uiHrnHl2mLplpJtphiDj2O5NXeQTAbMaf/8vPg3oNg65UbqGJaZgHpHA9 xtZb3WSLT5+Ttu+YOZdSBvbHoLCc3ITakDZBamcmcUlL0c7pTxnwr+k/Ki3DOdDImkw7FPcFkc3 /bmD6cKf0VQ83Sz8frSaKsnjrea59T9CCuxlLDVQeg/Hj8+35red0BsZxksIFOaPGDMk2pws8ga aRaYxbK6JV8vvnSpLFSHryISeBecRfFrZUD3uFehQmZSvsyGZx4kuTL1b5xwwnKua+9j5ln4TF5 6BfIOH9/bcSSvFgxiO3e9yJsGWTDcdwHh92ko7wLtXbVhS8X8VLcaBlYVdfeh5hNxbyZ/qHChHt UP8RGhuPWR4UwDlfAXg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 adultscore=0 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" QAAF enables s390 hosts to gain information about the support and handling of various arm features supported by the machine. Function code 1 provides general information about available formats, machine defined content of system/id register, and other various information for running arm guests. Co-developed-by: Andreas Grapentin Signed-off-by: Andreas Grapentin Signed-off-by: Steffen Eiden --- arch/s390/include/asm/kvm_host_arm64_types.h | 96 ++++++++++++++++++++ arch/s390/include/asm/sae.h | 28 ++++++ arch/s390/tools/opcodes.txt | 1 + 3 files changed, 125 insertions(+) diff --git a/arch/s390/include/asm/kvm_host_arm64_types.h b/arch/s390/inclu= de/asm/kvm_host_arm64_types.h index 3882d5462a05..16f7018a1714 100644 --- a/arch/s390/include/asm/kvm_host_arm64_types.h +++ b/arch/s390/include/asm/kvm_host_arm64_types.h @@ -126,4 +126,100 @@ struct kvm_sae_save_area { } __packed __aligned(PAGE_SIZE); static_assert(sizeof(struct kvm_sae_save_area) =3D=3D PAGE_SIZE); =20 +#define QAAF_FC_QMC 1 + +/* QAAF Query Model Capabilities */ +struct qaaf_qmc_block { + u64 _0000; /* 0x0000 */ + u8 ssdf; /* 0x0008 */ + u8 _0009; /* 0x0009 */ + u8 ssaf; /* 0x000a */ + u8 _000b[3]; /* 0x000b */ + u16 maxncpu; /* 0x000e */ + u64 regs[0x1fe]; /* 0x0010 */ +} __aligned(PAGE_SIZE); +static_assert(sizeof(struct qaaf_qmc_block) =3D=3D PAGE_SIZE); + +union qaaf_block { + struct qaaf_qmc_block qmc; +} __aligned(PAGE_SIZE); +static_assert(sizeof(union qaaf_block) =3D=3D PAGE_SIZE); + +/* + * Keep in sync with mapping from SYS_* to QAAF_* in feature.c! + */ +enum { + QAAF_REG_MIDR_EL1 =3D 0x02, + /* 0x03 -0x06 reserved */ + QAAF_REG_MPIDR_EL1 =3D 0x07, + QAAF_REG_REVIDR_EL1 =3D 0x08, + /* 0x09 reserved */ + QAAF_REG_ID_PFR0_EL1 =3D 0x0a, + QAAF_REG_ID_PFR1_EL1 =3D 0x0b, + QAAF_REG_ID_DFR0_EL1 =3D 0x0c, + QAAF_REG_ID_AFR0_EL1 =3D 0x0d, + QAAF_REG_ID_MMFR0_EL1 =3D 0x0e, + QAAF_REG_ID_MMFR1_EL1 =3D 0x0f, + QAAF_REG_ID_MMFR2_EL1 =3D 0x10, + QAAF_REG_ID_MMFR3_EL1 =3D 0x11, + QAAF_REG_ID_ISAR0_EL1 =3D 0x12, + QAAF_REG_ID_ISAR1_EL1 =3D 0x13, + QAAF_REG_ID_ISAR2_EL1 =3D 0x14, + QAAF_REG_ID_ISAR3_EL1 =3D 0x15, + QAAF_REG_ID_ISAR4_EL1 =3D 0x16, + QAAF_REG_ID_ISAR5_EL1 =3D 0x17, + QAAF_REG_ID_MMFR4_EL1 =3D 0x18, + QAAF_REG_ID_ISAR6_EL1 =3D 0x19, + QAAF_REG_MVFR0_EL1 =3D 0x1a, + QAAF_REG_MVFR1_EL1 =3D 0x1b, + QAAF_REG_MVFR2_EL1 =3D 0x1c, + /* 0x1d reserved */ + QAAF_REG_ID_PFR2_EL1 =3D 0x1e, + QAAF_REG_ID_DFR1_EL1 =3D 0x1f, + QAAF_REG_ID_MMFR5_EL1 =3D 0x20, + /* 0x21 reserved */ + QAAF_REG_ID_AA64PFR0_EL1 =3D 0x22, + QAAF_REG_ID_AA64PFR1_EL1 =3D 0x23, + QAAF_REG_ID_AA64PFR2_EL1 =3D 0x24, + /* 0x25 reserved */ + QAAF_REG_ID_AA64ZFR0_EL1 =3D 0x26, + QAAF_REG_ID_AA64SMFR0_EL1 =3D 0x27, + /* 0x28 reserved */ + QAAF_REG_ID_AA64FPFR0_EL1 =3D 0x29, + QAAF_REG_ID_AA64DFR0_EL1 =3D 0x2a, + QAAF_REG_ID_AA64DFR1_EL1 =3D 0x2b, + QAAF_REG_ID_AA64DFR2_EL1 =3D 0x2c, + /* 0x2d reserved */ + QAAF_REG_ID_AA64AFR0_EL1 =3D 0x2e, + QAAF_REG_ID_AA64AFR1_EL1 =3D 0x2f, + /* 0x30,0x31 reserved */ + QAAF_REG_ID_AA64ISAR0_EL1 =3D 0x32, + QAAF_REG_ID_AA64ISAR1_EL1 =3D 0x33, + QAAF_REG_ID_AA64ISAR2_EL1 =3D 0x34, + QAAF_REG_ID_AA64ISAR3_EL1 =3D 0x35, + /* 0x36-0x39 reserved */ + QAAF_REG_ID_AA64MMFR0_EL1 =3D 0x3a, + QAAF_REG_ID_AA64MMFR1_EL1 =3D 0x3b, + QAAF_REG_ID_AA64MMFR2_EL1 =3D 0x3c, + QAAF_REG_ID_AA64MMFR3_EL1 =3D 0x3d, + QAAF_REG_ID_AA64MMFR4_EL1 =3D 0x3e, + /* 0x3f-0x41 reserved */ + QAAF_REG_CNTFRQ_EL0 =3D 0x42, + QAAF_REG_CTR_EL0 =3D 0x43, + /* 0x44-0x49 reserved */ + QAAF_IRPTC =3D 0x4a, + /* 0x4b reserved */ + QAAF_REG_ICH_VTR_EL2 =3D 0x4c, + QAAF_GIC_ATTR =3D 0x4d, + /* 0x4E-0x51 reserved */ + QAAF_REG_PMMIR_EL1 =3D 0x52, + QAAF_REG_PMCR_EL0 =3D 0x53, + QAAF_REG_PMCEID0_EL0 =3D 0x54, + QAAF_REG_PMCEID1_EL0 =3D 0x55, + /* 0x56-0x1ff reserved */ + _QAAF_MAX +}; + +static_assert(sizeof(struct qaaf_qmc_block) / 8 + 1 >=3D _QAAF_MAX); + #endif /* ASM_KVM_HOST_ARM64_TYPES_H */ diff --git a/arch/s390/include/asm/sae.h b/arch/s390/include/asm/sae.h index 1d9a16b91b23..f6f79443d6ce 100644 --- a/arch/s390/include/asm/sae.h +++ b/arch/s390/include/asm/sae.h @@ -110,5 +110,33 @@ static __always_inline void lasrm(struct kvm_sae_save_= area *save_area) ); } =20 +/** + * qaaf() - Query Available Arm Features + * @gr0: QAAF function code, placed in greg 0 + * @qaaf_block: Pointer to the page for the output + * + * Perform QAAF. The result ins written to qaaf_block. + */ +static __always_inline void qaaf(u64 gr0, union qaaf_block *qaaf_block) +{ + asm volatile( + " lgr 0,%[r0]\n" + " .insn rre,0xb9ad0000,%[r1],0" + : "=3Dm"(*qaaf_block) + : [r1] "a"(qaaf_block), [r0] "d"(gr0) + : "r0" + ); +} + +/** + * qaaf_qmc() - Query Available Arm Features for Model Capabilities + * @qmc: Pointer to qaaf_qmc_block structure to receive model capabilities + * + */ +static __always_inline void qaaf_qmc(struct qaaf_qmc_block *qmc) +{ + qaaf(QAAF_FC_QMC, (union qaaf_block *)qmc); +} + #endif /* !__ASSEMBLER__ */ #endif /* __ASM_S390_SAE_H */ diff --git a/arch/s390/tools/opcodes.txt b/arch/s390/tools/opcodes.txt index 18af14071290..fd5483107961 100644 --- a/arch/s390/tools/opcodes.txt +++ b/arch/s390/tools/opcodes.txt @@ -600,6 +600,7 @@ b9a7 stiasrm RRE_R0 b9aa lptea RRF_RURR2 b9ab essa RRF_U0RR b9ac irbm RRE_RR +b9ad qaaf RRE_R0 b9ae rrbm RRE_RR b9af pfmf RRE_RR b9b0 cu14 RRF_U0RR --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 50C1F3DA7F5; Fri, 29 May 2026 15:56:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070219; cv=none; b=Z30YEd1GQMVwnyY0iDb+f60W94ym1gmJaTX3XBEeefoPBHQcxholFhOWYlAsNxY/1q8XVlmeE9eafRJf0gNZKuRHqXpD60pSCISjKfiBjgj184qpK/5MNuivV09O+1Z7VckHNVf12NGi4XwvM+cWpBIAZ/GLcbT2mu6t6/F/3CM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070219; c=relaxed/simple; bh=Kjsr5tXV2TixyM/dq6YUT3Xky/CisxizSj98DM/4okU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=H7jaVUJrae4oJPXroagKVROtU5B7gC/dNDLCah5ZEE/9ykFeCS5fLLo7puLDb0fDGPhd1HMG5WM8FTD4Ft7IZyiSeZI+LmzfMP+YUvfCLWe6J0EAQOV6W1oesJ2ndzSeZI3/dHtgoeYLDeDGQID4bWJWS2I5Xf6AlAXGow7gFCE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=I0nhmUfo; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="I0nhmUfo" Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TF7d4s1468503; Fri, 29 May 2026 15:56:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=EQ2VuK7ZFaehrQoRt zvCBljTp7pTrarwgW+FNoWOdfE=; b=I0nhmUfo4LDAlEHf3BKf2nOYyI/Je41nO igFFNOwda9L57DJa/sMfVSmqDD4UOFrfl/ns1Zh7aMDpMZjElW1KxI7YenFnSe8z Fb0J0cDY2jam7h7Q+d0XffE/TGeD5gAoajRvPXWxuoOpxjdlb7wRThElrfMazEU4 rRxqMoXJkMNd9+DnEvOGuwe7xIxbZuKL6Nf+8+0EYcmy21wFAEbtZQYJzNL5Unju ADp7xZZZKyOr62Nxctgy7CYUd2Y6sSm6u6bR3bYuwaOUYcJ3R2dq3OkehQTGoYhs UJgSSiyKiQafZ/d3CvYSedv63LAHsx1M6KXrA2WPhsrnYNA/w+J9g== Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee886mgjh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:18 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs9LX029222; Fri, 29 May 2026 15:56:16 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgks5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:16 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu7tH50004440 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:08 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DC33820040; Fri, 29 May 2026 15:56:07 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 8EDCA2004B; Fri, 29 May 2026 15:56:07 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:07 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 15/26] s390: Add functions to query arm guest time Date: Fri, 29 May 2026 17:55:48 +0200 Message-ID: <20260529155601.2927240-16-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: zh0j-2KLsmXGXQtSfEQu2miThfmIi10t X-Authority-Analysis: v=2.4 cv=Z8Dc2nRA c=1 sm=1 tr=0 ts=6a19b722 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=Hmczd7efCeE0AqCQNNQA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfXwHVnBeyemYoW TMg9EI8tQhju9p1KhbfdE08dbjeWDSJ8P5oJJCiJ6wup0bFIwxSCgUcFure2M36PZCTQfq3uWza /rakQn7/qjlP2ZWcpWwcSzwdDu8X3ZjU9x2f1jRQ/tUO0z7WV/z3OmJVfeIcDYlzHoRcx6kvtBy xko2J7N3LnkDLWTiPhbpDNrv32fDd54Uyw+3qAg77u75nfceFUzxGg6NzWAGAIVe1uILaJX7s8t 2c6ZzWQNt87a5st8cZ70HkjrVKmT4Yudclhq+XCCJM8cdysaUAZDyZ7knZicepFWnTNU91xVR8v IvxIHaQCp2uIBqV/DSlDKKYwTygRUnNPObi27ULQ050OlaT7q6lSmpeQ8bBNEtViePN2hU4zg8Y 6/trH9IAoFstnckcZfvfBy5a0DcodKx/3ocBxFacSrwjb0k4dJCcP+L+V10RobxUk5ID5yMl/aa 94fQ/gYd6qQ0twv0o/g== X-Proofpoint-ORIG-GUID: zh0j-2KLsmXGXQtSfEQu2miThfmIi10t X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 bulkscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 phishscore=0 suspectscore=0 adultscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Add functions to convert between ARM guest time (LSB0) and s390 host time (MSB0) using new ptff function codes. Co-developed-by: Nico Boehr Signed-off-by: Nico Boehr Signed-off-by: Steffen Eiden --- arch/s390/include/asm/timex.h | 49 +++++++++++++++++++++++++++++++++++ arch/s390/kernel/time.c | 1 + arch/s390/kvm/arm64/arm.c | 9 ++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index 49447b40f038..9ec22a28bbda 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -99,6 +99,8 @@ extern unsigned char ptff_function_mask[16]; #define PTFF_QSI 0x02 /* query steering information */ #define PTFF_QPT 0x03 /* query physical clock */ #define PTFF_QUI 0x04 /* query UTC information */ +#define PTFF_QAGTO 0x10 /* query arm guest time offset */ +#define PTFF_QAGPT 0x11 /* query arm guest physical time offset */ #define PTFF_ATO 0x40 /* adjust tod offset */ #define PTFF_STO 0x41 /* set tod offset */ #define PTFF_SFS 0x42 /* set fine steering rate */ @@ -136,6 +138,17 @@ struct ptff_qui { unsigned int pad_0x5c[41]; } __packed; =20 +/* + * Query Arm Guest Time + * used for: + * - Query Arm Guest Time Offset + * - Query Arm Guest Physical Time + */ +struct ptff_qagt { + u64 in; + u64 out; +}; + /* * ptff - Perform timing facility function * @ptff_block: Pointer to ptff parameter block @@ -286,4 +299,40 @@ static inline int tod_after_eq(unsigned long a, unsign= ed long b) return a >=3D b; } =20 +/* + * ptff_qagto() - Query Arm Guest Time Offset + * + * @physical_time: Arm guest physical time in MSb 0 + * + * Converts Arm guest physical time in MSb 0 bit ordering + * into the Arm guest offset in LSb 0 bit ordering. + * + * Return: Arm guest time offset in LSb 0 + */ +static inline u64 ptff_qagto(u64 physical_time) +{ + struct ptff_qagt qagto =3D { .in =3D physical_time }; + + ptff(&qagto, sizeof(qagto), PTFF_QAGTO); + return qagto.out; +} + +/* + * ptff_qagpt() - Query Arm Guest Physical Time + * + * @guest_time_offset: Arm guest time offset in MSb 0 + * + * Converts Arm guest offset in MSb 0 bit ordering + * into the Arm guest physical time in LSb 0 bit ordering. + * + * Return: Arm guest physical time in LSb 0 + * */ +static inline u64 ptff_qagpt(u64 guest_time_offset) +{ + struct ptff_qagt qagpt =3D { .in =3D guest_time_offset }; + + ptff(&qagpt, sizeof(qagpt), PTFF_QAGPT); + return qagpt.out; +} + #endif diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index bd0df61d1907..2b989bebd220 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -65,6 +65,7 @@ ATOMIC_NOTIFIER_HEAD(s390_epoch_delta_notifier); EXPORT_SYMBOL(s390_epoch_delta_notifier); =20 unsigned char ptff_function_mask[16]; +EXPORT_SYMBOL(ptff_function_mask); =20 static unsigned long lpar_offset; static unsigned long initial_leap_seconds; diff --git a/arch/s390/kvm/arm64/arm.c b/arch/s390/kvm/arm64/arm.c index bf0866659421..636bbeda98a8 100644 --- a/arch/s390/kvm/arm64/arm.c +++ b/arch/s390/kvm/arm64/arm.c @@ -692,8 +692,15 @@ long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, u= nsigned int ioctl, =20 static int __init kvm_s390_arm64_init(void) { - if (!sclp.has_aef) + if (!sclp.has_aef) { + pr_info("SAE is not available\n"); return -ENXIO; + } + + if (!(ptff_query(PTFF_QAGTO) && ptff_query(PTFF_QAGPT))) { + pr_info("PTFF for arm on s390 is not available\n"); + return -ENXIO; + } =20 return kvm_init_with_dev(sizeof(struct kvm_vcpu), 0, THIS_MODULE, KVM_DEV_NAME, MISC_DYNAMIC_MINOR); --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 03FD4402B82; Fri, 29 May 2026 15:56:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070205; cv=none; b=pgngsnvwSAVmsZrIzEOU1czOImyHhM/MezcNf7MMbnVdLxCz8oMvHQ+SXN6G3Bv+ydOoH/n9v9pgprLSvbnaq9jtNUEplxqAKOyq5Ff0j0cmr2HleupyaTBnJF3owRdpBaIwrd1S60aTXTa61F+asCtuF0JlZJKXfJMTHkBm5r8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070205; c=relaxed/simple; bh=2ivqFMlHIwtpqNyQCSR2gQAjjtAvPTwhTxp/oDtimZE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qAJzzteJc34zsFQv77dxcbG4r0Dl06uWeWAAfcVNxC8N7fqHX5d/cmRcq/B4ExIqAoOncLrS7wNDNB23l/DoxGtAefacxCS2YDAjwJm2b21ECeEkvhTtzywWJ8FFxTdQPtCUgB6/0D/XQBycYZEiTLc85nnl84yzQsZj3BJAvB0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=i6RMln5/; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="i6RMln5/" Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFEloI1687341; Fri, 29 May 2026 15:56:16 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=e3M5oeXK8/HvvH8AI JsdSiaYNNCDui2bO7UvB9DCeHA=; b=i6RMln5/jJlE9sRYdUs19yeO3qgElHN75 w1OYoFfHfGoHKbqwXGHgxcRg7zGPauhY5bO7zvnJWXSnSjk83Kc2KFDrfYLcRnJq LTbZERCSq0zDuiueEEBqMNFrhgaRGIbISlU3KCr2eCVVMHqcza9PVP7RfK9+d4Xl 90p6xPYL6zeGLIcd27eYB1NdK5iQk7vIWwEDUivFo0UpifnchKNysEGphyclpb9u PRCZ6Ta6FKyky8lzqEdhG0oJbC3ULQ+YkRi5x0pfn7SxG8o6sziuIdEYUP8Z+w4E 8QTN+b7M4KRyGQvq8WbnaCm6/jwYZ0O6Ba2AgmCzTIE/xBT1nZEHA== Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884mh72-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:15 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs6O9016985; Fri, 29 May 2026 15:56:14 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgjpw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu8Kp30212444 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:08 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 40F1B20040; Fri, 29 May 2026 15:56:08 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E6FFB2004D; Fri, 29 May 2026 15:56:07 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:07 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 16/26] KVM: s390: arm64: Add sysreg related functions and definitions Date: Fri, 29 May 2026 17:55:49 +0200 Message-ID: <20260529155601.2927240-17-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=fIYJG5ae c=1 sm=1 tr=0 ts=6a19b71f cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=MsWRDpXVTiI-Ka77MfMA:9 X-Proofpoint-ORIG-GUID: 59SpjLFTUJAUYtbHRDBRyeo-pxmJMK2j X-Proofpoint-GUID: 59SpjLFTUJAUYtbHRDBRyeo-pxmJMK2j X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfXxHpZFV9dBMdY maZ4wn1wka7bBZQJPfQGGkbJ+DdOlFxGM5Q8fB8ATc430t4I2iLPXu7w0nqbnG5xtNNVb1UWlAt B7W1FnC51ffdKIzio9Ejid7scvtLtfOes//jH2NU63b8rd5WXNW6nrNYr6gR+B6X0NR/Fp+Jvqg awXd6NKhIe+R8u1B1/5uC0HzyiQk/p0XRm4ED1TsRHhedo+8vQIcTJZPSTC5J0E8eZGhL/Reepr JsAntrgqoFy8XUw88bDx2S9D5uMUTRVSj8xcG9O35p4MfMCZkemBEXkCafIE94OypLjDezgCfFD F3+B79bWhV3Oj63VS9fjghDNUJgBI81BhxNW4X5kTNc5rSUXQvm2eZGQgmTYjq0HeEnMo9cQWQi D3huPyi/X4TUH++KGY9NmDl3ZhfMWRuM3aCUbsw6sMBa1GUEa7R2mANkgtB1KyIIxLvAlfau8UM L+cJAriTG89JsQQm/lA== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 adultscore=0 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Add guest sysreg access macros in asm/kvm_host_arm64.h using easr()/sasr()-based helpers for sysregs that map to the SAE save area. Also add the guest-visible sysreg enum and per-vCPU/per-VM storage for state that is not directly covered by the save area, such as CLIDR_EL1, CSSELR_EL1, MPIDR_EL1, and VM-wide ID register state. This lays out the header-side definitions needed to ensure compilation success during for the share-code-patches and later sysreg handling during vCPU setup and runtime. Signed-off-by: Steffen Eiden --- arch/s390/include/asm/kvm_host_arm64.h | 165 +++++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/arch/s390/include/asm/kvm_host_arm64.h b/arch/s390/include/asm= /kvm_host_arm64.h index 8c3214c5b004..d6d9e3ad7a8e 100644 --- a/arch/s390/include/asm/kvm_host_arm64.h +++ b/arch/s390/include/asm/kvm_host_arm64.h @@ -44,10 +44,19 @@ struct kvm_vcpu_arch { struct kvm_sae_save_area save_area; struct kvm_cpu_context ctxt; =20 + /* Guest system registers not part of save area or ID registers */ + u64 sys_reg_clidr_el1; + u64 sys_reg_csselr_el1; + /* Per-vcpu CCSIDR override or NULL */ + u32 *ccsidr; + u32 host_acrs[NUM_ACRS]; =20 /* Hypervisor Configuration Register */ u64 hcr_elz; + u64 hcrx_elz; + + u64 mpidr; =20 /* Configuration flags, set once and for all before the vcpu can run */ u8 cflags; @@ -209,4 +218,160 @@ static inline void kvm_arch_async_page_present_queued= (struct kvm_vcpu *vcpu) =20 #define kvm_supports_32bit_el0() false =20 +#define vcpu_read_sys_reg(_v, _r) 0xbad1234bad +#define vcpu_write_sys_reg(_v, _p, _r) ((void)0) + +#define __vcpu_sys_reg(__vcpu, __reg) \ + vcpu_read_sys_reg(__vcpu, __reg) + +#define __vcpu_assign_sys_reg(__vcpu, __reg, __val) \ + vcpu_write_sys_reg(__vcpu, __val, __reg) + +/* Read, modify and write system register + * + */ +#define _vcpu_rmw_sys_reg(C, V, OP, R) \ +({ \ + u64 __val =3D vcpu_read_sys_reg(C, R); \ + __val OP V; \ + vcpu_write_sys_reg(C, __val, R); \ +}) + +/** + * _vcpu_read_sys_reg() - read a guest sysreg with easr + * - R - sysreg id; must be readable by easr; must be compile time constant + * + * if SYSREGS_ON_CPU: proceed with flags =3D 0 + * otherwise: proceed with either + * read: flags =3D EASR_FLAG_SA + * write: flags =3D SASR_FLAG_INITIALIZED + * + */ +#define _vcpu_read_sys_reg(C, R) \ + ({ BUILD_BUG_ON(!__builtin_constant_p((R))); \ + BUG_ON(vcpu_is_loaded(C) && smp_processor_id() !=3D (C)->cpu); \ + (vcpu_is_loaded(C)) \ + ? __vcpu_read_sr((C), (R), 0) \ + : __vcpu_read_sr((C), (R), EASR_FLAG_SA); }) + +/** + * _vcpu_write_sys_reg() - write a guest sysreg with sasr + * - R - sysreg id; must be readable by sasr; must be compile time constant + + * if SYSREGS_ON_CPU: proceed with flags =3D 0 + * otherwise: proceed with either + * read: flags =3D EASR_FLAG_SA + * write: flags =3D SASR_FLAG_INITIALIZED + */ +#define _vcpu_write_sys_reg(C, V, R) \ + ({ BUILD_BUG_ON(!__builtin_constant_p((R))); \ + BUG_ON(vcpu_is_loaded(C) && smp_processor_id() !=3D (C)->cpu); \ + (vcpu_is_loaded(C)) \ + ? __vcpu_write_sr((C), (V), (R), 0) \ + : __vcpu_write_sr((C), (V), (R), SASR_FLAG_INITIALIZED); }) + +/* Forward to easr / sasr + * assert that F and R are constant + */ +#define __vcpu_read_sr(C, R, F) \ + ({ BUILD_BUG_ON(!__builtin_constant_p((R))); \ + BUILD_BUG_ON(!__builtin_constant_p((F))); \ + easr((R), &(C)->arch.save_area, (F)); }) + +#define __vcpu_write_sr(C, V, R, F) \ + ({ BUILD_BUG_ON(!__builtin_constant_p((R))); \ + BUILD_BUG_ON(!__builtin_constant_p((F))); \ + sasr((R), (V), &(C)->arch.save_area, (F)); }) + +#define SR_GROUP(NAME, ...) \ + __##NAME##_BEGIN__, \ + __VA_ARGS__ \ + __##NAME##_END__ + +/** enum vcpu_sysreg - available guest sysregs + * + * Contains all arm64 guest-syregs supported by s390. + */ +enum vcpu_sysreg { + __INVALID_SYSREG__, /* 0 is reserved as an invalid value */ + + /* EL 0,1 Register from state description in order of appearance */ + SR_GROUP(STATE_DESC, + CNTP_CTL_EL0, + CNTV_CTL_EL0, + CONTEXTIDR_EL1, + SP_EL1, + ), + + /* EL 0,1 Register requiring special handling. */ + SR_GROUP(SPECIAL, + CSSELR_EL1, + CLIDR_EL1, + MPIDR_EL1, + ), + + /* EL 0,1 register from save area in order of appearance */ + SR_GROUP(SAVE_AREA, + ACTLR_EL1, + AFSR0_EL1, + AFSR1_EL1, + CNTFRQ_EL0, + CNTP_CVAL_EL0, + CNTV_CVAL_EL0, + DISR_EL1, + MIDR_EL1, + OSLSR_EL1, + PAR_EL1, + OSLAR_EL1, + SCTLR_EL1, + CPACR_EL1, + VBAR_EL1, + SPSR_EL1, + ELR_EL1, + ESR_EL1, + TCR_EL1, + MAIR_EL1, + TTBR0_EL1, + TTBR1_EL1, + FAR_EL1, + TPIDR_EL0, + TPIDR_EL1, + TPIDRRO_EL0, + CNTKCTL_EL1, + ZCR_EL1, + SCXTNUM_EL0, + SCXTNUM_EL1, + APIBKEYLO_EL1, + APIBKEYHI_EL1, + APIAKEYLO_EL1, + APIAKEYHI_EL1, + APGAKEYLO_EL1, + APGAKEYHI_EL1, + APDBKEYLO_EL1, + APDBKEYHI_EL1, + APDAKEYLO_EL1, + APDAKEYHI_EL1, + MDSCR_EL1, + ), + + NR_SYS_REGS /* Nothing after this line! */ +}; + +void vcpu_write_host_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg); +u64 vcpu_read_host_sys_reg(const struct kvm_vcpu *vcpu, int reg); + +#define kvm_debug_handle_oslar(_v, _val) /* debug not implemented yet*/ + +static inline u8 kvm_arm_pmu_get_pmuver_limit(void) +{ + return 0; +} + +int __init kvm_sys_reg_table_init(void); + +static inline u64 kvm_sanitised_host_ftr_reg(u32 id) +{ + return 0xbad1234bad; +} + #endif /* ASM_KVM_HOST_ARM64_H */ --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 2687C42E00A; Fri, 29 May 2026 15:56:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070215; cv=none; b=h0Wj0vCOkAidocOMVEz39QCtvROyStt6BuYrOdwfPC4giWR0DCPSsw2bMi6uARbZ+40twDImjQYGpdwvjKx5gm+ob68LLMMJaBk8zIMUeO0hBCuZB9wbuAclkd+RBd6HsNRlUNMXjIyeXzsL3fUOB2QhPuYESwMa/pTxdIBNfOc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070215; c=relaxed/simple; bh=nvH5ExHBNuEU0ejc4JAuj1WtgtBL0E6UaEDyVGGLJUg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JPTFMUsXSB7vrCNyGqlH7pd22YmESSsT2fIXC/V8n6imYlvBRTUOWZqRUEdTMTWJZWLftppoJx9jfsaJoFtoU1iZAcXoledKLghrt0Exl+aoQDMazMEFE+3mffXjuvr73uMLpdOgVRs6iNlYhFh37eBmpjtrr1qhkdqLULMPLrM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=VQ9qNVER; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="VQ9qNVER" Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TF73Vs2778440; Fri, 29 May 2026 15:56:19 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=Is1nyIcJfv6NVfSOr nexMYVzhmTQoSC3qzLaTacV2Nk=; b=VQ9qNVER0U9fgEyCiuxMLQBja3KHoy5zF irJwrYtYLf7aCPM3NzBL9FWDx1ciIm2p4S/tdpKXEwl+HtIX0KTgBQkig5rWEVJh NYA4FXgdNsbBhxN4VmW1ydayKts6cR/zj4eLzOucKOFbzJv6mttvo7JZ7C5WGCEb lJqXwTNttbMK+IOmSc/pB0HYf12pFRUqtRF70k9zW+o3LBH3rsLcBPVfI/GDSMaG /q2kAdAPLDbt07IUMY6hvzTVQIycZhTrSRbO0ZT7Ho85RKzdHC5mHtNhlNo/az+p EZfF38hBG4xUFbxGnUYOu6gpfRvg+43kUqsewoier5s5DOEFyKuRg== Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee889m2dq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:18 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs7Xa009669; Fri, 29 May 2026 15:56:17 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgkwa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:17 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu8FB30212446 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:08 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AFC6D20040; Fri, 29 May 2026 15:56:08 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4E2AC2004B; Fri, 29 May 2026 15:56:08 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:08 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 17/26] arm64: Extract cputype definitions. Date: Fri, 29 May 2026 17:55:50 +0200 Message-ID: <20260529155601.2927240-18-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: O_8cEhutoYgDeJRmdXjOcEwlst_hBrz4 X-Proofpoint-GUID: O_8cEhutoYgDeJRmdXjOcEwlst_hBrz4 X-Authority-Analysis: v=2.4 cv=XqfK/1F9 c=1 sm=1 tr=0 ts=6a19b723 cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=T5dvmTGJR8rAyywy3tIA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfXz7uDMCyl0q2e IriHEkU9hzFpxAFfGTcC9HzsooxKWns80nuTxf+ZI7uS7YmmgYK/GfFMjE0s/J60H6peW4AcKUA qVY2yQ1MPflYyXEygYeL7nNCOFWkqasJ2/L6ub4uQ3lpJGFh4ZRDwMFuFO27eUmqmLmiaA6IlVy u5vEG8ABEdNvXl4bvFqNEI/jV1wqhPSVLl+QSrAWIWrrh5yKT8iPGiPBTJo1j4nmMDCFRV0g+s4 JEFmPBsxXreBkfCk3l6VOyaU7AMGkR8WUXnsMVdNvRdJvoh50dNvb0xeFneEhDI/dL74ETxdp/L W/CjBrPodXuChuS3WPP3h3dDzkf6OGhLhr0+suIaUYO+LAKmHx9L0J43+LC6B8bcjp7JreUrQT8 edm8z84Pxbn2V4s7hRIZeJlNpBCu2oIG3CqrYOOieAP7C1DWcie58Crfu7YYkDdxae/cBVMUbic U9xh2jMxiffnzM9q1fA== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 impostorscore=0 adultscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 bulkscore=0 suspectscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Move CPU type definitions from arch/arm64/include/asm/cputype.h to include/arch/arm64/asm/cputype-defs.h to prepare sharing with other architectures. No functional changes. Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/cputype.h | 246 +----------------- .../arch/arm64/asm/cputype-defs.h | 92 +------ 2 files changed, 6 insertions(+), 332 deletions(-) copy arch/arm64/include/asm/cputype.h =3D> include/arch/arm64/asm/cputype-= defs.h (85%) diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cput= ype.h index 7b518e81dd15..67765cdbce84 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -5,251 +5,7 @@ #ifndef __ASM_CPUTYPE_H #define __ASM_CPUTYPE_H =20 -#define INVALID_HWID ULONG_MAX - -#define MPIDR_UP_BITMASK (0x1 << 30) -#define MPIDR_MT_BITMASK (0x1 << 24) -#define MPIDR_HWID_BITMASK UL(0xff00ffffff) - -#define MPIDR_LEVEL_BITS_SHIFT 3 -#define MPIDR_LEVEL_BITS (1 << MPIDR_LEVEL_BITS_SHIFT) -#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) - -#define MPIDR_LEVEL_SHIFT(level) \ - (((1 << level) >> 1) << MPIDR_LEVEL_BITS_SHIFT) - -#define MPIDR_AFFINITY_LEVEL(mpidr, level) \ - ((mpidr >> MPIDR_LEVEL_SHIFT(level)) & MPIDR_LEVEL_MASK) - -#define MIDR_REVISION_MASK 0xf -#define MIDR_REVISION(midr) ((midr) & MIDR_REVISION_MASK) -#define MIDR_PARTNUM_SHIFT 4 -#define MIDR_PARTNUM_MASK (0xfff << MIDR_PARTNUM_SHIFT) -#define MIDR_PARTNUM(midr) \ - (((midr) & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT) -#define MIDR_ARCHITECTURE_SHIFT 16 -#define MIDR_ARCHITECTURE_MASK (0xf << MIDR_ARCHITECTURE_SHIFT) -#define MIDR_ARCHITECTURE(midr) \ - (((midr) & MIDR_ARCHITECTURE_MASK) >> MIDR_ARCHITECTURE_SHIFT) -#define MIDR_VARIANT_SHIFT 20 -#define MIDR_VARIANT_MASK (0xf << MIDR_VARIANT_SHIFT) -#define MIDR_VARIANT(midr) \ - (((midr) & MIDR_VARIANT_MASK) >> MIDR_VARIANT_SHIFT) -#define MIDR_IMPLEMENTOR_SHIFT 24 -#define MIDR_IMPLEMENTOR_MASK (0xffU << MIDR_IMPLEMENTOR_SHIFT) -#define MIDR_IMPLEMENTOR(midr) \ - (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT) - -#define MIDR_CPU_MODEL(imp, partnum) \ - ((_AT(u32, imp) << MIDR_IMPLEMENTOR_SHIFT) | \ - (0xf << MIDR_ARCHITECTURE_SHIFT) | \ - ((partnum) << MIDR_PARTNUM_SHIFT)) - -#define MIDR_CPU_VAR_REV(var, rev) \ - (((var) << MIDR_VARIANT_SHIFT) | (rev)) - -#define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \ - MIDR_ARCHITECTURE_MASK) - -#define ARM_CPU_IMP_ARM 0x41 -#define ARM_CPU_IMP_APM 0x50 -#define ARM_CPU_IMP_CAVIUM 0x43 -#define ARM_CPU_IMP_BRCM 0x42 -#define ARM_CPU_IMP_QCOM 0x51 -#define ARM_CPU_IMP_NVIDIA 0x4E -#define ARM_CPU_IMP_FUJITSU 0x46 -#define ARM_CPU_IMP_HISI 0x48 -#define ARM_CPU_IMP_APPLE 0x61 -#define ARM_CPU_IMP_AMPERE 0xC0 -#define ARM_CPU_IMP_MICROSOFT 0x6D - -#define ARM_CPU_PART_AEM_V8 0xD0F -#define ARM_CPU_PART_FOUNDATION 0xD00 -#define ARM_CPU_PART_CORTEX_A57 0xD07 -#define ARM_CPU_PART_CORTEX_A72 0xD08 -#define ARM_CPU_PART_CORTEX_A53 0xD03 -#define ARM_CPU_PART_CORTEX_A73 0xD09 -#define ARM_CPU_PART_CORTEX_A75 0xD0A -#define ARM_CPU_PART_CORTEX_A35 0xD04 -#define ARM_CPU_PART_CORTEX_A55 0xD05 -#define ARM_CPU_PART_CORTEX_A76 0xD0B -#define ARM_CPU_PART_NEOVERSE_N1 0xD0C -#define ARM_CPU_PART_CORTEX_A77 0xD0D -#define ARM_CPU_PART_CORTEX_A76AE 0xD0E -#define ARM_CPU_PART_NEOVERSE_V1 0xD40 -#define ARM_CPU_PART_CORTEX_A78 0xD41 -#define ARM_CPU_PART_CORTEX_A78AE 0xD42 -#define ARM_CPU_PART_CORTEX_X1 0xD44 -#define ARM_CPU_PART_CORTEX_A510 0xD46 -#define ARM_CPU_PART_CORTEX_A520 0xD80 -#define ARM_CPU_PART_CORTEX_A710 0xD47 -#define ARM_CPU_PART_CORTEX_A715 0xD4D -#define ARM_CPU_PART_CORTEX_X2 0xD48 -#define ARM_CPU_PART_NEOVERSE_N2 0xD49 -#define ARM_CPU_PART_CORTEX_A78C 0xD4B -#define ARM_CPU_PART_CORTEX_X1C 0xD4C -#define ARM_CPU_PART_CORTEX_X3 0xD4E -#define ARM_CPU_PART_NEOVERSE_V2 0xD4F -#define ARM_CPU_PART_CORTEX_A720 0xD81 -#define ARM_CPU_PART_CORTEX_X4 0xD82 -#define ARM_CPU_PART_NEOVERSE_V3AE 0xD83 -#define ARM_CPU_PART_NEOVERSE_V3 0xD84 -#define ARM_CPU_PART_CORTEX_X925 0xD85 -#define ARM_CPU_PART_CORTEX_A725 0xD87 -#define ARM_CPU_PART_CORTEX_A720AE 0xD89 -#define ARM_CPU_PART_NEOVERSE_N3 0xD8E -#define ARM_CPU_PART_C1_PRO 0xD8B - -#define APM_CPU_PART_XGENE 0x000 -#define APM_CPU_VAR_POTENZA 0x00 - -#define CAVIUM_CPU_PART_THUNDERX 0x0A1 -#define CAVIUM_CPU_PART_THUNDERX_81XX 0x0A2 -#define CAVIUM_CPU_PART_THUNDERX_83XX 0x0A3 -#define CAVIUM_CPU_PART_THUNDERX2 0x0AF -/* OcteonTx2 series */ -#define CAVIUM_CPU_PART_OCTX2_98XX 0x0B1 -#define CAVIUM_CPU_PART_OCTX2_96XX 0x0B2 -#define CAVIUM_CPU_PART_OCTX2_95XX 0x0B3 -#define CAVIUM_CPU_PART_OCTX2_95XXN 0x0B4 -#define CAVIUM_CPU_PART_OCTX2_95XXMM 0x0B5 -#define CAVIUM_CPU_PART_OCTX2_95XXO 0x0B6 - -#define BRCM_CPU_PART_BRAHMA_B53 0x100 -#define BRCM_CPU_PART_VULCAN 0x516 - -#define QCOM_CPU_PART_FALKOR_V1 0x800 -#define QCOM_CPU_PART_FALKOR 0xC00 -#define QCOM_CPU_PART_KRYO 0x200 -#define QCOM_CPU_PART_KRYO_2XX_GOLD 0x800 -#define QCOM_CPU_PART_KRYO_2XX_SILVER 0x801 -#define QCOM_CPU_PART_KRYO_3XX_GOLD 0x802 -#define QCOM_CPU_PART_KRYO_3XX_SILVER 0x803 -#define QCOM_CPU_PART_KRYO_4XX_GOLD 0x804 -#define QCOM_CPU_PART_KRYO_4XX_SILVER 0x805 -#define QCOM_CPU_PART_ORYON_X1 0x001 - -#define NVIDIA_CPU_PART_DENVER 0x003 -#define NVIDIA_CPU_PART_CARMEL 0x004 -#define NVIDIA_CPU_PART_OLYMPUS 0x010 - -#define FUJITSU_CPU_PART_A64FX 0x001 - -#define HISI_CPU_PART_TSV110 0xD01 -#define HISI_CPU_PART_HIP09 0xD02 -#define HISI_CPU_PART_HIP12 0xD06 - -#define APPLE_CPU_PART_M1_ICESTORM 0x022 -#define APPLE_CPU_PART_M1_FIRESTORM 0x023 -#define APPLE_CPU_PART_M1_ICESTORM_PRO 0x024 -#define APPLE_CPU_PART_M1_FIRESTORM_PRO 0x025 -#define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028 -#define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029 -#define APPLE_CPU_PART_M2_BLIZZARD 0x032 -#define APPLE_CPU_PART_M2_AVALANCHE 0x033 -#define APPLE_CPU_PART_M2_BLIZZARD_PRO 0x034 -#define APPLE_CPU_PART_M2_AVALANCHE_PRO 0x035 -#define APPLE_CPU_PART_M2_BLIZZARD_MAX 0x038 -#define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039 - -#define AMPERE_CPU_PART_AMPERE1 0xAC3 -#define AMPERE_CPU_PART_AMPERE1A 0xAC4 - -#define MICROSOFT_CPU_PART_AZURE_COBALT_100 0xD49 /* Based on r0p0 of ARM = Neoverse N2 */ - -#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_A53) -#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_A57) -#define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_A72) -#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_A73) -#define MIDR_CORTEX_A75 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_A75) -#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_A35) -#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_A55) -#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_A76) -#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOV= ERSE_N1) -#define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_A77) -#define MIDR_CORTEX_A76AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_COR= TEX_A76AE) -#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOV= ERSE_V1) -#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_A78) -#define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_COR= TEX_A78AE) -#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX= _X1) -#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORT= EX_A510) -#define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORT= EX_A520) -#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORT= EX_A710) -#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORT= EX_A715) -#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX= _X2) -#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOV= ERSE_N2) -#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORT= EX_A78C) -#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTE= X_X1C) -#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX= _X3) -#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOV= ERSE_V2) -#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORT= EX_A720) -#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX= _X4) -#define MIDR_NEOVERSE_V3AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NE= OVERSE_V3AE) -#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOV= ERSE_V3) -#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORT= EX_X925) -#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORT= EX_A725) -#define MIDR_CORTEX_A720AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CO= RTEX_A720AE) -#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOV= ERSE_N3) -#define MIDR_C1_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_PRO) -#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_T= HUNDERX) -#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_P= ART_THUNDERX_81XX) -#define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_P= ART_THUNDERX_83XX) -#define MIDR_OCTX2_98XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART= _OCTX2_98XX) -#define MIDR_OCTX2_96XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART= _OCTX2_96XX) -#define MIDR_OCTX2_95XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART= _OCTX2_95XX) -#define MIDR_OCTX2_95XXN MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PAR= T_OCTX2_95XXN) -#define MIDR_OCTX2_95XXMM MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PA= RT_OCTX2_95XXMM) -#define MIDR_OCTX2_95XXO MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PAR= T_OCTX2_95XXO) -#define MIDR_CAVIUM_THUNDERX2 MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CP= U_PART_THUNDERX2) -#define MIDR_BRAHMA_B53 MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_BRA= HMA_B53) -#define MIDR_BRCM_VULCAN MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VU= LCAN) -#define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART= _FALKOR_V1) -#define MIDR_QCOM_FALKOR MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FA= LKOR) -#define MIDR_QCOM_KRYO MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_KRYO) -#define MIDR_QCOM_KRYO_2XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_= PART_KRYO_2XX_GOLD) -#define MIDR_QCOM_KRYO_2XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CP= U_PART_KRYO_2XX_SILVER) -#define MIDR_QCOM_KRYO_3XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_= PART_KRYO_3XX_GOLD) -#define MIDR_QCOM_KRYO_3XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CP= U_PART_KRYO_3XX_SILVER) -#define MIDR_QCOM_KRYO_4XX_GOLD MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_= PART_KRYO_4XX_GOLD) -#define MIDR_QCOM_KRYO_4XX_SILVER MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CP= U_PART_KRYO_4XX_SILVER) -#define MIDR_QCOM_ORYON_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_= ORYON_X1) - -/* - * NOTES: - * - Qualcomm Kryo 5XX Prime / Gold ID themselves as MIDR_CORTEX_A77 - * - Qualcomm Kryo 5XX Silver IDs itself as MIDR_QCOM_KRYO_4XX_SILVER - * - Qualcomm Kryo 6XX Prime IDs itself as MIDR_CORTEX_X1 - * - Qualcomm Kryo 6XX Gold IDs itself as ARM_CPU_PART_CORTEX_A78 - * - Qualcomm Kryo 6XX Silver IDs itself as MIDR_CORTEX_A55 - */ - -#define MIDR_NVIDIA_DENVER MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_P= ART_DENVER) -#define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_P= ART_CARMEL) -#define MIDR_NVIDIA_OLYMPUS MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_= PART_OLYMPUS) -#define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU= _PART_A64FX) -#define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TS= V110) -#define MIDR_HISI_HIP09 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_HIP= 09) -#define MIDR_HISI_HIP12 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_HIP= 12) -#define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU= _PART_M1_ICESTORM) -#define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CP= U_PART_M1_FIRESTORM) -#define MIDR_APPLE_M1_ICESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE= _CPU_PART_M1_ICESTORM_PRO) -#define MIDR_APPLE_M1_FIRESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPL= E_CPU_PART_M1_FIRESTORM_PRO) -#define MIDR_APPLE_M1_ICESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE= _CPU_PART_M1_ICESTORM_MAX) -#define MIDR_APPLE_M1_FIRESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPL= E_CPU_PART_M1_FIRESTORM_MAX) -#define MIDR_APPLE_M2_BLIZZARD MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU= _PART_M2_BLIZZARD) -#define MIDR_APPLE_M2_AVALANCHE MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CP= U_PART_M2_AVALANCHE) -#define MIDR_APPLE_M2_BLIZZARD_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE= _CPU_PART_M2_BLIZZARD_PRO) -#define MIDR_APPLE_M2_AVALANCHE_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPL= E_CPU_PART_M2_AVALANCHE_PRO) -#define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE= _CPU_PART_M2_BLIZZARD_MAX) -#define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPL= E_CPU_PART_M2_AVALANCHE_MAX) -#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AM= PERE1) -#define MIDR_AMPERE1A MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_A= MPERE1A) -#define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSO= FT, MICROSOFT_CPU_PART_AZURE_COBALT_100) - -/* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */ -#define MIDR_FUJITSU_ERRATUM_010001 MIDR_FUJITSU_A64FX -#define MIDR_FUJITSU_ERRATUM_010001_MASK (~MIDR_CPU_VAR_REV(1, 0)) -#define TCR_CLEAR_FUJITSU_ERRATUM_010001 (TCR_EL1_NFD1 | TCR_EL1_NFD0) +#include =20 #ifndef __ASSEMBLER__ =20 diff --git a/arch/arm64/include/asm/cputype.h b/include/arch/arm64/asm/cput= ype-defs.h similarity index 85% copy from arch/arm64/include/asm/cputype.h copy to include/arch/arm64/asm/cputype-defs.h index 7b518e81dd15..6f5279aaaa19 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/include/arch/arm64/asm/cputype-defs.h @@ -1,9 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2012 ARM Ltd. - */ -#ifndef __ASM_CPUTYPE_H -#define __ASM_CPUTYPE_H +#ifndef __ASM_CPUTYPE_DEFS_H +#define __ASM_CPUTYPE_DEFS_H + +#include =20 #define INVALID_HWID ULONG_MAX =20 @@ -251,85 +250,4 @@ #define MIDR_FUJITSU_ERRATUM_010001_MASK (~MIDR_CPU_VAR_REV(1, 0)) #define TCR_CLEAR_FUJITSU_ERRATUM_010001 (TCR_EL1_NFD1 | TCR_EL1_NFD0) =20 -#ifndef __ASSEMBLER__ - -#include - -#define read_cpuid(reg) read_sysreg_s(SYS_ ## reg) - -/* - * The CPU ID never changes at run time, so we might as well tell the - * compiler that it's constant. Use this function to read the CPU ID - * rather than directly reading processor_id or read_cpuid() directly. - */ -static inline u32 __attribute_const__ read_cpuid_id(void) -{ - return read_cpuid(MIDR_EL1); -} - -/* - * Represent a range of MIDR values for a given CPU model and a - * range of variant/revision values. - * - * @model - CPU model as defined by MIDR_CPU_MODEL - * @rv_min - Minimum value for the revision/variant as defined by - * MIDR_CPU_VAR_REV - * @rv_max - Maximum value for the variant/revision for the range. - */ -struct midr_range { - u32 model; - u32 rv_min; - u32 rv_max; -}; - -#define MIDR_RANGE(m, v_min, r_min, v_max, r_max) \ - { \ - .model =3D m, \ - .rv_min =3D MIDR_CPU_VAR_REV(v_min, r_min), \ - .rv_max =3D MIDR_CPU_VAR_REV(v_max, r_max), \ - } - -#define MIDR_REV_RANGE(m, v, r_min, r_max) MIDR_RANGE(m, v, r_min, v, r_ma= x) -#define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r) -#define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf) - -static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min, - u32 rv_max) -{ - u32 _model =3D midr & MIDR_CPU_MODEL_MASK; - u32 rv =3D midr & (MIDR_REVISION_MASK | MIDR_VARIANT_MASK); - - return _model =3D=3D model && rv >=3D rv_min && rv <=3D rv_max; -} - -struct target_impl_cpu { - u64 midr; - u64 revidr; - u64 aidr; -}; - -bool cpu_errata_set_target_impl(u64 num, void *impl_cpus); -bool is_midr_in_range_list(struct midr_range const *ranges); - -static inline u64 __attribute_const__ read_cpuid_mpidr(void) -{ - return read_cpuid(MPIDR_EL1); -} - -static inline unsigned int __attribute_const__ read_cpuid_implementor(void) -{ - return MIDR_IMPLEMENTOR(read_cpuid_id()); -} - -static inline unsigned int __attribute_const__ read_cpuid_part_number(void) -{ - return MIDR_PARTNUM(read_cpuid_id()); -} - -static inline u32 __attribute_const__ read_cpuid_cachetype(void) -{ - return read_cpuid(CTR_EL0); -} -#endif /* __ASSEMBLER__ */ - -#endif +#endif /* __ASM_CPUTYPE_DEFS_H */ --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 23C7A3FCB05; Fri, 29 May 2026 15:56:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070196; cv=none; b=Ed0LGfF/bnIoZtbApAMkpeFuKGDmI/DZOXAvIBXsRWoLZ+QOPUeSWnZ9tIMn1z0JD0wBgI7ZHFJ9EiYlyua743RG5t8jxMntCvyfye9E+ewC6XNDXOTvL0xX9f1k6Zahs5kSJQVnHkk39inalSmeu6/Au1P138sKVy1sD0KCAF8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070196; c=relaxed/simple; bh=08dDH/WQ5nCpUwhSaD4IpI4Ds/DHX915A/9pOS+YeJ0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BCMm69/Un0dvaO6KQZ14ahmH/2/qzih64oXA28VDLHz0KEUbD72WHfMVsx1GFdwG7ivEvq3YYxUnPqGMnmJSD0Km+RH1/PWNzDiE7GXAH7TDED1PgCrRvtNadObZv99n+cerkTFkXjGk4vXg7hLcLVIHXQDKNBnK2+DEVkd+6yQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=mN6mvRaV; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="mN6mvRaV" Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TF3exw2418298; Fri, 29 May 2026 15:56:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=wFi3vpS98Cj8L/89G xByeqkjSs7xfkPP7T3TglTvHvU=; b=mN6mvRaV/WU2ABvtdg9qy1lVex6VQvKCF UctlLCEnILwDfr1GyNn9b/7miC5mIaVJWbeeT7kzGk3rtCU54290uUMrePWDfeOl yIdE2YkzZjPqh4/4OmVRHhN+9lMiNofSrH1mRIuMqXVVYhS3PB+rzSnuvNG26v3q KRwjrzRaZhZctmnFO8BElxqclp7mRQDcwLYLDCssE9saAW5M4wgl+Y23EChTqdlS AtXGUXPjl14KLg1sJ+a2+22CoTJrUTiZOdNLr2XCMuA1VpStuqZUVfyKRoeo5cHF 8vBOBw5JRauwpSBu4fv8g1whff7kZEKk/Z0gP/t45laIom4xCUSFQ== Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884vkrr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:17 +0000 (GMT) Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs5OA003161; Fri, 29 May 2026 15:56:16 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgmae-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:16 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay07.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu9U450594192 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:09 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1348820040; Fri, 29 May 2026 15:56:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BA18D2004D; Fri, 29 May 2026 15:56:08 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:08 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 18/26] arm64: Extract cache definitions Date: Fri, 29 May 2026 17:55:51 +0200 Message-ID: <20260529155601.2927240-19-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=L4MtheT8 c=1 sm=1 tr=0 ts=6a19b721 cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=VnNF1IyMAAAA:8 a=pRZW_VWv9im2awHLU-wA:9 X-Proofpoint-ORIG-GUID: slVjF5f-oq9tzH_qacJlnFctQDu0_ACn X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX8oPtDgaMF3m/ MK1rxSS24KimAM7XsXvGSzWrJUIQDlWN7vlqTJKBpq4YLq8slBqI21QltNLBxqL6sfhAYWDMkmn jX/TbdHyjz1bfKFB6mWCYOCXysOCkf0GM+kfz9F1UvX6lZPWlP0kesce3iV3o9EA5dZ2ICfO9PF lmHWj9khK3BOvHHKKJrens/l+KFqet1gMMLO0NKL9pnbMKOix2jizeCl48YESDv/pHUhCw/+C6L dq++JTdd8ckUxpzBagTClP5VP/LHq+0RMIOhsvyiWr4u6RU2v+9aqEqgewnrpXvI/NFyN3uI8r1 TNBGtV1n63cM5DGg0XHURVH9I1jma47Yz3PNyuk7Xu8xSp2Au66orrd9iYGPMwIL1WKM1ONyU3/ h/nmLRaakTdUQNPh63BJBCUD0n342it//rYPKiJaAaia1dEfoy/EVQkP7Ereh3zkaVxf28ToZgQ gFynb9FophKzvpV/E3w== X-Proofpoint-GUID: slVjF5f-oq9tzH_qacJlnFctQDu0_ACn X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 clxscore=1015 malwarescore=0 bulkscore=0 impostorscore=0 adultscore=0 priorityscore=1501 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Move CPU type definitions from arch/arm64/include/asm/cache.h.h to include/arch/arm64/asm/cache-defs.h to prepare sharing with other architectures. No functional changes. Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/cache.h | 19 ++----------------- include/arch/arm64/asm/cache-defs.h | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 17 deletions(-) create mode 100644 include/arch/arm64/asm/cache-defs.h diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h index 10a7ffadee3d..0f67fe470c29 100644 --- a/arch/arm64/include/asm/cache.h +++ b/arch/arm64/include/asm/cache.h @@ -5,26 +5,11 @@ #ifndef __ASM_CACHE_H #define __ASM_CACHE_H =20 +#include + #define L1_CACHE_SHIFT (6) #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) =20 -#define CLIDR_LOUU_SHIFT 27 -#define CLIDR_LOC_SHIFT 24 -#define CLIDR_LOUIS_SHIFT 21 - -#define CLIDR_LOUU(clidr) (((clidr) >> CLIDR_LOUU_SHIFT) & 0x7) -#define CLIDR_LOC(clidr) (((clidr) >> CLIDR_LOC_SHIFT) & 0x7) -#define CLIDR_LOUIS(clidr) (((clidr) >> CLIDR_LOUIS_SHIFT) & 0x7) - -/* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n =3D 1 to 7 */ -#define CLIDR_CTYPE_SHIFT(level) (3 * (level - 1)) -#define CLIDR_CTYPE_MASK(level) (7 << CLIDR_CTYPE_SHIFT(level)) -#define CLIDR_CTYPE(clidr, level) \ - (((clidr) & CLIDR_CTYPE_MASK(level)) >> CLIDR_CTYPE_SHIFT(level)) - -/* Ttypen, bits [2(n - 1) + 34 : 2(n - 1) + 33], for n =3D 1 to 7 */ -#define CLIDR_TTYPE_SHIFT(level) (2 * ((level) - 1) + CLIDR_EL1_Ttypen_SHI= FT) - /* * Memory returned by kmalloc() may be used for DMA, so we must make * sure that all such allocations are cache aligned. Otherwise, diff --git a/include/arch/arm64/asm/cache-defs.h b/include/arch/arm64/asm/c= ache-defs.h new file mode 100644 index 000000000000..bb0ab69a9cd6 --- /dev/null +++ b/include/arch/arm64/asm/cache-defs.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ASM_CACHE_DEFS_H +#define __ASM_CACHE_DEFS_H + +#define CLIDR_LOUU_SHIFT 27 +#define CLIDR_LOC_SHIFT 24 +#define CLIDR_LOUIS_SHIFT 21 + +#define CLIDR_LOUU(clidr) (((clidr) >> CLIDR_LOUU_SHIFT) & 0x7) +#define CLIDR_LOC(clidr) (((clidr) >> CLIDR_LOC_SHIFT) & 0x7) +#define CLIDR_LOUIS(clidr) (((clidr) >> CLIDR_LOUIS_SHIFT) & 0x7) + +/* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n =3D 1 to 7 */ +#define CLIDR_CTYPE_SHIFT(level) (3 * (level - 1)) +#define CLIDR_CTYPE_MASK(level) (7 << CLIDR_CTYPE_SHIFT(level)) +#define CLIDR_CTYPE(clidr, level) \ + (((clidr) & CLIDR_CTYPE_MASK(level)) >> CLIDR_CTYPE_SHIFT(level)) + +/* Ttypen, bits [2(n - 1) + 34 : 2(n - 1) + 33], for n =3D 1 to 7 */ +#define CLIDR_TTYPE_SHIFT(level) (2 * ((level) - 1) + CLIDR_EL1_Ttypen_SHI= FT) + +#endif /* __ASM_CACHE_DEFS_H */ --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 163E442189A; Fri, 29 May 2026 15:56:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070208; cv=none; b=oza2isq34YbJjaHAaJULgLB3T1anSS6489hKnNX+41QpeS7Wxe6fqDlUq2c7K6YM7TCBpFnvGo0qasabJJysWEPYE1lQauCwj1WrUEPj+M2vf3yCZewxo1mdZWiNvrD1C75QH+1XWAjU3z73U2CVuyC77cQVVk9vugBiX5KqqnU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070208; c=relaxed/simple; bh=7UbxpkEnieP8qmC8SH0fNHWVwIA7YnI3HCzNjXbo/iQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y+WEfErGgCIPw6skcauCndeI99TE/jhw0fbXnQnVW5YtB2Oz+zKUeHAF/BPQwXUNvc/YEGhFm3oM6fHhDTK6nyfB9/gwpP72bq1CtA+wC6Wh2KEOe1jUWUiWIrC0mkgwa+FiigEEkTmDJxIdpK++gkED6qjAuUMpEKMp2NJreEI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=Br07LJqV; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="Br07LJqV" Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFAYU72776975; Fri, 29 May 2026 15:56:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=HvS5ygHypbJ75jCe1 4OYm4t9n4F8Jw6nQDIGnTnTBbo=; b=Br07LJqVccDj11BHABnbfpAinPDJhDQyz //ajbUVn59mmqveBwbisoas67DHY4xyZ0+9DKfKcrRqP8ViC/0s9d/OByh6PkPHM JQgIahsuwnBMgwNoU1ndbbmROOlgu+5sWBwa2DPUddABnkXPKSK1rGL3S9U5w7da FgZ6g3yWFT095uoeTUauo7zszH7AW2noaEwFlaDRSoTgdwUrmJfb9YfzkTPcKVG2 7LTbuDFfByuN/4lJ3yCFT6/rWxsWuz9PGA6o4It/XIoaA/9kK7+UV0MvYQwAcGha AmBKsnb28U/x20o9IuZ36dj/OxPQxj2vT8kZi+9fOjvUQum5ryrsg== Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee889m2d6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:17 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs7d9009674; Fri, 29 May 2026 15:56:16 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgkw0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:16 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay07.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu9tX47120694 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:09 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 72F0020040; Fri, 29 May 2026 15:56:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 217952004B; Fri, 29 May 2026 15:56:09 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:09 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 19/26] KVM: arm64: Share KVM feature detection macros Date: Fri, 29 May 2026 17:55:52 +0200 Message-ID: <20260529155601.2927240-20-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: g14Y61h8uAxZVsdbu3T7k6nMLecUnH8y X-Proofpoint-GUID: g14Y61h8uAxZVsdbu3T7k6nMLecUnH8y X-Authority-Analysis: v=2.4 cv=XqfK/1F9 c=1 sm=1 tr=0 ts=6a19b721 cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=jOJeQztrt6vKKCgc4XMA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX/jwSK6rRsyho 2nIBltCjJMUMeEh8dKZ2tjLZobHXN+jrO55sYqE797bQ4oESaB0Hgb5ZVPXr/a1bBgpyDmSYFom PDhcdBMBn+dMREelMLs8A/8oG+1Mymfx2l5JhZ6re8aISrUtFYQTiacebKWG8DUY/2UbmP+97yW LSsj6YH9rDl9eggcv55CXKj0fyGwUTV9iTaLUH7GQB4PbRWH8TPDQc9dUuYIrD52r3K//LV7Cty DMQJU3MxDCShags7TJTCwzhjfs6DF5Uj4gMJROus5Q9gyvN5GLId2fnG13SS4t/Y4FtyF1wKGFk rqM69GF/9KwW23ZqDvd0FdNAASLREImVIryp0AamhgyMg0ffZKEB7hx6pezvjI9IWPGc0nAlQw+ iSC7lgubovmbAEVBcWZVmT7BL3akZPwwjgDQcNebahUVJHYBkf+/yxI93r21MVz/VGZa0YrKEzY tKHg5MAz8vUjKO1ZEvg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 impostorscore=0 adultscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 bulkscore=0 suspectscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Move kvm feature definitions from arch/arm64/include to a shared location (include/kvm/arm64) to enable reuse by e.g. s390 for KVM/arm64 on s390 support. Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_feature.h | 60 +------------------ .../asm =3D> include/kvm/arm64}/kvm_feature.h | 28 ++------- 2 files changed, 5 insertions(+), 83 deletions(-) copy {arch/arm64/include/asm =3D> include/kvm/arm64}/kvm_feature.h (76%) diff --git a/arch/arm64/include/asm/kvm_feature.h b/arch/arm64/include/asm/= kvm_feature.h index 27a472d2343e..e1fb8b9f5ce2 100644 --- a/arch/arm64/include/asm/kvm_feature.h +++ b/arch/arm64/include/asm/kvm_feature.h @@ -2,65 +2,7 @@ #ifndef __ARM64_KVM_FEATURE_H__ #define __ARM64_KVM_FEATURE_H__ =20 -#include -#include -#include - -#define extract_id_field_unsigned(val, id, fld) \ - (FIELD_GET(id##_##fld##_MASK, (val))) - -#define extract_id_field_signed(val, id, fld) \ - ({ \ - u64 __val =3D extract_id_field_unsigned((val), id, fld); \ - sign_extend64(__val, id##_##fld##_WIDTH - 1); \ - }) - -#define cmp_id_feat_signed(val, id, fld, op, limit) \ - (extract_id_field_signed((val), id, fld) op S64_SYS_FIELD_VALUE(id, fld, = limit)) - -#define cmp_id_feat_unsigned(val, id, fld, op, limit) \ - (extract_id_field_unsigned((val), id, fld) op (u64)SYS_FIELD_VALUE(id, fl= d, limit)) - -#define cmp_id_feat(val, id, fld, op, limit) \ - (id##_##fld##_SIGNED ? \ - cmp_id_feat_signed(val, id, fld, op, limit) : \ - cmp_id_feat_unsigned(val, id, fld, op, limit)) - -#define id_has_feat(val, id, fld, limit) \ - cmp_id_feat(val, id, fld, >=3D, limit) - -#define id_has_feat_enum(val, id, fld, variant) \ - cmp_id_feat_unsigned(val, id, fld, =3D=3D, variant) - -#define id_has_feat_range(val, id, fld, min, max) \ - (cmp_id_feat(val, id, fld, >=3D, min) && \ - cmp_id_feat(val, id, fld, <=3D, max)) - -#define __kvm_has_feat(kvm, id, fld, limit) \ - id_has_feat(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, limit) - -#define kvm_has_feat(kvm, ...) __kvm_has_feat(kvm, __VA_ARGS__) - -#define __kvm_has_feat_enum(kvm, id, fld, val) \ - id_has_feat_enum(kvm_read_vm_id_reg((kvm), SYS_##id), id, fld, val) - -#define kvm_has_feat_enum(kvm, ...) __kvm_has_feat_enum(kvm, __VA_ARGS__) - - -/* Check for a given level of PAuth support */ -#define kvm_has_pauth(k, l) \ - ({ \ - bool pa, pi, pa3; \ - \ - pa =3D kvm_has_feat((k), ID_AA64ISAR1_EL1, APA, l); \ - pa &=3D kvm_has_feat((k), ID_AA64ISAR1_EL1, GPA, IMP); \ - pi =3D kvm_has_feat((k), ID_AA64ISAR1_EL1, API, l); \ - pi &=3D kvm_has_feat((k), ID_AA64ISAR1_EL1, GPI, IMP); \ - pa3 =3D kvm_has_feat((k), ID_AA64ISAR2_EL1, APA3, l); \ - pa3 &=3D kvm_has_feat((k), ID_AA64ISAR2_EL1, GPA3, IMP); \ - \ - (pa + pi + pa3) =3D=3D 1; \ - }) +#include =20 #define kvm_has_fpmr(k) \ (system_supports_fpmr() && \ diff --git a/arch/arm64/include/asm/kvm_feature.h b/include/kvm/arm64/kvm_f= eature.h similarity index 76% copy from arch/arm64/include/asm/kvm_feature.h copy to include/kvm/arm64/kvm_feature.h index 27a472d2343e..945abbbf1aa8 100644 --- a/arch/arm64/include/asm/kvm_feature.h +++ b/include/kvm/arm64/kvm_feature.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef __ARM64_KVM_FEATURE_H__ -#define __ARM64_KVM_FEATURE_H__ + +#ifndef __KVM_ARM64_FEATURE_H__ +#define __KVM_ARM64_FEATURE_H__ =20 #include #include @@ -46,7 +47,6 @@ =20 #define kvm_has_feat_enum(kvm, ...) __kvm_has_feat_enum(kvm, __VA_ARGS__) =20 - /* Check for a given level of PAuth support */ #define kvm_has_pauth(k, l) \ ({ \ @@ -62,24 +62,4 @@ (pa + pi + pa3) =3D=3D 1; \ }) =20 -#define kvm_has_fpmr(k) \ - (system_supports_fpmr() && \ - kvm_has_feat((k), ID_AA64PFR2_EL1, FPMR, IMP)) - -#define kvm_has_tcr2(k) \ - (kvm_has_feat((k), ID_AA64MMFR3_EL1, TCRX, IMP)) - -#define kvm_has_s1pie(k) \ - (kvm_has_feat((k), ID_AA64MMFR3_EL1, S1PIE, IMP)) - -#define kvm_has_s1poe(k) \ - (system_supports_poe() && \ - kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP)) - -#define kvm_has_ras(k) \ - (kvm_has_feat((k), ID_AA64PFR0_EL1, RAS, IMP)) - -#define kvm_has_sctlr2(k) \ - (kvm_has_feat((k), ID_AA64MMFR3_EL1, SCTLRX, IMP)) - -#endif /* __ARM64_KVM_FEATURE_H__*/ +#endif /* __KVM_ARM64_FEATURE_H__*/ --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 9A18E3FE646; Fri, 29 May 2026 15:56:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070199; cv=none; b=LhzSod373i9v0gEjmQqluNM+GfhXBUL+R4iu5MSy6kUgk/bLGC2wa6CtaA/uHCradtKQLq2NuIiUqdf9a6aOPiI1r6pNh+TiswmAzuNP1juXqXsVXQ3yi+7pYZ27Ft94JumvaSV8Ny28HmxlUA0SGCaarIf8blrF4mWXEekwkr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070199; c=relaxed/simple; bh=k6jpwAJD+GpMgdTOpupivcl9kr5vuQkQIUNZMLe2ItA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BywSlO6PrMiDQUmGoMIHYXpbn7Mz2fufpe8WfR5M3q8go5PdN+K7orAsdIANqgSZ+c/VhqdY9ciz+qg468F2Rvuv3gZw58kJd7ko6U4dvFXJMTYA+rqrYpLo19VlSGLIv7nv5yyghvrdyS8GL4bmGHpejhP5vbZUifJH6PELGV8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=K27KKNdr; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="K27KKNdr" Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFDGnm1684869; Fri, 29 May 2026 15:56:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=3Vy2znU6BE4rmaBvm 7MA/uVOlXjosiNrrWucqsFdf9c=; b=K27KKNdreoIEGHSTowUgvDrVoDEGlaaIk KKFeC2moTvrOwELxIq/fCLEUTqNwIR16vBd9KFN/EzVI7jFCQaSKMAY5ltCsQ8AW TupsHjs5vd3uBLKmMLAgnQe4AW+vRx7ArNUNcJImG8/Z3u3FMxMUpt2Sf/gx/tB0 slS9HntHuPN4IiRdzo+7gzKVAidoszJZ0LPI/uVRQHnvLlsZ839eauE6/DlbIIOp dbQtQziRMKjIvsFg/Q+U0Fdmzv88/ubR4+eWJBqAfQ4n7d/vaOJIeAMfXBCbvoM+ 8VJPdG3bJlp48Tf4d4FK5SSc7CMwhbrBwpyzR3NRtg5Ivn9Q6BDww== Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884mh8f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:18 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs5Ej016940; Fri, 29 May 2026 15:56:17 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgjr6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:17 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay07.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFu9ss47120700 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:09 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C734620040; Fri, 29 May 2026 15:56:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7A7352004E; Fri, 29 May 2026 15:56:09 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:09 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 20/26] KVM: arm64: Share ID reg handling Date: Fri, 29 May 2026 17:55:53 +0200 Message-ID: <20260529155601.2927240-21-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=fIYJG5ae c=1 sm=1 tr=0 ts=6a19b722 cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=zX106nZOjTGFKEJQ2UEA:9 X-Proofpoint-ORIG-GUID: ZzHTE0AERXso7IIrM-FN81R4I5MxuTO1 X-Proofpoint-GUID: ZzHTE0AERXso7IIrM-FN81R4I5MxuTO1 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX2vj6YkRj7S/C /fxSSkbOGVA5zBBSZdvjrlGMcnXyGE4kTca+RTxJLMmJsXkDHQFXBNywofBFuGNuvi3ZISjzWco 1HUwkMl1+js7fUQItP6Kp7bfj9rm84EQgt4+imjAEFLqtMfPgRnDtFdqq7yHFvUzZVzqAdAtSN0 aaCiARNmGFqHoFqzaiZBVQ4O2DFXi0XBCKg4ffzO3IRJr1yz8sYlIjaYcdBJ6RBPj+QyeV8iVZ3 SuhMcQLOkESCjOntKD5rZfHaZ9Wru02+ElmA7bGNb1ff2fwoIQzJR5NFE2mC1WPLroKkU00BJZg sB3vf8JpvAi8ZopBrJW1QQ9QEURxjgAlUvkNESpoiXGBGrVHwCejNHCEaOAXQuW6HA/Fq2yEa2I lmwlAq3XYm6a3CGhR9ZWSZ+r4TdSyRtZp4Nk/wVNja0D8sQCXf44s4CuqtHpmgaZr6Z8j9e/gFh EiE/w34gfmchWc+mn7g== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 clxscore=1015 adultscore=0 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Move ID register definitions from arch/arm64/include to a shared location (include/kvm/arm64) to enable reuse by e.g. s390 for KVM/arm64 on s390 support. Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_host.h | 41 ------------------------------ include/kvm/arm64/kvm_host.h | 42 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 5734e93cad57..a5fca468cc4a 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -1385,47 +1385,6 @@ static inline void kvm_hyp_reserve(void) { } void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu); bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu); =20 -struct kvm_vm_id_regs { - /* - * Emulated CPU ID registers per VM - * (Op0, Op1, CRn, CRm, Op2) of the ID registers to be saved in it - * is (3, 0, 0, crm, op2), where 1<=3Dcrm<8, 0<=3Dop2<8. - * - * These emulated idregs are VM-wide, but accessed from the context of a = vCPU. - * Atomic access to multiple idregs are guarded by kvm_arch.config_lock. - */ -#define IDREG_IDX(id) (((sys_reg_CRm(id) - 1) << 3) | sys_reg_Op2(id)) -#define KVM_ARM_ID_REG_NUM (IDREG_IDX(sys_reg(3, 0, 0, 7, 7)) + 1) - u64 normal[KVM_ARM_ID_REG_NUM]; - - u64 midr_el1; - u64 revidr_el1; - u64 aidr_el1; - u64 ctr_el0; -}; - -static inline u64 *__vm_id_reg(struct kvm_vm_id_regs *id_regs, u32 reg) -{ - switch (reg) { - case sys_reg(3, 0, 0, 1, 0) ... sys_reg(3, 0, 0, 7, 7): - return &id_regs->normal[IDREG_IDX(reg)]; - case SYS_CTR_EL0: - return &id_regs->ctr_el0; - case SYS_MIDR_EL1: - return &id_regs->midr_el1; - case SYS_REVIDR_EL1: - return &id_regs->revidr_el1; - case SYS_AIDR_EL1: - return &id_regs->aidr_el1; - default: - WARN_ON_ONCE(1); - return NULL; - } -} - -#define kvm_read_vm_id_reg(kvm, reg) \ - ({ u64 __val =3D *__vm_id_reg(&(kvm)->arch.id_regs, reg); __val; }) - void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); =20 static inline bool kvm_arch_has_irq_bypass(void) diff --git a/include/kvm/arm64/kvm_host.h b/include/kvm/arm64/kvm_host.h index 8bf399508757..379942225d5f 100644 --- a/include/kvm/arm64/kvm_host.h +++ b/include/kvm/arm64/kvm_host.h @@ -4,6 +4,7 @@ #define __KVM_ARM64_KVM_HOST_H =20 #include +#include =20 #define KVM_VCPU_MAX_FEATURES 9 =20 @@ -21,6 +22,47 @@ #define KVM_REQ_MAP_L1_VNCR_EL2 KVM_ARCH_REQ(10) #define KVM_REQ_VGIC_PROCESS_UPDATE KVM_ARCH_REQ(11) =20 +struct kvm_vm_id_regs { + /* + * Emulated CPU ID registers per VM + * (Op0, Op1, CRn, CRm, Op2) of the ID registers to be saved in it + * is (3, 0, 0, crm, op2), where 1<=3Dcrm<8, 0<=3Dop2<8. + * + * These emulated idregs are VM-wide, but accessed from the context of a = vCPU. + * Atomic access to multiple idregs are guarded by kvm_arch.config_lock. + */ +#define IDREG_IDX(id) (((sys_reg_CRm(id) - 1) << 3) | sys_reg_Op2(id)) +#define KVM_ARM_ID_REG_NUM (IDREG_IDX(sys_reg(3, 0, 0, 7, 7)) + 1) + u64 normal[KVM_ARM_ID_REG_NUM]; + + u64 midr_el1; + u64 revidr_el1; + u64 aidr_el1; + u64 ctr_el0; +}; + +static inline u64 *__vm_id_reg(struct kvm_vm_id_regs *id_regs, u32 reg) +{ + switch (reg) { + case sys_reg(3, 0, 0, 1, 0) ... sys_reg(3, 0, 0, 7, 7): + return &id_regs->normal[IDREG_IDX(reg)]; + case SYS_CTR_EL0: + return &id_regs->ctr_el0; + case SYS_MIDR_EL1: + return &id_regs->midr_el1; + case SYS_REVIDR_EL1: + return &id_regs->revidr_el1; + case SYS_AIDR_EL1: + return &id_regs->aidr_el1; + default: + WARN_ON_ONCE(1); + return NULL; + } +} + +#define kvm_read_vm_id_reg(kvm, reg) \ + ({ u64 __val =3D *__vm_id_reg(&(kvm)->arch.id_regs, reg); __val; }) + struct vcpu_reset_state { unsigned long pc; unsigned long r0; --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 38C0A3ED122; Fri, 29 May 2026 15:57:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070237; cv=none; b=TZz/anjLrxhsnaHagvKsls6tavD5ul93sbWBWwGCk+w2JjgYhZs0FJoZNadcyQ6Ro/vQzQU0qGTkZUvB248bG3d30nWGXIbiN+tukZs2IVnogFUDGKQfe9SkFWM8xu1Iy7qnWqcmgWaLcwaMrR3uuxRAq1/J2QNQD9fzmj8ei2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070237; c=relaxed/simple; bh=cyXILq1LLFkDFrc0kGqmBLvqFD/iCpmLI91ZjU6FB1o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n90IDvHjZ6d3gWu6D3rRLHxCvEmLFF2iOJ/HLQaUzafmxr2jay/g4n/0YW3qfShK1GYxn0x9bkF7qfbK8eczkyj9pKn3Ixb4VDCZGKzbhrWLn0no35dullb/rB3D5/mhqDfZ5u5QhFrW6pBS/Z5Wv7pktKwyvbhsN7ELKw5YDOU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=fx6amajS; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="fx6amajS" Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFA3JN3216069; Fri, 29 May 2026 15:56:19 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=TL40fMZy2fWepaNwM 1qtWRxV/Tf0P7eTV3P3XEqPeUQ=; b=fx6amajSEZG9eQadH97mpWNb+sWSQ3Lfg uluSuUIV08qYYkdKCgWrn+uN8ZTpk1FxXVguQ3axWtk7/HSQQ8UyF3rAXLrMUNPR Sl5+xx9/hkt+ZHkzmCl2U8vYrf7+ySyQPcxsZPQ1zIMTYuwDLdhB8JLhGJOvC+Fl H7Fsexuico2Z2VRb3YyFbwaGBvG6wjEG/GETD0i/1ZcTxXDMf98k40DXGb2I4a5P enpvuHKEC+CcjixS2CDC9ev6PGEgjPg6SX5ZyRY9+YovkX4F5Js2xf56PG+YRK9y 40zI6jET3g9Vdh+dUkcZGt/boP2QPEXo1WiQM+nUrXdq2jLJl11sw== Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee88bm2p7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:18 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs7xi027794; Fri, 29 May 2026 15:56:18 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrc8jp5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:17 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFuAg649414436 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:10 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5A17C20040; Fri, 29 May 2026 15:56:10 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D528720043; Fri, 29 May 2026 15:56:09 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:09 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 21/26] KVM: arm64: Share sys-reg handling Date: Fri, 29 May 2026 17:55:54 +0200 Message-ID: <20260529155601.2927240-22-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX8jUTfgrFCSjx mqFKqkU+Nf83KKfu3qKOCO3c4sFy1aaOX2FaK1wgpJTrpXi5hlCUqCzLjVmDDoyhtwmD1CTWiDJ 435ksW1Cud3WMQsdd6W6BnWVuvq1sGLA9NRtthCGithA+6VJ0X4rk2N59jiWrG5yvFDscOF3cX0 TYdZESjCCHsHMsj+jtgCa+jm2uNXTFZqJWzvp9tmTEdymp8nNMZgVmScb6wL4F0LSTG5dJS7oOC uKWWSJnV8wOs8qwD9niyRVqQAOeJ4GErD436nI9V/045fyQXfcEvr3e+V65/0xB7/GyIm0OVnwo SExO5LVuAk32/0/0+jkn9NJmt3NjdgxVl5zKYe4MmvgM7e4Jdc6a8Lrq9NQDZr/tRzJ8r3/uBLa W6bUM9uCqhzmHRvNSgYGFXSAp5lBrhx6jpSC/LFZbgzchnl6gN8MdY9d6hVz45rlEgFUAfgjLVL Q3m0KHij8Ge9r3CXhcA== X-Proofpoint-ORIG-GUID: LU_bZm0FbEwXxFgJ45qb8q_a_dsHJj1J X-Authority-Analysis: v=2.4 cv=IJEyzAvG c=1 sm=1 tr=0 ts=6a19b722 cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=7CQSdrXTAAAA:8 a=UQM1QJzDAAAA:8 a=1dDqwGSCEFCIWNWQU7AA:9 a=a-qgeE7W1pNrGK8U0ZQC:22 a=Y_cFJIg8yfREFdlijoxh:22 X-Proofpoint-GUID: LU_bZm0FbEwXxFgJ45qb8q_a_dsHJj1J X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 phishscore=0 clxscore=1015 spamscore=0 bulkscore=0 adultscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Move system register handling code from arch/arm64/kvm to shared locations (virt/kvm/arm64 and include/kvm/arm64) to enable reuse by e.g. s390 for KVM/arm64 on s390 support. Stub functions in s390 are added to maintain linking compatibility. No functional changes. Signed-off-by: Steffen Eiden --- arch/arm64/include/asm/kvm_host.h | 13 - arch/arm64/kvm/Makefile | 1 + arch/arm64/kvm/arm.c | 2 +- arch/arm64/kvm/hyp/nvhe/sys_regs.c | 2 +- arch/arm64/kvm/nested.c | 2 +- arch/arm64/kvm/sys_regs.c | 1250 +----------------------- arch/arm64/kvm/sys_regs.h | 363 ------- arch/arm64/kvm/trace_handle_exit.h | 36 +- arch/arm64/kvm/vgic-sys-reg-v3.c | 2 +- arch/arm64/kvm/vgic/vgic-init.c | 1 + arch/s390/include/asm/kvm_host_arm64.h | 5 +- arch/s390/kvm/arm64/arm.c | 9 + include/kvm/arm64/kvm_host.h | 10 + include/kvm/arm64/sys_regs.h | 548 +++++++++++ virt/kvm/arm64/mmio.c | 1 + virt/kvm/arm64/sys_regs.c | 1039 ++++++++++++++++++++ virt/kvm/arm64/trace.h | 34 + 17 files changed, 1684 insertions(+), 1634 deletions(-) delete mode 100644 arch/arm64/kvm/sys_regs.h create mode 100644 include/kvm/arm64/sys_regs.h create mode 100644 virt/kvm/arm64/sys_regs.c diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index a5fca468cc4a..f3113cdcea0e 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -1073,9 +1073,6 @@ u64 kvm_vcpu_apply_reg_masks(const struct kvm_vcpu *,= enum vcpu_sysreg, u64); __v; \ }) =20 -u64 vcpu_read_sys_reg(const struct kvm_vcpu *, enum vcpu_sysreg); -void vcpu_write_sys_reg(struct kvm_vcpu *, u64, enum vcpu_sysreg); - struct kvm_vm_stat { struct kvm_vm_stat_generic generic; }; @@ -1095,9 +1092,6 @@ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); =20 -unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu); -int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindic= es); - int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu, struct kvm_vcpu_events *events); =20 @@ -1161,11 +1155,9 @@ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu); int kvm_handle_cp14_64(struct kvm_vcpu *vcpu); int kvm_handle_cp15_32(struct kvm_vcpu *vcpu); int kvm_handle_cp15_64(struct kvm_vcpu *vcpu); -int kvm_handle_sys_reg(struct kvm_vcpu *vcpu); int kvm_handle_cp10_id(struct kvm_vcpu *vcpu); =20 void kvm_sys_regs_create_debugfs(struct kvm *kvm); -void kvm_reset_sys_regs(struct kvm_vcpu *vcpu); =20 int __init kvm_sys_reg_table_init(void); struct sys_reg_desc; @@ -1362,9 +1354,6 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); (system_supports_32bit_el0() && \ !static_branch_unlikely(&arm64_mismatched_32bit_el0)) =20 -#define kvm_vm_has_ran_once(kvm) \ - (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &(kvm)->arch.flags)) - static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int featu= re) { return test_bit(feature, ka->vcpu_features); @@ -1385,8 +1374,6 @@ static inline void kvm_hyp_reserve(void) { } void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu); bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu); =20 -void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); - static inline bool kvm_arch_has_irq_bypass(void) { return true; diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 5b4a8d002fc9..d55c7245aad9 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -19,6 +19,7 @@ kvm-y +=3D arm.o mmu.o psci.o hypercalls.o pvtime.o \ guest.o debug.o reset.o sys_regs.o stacktrace.o \ vgic-sys-reg-v3.o fpsimd.o pkvm.o \ arch_timer.o trng.o vmid.o emulate-nested.o nested.o at.o \ + $(KVM_ARM64)/sys_regs.o \ vgic/vgic.o vgic/vgic-init.o \ vgic/vgic-irqfd.o vgic/vgic-v2.o \ vgic/vgic-v3.o vgic/vgic-v4.o \ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 929b8e6eae9a..99044b1e3c9f 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -54,7 +54,7 @@ =20 #include =20 -#include "sys_regs.h" +#include =20 static enum kvm_mode kvm_mode =3D KVM_MODE_DEFAULT; =20 diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/s= ys_regs.c index 08b14053568b..51fd49d00c95 100644 --- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c @@ -14,7 +14,7 @@ =20 #include =20 -#include "../../sys_regs.h" +#include =20 /* * Copies of the host's CPU features registers holding sanitized values at= hyp. diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c index 5321911f19e0..dce896e2a151 100644 --- a/arch/arm64/kvm/nested.c +++ b/arch/arm64/kvm/nested.c @@ -15,7 +15,7 @@ #include #include =20 -#include "sys_regs.h" +#include =20 struct vncr_tlb { /* The guest's VNCR_EL2 */ diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 46b24529ec70..b68622f93621 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -34,7 +34,7 @@ =20 #include =20 -#include "sys_regs.h" +#include #include "vgic/vgic.h" =20 #include "trace.h" @@ -45,43 +45,6 @@ * 64bit interface. */ =20 -static u64 sys_reg_to_index(const struct sys_reg_desc *reg); -static int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, - u64 val); - -static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p, - const struct sys_reg_desc *r) -{ - kvm_inject_undefined(vcpu); - return false; -} - -static bool bad_trap(struct kvm_vcpu *vcpu, - struct sys_reg_params *params, - const struct sys_reg_desc *r, - const char *msg) -{ - WARN_ONCE(1, "Unexpected %s\n", msg); - print_sys_reg_instr(params); - return undef_access(vcpu, params, r); -} - -static bool read_from_write_only(struct kvm_vcpu *vcpu, - struct sys_reg_params *params, - const struct sys_reg_desc *r) -{ - return bad_trap(vcpu, params, r, - "sys_reg read to write-only register"); -} - -static bool write_to_read_only(struct kvm_vcpu *vcpu, - struct sys_reg_params *params, - const struct sys_reg_desc *r) -{ - return bad_trap(vcpu, params, r, - "sys_reg write to read-only register"); -} - enum sr_loc_attr { SR_LOC_MEMORY =3D 0, /* Register definitely in memory */ SR_LOC_LOADED =3D BIT(0), /* Register on CPU, unless it cannot */ @@ -391,111 +354,8 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 va= l, enum vcpu_sysreg reg) __vcpu_assign_sys_reg(vcpu, reg, val); } =20 -/* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */ #define CSSELR_MAX 14 =20 -/* - * Returns the minimum line size for the selected cache, expressed as - * Log2(bytes). - */ -static u8 get_min_cache_line_size(bool icache) -{ - u64 ctr =3D read_sanitised_ftr_reg(SYS_CTR_EL0); - u8 field; - - if (icache) - field =3D SYS_FIELD_GET(CTR_EL0, IminLine, ctr); - else - field =3D SYS_FIELD_GET(CTR_EL0, DminLine, ctr); - - /* - * Cache line size is represented as Log2(words) in CTR_EL0. - * Log2(bytes) can be derived with the following: - * - * Log2(words) + 2 =3D Log2(bytes / 4) + 2 - * =3D Log2(bytes) - 2 + 2 - * =3D Log2(bytes) - */ - return field + 2; -} - -/* Which cache CCSIDR represents depends on CSSELR value. */ -static u32 get_ccsidr(struct kvm_vcpu *vcpu, u32 csselr) -{ - u8 line_size; - - if (vcpu->arch.ccsidr) - return vcpu->arch.ccsidr[csselr]; - - line_size =3D get_min_cache_line_size(csselr & CSSELR_EL1_InD); - - /* - * Fabricate a CCSIDR value as the overriding value does not exist. - * The real CCSIDR value will not be used as it can vary by the - * physical CPU which the vcpu currently resides in. - * - * The line size is determined with get_min_cache_line_size(), which - * should be valid for all CPUs even if they have different cache - * configuration. - * - * The associativity bits are cleared, meaning the geometry of all data - * and unified caches (which are guaranteed to be PIPT and thus - * non-aliasing) are 1 set and 1 way. - * Guests should not be doing cache operations by set/way at all, and - * for this reason, we trap them and attempt to infer the intent, so - * that we can flush the entire guest's address space at the appropriate - * time. The exposed geometry minimizes the number of the traps. - * [If guests should attempt to infer aliasing properties from the - * geometry (which is not permitted by the architecture), they would - * only do so for virtually indexed caches.] - * - * We don't check if the cache level exists as it is allowed to return - * an UNKNOWN value if not. - */ - return SYS_FIELD_PREP(CCSIDR_EL1, LineSize, line_size - 4); -} - -static int set_ccsidr(struct kvm_vcpu *vcpu, u32 csselr, u32 val) -{ - u8 line_size =3D FIELD_GET(CCSIDR_EL1_LineSize, val) + 4; - u32 *ccsidr =3D vcpu->arch.ccsidr; - u32 i; - - if ((val & CCSIDR_EL1_RES0) || - line_size < get_min_cache_line_size(csselr & CSSELR_EL1_InD)) - return -EINVAL; - - if (!ccsidr) { - if (val =3D=3D get_ccsidr(vcpu, csselr)) - return 0; - - ccsidr =3D kmalloc_array(CSSELR_MAX, sizeof(u32), GFP_KERNEL_ACCOUNT); - if (!ccsidr) - return -ENOMEM; - - for (i =3D 0; i < CSSELR_MAX; i++) - ccsidr[i] =3D get_ccsidr(vcpu, i); - - vcpu->arch.ccsidr =3D ccsidr; - } - - ccsidr[csselr] =3D val; - - return 0; -} - -static bool access_rw(struct kvm_vcpu *vcpu, - struct sys_reg_params *p, - const struct sys_reg_desc *r) -{ - if (p->is_write) - vcpu_write_sys_reg(vcpu, p->regval, r->reg); - else - p->regval =3D vcpu_read_sys_reg(vcpu, r->reg); - - return true; -} - /* * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualize= d). */ @@ -530,24 +390,6 @@ static bool access_dcgsw(struct kvm_vcpu *vcpu, return access_dcsw(vcpu, p, r); } =20 -static void get_access_mask(const struct sys_reg_desc *r, u64 *mask, u64 *= shift) -{ - switch (r->aarch32_map) { - case AA32_LO: - *mask =3D GENMASK_ULL(31, 0); - *shift =3D 0; - break; - case AA32_HI: - *mask =3D GENMASK_ULL(63, 32); - *shift =3D 32; - break; - default: - *mask =3D GENMASK_ULL(63, 0); - *shift =3D 0; - break; - } -} - /* * Generic accessor for VM registers. Only called as long as HCR_TVM * is set. If the guest enables the MMU, we stop trapping the VM @@ -766,16 +608,6 @@ static bool access_gicv5_ppi_enabler(struct kvm_vcpu *= vcpu, return true; } =20 -static bool trap_raz_wi(struct kvm_vcpu *vcpu, - struct sys_reg_params *p, - const struct sys_reg_desc *r) -{ - if (p->is_write) - return ignore_write(vcpu, p); - else - return read_zero(vcpu, p); -} - /* * ARMv8.1 mandates at least a trivial LORegion implementation, where all = the * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0 @@ -797,50 +629,6 @@ static bool trap_loregion(struct kvm_vcpu *vcpu, return trap_raz_wi(vcpu, p, r); } =20 -static bool trap_oslar_el1(struct kvm_vcpu *vcpu, - struct sys_reg_params *p, - const struct sys_reg_desc *r) -{ - if (!p->is_write) - return read_from_write_only(vcpu, p, r); - - kvm_debug_handle_oslar(vcpu, p->regval); - return true; -} - -static bool trap_oslsr_el1(struct kvm_vcpu *vcpu, - struct sys_reg_params *p, - const struct sys_reg_desc *r) -{ - if (p->is_write) - return write_to_read_only(vcpu, p, r); - - p->regval =3D __vcpu_sys_reg(vcpu, r->reg); - return true; -} - -static int set_oslsr_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc = *rd, - u64 val) -{ - u64 oslk; - - /* - * The only modifiable bit is the OSLK bit. Refuse the write if - * userspace attempts to change any other bit in the register. - */ - if ((val ^ rd->val) & ~OSLSR_EL1_OSLK) - return -EINVAL; - - /* - * Redirect the write to the proper control register. - * OSLSR is read-only - */ - oslk =3D SYS_FIELD_GET(OSLSR_EL1, OSLK, val); - __vcpu_assign_sys_reg(vcpu, OSLAR_EL1, - SYS_FIELD_PREP(OSLAR_EL1, OSLK, oslk)); - return 0; -} - static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) @@ -985,26 +773,6 @@ static u64 reset_actlr(struct kvm_vcpu *vcpu, const st= ruct sys_reg_desc *r) return actlr; } =20 -static u64 reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) -{ - u64 mpidr; - - /* - * Map the vcpu_id into the first three affinity level fields of - * the MPIDR. We limit the number of VCPUs in level 0 due to a - * limitation to 16 CPUs in that level in the ICC_SGIxR registers - * of the GICv3 to be able to address each CPU directly when - * sending IPIs. - */ - mpidr =3D (vcpu->vcpu_id & 0x0f) << MPIDR_LEVEL_SHIFT(0); - mpidr |=3D ((vcpu->vcpu_id >> 4) & 0xff) << MPIDR_LEVEL_SHIFT(1); - mpidr |=3D ((vcpu->vcpu_id >> 12) & 0xff) << MPIDR_LEVEL_SHIFT(2); - mpidr |=3D (1ULL << 31); - vcpu_write_sys_reg(vcpu, mpidr, MPIDR_EL1); - - return mpidr; -} - static unsigned int hidden_visibility(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { @@ -1783,7 +1551,7 @@ static s64 kvm_arm64_ftr_safe_value(u32 id, const str= uct arm64_ftr_bits *ftrp, * * Return: 0 if all the fields are safe. Otherwise, return negative errno. */ -static int arm64_check_features(struct kvm_vcpu *vcpu, +int arm64_check_features(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, u64 val) { @@ -1905,188 +1673,6 @@ u64 kvm_sanitised_host_ftr_reg(u32 id) return val; } =20 -/* - * Statically sanitise the host's feature register, independent of the gue= st's - * configuration and host implementation. - */ -static u64 kvm_max_possible_guest_ftr_reg(u32 id, u64 val) -{ - switch (id) { - case SYS_ID_AA64DFR0_EL1: - val =3D ID_REG_LIMIT_FIELD_ENUM(val, ID_AA64DFR0_EL1, DebugVer, V8P8); - - /* Hide SPE from guests */ - val &=3D ~ID_AA64DFR0_EL1_PMSVer_MASK; - - /* Hide BRBE from guests */ - val &=3D ~ID_AA64DFR0_EL1_BRBE_MASK; - break; - case SYS_ID_AA64ISAR2_EL1: - /* Mask WFxT field unless *both* WFET & WFIT are present. */ - if (!id_has_feat(val, ID_AA64ISAR2_EL1, WFxT, IMP)) - val &=3D ~ID_AA64ISAR2_EL1_WFxT; - break; - case SYS_ID_AA64ISAR3_EL1: - val &=3D ID_AA64ISAR3_EL1_FPRCVT | ID_AA64ISAR3_EL1_LSFE | - ID_AA64ISAR3_EL1_FAMINMAX | ID_AA64ISAR3_EL1_LSUI; - break; - case SYS_ID_AA64MMFR2_EL1: - val &=3D ~ID_AA64MMFR2_EL1_CCIDX_MASK; - val &=3D ~ID_AA64MMFR2_EL1_NV; - break; - case SYS_ID_AA64MMFR3_EL1: - val &=3D ID_AA64MMFR3_EL1_TCRX | - ID_AA64MMFR3_EL1_SCTLRX | - ID_AA64MMFR3_EL1_S1POE | - ID_AA64MMFR3_EL1_S1PIE; - break; - case SYS_ID_MMFR4_EL1: - val &=3D ~ID_MMFR4_EL1_CCIDX; - break; - case SYS_ID_AA64PFR0_EL1: - val &=3D ~ID_AA64PFR0_EL1_AMU_MASK; - /* - * MPAM is disabled by default as KVM also needs a set of PARTID to - * program the MPAMVPMx_EL2 PARTID remapping registers with. But some - * older kernels let the guest see the ID bit. - */ - val &=3D ~ID_AA64PFR0_EL1_MPAM_MASK; - break; - case SYS_ID_AA64PFR1_EL1: - 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; - val &=3D ~ID_AA64PFR1_EL1_MPAM_frac; - break; - case SYS_ID_AA64PFR2_EL1: - val &=3D ID_AA64PFR2_EL1_FPMR | - ID_AA64PFR2_EL1_MTEFAR | - ID_AA64PFR2_EL1_MTESTOREONLY; - break; - } - - return val; -} - -/* - * Sanitise based on vCPU configuration. - */ -static u64 kvm_sanitise_vcpu_ftr_reg(const struct kvm_vcpu *vcpu, u32 id, = u64 val) -{ - switch (id) { - case SYS_ID_AA64DFR0_EL1: - /* - * Only initialize the PMU version if the vCPU was configured with one. - */ - val &=3D ~ID_AA64DFR0_EL1_PMUVer_MASK; - if (kvm_vcpu_has_pmu(vcpu)) - val |=3D SYS_FIELD_PREP(ID_AA64DFR0_EL1, PMUVer, - kvm_arm_pmu_get_pmuver_limit()); - break; - case SYS_ID_AA64PFR0_EL1: - if (!vcpu_has_sve(vcpu)) - val &=3D ~ID_AA64PFR0_EL1_SVE_MASK; - break; - case SYS_ID_AA64PFR1_EL1: - if (!kvm_has_mte(vcpu->kvm)) { - val &=3D ~ID_AA64PFR1_EL1_MTE; - val &=3D ~ID_AA64PFR1_EL1_MTE_frac; - } - break; - case SYS_ID_AA64PFR2_EL1: - if (!kvm_has_mte(vcpu->kvm)) { - val &=3D ~ID_AA64PFR2_EL1_MTEFAR; - val &=3D ~ID_AA64PFR2_EL1_MTESTOREONLY; - } - break; - case SYS_ID_AA64ISAR1_EL1: - if (!vcpu_has_ptrauth(vcpu)) - val &=3D ~(ID_AA64ISAR1_EL1_APA | - ID_AA64ISAR1_EL1_API | - ID_AA64ISAR1_EL1_GPA | - ID_AA64ISAR1_EL1_GPI); - break; - case SYS_ID_AA64ISAR2_EL1: - if (!vcpu_has_ptrauth(vcpu)) - val &=3D ~(ID_AA64ISAR2_EL1_APA3 | - ID_AA64ISAR2_EL1_GPA3); - } - - if (vcpu_has_nv(vcpu)) - val =3D limit_nv_id_reg(vcpu->kvm, id, val); - - return val; -} - -/* Read a sanitised cpufeature ID register by sys_reg_desc */ -static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - u32 id =3D reg_to_encoding(r); - u64 val; - - if (sysreg_visible_as_raz(vcpu, r)) - return 0; - - val =3D kvm_sanitised_host_ftr_reg(id); - val =3D kvm_max_possible_guest_ftr_reg(id, val); - val =3D kvm_sanitise_vcpu_ftr_reg(vcpu, id, val); - - return val; -} - -u64 kvm_read_sanitised_id_reg(struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - return __kvm_read_sanitised_id_reg(vcpu, r); -} - -static u64 read_id_reg(const struct kvm_vcpu *vcpu, const struct sys_reg_d= esc *r) -{ - return kvm_read_vm_id_reg(vcpu->kvm, reg_to_encoding(r)); -} - -static bool is_feature_id_reg(u32 encoding) -{ - return (sys_reg_Op0(encoding) =3D=3D 3 && - (sys_reg_Op1(encoding) < 2 || sys_reg_Op1(encoding) =3D=3D 3) && - sys_reg_CRn(encoding) =3D=3D 0 && - sys_reg_CRm(encoding) <=3D 7); -} - -/* - * Return true if the register's (Op0, Op1, CRn, CRm, Op2) is - * (3, 0, 0, crm, op2), where 1<=3Dcrm<8, 0<=3Dop2<8, which is the range o= f ID - * registers KVM maintains on a per-VM basis. - * - * Additionally, the implementation ID registers and CTR_EL0 are handled as - * per-VM registers. - */ -static inline bool is_vm_ftr_id_reg(u32 id) -{ - switch (id) { - case SYS_CTR_EL0: - case SYS_MIDR_EL1: - case SYS_REVIDR_EL1: - case SYS_AIDR_EL1: - return true; - default: - return (sys_reg_Op0(id) =3D=3D 3 && sys_reg_Op1(id) =3D=3D 0 && - sys_reg_CRn(id) =3D=3D 0 && sys_reg_CRm(id) >=3D 1 && - sys_reg_CRm(id) < 8); - - } -} - -static inline bool is_vcpu_ftr_id_reg(u32 id) -{ - return is_feature_id_reg(id) && !is_vm_ftr_id_reg(id); -} - static inline bool is_aa32_id_reg(u32 id) { return (sys_reg_Op0(id) =3D=3D 3 && sys_reg_Op1(id) =3D=3D 0 && @@ -2094,49 +1680,6 @@ static inline bool is_aa32_id_reg(u32 id) sys_reg_CRm(id) <=3D 3); } =20 -static unsigned int id_visibility(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - u32 id =3D reg_to_encoding(r); - - switch (id) { - case SYS_ID_AA64ZFR0_EL1: - if (!vcpu_has_sve(vcpu)) - return REG_RAZ; - break; - } - - return 0; -} - -static unsigned int aa32_id_visibility(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - /* - * AArch32 ID registers are UNKNOWN if AArch32 isn't implemented at any - * EL. Promote to RAZ/WI in order to guarantee consistency between - * systems. - */ - if (!kvm_supports_32bit_el0()) - return REG_RAZ | REG_USER_WI; - - return id_visibility(vcpu, r); -} - -/* cpufeature ID register access trap handlers */ - -static bool access_id_reg(struct kvm_vcpu *vcpu, - struct sys_reg_params *p, - const struct sys_reg_desc *r) -{ - if (p->is_write) - return write_to_read_only(vcpu, p, r); - - p->regval =3D read_id_reg(vcpu, r); - - return true; -} - /* Visibility overrides for SVE-specific control registers */ static unsigned int sve_visibility(const struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) @@ -2333,290 +1876,48 @@ static int set_id_aa64pfr1_el1(struct kvm_vcpu *vc= pu, return set_id_reg(vcpu, rd, user_val); } =20 -static int set_id_aa64pfr2_el1(struct kvm_vcpu *vcpu, - const struct sys_reg_desc *rd, u64 user_val) -{ - return set_id_reg(vcpu, rd, user_val); -} - -/* - * Allow userspace to de-feature a stage-2 translation granule but prevent= it - * from claiming the impossible. - */ -#define tgran2_val_allowed(tg, safe, user) \ -({ \ - u8 __s =3D SYS_FIELD_GET(ID_AA64MMFR0_EL1, tg, safe); \ - u8 __u =3D SYS_FIELD_GET(ID_AA64MMFR0_EL1, tg, user); \ - \ - __s =3D=3D __u || __u =3D=3D ID_AA64MMFR0_EL1_##tg##_NI; \ -}) - -static int set_id_aa64mmfr0_el1(struct kvm_vcpu *vcpu, - const struct sys_reg_desc *rd, u64 user_val) -{ - u64 sanitized_val =3D kvm_read_sanitised_id_reg(vcpu, rd); - - if (!vcpu_has_nv(vcpu)) - return set_id_reg(vcpu, rd, user_val); - - if (!tgran2_val_allowed(TGRAN4_2, sanitized_val, user_val) || - !tgran2_val_allowed(TGRAN16_2, sanitized_val, user_val) || - !tgran2_val_allowed(TGRAN64_2, sanitized_val, user_val)) - return -EINVAL; - - return set_id_reg(vcpu, rd, user_val); -} - -static int set_id_aa64mmfr2_el1(struct kvm_vcpu *vcpu, - const struct sys_reg_desc *rd, u64 user_val) -{ - u64 hw_val =3D read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1); - u64 nv_mask =3D ID_AA64MMFR2_EL1_NV_MASK; - - /* - * We made the mistake to expose the now deprecated NV field, - * so allow userspace to write it, but silently ignore it. - */ - if ((hw_val & nv_mask) =3D=3D (user_val & nv_mask)) - user_val &=3D ~nv_mask; - - return set_id_reg(vcpu, rd, user_val); -} - -static int set_ctr_el0(struct kvm_vcpu *vcpu, - const struct sys_reg_desc *rd, u64 user_val) -{ - u8 user_L1Ip =3D SYS_FIELD_GET(CTR_EL0, L1Ip, user_val); - - /* - * Both AIVIVT (0b01) and VPIPT (0b00) are documented as reserved. - * Hence only allow to set VIPT(0b10) or PIPT(0b11) for L1Ip based - * on what hardware reports. - * - * Using a VIPT software model on PIPT will lead to over invalidation, - * but still correct. Hence, we can allow downgrading PIPT to VIPT, - * but not the other way around. This is handled via arm64_ftr_safe_value= () - * as CTR_EL0 ftr_bits has L1Ip field with type FTR_EXACT and safe value - * set as VIPT. - */ - switch (user_L1Ip) { - case CTR_EL0_L1Ip_RESERVED_VPIPT: - case CTR_EL0_L1Ip_RESERVED_AIVIVT: - return -EINVAL; - case CTR_EL0_L1Ip_VIPT: - case CTR_EL0_L1Ip_PIPT: - return set_id_reg(vcpu, rd, user_val); - default: - return -ENOENT; - } -} - -/* - * cpufeature ID register user accessors - * - * For now, these registers are immutable for userspace, so no values - * are stored, and for set_id_reg() we don't allow the effective value - * to be changed. - */ -static int get_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, - u64 *val) -{ - /* - * Avoid locking if the VM has already started, as the ID registers are - * guaranteed to be invariant at that point. - */ - if (kvm_vm_has_ran_once(vcpu->kvm)) { - *val =3D read_id_reg(vcpu, rd); - return 0; - } - - mutex_lock(&vcpu->kvm->arch.config_lock); - *val =3D read_id_reg(vcpu, rd); - mutex_unlock(&vcpu->kvm->arch.config_lock); - - return 0; -} - -static int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, - u64 val) -{ - u32 id =3D reg_to_encoding(rd); - int ret; - - mutex_lock(&vcpu->kvm->arch.config_lock); - - /* - * Once the VM has started the ID registers are immutable. Reject any - * write that does not match the final register value. - */ - if (kvm_vm_has_ran_once(vcpu->kvm)) { - if (val !=3D read_id_reg(vcpu, rd)) - ret =3D -EBUSY; - else - ret =3D 0; - - mutex_unlock(&vcpu->kvm->arch.config_lock); - return ret; - } - - ret =3D arm64_check_features(vcpu, rd, val); - if (!ret) - kvm_set_vm_id_reg(vcpu->kvm, id, val); - - mutex_unlock(&vcpu->kvm->arch.config_lock); - - /* - * arm64_check_features() returns -E2BIG to indicate the register's - * feature set is a superset of the maximally-allowed register value. - * While it would be nice to precisely describe this to userspace, the - * existing UAPI for KVM_SET_ONE_REG has it that invalid register - * writes return -EINVAL. - */ - if (ret =3D=3D -E2BIG) - ret =3D -EINVAL; - return ret; -} - -void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val) -{ - u64 *p =3D __vm_id_reg(&kvm->arch.id_regs, reg); - - lockdep_assert_held(&kvm->arch.config_lock); - - if (KVM_BUG_ON(kvm_vm_has_ran_once(kvm) || !p, kvm)) - return; - - *p =3D val; -} - -static int get_raz_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r= d, - u64 *val) -{ - *val =3D 0; - return 0; -} - -static int set_wi_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, - u64 val) -{ - return 0; -} - -static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, - const struct sys_reg_desc *r) -{ - if (p->is_write) - return write_to_read_only(vcpu, p, r); - - p->regval =3D kvm_read_vm_id_reg(vcpu->kvm, SYS_CTR_EL0); - return true; -} - -static bool access_clidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, - const struct sys_reg_desc *r) -{ - if (p->is_write) - return write_to_read_only(vcpu, p, r); - - p->regval =3D __vcpu_sys_reg(vcpu, r->reg); - return true; -} - -/* - * Fabricate a CLIDR_EL1 value instead of using the real value, which can = vary - * by the physical CPU which the vcpu currently resides in. - */ -static u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) -{ - u64 ctr_el0 =3D read_sanitised_ftr_reg(SYS_CTR_EL0); - u64 clidr; - u8 loc; - - if ((ctr_el0 & CTR_EL0_IDC)) { - /* - * Data cache clean to the PoU is not required so LoUU and LoUIS - * will not be set and a unified cache, which will be marked as - * LoC, will be added. - * - * If not DIC, let the unified cache L2 so that an instruction - * cache can be added as L1 later. - */ - loc =3D (ctr_el0 & CTR_EL0_DIC) ? 1 : 2; - clidr =3D CACHE_TYPE_UNIFIED << CLIDR_CTYPE_SHIFT(loc); - } else { - /* - * Data cache clean to the PoU is required so let L1 have a data - * cache and mark it as LoUU and LoUIS. As L1 has a data cache, - * it can be marked as LoC too. - */ - loc =3D 1; - clidr =3D 1 << CLIDR_LOUU_SHIFT; - clidr |=3D 1 << CLIDR_LOUIS_SHIFT; - clidr |=3D CACHE_TYPE_DATA << CLIDR_CTYPE_SHIFT(1); - } - - /* - * Instruction cache invalidation to the PoU is required so let L1 have - * an instruction cache. If L1 already has a data cache, it will be - * CACHE_TYPE_SEPARATE. - */ - if (!(ctr_el0 & CTR_EL0_DIC)) - clidr |=3D CACHE_TYPE_INST << CLIDR_CTYPE_SHIFT(1); +static int set_id_aa64pfr2_el1(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, u64 user_val) +{ + return set_id_reg(vcpu, rd, user_val); +} =20 - clidr |=3D loc << CLIDR_LOC_SHIFT; +static int set_id_aa64mmfr2_el1(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, u64 user_val) +{ + u64 hw_val =3D read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1); + u64 nv_mask =3D ID_AA64MMFR2_EL1_NV_MASK; =20 /* - * Add tag cache unified to data cache. Allocation tags and data are - * unified in a cache line so that it looks valid even if there is only - * one cache line. + * We made the mistake to expose the now deprecated NV field, + * so allow userspace to write it, but silently ignore it. */ - if (kvm_has_mte(vcpu->kvm)) - clidr |=3D 2ULL << CLIDR_TTYPE_SHIFT(loc); - - __vcpu_assign_sys_reg(vcpu, r->reg, clidr); + if ((hw_val & nv_mask) =3D=3D (user_val & nv_mask)) + user_val &=3D ~nv_mask; =20 - return __vcpu_sys_reg(vcpu, r->reg); + return set_id_reg(vcpu, rd, user_val); } =20 -static int set_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, - u64 val) +static int get_raz_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r= d, + u64 *val) { - u64 ctr_el0 =3D read_sanitised_ftr_reg(SYS_CTR_EL0); - u64 idc =3D !CLIDR_LOC(val) || (!CLIDR_LOUIS(val) && !CLIDR_LOUU(val)); - - if ((val & CLIDR_EL1_RES0) || (!(ctr_el0 & CTR_EL0_IDC) && idc)) - return -EINVAL; - - __vcpu_assign_sys_reg(vcpu, rd->reg, val); - + *val =3D 0; return 0; } =20 -static bool access_csselr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, - const struct sys_reg_desc *r) +static int set_wi_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + u64 val) { - int reg =3D r->reg; - - if (p->is_write) - vcpu_write_sys_reg(vcpu, p->regval, reg); - else - p->regval =3D vcpu_read_sys_reg(vcpu, reg); - return true; + return 0; } =20 -static bool access_ccsidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, - const struct sys_reg_desc *r) +static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) { - u32 csselr; - if (p->is_write) return write_to_read_only(vcpu, p, r); =20 - csselr =3D vcpu_read_sys_reg(vcpu, CSSELR_EL1); - csselr &=3D CSSELR_EL1_Level | CSSELR_EL1_InD; - if (csselr < CSSELR_MAX) - p->regval =3D get_ccsidr(vcpu, csselr); - + p->regval =3D kvm_read_vm_id_reg(vcpu->kvm, SYS_CTR_EL0); return true; } =20 @@ -2700,82 +2001,6 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu, SYS_REG_USER_FILTER(name, access_arch_timer, reset_val, 0, \ arch_timer_get_user, arch_timer_set_user, vis) =20 -/* - * Since reset() callback and field val are not used for idregs, they will= be - * used for specific purposes for idregs. - * The reset() would return KVM sanitised register value. The value would = be the - * same as the host kernel sanitised value if there is no KVM sanitisation. - * The val would be used as a mask indicating writable fields for the idre= g. - * Only bits with 1 are writable from userspace. This mask might not be - * necessary in the future whenever all ID registers are enabled as writab= le - * from userspace. - */ - -#define ID_DESC_DEFAULT_CALLBACKS \ - .access =3D access_id_reg, \ - .get_user =3D get_id_reg, \ - .set_user =3D set_id_reg, \ - .visibility =3D id_visibility, \ - .reset =3D kvm_read_sanitised_id_reg - -#define ID_DESC(name) \ - SYS_DESC(SYS_##name), \ - ID_DESC_DEFAULT_CALLBACKS - -/* sys_reg_desc initialiser for known cpufeature ID registers */ -#define ID_SANITISED(name) { \ - ID_DESC(name), \ - .val =3D 0, \ -} - -/* sys_reg_desc initialiser for writable ID registers */ -#define ID_WRITABLE(name, mask) { \ - ID_DESC(name), \ - .val =3D mask, \ -} - -/* - * 32bit ID regs are fully writable when the guest is 32bit - * capable. Nothing in the KVM code should rely on 32bit features - * anyway, only 64bit, so let the VMM do its worse. - */ -#define AA32_ID_WRITABLE(name) { \ - ID_DESC(name), \ - .visibility =3D aa32_id_visibility, \ - .val =3D GENMASK(31, 0), \ -} - -/* sys_reg_desc initialiser for cpufeature ID registers that need filterin= g */ -#define ID_FILTERED(sysreg, name, mask) { \ - ID_DESC(sysreg), \ - .set_user =3D set_##name, \ - .val =3D (mask), \ -} - -/* - * sys_reg_desc initialiser for architecturally unallocated cpufeature ID - * register with encoding Op0=3D3, Op1=3D0, CRn=3D0, CRm=3Dcrm, Op2=3Dop2 - * (1 <=3D crm < 8, 0 <=3D Op2 < 8). - */ -#define ID_UNALLOCATED(crm, op2) { \ - .name =3D "S3_0_0_" #crm "_" #op2, \ - Op0(3), Op1(0), CRn(0), CRm(crm), Op2(op2), \ - ID_DESC_DEFAULT_CALLBACKS, \ - .visibility =3D raz_visibility, \ - .val =3D 0, \ -} - -/* - * sys_reg_desc initialiser for known ID registers that we hide from guest= s. - * For now, these are exposed just like unallocated ID regs: they appear - * RAZ for the guest. - */ -#define ID_HIDDEN(name) { \ - ID_DESC(name), \ - .visibility =3D raz_visibility, \ - .val =3D 0, \ -} - static bool access_sp_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) @@ -3100,7 +2325,7 @@ static bool access_ras(struct kvm_vcpu *vcpu, * follows attempts to give a user / guest view consistent with the existi= ng * ABI. */ -static bool access_imp_id_reg(struct kvm_vcpu *vcpu, +bool access_imp_id_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { @@ -3143,7 +2368,7 @@ static void init_imp_id_regs(void) boot_cpu_aidr_val =3D read_sysreg(aidr_el1); } =20 -static u64 reset_imp_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_de= sc *r) + u64 reset_imp_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { switch (reg_to_encoding(r)) { case SYS_MIDR_EL1: @@ -3158,48 +2383,6 @@ static u64 reset_imp_id_reg(struct kvm_vcpu *vcpu, c= onst struct sys_reg_desc *r) } } =20 -static int set_imp_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc= *r, - u64 val) -{ - struct kvm *kvm =3D vcpu->kvm; - u64 expected; - - guard(mutex)(&kvm->arch.config_lock); - - expected =3D read_id_reg(vcpu, r); - if (expected =3D=3D val) - return 0; - - if (!test_bit(KVM_ARCH_FLAG_WRITABLE_IMP_ID_REGS, &kvm->arch.flags)) - return -EINVAL; - - /* - * Once the VM has started the ID registers are immutable. Reject the - * write if userspace tries to change it. - */ - if (kvm_vm_has_ran_once(kvm)) - return -EBUSY; - - /* - * Any value is allowed for the implementation ID registers so long as - * it is within the writable mask. - */ - if ((val & r->val) !=3D val) - return -EINVAL; - - kvm_set_vm_id_reg(kvm, reg_to_encoding(r), val); - return 0; -} - -#define IMPLEMENTATION_ID(reg, mask) { \ - SYS_DESC(SYS_##reg), \ - .access =3D access_imp_id_reg, \ - .get_user =3D get_id_reg, \ - .set_user =3D set_imp_id_reg, \ - .reset =3D reset_imp_id_reg, \ - .val =3D mask, \ - } - static u64 reset_mdcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { __vcpu_assign_sys_reg(vcpu, r->reg, vcpu->kvm->arch.nr_pmu_counters); @@ -4747,61 +3930,12 @@ static const struct sys_reg_desc cp15_64_regs[] =3D= { { SYS_DESC(SYS_AARCH32_CNTVCTSS), access_arch_timer }, }; =20 -static bool check_sysreg_table(const struct sys_reg_desc *table, unsigned = int n, - bool reset_check) -{ - unsigned int i; - - for (i =3D 0; i < n; i++) { - if (reset_check && table[i].reg && !table[i].reset) { - kvm_err("sys_reg table %pS entry %d (%s) lacks reset\n", - &table[i], i, table[i].name); - return false; - } - - if (i && cmp_sys_reg(&table[i-1], &table[i]) >=3D 0) { - kvm_err("sys_reg table %pS entry %d (%s -> %s) out of order\n", - &table[i], i, table[i - 1].name, table[i].name); - return false; - } - } - - return true; -} - int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu) { kvm_inject_undefined(vcpu); return 1; } =20 -static void perform_access(struct kvm_vcpu *vcpu, - struct sys_reg_params *params, - const struct sys_reg_desc *r) -{ - trace_kvm_sys_access(*vcpu_pc(vcpu), params, r); - - /* Check for regs disabled by runtime config */ - if (sysreg_hidden(vcpu, r)) { - kvm_inject_undefined(vcpu); - return; - } - - /* - * Not having an accessor means that we have configured a trap - * that we don't know how to handle. This certainly qualifies - * as a gross bug that should be fixed right away. - */ - if (!r->access) { - bad_trap(vcpu, params, r, "register access"); - return; - } - - /* Skip instruction if instructed so */ - if (likely(r->access(vcpu, params, r))) - kvm_incr_pc(vcpu); -} - /* * emulate_cp -- tries to match a sys_reg access in a handling table, and * call the corresponding trap handler. @@ -5256,26 +4390,6 @@ void kvm_sys_regs_create_debugfs(struct kvm *kvm) &sr_resx_fops); } =20 -static void reset_vm_ftr_id_reg(struct kvm_vcpu *vcpu, const struct sys_re= g_desc *reg) -{ - u32 id =3D reg_to_encoding(reg); - struct kvm *kvm =3D vcpu->kvm; - - if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags)) - return; - - kvm_set_vm_id_reg(kvm, id, reg->reset(vcpu, reg)); -} - -static void reset_vcpu_ftr_id_reg(struct kvm_vcpu *vcpu, - const struct sys_reg_desc *reg) -{ - if (kvm_vcpu_initialized(vcpu)) - return; - - reg->reset(vcpu, reg); -} - /** * kvm_reset_sys_regs - sets system registers to reset value * @vcpu: The VCPU pointer @@ -5352,321 +4466,25 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu) * Userspace API *************************************************************************= ****/ =20 -static bool index_to_params(u64 id, struct sys_reg_params *params) -{ - switch (id & KVM_REG_SIZE_MASK) { - case KVM_REG_SIZE_U64: - /* Any unused index bits means it's not valid. */ - if (id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK - | KVM_REG_ARM_COPROC_MASK - | KVM_REG_ARM64_SYSREG_OP0_MASK - | KVM_REG_ARM64_SYSREG_OP1_MASK - | KVM_REG_ARM64_SYSREG_CRN_MASK - | KVM_REG_ARM64_SYSREG_CRM_MASK - | KVM_REG_ARM64_SYSREG_OP2_MASK)) - return false; - params->Op0 =3D ((id & KVM_REG_ARM64_SYSREG_OP0_MASK) - >> KVM_REG_ARM64_SYSREG_OP0_SHIFT); - params->Op1 =3D ((id & KVM_REG_ARM64_SYSREG_OP1_MASK) - >> KVM_REG_ARM64_SYSREG_OP1_SHIFT); - params->CRn =3D ((id & KVM_REG_ARM64_SYSREG_CRN_MASK) - >> KVM_REG_ARM64_SYSREG_CRN_SHIFT); - params->CRm =3D ((id & KVM_REG_ARM64_SYSREG_CRM_MASK) - >> KVM_REG_ARM64_SYSREG_CRM_SHIFT); - params->Op2 =3D ((id & KVM_REG_ARM64_SYSREG_OP2_MASK) - >> KVM_REG_ARM64_SYSREG_OP2_SHIFT); - return true; - default: - return false; - } -} - -const struct sys_reg_desc *get_reg_by_id(u64 id, - const struct sys_reg_desc table[], - unsigned int num) -{ - struct sys_reg_params params; - - if (!index_to_params(id, ¶ms)) - return NULL; - - return find_reg(¶ms, table, num); -} - -/* Decode an index value, and find the sys_reg_desc entry. */ -static const struct sys_reg_desc * -id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id, - const struct sys_reg_desc table[], unsigned int num) - -{ - const struct sys_reg_desc *r; - - /* We only do sys_reg for now. */ - if ((id & KVM_REG_ARM_COPROC_MASK) !=3D KVM_REG_ARM64_SYSREG) - return NULL; - - r =3D get_reg_by_id(id, table, num); - - /* Not saved in the sys_reg array and not otherwise accessible? */ - if (r && (!(r->reg || r->get_user) || sysreg_hidden(vcpu, r))) - r =3D NULL; - - return r; -} - -static int demux_c15_get(struct kvm_vcpu *vcpu, u64 id, void __user *uaddr) -{ - u32 val; - u32 __user *uval =3D uaddr; - - /* Fail if we have unknown bits set. */ - if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK - | ((1 << KVM_REG_ARM_COPROC_SHIFT)-1))) - return -ENOENT; - - switch (id & KVM_REG_ARM_DEMUX_ID_MASK) { - case KVM_REG_ARM_DEMUX_ID_CCSIDR: - if (KVM_REG_SIZE(id) !=3D 4) - return -ENOENT; - val =3D (id & KVM_REG_ARM_DEMUX_VAL_MASK) - >> KVM_REG_ARM_DEMUX_VAL_SHIFT; - if (val >=3D CSSELR_MAX) - return -ENOENT; - - return put_user(get_ccsidr(vcpu, val), uval); - default: - return -ENOENT; - } -} - -static int demux_c15_set(struct kvm_vcpu *vcpu, u64 id, void __user *uaddr) -{ - u32 val, newval; - u32 __user *uval =3D uaddr; - - /* Fail if we have unknown bits set. */ - if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK - | ((1 << KVM_REG_ARM_COPROC_SHIFT)-1))) - return -ENOENT; - - switch (id & KVM_REG_ARM_DEMUX_ID_MASK) { - case KVM_REG_ARM_DEMUX_ID_CCSIDR: - if (KVM_REG_SIZE(id) !=3D 4) - return -ENOENT; - val =3D (id & KVM_REG_ARM_DEMUX_VAL_MASK) - >> KVM_REG_ARM_DEMUX_VAL_SHIFT; - if (val >=3D CSSELR_MAX) - return -ENOENT; - - if (get_user(newval, uval)) - return -EFAULT; - - return set_ccsidr(vcpu, val, newval); - default: - return -ENOENT; - } -} - -static u64 kvm_one_reg_to_id(const struct kvm_one_reg *reg) -{ - switch(reg->id) { - case KVM_REG_ARM_TIMER_CVAL: - return TO_ARM64_SYS_REG(CNTV_CVAL_EL0); - case KVM_REG_ARM_TIMER_CNT: - return TO_ARM64_SYS_REG(CNTVCT_EL0); - default: - return reg->id; - } -} - -int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *= reg, - const struct sys_reg_desc table[], unsigned int num) -{ - u64 __user *uaddr =3D (u64 __user *)(unsigned long)reg->addr; - const struct sys_reg_desc *r; - u64 id =3D kvm_one_reg_to_id(reg); - u64 val; - int ret; - - r =3D id_to_sys_reg_desc(vcpu, id, table, num); - if (!r || sysreg_hidden(vcpu, r)) - return -ENOENT; - - if (r->get_user) { - ret =3D (r->get_user)(vcpu, r, &val); - } else { - val =3D __vcpu_sys_reg(vcpu, r->reg); - ret =3D 0; - } - - if (!ret) - ret =3D put_user(val, uaddr); - - return ret; -} - int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_re= g *reg) { - void __user *uaddr =3D (void __user *)(unsigned long)reg->addr; - - if ((reg->id & KVM_REG_ARM_COPROC_MASK) =3D=3D KVM_REG_ARM_DEMUX) - return demux_c15_get(vcpu, reg->id, uaddr); - - return kvm_sys_reg_get_user(vcpu, reg, - sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); -} - -int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *= reg, - const struct sys_reg_desc table[], unsigned int num) -{ - u64 __user *uaddr =3D (u64 __user *)(unsigned long)reg->addr; - const struct sys_reg_desc *r; - u64 id =3D kvm_one_reg_to_id(reg); - u64 val; - int ret; - - if (get_user(val, uaddr)) - return -EFAULT; - - r =3D id_to_sys_reg_desc(vcpu, id, table, num); - if (!r || sysreg_hidden(vcpu, r)) - return -ENOENT; - - if (sysreg_user_write_ignore(vcpu, r)) - return 0; - - if (r->set_user) { - ret =3D (r->set_user)(vcpu, r, val); - } else { - __vcpu_assign_sys_reg(vcpu, r->reg, val); - ret =3D 0; - } - - return ret; + return __kvm_arm_sys_reg_get_reg(vcpu, reg, ARRAY_SIZE(sys_reg_descs), sy= s_reg_descs); } =20 int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_re= g *reg) { - void __user *uaddr =3D (void __user *)(unsigned long)reg->addr; - - if ((reg->id & KVM_REG_ARM_COPROC_MASK) =3D=3D KVM_REG_ARM_DEMUX) - return demux_c15_set(vcpu, reg->id, uaddr); - - return kvm_sys_reg_set_user(vcpu, reg, - sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); -} - -static unsigned int num_demux_regs(void) -{ - return CSSELR_MAX; -} - -static int write_demux_regids(u64 __user *uindices) -{ - u64 val =3D KVM_REG_ARM64 | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX; - unsigned int i; - - val |=3D KVM_REG_ARM_DEMUX_ID_CCSIDR; - for (i =3D 0; i < CSSELR_MAX; i++) { - if (put_user(val | i, uindices)) - return -EFAULT; - uindices++; - } - return 0; -} - -static u64 sys_reg_to_index(const struct sys_reg_desc *reg) -{ - return (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | - KVM_REG_ARM64_SYSREG | - (reg->Op0 << KVM_REG_ARM64_SYSREG_OP0_SHIFT) | - (reg->Op1 << KVM_REG_ARM64_SYSREG_OP1_SHIFT) | - (reg->CRn << KVM_REG_ARM64_SYSREG_CRN_SHIFT) | - (reg->CRm << KVM_REG_ARM64_SYSREG_CRM_SHIFT) | - (reg->Op2 << KVM_REG_ARM64_SYSREG_OP2_SHIFT)); -} - -static bool copy_reg_to_user(const struct sys_reg_desc *reg, u64 __user **= uind) -{ - u64 idx; - - if (!*uind) - return true; - - switch (reg_to_encoding(reg)) { - case SYS_CNTV_CVAL_EL0: - idx =3D KVM_REG_ARM_TIMER_CVAL; - break; - case SYS_CNTVCT_EL0: - idx =3D KVM_REG_ARM_TIMER_CNT; - break; - default: - idx =3D sys_reg_to_index(reg); - } - - if (put_user(idx, *uind)) - return false; - - (*uind)++; - return true; -} - -static int walk_one_sys_reg(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *rd, - u64 __user **uind, - unsigned int *total) -{ - /* - * Ignore registers we trap but don't save, - * and for which no custom user accessor is provided. - */ - if (!(rd->reg || rd->get_user)) - return 0; - - if (sysreg_hidden(vcpu, rd)) - return 0; - - if (!copy_reg_to_user(rd, uind)) - return -EFAULT; - - (*total)++; - return 0; -} - -/* Assumed ordered tables, see kvm_sys_reg_table_init. */ -static int walk_sys_regs(struct kvm_vcpu *vcpu, u64 __user *uind) -{ - const struct sys_reg_desc *i2, *end2; - unsigned int total =3D 0; - int err; - - i2 =3D sys_reg_descs; - end2 =3D sys_reg_descs + ARRAY_SIZE(sys_reg_descs); =20 - while (i2 !=3D end2) { - err =3D walk_one_sys_reg(vcpu, i2++, &uind, &total); - if (err) - return err; - } - return total; + return __kvm_arm_sys_reg_set_reg(vcpu, reg, ARRAY_SIZE(sys_reg_descs), sy= s_reg_descs); } =20 unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu) { - return num_demux_regs() - + walk_sys_regs(vcpu, (u64 __user *)NULL); -} + return __kvm_arm_num_sys_reg_descs(vcpu, ARRAY_SIZE(sys_reg_descs), sys_r= eg_descs);} =20 -int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindic= es) +int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu * vcpu, u64 __user * uind= ices) { - int err; - - err =3D walk_sys_regs(vcpu, uindices); - if (err < 0) - return err; - uindices +=3D err; - - return write_demux_regids(uindices); + return __kvm_arm_copy_sys_reg_indices( + vcpu, uindices, ARRAY_SIZE(sys_reg_descs), sys_reg_descs); } =20 #define KVM_ARM_FEATURE_ID_RANGE_INDEX(r) \ diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h deleted file mode 100644 index 75d581050b09..000000000000 --- a/arch/arm64/kvm/sys_regs.h +++ /dev/null @@ -1,363 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2012,2013 - ARM Ltd - * Author: Marc Zyngier - * - * Derived from arch/arm/kvm/coproc.h - * Copyright (C) 2012 - Virtual Open Systems and Columbia University - * Authors: Christoffer Dall - */ - -#ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__ -#define __ARM64_KVM_SYS_REGS_LOCAL_H__ - -#include - -#define reg_to_encoding(x) \ - sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ - (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2) - -struct sys_reg_params { - u8 Op0; - u8 Op1; - u8 CRn; - u8 CRm; - u8 Op2; - u64 regval; - bool is_write; -}; - -#define encoding_to_params(reg) \ - ((struct sys_reg_params){ .Op0 =3D sys_reg_Op0(reg), \ - .Op1 =3D sys_reg_Op1(reg), \ - .CRn =3D sys_reg_CRn(reg), \ - .CRm =3D sys_reg_CRm(reg), \ - .Op2 =3D sys_reg_Op2(reg) }) - -#define esr_sys64_to_params(esr) = \ - ((struct sys_reg_params){ .Op0 =3D ((esr) >> 20) & 3, \ - .Op1 =3D ((esr) >> 14) & 0x7, \ - .CRn =3D ((esr) >> 10) & 0xf, \ - .CRm =3D ((esr) >> 1) & 0xf, \ - .Op2 =3D ((esr) >> 17) & 0x7, \ - .is_write =3D !((esr) & 1) }) - -#define esr_cp1x_32_to_params(esr) \ - ((struct sys_reg_params){ .Op1 =3D ((esr) >> 14) & 0x7, \ - .CRn =3D ((esr) >> 10) & 0xf, \ - .CRm =3D ((esr) >> 1) & 0xf, \ - .Op2 =3D ((esr) >> 17) & 0x7, \ - .is_write =3D !((esr) & 1) }) - -/* - * The Feature ID space is defined as the System register space in AArch64 - * with op0=3D=3D3, op1=3D=3D{0, 1, 3}, CRn=3D=3D0, CRm=3D=3D{0-7}, op2=3D= =3D{0-7}. - */ -static inline bool in_feat_id_space(struct sys_reg_params *p) -{ - return (p->Op0 =3D=3D 3 && !(p->Op1 & 0b100) && p->Op1 !=3D 2 && - p->CRn =3D=3D 0 && !(p->CRm & 0b1000)); -} - -struct sys_reg_desc { - /* Sysreg string for debug */ - const char *name; - - enum { - AA32_DIRECT, - AA32_LO, - AA32_HI, - } aarch32_map; - - /* MRS/MSR instruction which accesses it. */ - u8 Op0; - u8 Op1; - u8 CRn; - u8 CRm; - u8 Op2; - - /* Trapped access from guest, if non-NULL. */ - bool (*access)(struct kvm_vcpu *, - struct sys_reg_params *, - const struct sys_reg_desc *); - - /* - * Initialization for vcpu. Return initialized value, or KVM - * sanitized value for ID registers. - */ - u64 (*reset)(struct kvm_vcpu *, const struct sys_reg_desc *); - - /* Index into sys_reg[], or 0 if we don't need to save it. */ - int reg; - - /* Value (usually reset value), or write mask for idregs */ - u64 val; - - /* Custom get/set_user functions, fallback to generic if NULL */ - int (*get_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, - u64 *val); - int (*set_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, - u64 val); - - /* Return mask of REG_* runtime visibility overrides */ - unsigned int (*visibility)(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *rd); -}; - -#define REG_HIDDEN (1 << 0) /* hidden from userspace and guest */ -#define REG_RAZ (1 << 1) /* RAZ from userspace and guest */ -#define REG_USER_WI (1 << 2) /* WI from userspace only */ - -static inline unsigned int raz_visibility(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - return REG_RAZ; -} - -static __printf(2, 3) -inline void print_sys_reg_msg(const struct sys_reg_params *p, - char *fmt, ...) -{ - va_list va; - - va_start(va, fmt); - /* Look, we even formatted it for you to paste into the table! */ - kvm_pr_unimpl("%pV { Op0(%2u), Op1(%2u), CRn(%2u), CRm(%2u), Op2(%2u), fu= nc_%s },\n", - &(struct va_format){ fmt, &va }, - p->Op0, p->Op1, p->CRn, p->CRm, p->Op2, str_write_read(p->is_write= )); - va_end(va); -} - -static inline void print_sys_reg_instr(const struct sys_reg_params *p) -{ - /* GCC warns on an empty format string */ - print_sys_reg_msg(p, "%s", ""); -} - -static inline bool ignore_write(struct kvm_vcpu *vcpu, - const struct sys_reg_params *p) -{ - return true; -} - -static inline bool read_zero(struct kvm_vcpu *vcpu, - struct sys_reg_params *p) -{ - p->regval =3D 0; - return true; -} - -/* Reset functions */ -static inline u64 reset_unknown(struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - BUG_ON(!r->reg); - BUG_ON(r->reg >=3D NR_SYS_REGS); - __vcpu_assign_sys_reg(vcpu, r->reg, 0x1de7ec7edbadc0deULL); - return __vcpu_sys_reg(vcpu, r->reg); -} - -static inline u64 reset_val(struct kvm_vcpu *vcpu, const struct sys_reg_de= sc *r) -{ - BUG_ON(!r->reg); - BUG_ON(r->reg >=3D NR_SYS_REGS); - __vcpu_assign_sys_reg(vcpu, r->reg, r->val); - return __vcpu_sys_reg(vcpu, r->reg); -} - -static inline unsigned int sysreg_visibility(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - if (likely(!r->visibility)) - return 0; - - return r->visibility(vcpu, r); -} - -static inline bool sysreg_hidden(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - return sysreg_visibility(vcpu, r) & REG_HIDDEN; -} - -static inline bool sysreg_visible_as_raz(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - return sysreg_visibility(vcpu, r) & REG_RAZ; -} - -static inline bool sysreg_user_write_ignore(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r) -{ - return sysreg_visibility(vcpu, r) & REG_USER_WI; -} - -static inline int cmp_sys_reg(const struct sys_reg_desc *i1, - const struct sys_reg_desc *i2) -{ - BUG_ON(i1 =3D=3D i2); - if (!i1) - return 1; - else if (!i2) - return -1; - if (i1->Op0 !=3D i2->Op0) - return i1->Op0 - i2->Op0; - if (i1->Op1 !=3D i2->Op1) - return i1->Op1 - i2->Op1; - if (i1->CRn !=3D i2->CRn) - return i1->CRn - i2->CRn; - if (i1->CRm !=3D i2->CRm) - return i1->CRm - i2->CRm; - return i1->Op2 - i2->Op2; -} - -static inline int match_sys_reg(const void *key, const void *elt) -{ - const unsigned long pval =3D (unsigned long)key; - const struct sys_reg_desc *r =3D elt; - - return pval - reg_to_encoding(r); -} - -static inline const struct sys_reg_desc * -find_reg(const struct sys_reg_params *params, const struct sys_reg_desc ta= ble[], - unsigned int num) -{ - unsigned long pval =3D reg_to_encoding(params); - - return __inline_bsearch((void *)pval, table, num, sizeof(table[0]), match= _sys_reg); -} - -const struct sys_reg_desc *get_reg_by_id(u64 id, - const struct sys_reg_desc table[], - unsigned int num); - -int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_re= g *); -int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_re= g *); -int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *= reg, - const struct sys_reg_desc table[], unsigned int num); -int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *= reg, - const struct sys_reg_desc table[], unsigned int num); - -bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index); - -int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu); - -u64 kvm_read_sanitised_id_reg(struct kvm_vcpu *vcpu, - const struct sys_reg_desc *r); - -/* Implemented by each architecture */ -u64 kvm_sanitised_host_ftr_reg(u32 id); - -#define AA32(_x) .aarch32_map =3D AA32_##_x -#define Op0(_x) .Op0 =3D _x -#define Op1(_x) .Op1 =3D _x -#define CRn(_x) .CRn =3D _x -#define CRm(_x) .CRm =3D _x -#define Op2(_x) .Op2 =3D _x - -#define SYS_DESC(reg) \ - .name =3D #reg, \ - Op0(sys_reg_Op0(reg)), Op1(sys_reg_Op1(reg)), \ - CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)), \ - Op2(sys_reg_Op2(reg)) - -#define CP15_SYS_DESC(reg) \ - .name =3D #reg, \ - .aarch32_map =3D AA32_DIRECT, \ - Op0(0), Op1(sys_reg_Op1(reg)), \ - CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)), \ - Op2(sys_reg_Op2(reg)) - -/* - * Since reset() callback and field val are not used for idregs, they will= be - * used for specific purposes for idregs. - * The reset() would return KVM sanitised register value. The value would = be the - * same as the host kernel sanitised value if there is no KVM sanitisation. - * The val would be used as a mask indicating writable fields for the idre= g. - * Only bits with 1 are writable from userspace. This mask might not be - * necessary in the future whenever all ID registers are enabled as writab= le - * from userspace. - */ - -#define ID_DESC_DEFAULT_CALLBACKS \ - .access =3D access_id_reg, \ - .get_user =3D get_id_reg, \ - .set_user =3D set_id_reg, \ - .visibility =3D id_visibility, \ - .reset =3D kvm_read_sanitised_id_reg - -#define ID_DESC(name) \ - SYS_DESC(SYS_##name), \ - ID_DESC_DEFAULT_CALLBACKS - -/* sys_reg_desc initialiser for known cpufeature ID registers */ -#define ID_SANITISED(name) { \ - ID_DESC(name), \ - .val =3D 0, \ -} - -/* sys_reg_desc initialiser for writable ID registers */ -#define ID_WRITABLE(name, mask) { \ - ID_DESC(name), \ - .val =3D mask, \ -} - -/* - * 32bit ID regs are fully writable when the guest is 32bit - * capable. Nothing in the KVM code should rely on 32bit features - * anyway, only 64bit, so let the VMM do its worse. - */ -#define AA32_ID_WRITABLE(name) { \ - ID_DESC(name), \ - .visibility =3D aa32_id_visibility, \ - .val =3D GENMASK(31, 0), \ -} - -/* sys_reg_desc initialiser for cpufeature ID registers that need filterin= g */ -#define ID_FILTERED(sysreg, name, mask) { \ - ID_DESC(sysreg), \ - .set_user =3D set_##name, \ - .val =3D (mask), \ -} - -/* - * sys_reg_desc initialiser for architecturally unallocated cpufeature ID - * register with encoding Op0=3D3, Op1=3D0, CRn=3D0, CRm=3Dcrm, Op2=3Dop2 - * (1 <=3D crm < 8, 0 <=3D Op2 < 8). - */ -#define ID_UNALLOCATED(crm, op2) { \ - .name =3D "S3_0_0_" #crm "_" #op2, \ - Op0(3), Op1(0), CRn(0), CRm(crm), Op2(op2), \ - ID_DESC_DEFAULT_CALLBACKS, \ - .visibility =3D raz_visibility, \ - .val =3D 0, \ -} - -/* - * sys_reg_desc initialiser for known ID registers that we hide from guest= s. - * For now, these are exposed just like unallocated ID regs: they appear - * RAZ for the guest. - */ -#define ID_HIDDEN(name) { \ - ID_DESC(name), \ - .visibility =3D raz_visibility, \ - .val =3D 0, \ -} -#define ID_REG_LIMIT_FIELD_ENUM(val, reg, field, limit) \ -({ \ - u64 __f_val =3D FIELD_GET(reg##_##field##_MASK, val); \ - (val) &=3D ~reg##_##field##_MASK; \ - (val) |=3D FIELD_PREP(reg##_##field##_MASK, \ - min(__f_val, \ - (u64)SYS_FIELD_VALUE(reg, field, limit))); \ - (val); \ -}) - -#define TO_ARM64_SYS_REG(r) 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)) - -#endif /* __ARM64_KVM_SYS_REGS_LOCAL_H__ */ diff --git a/arch/arm64/kvm/trace_handle_exit.h b/arch/arm64/kvm/trace_hand= le_exit.h index a7ab9a3bbed0..280d79469551 100644 --- a/arch/arm64/kvm/trace_handle_exit.h +++ b/arch/arm64/kvm/trace_handle_exit.h @@ -3,7 +3,7 @@ #define _TRACE_HANDLE_EXIT_ARM64_KVM_H =20 #include -#include "sys_regs.h" +#include =20 #undef TRACE_SYSTEM #define TRACE_SYSTEM kvm @@ -82,40 +82,6 @@ TRACE_EVENT(kvm_handle_sys_reg, TP_printk("HSR 0x%08lx", __entry->hsr) ); =20 -TRACE_EVENT(kvm_sys_access, - TP_PROTO(unsigned long vcpu_pc, struct sys_reg_params *params, const stru= ct sys_reg_desc *reg), - TP_ARGS(vcpu_pc, params, reg), - - TP_STRUCT__entry( - __field(unsigned long, vcpu_pc) - __field(bool, is_write) - __field(const char *, name) - __field(u8, Op0) - __field(u8, Op1) - __field(u8, CRn) - __field(u8, CRm) - __field(u8, Op2) - ), - - TP_fast_assign( - __entry->vcpu_pc =3D vcpu_pc; - __entry->is_write =3D params->is_write; - __entry->name =3D reg->name; - __entry->Op0 =3D reg->Op0; - __entry->Op0 =3D reg->Op0; - __entry->Op1 =3D reg->Op1; - __entry->CRn =3D reg->CRn; - __entry->CRm =3D reg->CRm; - __entry->Op2 =3D reg->Op2; - ), - - TP_printk("PC: %lx %s (%d,%d,%d,%d,%d) %s", - __entry->vcpu_pc, __entry->name ?: "UNKN", - __entry->Op0, __entry->Op1, __entry->CRn, - __entry->CRm, __entry->Op2, - str_write_read(__entry->is_write)) -); - TRACE_EVENT(kvm_set_guest_debug, TP_PROTO(struct kvm_vcpu *vcpu, __u32 guest_debug), TP_ARGS(vcpu, guest_debug), diff --git a/arch/arm64/kvm/vgic-sys-reg-v3.c b/arch/arm64/kvm/vgic-sys-reg= -v3.c index bdc2d57370b2..b6cbe8ea679e 100644 --- a/arch/arm64/kvm/vgic-sys-reg-v3.c +++ b/arch/arm64/kvm/vgic-sys-reg-v3.c @@ -8,7 +8,7 @@ #include #include #include "vgic/vgic.h" -#include "sys_regs.h" +#include =20 static int set_gic_ctlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *= r, u64 val) diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-ini= t.c index 933983bb2005..d75c32f6909e 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "vgic.h" =20 /* diff --git a/arch/s390/include/asm/kvm_host_arm64.h b/arch/s390/include/asm= /kvm_host_arm64.h index d6d9e3ad7a8e..fcbe510cb868 100644 --- a/arch/s390/include/asm/kvm_host_arm64.h +++ b/arch/s390/include/asm/kvm_host_arm64.h @@ -145,6 +145,8 @@ struct kvm_arch { DECLARE_BITMAP(vcpu_features, KVM_VCPU_MAX_FEATURES); =20 unsigned long mem_limit; + + struct kvm_vm_id_regs id_regs; }; =20 static inline bool __vcpu_has_feature(const struct kvm_arch *ka, int featu= re) @@ -218,9 +220,6 @@ static inline void kvm_arch_async_page_present_queued(s= truct kvm_vcpu *vcpu) =20 #define kvm_supports_32bit_el0() false =20 -#define vcpu_read_sys_reg(_v, _r) 0xbad1234bad -#define vcpu_write_sys_reg(_v, _p, _r) ((void)0) - #define __vcpu_sys_reg(__vcpu, __reg) \ vcpu_read_sys_reg(__vcpu, __reg) =20 diff --git a/arch/s390/kvm/arm64/arm.c b/arch/s390/kvm/arm64/arm.c index 636bbeda98a8..48418c46e451 100644 --- a/arch/s390/kvm/arm64/arm.c +++ b/arch/s390/kvm/arm64/arm.c @@ -690,6 +690,15 @@ long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, u= nsigned int ioctl, return -ENOIOCTLCMD; } =20 +void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, enum vcpu_sysreg r= eg) +{ +} + +u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg reg) +{ + return 0xbad12324bad; +} + static int __init kvm_s390_arm64_init(void) { if (!sclp.has_aef) { diff --git a/include/kvm/arm64/kvm_host.h b/include/kvm/arm64/kvm_host.h index 379942225d5f..deb115a737b5 100644 --- a/include/kvm/arm64/kvm_host.h +++ b/include/kvm/arm64/kvm_host.h @@ -233,7 +233,17 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fa= ult_ipa); /* Unhandled SEAs are taken to userspace */ #define KVM_ARCH_FLAG_EXIT_SEA 11 =20 +#define kvm_vm_has_ran_once(kvm) \ + (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &(kvm)->arch.flags)) + /* Implemented in architecture specific code */ unsigned long system_supported_vcpu_features(void); =20 +enum vcpu_sysreg; +void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, enum vcpu_sysreg r= eg); +u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg reg); + +int kvm_handle_sys_reg(struct kvm_vcpu *vcpu); +void kvm_reset_sys_regs(struct kvm_vcpu *vcpu); + #endif /* __KVM_ARM64_KVM_HOST_H */ diff --git a/include/kvm/arm64/sys_regs.h b/include/kvm/arm64/sys_regs.h new file mode 100644 index 000000000000..ca652274072a --- /dev/null +++ b/include/kvm/arm64/sys_regs.h @@ -0,0 +1,548 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2012,2013 - ARM Ltd + * Author: Marc Zyngier + * + * Derived from arch/arm/kvm/coproc.h + * Copyright (C) 2012 - Virtual Open Systems and Columbia University + * Authors: Christoffer Dall + */ + +#ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__ +#define __ARM64_KVM_SYS_REGS_LOCAL_H__ + +#include + +#include + +#define reg_to_encoding(x) \ + sys_reg((u32)(x)->Op0, (u32)(x)->Op1, \ + (u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2) + +struct sys_reg_params { + u8 Op0; + u8 Op1; + u8 CRn; + u8 CRm; + u8 Op2; + u64 regval; + bool is_write; +}; + +#define encoding_to_params(reg) \ + ((struct sys_reg_params){ .Op0 =3D sys_reg_Op0(reg), \ + .Op1 =3D sys_reg_Op1(reg), \ + .CRn =3D sys_reg_CRn(reg), \ + .CRm =3D sys_reg_CRm(reg), \ + .Op2 =3D sys_reg_Op2(reg) }) + +#define esr_sys64_to_params(esr) = \ + ((struct sys_reg_params){ .Op0 =3D ((esr) >> 20) & 3, \ + .Op1 =3D ((esr) >> 14) & 0x7, \ + .CRn =3D ((esr) >> 10) & 0xf, \ + .CRm =3D ((esr) >> 1) & 0xf, \ + .Op2 =3D ((esr) >> 17) & 0x7, \ + .is_write =3D !((esr) & 1) }) + +#define esr_cp1x_32_to_params(esr) \ + ((struct sys_reg_params){ .Op1 =3D ((esr) >> 14) & 0x7, \ + .CRn =3D ((esr) >> 10) & 0xf, \ + .CRm =3D ((esr) >> 1) & 0xf, \ + .Op2 =3D ((esr) >> 17) & 0x7, \ + .is_write =3D !((esr) & 1) }) + +/* + * The Feature ID space is defined as the System register space in AArch64 + * with op0=3D=3D3, op1=3D=3D{0, 1, 3}, CRn=3D=3D0, CRm=3D=3D{0-7}, op2=3D= =3D{0-7}. + */ +static inline bool in_feat_id_space(struct sys_reg_params *p) +{ + return (p->Op0 =3D=3D 3 && !(p->Op1 & 0b100) && p->Op1 !=3D 2 && + p->CRn =3D=3D 0 && !(p->CRm & 0b1000)); +} + +struct sys_reg_desc { + /* Sysreg string for debug */ + const char *name; + + enum { + AA32_DIRECT, + AA32_LO, + AA32_HI, + } aarch32_map; + + /* MRS/MSR instruction which accesses it. */ + u8 Op0; + u8 Op1; + u8 CRn; + u8 CRm; + u8 Op2; + + /* Trapped access from guest, if non-NULL. */ + bool (*access)(struct kvm_vcpu *, + struct sys_reg_params *, + const struct sys_reg_desc *); + + /* + * Initialization for vcpu. Return initialized value, or KVM + * sanitized value for ID registers. + */ + u64 (*reset)(struct kvm_vcpu *, const struct sys_reg_desc *); + + /* Index into sys_reg[], or 0 if we don't need to save it. */ + int reg; + + /* Value (usually reset value), or write mask for idregs */ + u64 val; + + /* Custom get/set_user functions, fallback to generic if NULL */ + int (*get_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + u64 *val); + int (*set_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + u64 val); + + /* Return mask of REG_* runtime visibility overrides */ + unsigned int (*visibility)(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd); +}; + +#define REG_HIDDEN (1 << 0) /* hidden from userspace and guest */ +#define REG_RAZ (1 << 1) /* RAZ from userspace and guest */ +#define REG_USER_WI (1 << 2) /* WI from userspace only */ + +static inline unsigned int raz_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + return REG_RAZ; +} + +static __printf(2, 3) +inline void print_sys_reg_msg(const struct sys_reg_params *p, + char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + /* Look, we even formatted it for you to paste into the table! */ + kvm_pr_unimpl("%pV { Op0(%2u), Op1(%2u), CRn(%2u), CRm(%2u), Op2(%2u), fu= nc_%s },\n", + &(struct va_format){ fmt, &va }, + p->Op0, p->Op1, p->CRn, p->CRm, p->Op2, str_write_read(p->is_write= )); + va_end(va); +} + +static inline void print_sys_reg_instr(const struct sys_reg_params *p) +{ + /* GCC warns on an empty format string */ + print_sys_reg_msg(p, "%s", ""); +} + +static inline bool ignore_write(struct kvm_vcpu *vcpu, + const struct sys_reg_params *p) +{ + return true; +} + +static inline bool read_zero(struct kvm_vcpu *vcpu, + struct sys_reg_params *p) +{ + p->regval =3D 0; + return true; +} + +/* Reset functions */ +static inline u64 reset_unknown(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + BUG_ON(!r->reg); + BUG_ON(r->reg >=3D NR_SYS_REGS); + __vcpu_assign_sys_reg(vcpu, r->reg, 0x1de7ec7edbadc0deULL); + return __vcpu_sys_reg(vcpu, r->reg); +} + +static inline u64 reset_val(struct kvm_vcpu *vcpu, const struct sys_reg_de= sc *r) +{ + BUG_ON(!r->reg); + BUG_ON(r->reg >=3D NR_SYS_REGS); + __vcpu_assign_sys_reg(vcpu, r->reg, r->val); + return __vcpu_sys_reg(vcpu, r->reg); +} + +static inline unsigned int sysreg_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + if (likely(!r->visibility)) + return 0; + + return r->visibility(vcpu, r); +} + +static inline bool sysreg_hidden(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + return sysreg_visibility(vcpu, r) & REG_HIDDEN; +} + +static inline bool sysreg_visible_as_raz(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + return sysreg_visibility(vcpu, r) & REG_RAZ; +} + +static inline bool sysreg_user_write_ignore(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + return sysreg_visibility(vcpu, r) & REG_USER_WI; +} + +static inline int cmp_sys_reg(const struct sys_reg_desc *i1, + const struct sys_reg_desc *i2) +{ + BUG_ON(i1 =3D=3D i2); + if (!i1) + return 1; + else if (!i2) + return -1; + if (i1->Op0 !=3D i2->Op0) + return i1->Op0 - i2->Op0; + if (i1->Op1 !=3D i2->Op1) + return i1->Op1 - i2->Op1; + if (i1->CRn !=3D i2->CRn) + return i1->CRn - i2->CRn; + if (i1->CRm !=3D i2->CRm) + return i1->CRm - i2->CRm; + return i1->Op2 - i2->Op2; +} + +static inline int match_sys_reg(const void *key, const void *elt) +{ + const unsigned long pval =3D (unsigned long)key; + const struct sys_reg_desc *r =3D elt; + + return pval - reg_to_encoding(r); +} + +static inline const struct sys_reg_desc * +find_reg(const struct sys_reg_params *params, const struct sys_reg_desc ta= ble[], + unsigned int num) +{ + unsigned long pval =3D reg_to_encoding(params); + + return __inline_bsearch((void *)pval, table, num, sizeof(table[0]), match= _sys_reg); +} + +const struct sys_reg_desc *get_reg_by_id(u64 id, + const struct sys_reg_desc table[], + unsigned int num); + +int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *= reg, + const struct sys_reg_desc table[], unsigned int num); +int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *= reg, + const struct sys_reg_desc table[], unsigned int num); + +bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index); + +int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu); + + +int __kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_= reg *reg, + size_t n_descs, + const struct sys_reg_desc sys_reg_descs[n_descs]) +; + +int __kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu,=20 + const struct kvm_one_reg *reg, + size_t n_descs, + const struct sys_reg_desc sys_reg_descs[n_descs]); +unsigned long __kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu, size_t n_= descs, + const struct sys_reg_desc sys_reg_descs[n_descs]); +int __kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, + u64 __user *uindices, + size_t n_descs, + const struct sys_reg_desc sys_reg_descs[n_descs]); +int get_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, u64 *= val); +int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, u64 v= al); +bool access_id_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r); +int set_id_aa64mmfr0_el1(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, + u64 user_val); +unsigned int id_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r); +unsigned int aa32_id_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r); +int set_imp_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, + u64 val); +void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); +int set_ctr_el0(struct kvm_vcpu *vcpu,=20 + const struct sys_reg_desc *rd, + u64 user_val); +bool trap_oslar_el1(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r); +bool trap_oslsr_el1(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r); +int set_oslsr_el1(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, + u64 val); + +bool trap_raz_wi(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r); + u64 reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r); + bool access_rw(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r); +bool access_clidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r); +u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r); +int set_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, u64 va= l); +bool access_csselr(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r); +u32 get_ccsidr(struct kvm_vcpu *vcpu, u32 csselr); +int set_ccsidr(struct kvm_vcpu *vcpu, u32 csselr, u32 val); +bool access_ccsidr(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r); +void perform_access(struct kvm_vcpu *vcpu, + struct sys_reg_params *params, + const struct sys_reg_desc *r); + +void reset_vm_ftr_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc = *reg); +void reset_vcpu_ftr_id_reg(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *reg); +bool check_sysreg_table(const struct sys_reg_desc *table, unsigned int n, + bool reset_check); + +static inline u64 read_id_reg(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + return kvm_read_vm_id_reg(vcpu->kvm, reg_to_encoding(r)); +} + +static bool is_feature_id_reg(u32 encoding) +{ + return (sys_reg_Op0(encoding) =3D=3D 3 && + (sys_reg_Op1(encoding) < 2 || sys_reg_Op1(encoding) =3D=3D 3) && + sys_reg_CRn(encoding) =3D=3D 0 && + sys_reg_CRm(encoding) <=3D 7); +} + +static inline bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_para= ms *p, + const struct sys_reg_desc *r) +{ + kvm_inject_undefined(vcpu); + return false; +} + +static inline bool bad_trap(struct kvm_vcpu *vcpu, + struct sys_reg_params *params, + const struct sys_reg_desc *r, const char *msg) +{ + WARN_ONCE(1, "Unexpected %s\n", msg); + print_sys_reg_instr(params); + return undef_access(vcpu, params, r); +} + +static inline bool read_from_write_only(struct kvm_vcpu *vcpu, + struct sys_reg_params *params, + const struct sys_reg_desc *r) +{ + return bad_trap(vcpu, params, r, + "sys_reg read to write-only register"); +} + +static inline bool write_to_read_only(struct kvm_vcpu *vcpu, + struct sys_reg_params *params, + const struct sys_reg_desc *r) +{ + return bad_trap(vcpu, params, r, + "sys_reg write to read-only register"); +} + +static inline void get_access_mask(const struct sys_reg_desc *r, u64 *mask= , u64 *shift) +{ + switch (r->aarch32_map) { + case AA32_LO: + *mask =3D GENMASK_ULL(31, 0); + *shift =3D 0; + break; + case AA32_HI: + *mask =3D GENMASK_ULL(63, 32); + *shift =3D 32; + break; + default: + *mask =3D GENMASK_ULL(63, 0); + *shift =3D 0; + break; + } +} + +/* + * Return true if the register's (Op0, Op1, CRn, CRm, Op2) is + * (3, 0, 0, crm, op2), where 1<=3Dcrm<8, 0<=3Dop2<8, which is the range o= f ID + * registers KVM maintains on a per-VM basis. + * + * Additionally, the implementation ID registers and CTR_EL0 are handled as + * per-VM registers. + */ +static inline bool is_vm_ftr_id_reg(u32 id) +{ + switch (id) { + case SYS_CTR_EL0: + case SYS_MIDR_EL1: + case SYS_REVIDR_EL1: + case SYS_AIDR_EL1: + return true; + default: + return (sys_reg_Op0(id) =3D=3D 3 && sys_reg_Op1(id) =3D=3D 0 && + sys_reg_CRn(id) =3D=3D 0 && sys_reg_CRm(id) >=3D 1 && + sys_reg_CRm(id) < 8); + } +} + +static inline bool is_vcpu_ftr_id_reg(u32 id) +{ + return is_feature_id_reg(id) && !is_vm_ftr_id_reg(id); +} + +#define AA32(_x) .aarch32_map =3D AA32_##_x +#define Op0(_x) .Op0 =3D _x +#define Op1(_x) .Op1 =3D _x +#define CRn(_x) .CRn =3D _x +#define CRm(_x) .CRm =3D _x +#define Op2(_x) .Op2 =3D _x + +#define SYS_DESC(reg) \ + .name =3D #reg, Op0(sys_reg_Op0(reg)), Op1(sys_reg_Op1(reg)), \ + CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)), Op2(sys_reg_Op2(reg)) + +#define CP15_SYS_DESC(reg) = \ + .name =3D #reg, .aarch32_map =3D AA32_DIRECT, Op0(0), = \ + Op1(sys_reg_Op1(reg)), CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)), \ + Op2(sys_reg_Op2(reg)) + +/* + * Since reset() callback and field val are not used for idregs, they will= be + * used for specific purposes for idregs. + * The reset() would return KVM sanitised register value. The value would = be the + * same as the host kernel sanitised value if there is no KVM sanitisation. + * The val would be used as a mask indicating writable fields for the idre= g. + * Only bits with 1 are writable from userspace. This mask might not be + * necessary in the future whenever all ID registers are enabled as writab= le + * from userspace. + */ + +#define ID_DESC_DEFAULT_CALLBACKS \ + .access =3D access_id_reg, .get_user =3D get_id_reg, \ + .set_user =3D set_id_reg, .visibility =3D id_visibility, \ + .reset =3D kvm_read_sanitised_id_reg + +#define ID_DESC(name) SYS_DESC(SYS_##name), ID_DESC_DEFAULT_CALLBACKS + +/* sys_reg_desc initialiser for known cpufeature ID registers */ +#define ID_SANITISED(name) \ + { \ + ID_DESC(name), \ + .val =3D 0, \ + } + +/* sys_reg_desc initialiser for writable ID registers */ +#define ID_WRITABLE(name, mask) \ + { \ + ID_DESC(name), \ + .val =3D mask, \ + } + +/* + * 32bit ID regs are fully writable when the guest is 32bit + * capable. Nothing in the KVM code should rely on 32bit features + * anyway, only 64bit, so let the VMM do its worse. + */ +#define AA32_ID_WRITABLE(name) \ + { \ + ID_DESC(name), \ + .visibility =3D aa32_id_visibility, \ + .val =3D GENMASK(31, 0), \ + } + +/* sys_reg_desc initialiser for cpufeature ID registers that need filterin= g */ +#define ID_FILTERED(sysreg, name, mask) \ + { \ + ID_DESC(sysreg), \ + .set_user =3D set_##name, \ + .val =3D (mask), \ + } + +/* + * sys_reg_desc initialiser for architecturally unallocated cpufeature ID + * register with encoding Op0=3D3, Op1=3D0, CRn=3D0, CRm=3Dcrm, Op2=3Dop2 + * (1 <=3D crm < 8, 0 <=3D Op2 < 8). + */ +#define ID_UNALLOCATED(crm, op2) \ + { \ + .name =3D "S3_0_0_" #crm "_" #op2, \ + Op0(3), \ + Op1(0), \ + CRn(0), \ + CRm(crm), \ + Op2(op2), \ + ID_DESC_DEFAULT_CALLBACKS, \ + .visibility =3D raz_visibility, \ + .val =3D 0, \ + } + +/* + * sys_reg_desc initialiser for known ID registers that we hide from guest= s. + * For now, these are exposed just like unallocated ID regs: they appear + * RAZ for the guest. + */ +#define ID_HIDDEN(name) \ + { \ + ID_DESC(name), \ + .visibility =3D raz_visibility, \ + .val =3D 0, \ + } +#define ID_REG_LIMIT_FIELD_ENUM(val, reg, field, limit) \ + ({ \ + u64 __f_val =3D FIELD_GET(reg##_##field##_MASK, val); \ + (val) &=3D ~reg##_##field##_MASK; \ + (val) |=3D FIELD_PREP( \ + reg##_##field##_MASK, \ + min(__f_val, \ + (u64)SYS_FIELD_VALUE(reg, field, limit))); \ + (val); \ + }) + +#define TO_ARM64_SYS_REG(r) \ + 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)) + +#define IMPLEMENTATION_ID(reg, mask) { \ + SYS_DESC(SYS_##reg), \ + .access =3D access_imp_id_reg, \ + .get_user =3D get_id_reg, \ + .set_user =3D set_imp_id_reg, \ + .reset =3D reset_imp_id_reg, \ + .val =3D mask, \ + } + +/* Implemented by each architecture */ +int arm64_check_features(struct kvm_vcpu *vcpu, const struct sys_reg_desc = *rd, + u64 val); +u64 kvm_sanitised_host_ftr_reg(u32 id); +bool access_imp_id_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r); +u64 reset_imp_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r); + +u64 kvm_read_sanitised_id_reg(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r); + +int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_re= g * reg); +int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_re= g * reg); +unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu); +int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindic= es); + +#endif /* __ARM64_KVM_SYS_REGS_LOCAL_H__ */ diff --git a/virt/kvm/arm64/mmio.c b/virt/kvm/arm64/mmio.c index 438a554ec1ed..089ee364df87 100644 --- a/virt/kvm/arm64/mmio.c +++ b/virt/kvm/arm64/mmio.c @@ -6,6 +6,7 @@ =20 #include #include +#include #include =20 #define CREATE_TRACE_POINTS diff --git a/virt/kvm/arm64/sys_regs.c b/virt/kvm/arm64/sys_regs.c new file mode 100644 index 000000000000..70664bd7d339 --- /dev/null +++ b/virt/kvm/arm64/sys_regs.c @@ -0,0 +1,1039 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include + +#include +#include +#include +#include +#include + +#include + +#include "trace.h" +/* + * Statically sanitise the host's feature register, independent of the gue= st's + * configuration and host implementation. + */ +static u64 kvm_max_possible_guest_ftr_reg(u32 id, u64 val) +{ + switch (id) { + case SYS_ID_AA64DFR0_EL1: + val =3D ID_REG_LIMIT_FIELD_ENUM(val, ID_AA64DFR0_EL1, DebugVer, V8P8); + + /* Hide SPE from guests */ + val &=3D ~ID_AA64DFR0_EL1_PMSVer_MASK; + + /* Hide BRBE from guests */ + val &=3D ~ID_AA64DFR0_EL1_BRBE_MASK; + break; + case SYS_ID_AA64ISAR2_EL1: + /* Mask WFxT field unless *both* WFET & WFIT are present. */ + if (!id_has_feat(val, ID_AA64ISAR2_EL1, WFxT, IMP)) + val &=3D ~ID_AA64ISAR2_EL1_WFxT; + break; + case SYS_ID_AA64ISAR3_EL1: + val &=3D ID_AA64ISAR3_EL1_FPRCVT | ID_AA64ISAR3_EL1_LSFE | + ID_AA64ISAR3_EL1_FAMINMAX | ID_AA64ISAR3_EL1_LSUI; + break; + case SYS_ID_AA64MMFR2_EL1: + val &=3D ~ID_AA64MMFR2_EL1_CCIDX_MASK; + val &=3D ~ID_AA64MMFR2_EL1_NV; + break; + case SYS_ID_AA64MMFR3_EL1: + val &=3D ID_AA64MMFR3_EL1_TCRX | + ID_AA64MMFR3_EL1_SCTLRX | + ID_AA64MMFR3_EL1_S1POE | + ID_AA64MMFR3_EL1_S1PIE; + break; + case SYS_ID_MMFR4_EL1: + val &=3D ~ID_MMFR4_EL1_CCIDX; + break; + case SYS_ID_AA64PFR0_EL1: + val &=3D ~ID_AA64PFR0_EL1_AMU_MASK; + /* + * MPAM is disabled by default as KVM also needs a set of PARTID to + * program the MPAMVPMx_EL2 PARTID remapping registers with. But some + * older kernels let the guest see the ID bit. + */ + val &=3D ~ID_AA64PFR0_EL1_MPAM_MASK; + break; + case SYS_ID_AA64PFR1_EL1: + 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; + val &=3D ~ID_AA64PFR1_EL1_MPAM_frac; + break; + case SYS_ID_AA64PFR2_EL1: + val &=3D ID_AA64PFR2_EL1_FPMR | + ID_AA64PFR2_EL1_MTEFAR | + ID_AA64PFR2_EL1_MTESTOREONLY; + break; + } + + return val; +} + +/* + * Sanitise based on vCPU configuration. + */ +static u64 kvm_sanitise_vcpu_ftr_reg(const struct kvm_vcpu *vcpu, u32 id, = u64 val) +{ + switch (id) { + case SYS_ID_AA64DFR0_EL1: + /* + * Only initialize the PMU version if the vCPU was configured with one. + */ + val &=3D ~ID_AA64DFR0_EL1_PMUVer_MASK; + if (kvm_vcpu_has_pmu(vcpu)) + val |=3D SYS_FIELD_PREP(ID_AA64DFR0_EL1, PMUVer, + kvm_arm_pmu_get_pmuver_limit()); + break; + case SYS_ID_AA64PFR0_EL1: + if (!vcpu_has_sve(vcpu)) + val &=3D ~ID_AA64PFR0_EL1_SVE_MASK; + break; + case SYS_ID_AA64PFR1_EL1: + if (!kvm_has_mte(vcpu->kvm)) { + val &=3D ~ID_AA64PFR1_EL1_MTE; + val &=3D ~ID_AA64PFR1_EL1_MTE_frac; + } + break; + case SYS_ID_AA64PFR2_EL1: + if (!kvm_has_mte(vcpu->kvm)) + val &=3D ~(ID_AA64PFR2_EL1_MTEFAR | + ID_AA64PFR2_EL1_MTESTOREONLY); + break; + case SYS_ID_AA64ISAR1_EL1: + if (!vcpu_has_ptrauth(vcpu)) + val &=3D ~(ID_AA64ISAR1_EL1_APA | + ID_AA64ISAR1_EL1_API | + ID_AA64ISAR1_EL1_GPA | + ID_AA64ISAR1_EL1_GPI); + break; + case SYS_ID_AA64ISAR2_EL1: + if (!vcpu_has_ptrauth(vcpu)) + val &=3D ~(ID_AA64ISAR2_EL1_APA3 | + ID_AA64ISAR2_EL1_GPA3); + break; + } + + if (vcpu_has_nv(vcpu)) + val =3D limit_nv_id_reg(vcpu->kvm, id, val); + + return val; +} + +/* Read a sanitised cpufeature ID register by sys_reg_desc */ +static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + u32 id =3D reg_to_encoding(r); + u64 val; + + if (sysreg_visible_as_raz(vcpu, r)) + return 0; + + val =3D kvm_sanitised_host_ftr_reg(id); + val =3D kvm_max_possible_guest_ftr_reg(id, val); + val =3D kvm_sanitise_vcpu_ftr_reg(vcpu, id, val); + + return val; +} + +u64 kvm_read_sanitised_id_reg(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + return __kvm_read_sanitised_id_reg(vcpu, r); +} + +/* cpufeature ID register access trap handlers */ +bool access_id_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (p->is_write) + return write_to_read_only(vcpu, p, r); + + p->regval =3D read_id_reg(vcpu, r); + + return true; +} + +unsigned int id_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + u32 id =3D reg_to_encoding(r); + + switch (id) { + case SYS_ID_AA64ZFR0_EL1: + if (!vcpu_has_sve(vcpu)) + return REG_RAZ; + break; + } + + return 0; +} + +unsigned int aa32_id_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + /* + * AArch32 ID registers are UNKNOWN if AArch32 isn't implemented at any + * EL. Promote to RAZ/WI in order to guarantee consistency between + * systems. + */ + if (!kvm_supports_32bit_el0()) + return REG_RAZ | REG_USER_WI; + + return id_visibility(vcpu, r); +} + +/* + * cpufeature ID register user accessors + * + * For now, these registers are immutable for userspace, so no values + * are stored, and for set_id_reg() we don't allow the effective value + * to be changed. + */ +int get_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, u64 *= val) +{ + /* + * Avoid locking if the VM has already started, as the ID registers are + * guaranteed to be invariant at that point. + */ + if (kvm_vm_has_ran_once(vcpu->kvm)) { + *val =3D read_id_reg(vcpu, rd); + return 0; + } + + mutex_lock(&vcpu->kvm->arch.config_lock); + *val =3D read_id_reg(vcpu, rd); + mutex_unlock(&vcpu->kvm->arch.config_lock); + + return 0; +} + +int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, u64 v= al) +{ + u32 id =3D reg_to_encoding(rd); + int ret; + + mutex_lock(&vcpu->kvm->arch.config_lock); + + /* + * Once the VM has started the ID registers are immutable. Reject any + * write that does not match the final register value. + */ + if (kvm_vm_has_ran_once(vcpu->kvm)) { + if (val !=3D read_id_reg(vcpu, rd)) + ret =3D -EBUSY; + else + ret =3D 0; + + mutex_unlock(&vcpu->kvm->arch.config_lock); + return ret; + } + + ret =3D arm64_check_features(vcpu, rd, val); + if (!ret) + kvm_set_vm_id_reg(vcpu->kvm, id, val); + + mutex_unlock(&vcpu->kvm->arch.config_lock); + + /* + * arm64_check_features() returns -E2BIG to indicate the register's + * feature set is a superset of the maximally-allowed register value. + * While it would be nice to precisely describe this to userspace, the + * existing UAPI for KVM_SET_ONE_REG has it that invalid register + * writes return -EINVAL. + */ + if (ret =3D=3D -E2BIG) + ret =3D -EINVAL; + return ret; +} + +int set_imp_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, u6= 4 val) +{ + struct kvm *kvm =3D vcpu->kvm; + u64 expected; + + guard(mutex)(&kvm->arch.config_lock); + + expected =3D read_id_reg(vcpu, r); + if (expected =3D=3D val) + return 0; + + if (!test_bit(KVM_ARCH_FLAG_WRITABLE_IMP_ID_REGS, &kvm->arch.flags)) + return -EINVAL; + + /* + * Once the VM has started the ID registers are immutable. Reject the + * write if userspace tries to change it. + */ + if (kvm_vm_has_ran_once(kvm)) + return -EBUSY; + + /* + * Any value is allowed for the implementation ID registers so long as + * it is within the writable mask. + */ + if ((val & r->val) !=3D val) + return -EINVAL; + + kvm_set_vm_id_reg(kvm, reg_to_encoding(r), val); + return 0; +} + +void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val) +{ + u64 *p =3D __vm_id_reg(&kvm->arch.id_regs, reg); + + lockdep_assert_held(&kvm->arch.config_lock); + + if (KVM_BUG_ON(kvm_vm_has_ran_once(kvm) || !p, kvm)) + return; + + *p =3D val; +} + +int set_ctr_el0(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, + u64 user_val) +{ + u8 user_L1Ip =3D SYS_FIELD_GET(CTR_EL0, L1Ip, user_val); + + /* + * Both AIVIVT (0b01) and VPIPT (0b00) are documented as reserved. + * Hence only allow to set VIPT(0b10) or PIPT(0b11) for L1Ip based + * on what hardware reports. + * + * Using a VIPT software model on PIPT will lead to over invalidation, + * but still correct. Hence, we can allow downgrading PIPT to VIPT, + * but not the other way around. This is handled via arm64_ftr_safe_value= () + * as CTR_EL0 ftr_bits has L1Ip field with type FTR_EXACT and safe value + * set as VIPT. + */ + switch (user_L1Ip) { + case CTR_EL0_L1Ip_RESERVED_VPIPT: + case CTR_EL0_L1Ip_RESERVED_AIVIVT: + return -EINVAL; + case CTR_EL0_L1Ip_VIPT: + case CTR_EL0_L1Ip_PIPT: + return set_id_reg(vcpu, rd, user_val); + default: + return -ENOENT; + } +} + +bool trap_oslar_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (!p->is_write) + return read_from_write_only(vcpu, p, r); + + kvm_debug_handle_oslar(vcpu, p->regval); + return true; +} + +bool trap_oslsr_el1(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (p->is_write) + return write_to_read_only(vcpu, p, r); + + p->regval =3D __vcpu_sys_reg(vcpu, r->reg); + return true; +} + +int set_oslsr_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, u6= 4 val) +{ + u64 oslk; + + /* + * The only modifiable bit is the OSLK bit. Refuse the write if + * userspace attempts to change any other bit in the register. + */ + if ((val ^ rd->val) & ~OSLSR_EL1_OSLK) + return -EINVAL; + + oslk =3D SYS_FIELD_GET(OSLSR_EL1, OSLK, val); + __vcpu_assign_sys_reg(vcpu, OSLAR_EL1, SYS_FIELD_PREP(OSLAR_EL1, OSLK, os= lk)); + return 0; +} + +bool trap_raz_wi(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (p->is_write) + return ignore_write(vcpu, p); + else + return read_zero(vcpu, p); +} + +u64 reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) +{ + u64 mpidr; + + /* + * Map the vcpu_id into the first three affinity level fields of + * the MPIDR. We limit the number of VCPUs in level 0 due to a + * limitation to 16 CPUs in that level in the ICC_SGIxR registers + * of the GICv3 to be able to address each CPU directly when + * sending IPIs. + */ + mpidr =3D (vcpu->vcpu_id & 0x0f) << MPIDR_LEVEL_SHIFT(0); + mpidr |=3D ((vcpu->vcpu_id >> 4) & 0xff) << MPIDR_LEVEL_SHIFT(1); + mpidr |=3D ((vcpu->vcpu_id >> 12) & 0xff) << MPIDR_LEVEL_SHIFT(2); + mpidr |=3D (1ULL << 31); + vcpu_write_sys_reg(vcpu, mpidr, MPIDR_EL1); + + return mpidr; +} + +/* + * Allow userspace to de-feature a stage-2 translation granule but prevent= it + * from claiming the impossible. + */ +#define tgran2_val_allowed(tg, safe, user) \ +({ \ + u8 __s =3D SYS_FIELD_GET(ID_AA64MMFR0_EL1, tg, safe); \ + u8 __u =3D SYS_FIELD_GET(ID_AA64MMFR0_EL1, tg, user); \ + \ + __s =3D=3D __u || __u =3D=3D ID_AA64MMFR0_EL1_##tg##_NI; \ +}) + +int set_id_aa64mmfr0_el1(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, + u64 user_val) +{ + u64 sanitized_val =3D kvm_read_sanitised_id_reg(vcpu, rd); + + if (!vcpu_has_nv(vcpu)) + return set_id_reg(vcpu, rd, user_val); + + if (!tgran2_val_allowed(TGRAN4_2, sanitized_val, user_val) || + !tgran2_val_allowed(TGRAN16_2, sanitized_val, user_val) || + !tgran2_val_allowed(TGRAN64_2, sanitized_val, user_val)) + return -EINVAL; + + return set_id_reg(vcpu, rd, user_val); +} + +bool access_rw(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (p->is_write) + vcpu_write_sys_reg(vcpu, p->regval, r->reg); + else + p->regval =3D vcpu_read_sys_reg(vcpu, r->reg); + + return true; +} + +bool access_clidr(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (p->is_write) + return write_to_read_only(vcpu, p, r); + + p->regval =3D __vcpu_sys_reg(vcpu, r->reg); + return true; +} + +/* + * Fabricate a CLIDR_EL1 value instead of using the real value, which can = vary + * by the physical CPU which the vcpu currently resides in. + */ +u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) +{ + u64 ctr_el0 =3D kvm_sanitised_host_ftr_reg(SYS_CTR_EL0); + u64 clidr; + u8 loc; + + if ((ctr_el0 & CTR_EL0_IDC)) { + /* + * Data cache clean to the PoU is not required so LoUU and LoUIS + * will not be set and a unified cache, which will be marked as + * LoC, will be added. + * + * If not DIC, let the unified cache L2 so that an instruction + * cache can be added as L1 later. + */ + loc =3D (ctr_el0 & CTR_EL0_DIC) ? 1 : 2; + clidr =3D CACHE_TYPE_UNIFIED << CLIDR_CTYPE_SHIFT(loc); + } else { + /* + * Data cache clean to the PoU is required so let L1 have a data + * cache and mark it as LoUU and LoUIS. As L1 has a data cache, + * it can be marked as LoC too. + */ + loc =3D 1; + clidr =3D 1 << CLIDR_LOUU_SHIFT; + clidr |=3D 1 << CLIDR_LOUIS_SHIFT; + clidr |=3D CACHE_TYPE_DATA << CLIDR_CTYPE_SHIFT(1); + } + + /* + * Instruction cache invalidation to the PoU is required so let L1 have + * an instruction cache. If L1 already has a data cache, it will be + * CACHE_TYPE_SEPARATE. + */ + if (!(ctr_el0 & CTR_EL0_DIC)) + clidr |=3D CACHE_TYPE_INST << CLIDR_CTYPE_SHIFT(1); + + clidr |=3D loc << CLIDR_LOC_SHIFT; + + /* + * Add tag cache unified to data cache. Allocation tags and data are + * unified in a cache line so that it looks valid even if there is only + * one cache line. + */ + if (kvm_has_mte(vcpu->kvm)) + clidr |=3D 2ULL << CLIDR_TTYPE_SHIFT(loc); + + __vcpu_assign_sys_reg(vcpu, r->reg, clidr); + + return __vcpu_sys_reg(vcpu, r->reg); +} + +int set_clidr(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, + u64 val) +{ + u64 ctr_el0 =3D kvm_sanitised_host_ftr_reg(SYS_CTR_EL0); + u64 idc =3D !CLIDR_LOC(val) || (!CLIDR_LOUIS(val) && !CLIDR_LOUU(val)); + + if ((val & CLIDR_EL1_RES0) || (!(ctr_el0 & CTR_EL0_IDC) && idc)) + return -EINVAL; + + __vcpu_assign_sys_reg(vcpu, rd->reg, val); + + return 0; +} + +bool access_csselr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + int reg =3D r->reg; + + if (p->is_write) + vcpu_write_sys_reg(vcpu, p->regval, reg); + else + p->regval =3D vcpu_read_sys_reg(vcpu, reg); + return true; +} + +/* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */ +#define CSSELR_MAX 14 + +/* + * Returns the minimum line size for the selected cache, expressed as + * Log2(bytes). + */ +static u8 get_min_cache_line_size(bool icache) +{ + u64 ctr =3D kvm_sanitised_host_ftr_reg(SYS_CTR_EL0); + u8 field; + + if (icache) + field =3D SYS_FIELD_GET(CTR_EL0, IminLine, ctr); + else + field =3D SYS_FIELD_GET(CTR_EL0, DminLine, ctr); + + /* + * Cache line size is represented as Log2(words) in CTR_EL0. + * Log2(bytes) can be derived with the following: + * + * Log2(words) + 2 =3D Log2(bytes / 4) + 2 + * =3D Log2(bytes) - 2 + 2 + * =3D Log2(bytes) + */ + return field + 2; +} + +/* Which cache CCSIDR represents depends on CSSELR value. */ +u32 get_ccsidr(struct kvm_vcpu *vcpu, u32 csselr) +{ + u8 line_size; + + if (vcpu->arch.ccsidr) + return vcpu->arch.ccsidr[csselr]; + + line_size =3D get_min_cache_line_size(csselr & CSSELR_EL1_InD); + + /* + * Fabricate a CCSIDR value as the overriding value does not exist. + * The real CCSIDR value will not be used as it can vary by the + * physical CPU which the vcpu currently resides in. + * + * The line size is determined with get_min_cache_line_size(), which + * should be valid for all CPUs even if they have different cache + * configuration. + * + * The associativity bits are cleared, meaning the geometry of all data + * and unified caches (which are guaranteed to be PIPT and thus + * non-aliasing) are 1 set and 1 way. + * Guests should not be doing cache operations by set/way at all, and + * for this reason, we trap them and attempt to infer the intent, so + * that we can flush the entire guest's address space at the appropriate + * time. The exposed geometry minimizes the number of the traps. + * [If guests should attempt to infer aliasing properties from the + * geometry (which is not permitted by the architecture), they would + * only do so for virtually indexed caches.] + * + * We don't check if the cache level exists as it is allowed to return + * an UNKNOWN value if not. + */ + return SYS_FIELD_PREP(CCSIDR_EL1, LineSize, line_size - 4); +} + +int set_ccsidr(struct kvm_vcpu *vcpu, u32 csselr, u32 val) +{ + u8 line_size =3D FIELD_GET(CCSIDR_EL1_LineSize, val) + 4; + u32 *ccsidr =3D vcpu->arch.ccsidr; + u32 i; + + if ((val & CCSIDR_EL1_RES0) || + line_size < get_min_cache_line_size(csselr & CSSELR_EL1_InD)) + return -EINVAL; + + if (!ccsidr) { + if (val =3D=3D get_ccsidr(vcpu, csselr)) + return 0; + + ccsidr =3D kmalloc_array(CSSELR_MAX, sizeof(u32), GFP_KERNEL_ACCOUNT); + if (!ccsidr) + return -ENOMEM; + + for (i =3D 0; i < CSSELR_MAX; i++) + ccsidr[i] =3D get_ccsidr(vcpu, i); + + vcpu->arch.ccsidr =3D ccsidr; + } + + ccsidr[csselr] =3D val; + + return 0; +} + +bool access_ccsidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + u32 csselr; + + if (p->is_write) + return write_to_read_only(vcpu, p, r); + + csselr =3D vcpu_read_sys_reg(vcpu, CSSELR_EL1); + csselr &=3D CSSELR_EL1_Level | CSSELR_EL1_InD; + if (csselr < CSSELR_MAX) + p->regval =3D get_ccsidr(vcpu, csselr); + + return true; +} + +void perform_access(struct kvm_vcpu *vcpu, + struct sys_reg_params *params, + const struct sys_reg_desc *r) +{ + trace_kvm_sys_access(*vcpu_pc(vcpu), params, r); + + /* Check for regs disabled by runtime config */ + if (sysreg_hidden(vcpu, r)) { + kvm_inject_undefined(vcpu); + return; + } + + /* + * Not having an accessor means that we have configured a trap + * that we don't know how to handle. This certainly qualifies + * as a gross bug that should be fixed right away. + */ + if (!r->access) { + bad_trap(vcpu, params, r, "register access"); + return; + } + + /* Skip instruction if instructed so */ + if (likely(r->access(vcpu, params, r))) + kvm_incr_pc(vcpu); +} + +void reset_vm_ftr_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc = *reg) +{ + u32 id =3D reg_to_encoding(reg); + struct kvm *kvm =3D vcpu->kvm; + + if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags)) + return; + + kvm_set_vm_id_reg(kvm, id, reg->reset(vcpu, reg)); +} + +void reset_vcpu_ftr_id_reg(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *reg) +{ + if (kvm_vcpu_initialized(vcpu)) + return; + + reg->reset(vcpu, reg); +} + +static int demux_c15_get(struct kvm_vcpu *vcpu, u64 id, void __user *uaddr) +{ + u32 val; + u32 __user *uval =3D uaddr; + + /* Fail if we have unknown bits set. */ + if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK + | ((1 << KVM_REG_ARM_COPROC_SHIFT)-1))) + return -ENOENT; + + switch (id & KVM_REG_ARM_DEMUX_ID_MASK) { + case KVM_REG_ARM_DEMUX_ID_CCSIDR: + if (KVM_REG_SIZE(id) !=3D 4) + return -ENOENT; + val =3D (id & KVM_REG_ARM_DEMUX_VAL_MASK) + >> KVM_REG_ARM_DEMUX_VAL_SHIFT; + if (val >=3D CSSELR_MAX) + return -ENOENT; + + return put_user(get_ccsidr(vcpu, val), uval); + default: + return -ENOENT; + } +} + +int __kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_= reg *reg, + size_t n_descs, + const struct sys_reg_desc sys_reg_descs[n_descs]) +{ + void __user *uaddr =3D (void __user *)(unsigned long)reg->addr; + + if ((reg->id & KVM_REG_ARM_COPROC_MASK) =3D=3D KVM_REG_ARM_DEMUX) + return demux_c15_get(vcpu, reg->id, uaddr); + + return kvm_sys_reg_get_user(vcpu, reg, sys_reg_descs, n_descs); +} + +static int demux_c15_set(struct kvm_vcpu *vcpu, u64 id, void __user *uaddr) +{ + u32 val, newval; + u32 __user *uval =3D uaddr; + + /* Fail if we have unknown bits set. */ + if (id & ~(KVM_REG_ARCH_MASK|KVM_REG_SIZE_MASK|KVM_REG_ARM_COPROC_MASK + | ((1 << KVM_REG_ARM_COPROC_SHIFT)-1))) + return -ENOENT; + + switch (id & KVM_REG_ARM_DEMUX_ID_MASK) { + case KVM_REG_ARM_DEMUX_ID_CCSIDR: + if (KVM_REG_SIZE(id) !=3D 4) + return -ENOENT; + val =3D (id & KVM_REG_ARM_DEMUX_VAL_MASK) + >> KVM_REG_ARM_DEMUX_VAL_SHIFT; + if (val >=3D CSSELR_MAX) + return -ENOENT; + + if (get_user(newval, uval)) + return -EFAULT; + + return set_ccsidr(vcpu, val, newval); + default: + return -ENOENT; + } +} + + +int __kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_= reg *reg, + size_t n_descs, + const struct sys_reg_desc sys_reg_descs[n_descs]) + +{ + void __user *uaddr =3D (void __user *)(unsigned long)reg->addr; + + if ((reg->id & KVM_REG_ARM_COPROC_MASK) =3D=3D KVM_REG_ARM_DEMUX) + return demux_c15_set(vcpu, reg->id, uaddr); + + return kvm_sys_reg_set_user(vcpu, reg, sys_reg_descs, n_descs); +} + +static unsigned int num_demux_regs(void) +{ + return CSSELR_MAX; +} + +static int write_demux_regids(u64 __user *uindices) +{ + u64 val =3D KVM_REG_ARM64 | KVM_REG_SIZE_U32 | KVM_REG_ARM_DEMUX; + unsigned int i; + + val |=3D KVM_REG_ARM_DEMUX_ID_CCSIDR; + for (i =3D 0; i < CSSELR_MAX; i++) { + if (put_user(val | i, uindices)) + return -EFAULT; + uindices++; + } + return 0; +} + +static u64 sys_reg_to_index(const struct sys_reg_desc *reg) +{ + return (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | + KVM_REG_ARM64_SYSREG | + (reg->Op0 << KVM_REG_ARM64_SYSREG_OP0_SHIFT) | + (reg->Op1 << KVM_REG_ARM64_SYSREG_OP1_SHIFT) | + (reg->CRn << KVM_REG_ARM64_SYSREG_CRN_SHIFT) | + (reg->CRm << KVM_REG_ARM64_SYSREG_CRM_SHIFT) | + (reg->Op2 << KVM_REG_ARM64_SYSREG_OP2_SHIFT)); +} + +static bool copy_reg_to_user(const struct sys_reg_desc *reg, u64 __user **= uind) +{ + u64 idx; + + if (!*uind) + return true; + + switch (reg_to_encoding(reg)) { + case SYS_CNTV_CVAL_EL0: + idx =3D KVM_REG_ARM_TIMER_CVAL; + break; + case SYS_CNTVCT_EL0: + idx =3D KVM_REG_ARM_TIMER_CNT; + break; + default: + idx =3D sys_reg_to_index(reg); + } + + if (put_user(idx, *uind)) + return false; + + (*uind)++; + return true; +} + +static int walk_one_sys_reg(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, + u64 __user **uind, + unsigned int *total) +{ + /* + * Ignore registers we trap but don't save, + * and for which no custom user accessor is provided. + */ + if (!(rd->reg || rd->get_user)) + return 0; + + if (sysreg_hidden(vcpu, rd)) + return 0; + + if (!copy_reg_to_user(rd, uind)) + return -EFAULT; + + (*total)++; + return 0; +} + +/* Assumed ordered tables, see kvm_sys_reg_table_init. */ +static int walk_sys_regs(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *start, + const struct sys_reg_desc *end2, + u64 __user *uind) +{ + const struct sys_reg_desc *i2; + unsigned int total =3D 0; + int err; + + i2 =3D start; + + while (i2 !=3D end2) { + err =3D walk_one_sys_reg(vcpu, i2++, &uind, &total); + if (err) + return err; + } + return total; +} + +unsigned long __kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu, size_t n_= descs, + const struct sys_reg_desc sys_reg_descs[n_descs]) +{ + return num_demux_regs() + + walk_sys_regs(vcpu, sys_reg_descs, sys_reg_descs + n_descs, (u64 __use= r *)NULL); +} + +int __kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uind= ices, + size_t n_descs, + const struct sys_reg_desc sys_reg_descs[n_descs]) +{ + int err; + + err =3D walk_sys_regs(vcpu, sys_reg_descs, sys_reg_descs + n_descs, uindi= ces); + if (err < 0) + return err; + uindices +=3D err; + + return write_demux_regids(uindices); +} + +bool check_sysreg_table(const struct sys_reg_desc *table, unsigned int n, + bool reset_check) +{ + unsigned int i; + + for (i =3D 0; i < n; i++) { + if (reset_check && table[i].reg && !table[i].reset) { + kvm_err("sys_reg table %pS entry %d (%s) lacks reset\n", + &table[i], i, table[i].name); + return false; + } + + if (i && cmp_sys_reg(&table[i-1], &table[i]) >=3D 0) { + kvm_err("sys_reg table %pS entry %d (%s -> %s) out of order\n", + &table[i], i, table[i - 1].name, table[i].name); + return false; + } + } + + return true; +} + +/*************************************************************************= ***** + * Userspace API + *************************************************************************= ****/ + +static bool index_to_params(u64 id, struct sys_reg_params *params) +{ + switch (id & KVM_REG_SIZE_MASK) { + case KVM_REG_SIZE_U64: + /* Any unused index bits means it's not valid. */ + if (id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK + | KVM_REG_ARM_COPROC_MASK + | KVM_REG_ARM64_SYSREG_OP0_MASK + | KVM_REG_ARM64_SYSREG_OP1_MASK + | KVM_REG_ARM64_SYSREG_CRN_MASK + | KVM_REG_ARM64_SYSREG_CRM_MASK + | KVM_REG_ARM64_SYSREG_OP2_MASK)) + return false; + params->Op0 =3D ((id & KVM_REG_ARM64_SYSREG_OP0_MASK) + >> KVM_REG_ARM64_SYSREG_OP0_SHIFT); + params->Op1 =3D ((id & KVM_REG_ARM64_SYSREG_OP1_MASK) + >> KVM_REG_ARM64_SYSREG_OP1_SHIFT); + params->CRn =3D ((id & KVM_REG_ARM64_SYSREG_CRN_MASK) + >> KVM_REG_ARM64_SYSREG_CRN_SHIFT); + params->CRm =3D ((id & KVM_REG_ARM64_SYSREG_CRM_MASK) + >> KVM_REG_ARM64_SYSREG_CRM_SHIFT); + params->Op2 =3D ((id & KVM_REG_ARM64_SYSREG_OP2_MASK) + >> KVM_REG_ARM64_SYSREG_OP2_SHIFT); + return true; + default: + return false; + } +} + +const struct sys_reg_desc *get_reg_by_id(u64 id, + const struct sys_reg_desc table[], + unsigned int num) +{ + struct sys_reg_params params; + + if (!index_to_params(id, ¶ms)) + return NULL; + + return find_reg(¶ms, table, num); +} + +/* Decode an index value, and find the sys_reg_desc entry. */ +static const struct sys_reg_desc * +id_to_sys_reg_desc(struct kvm_vcpu *vcpu, u64 id, + const struct sys_reg_desc table[], unsigned int num) + +{ + const struct sys_reg_desc *r; + + /* We only do sys_reg for now. */ + if ((id & KVM_REG_ARM_COPROC_MASK) !=3D KVM_REG_ARM64_SYSREG) + return NULL; + + r =3D get_reg_by_id(id, table, num); + + /* Not saved in the sys_reg array and not otherwise accessible? */ + if (r && (!(r->reg || r->get_user) || sysreg_hidden(vcpu, r))) + r =3D NULL; + + return r; +} + +static u64 kvm_one_reg_to_id(const struct kvm_one_reg *reg) +{ + switch (reg->id) { + case KVM_REG_ARM_TIMER_CVAL: + return TO_ARM64_SYS_REG(CNTV_CVAL_EL0); + case KVM_REG_ARM_TIMER_CNT: + return TO_ARM64_SYS_REG(CNTVCT_EL0); + default: + return reg->id; + } +} + +int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *= reg, + const struct sys_reg_desc table[], unsigned int num) +{ + u64 __user *uaddr =3D (u64 __user *)(unsigned long)reg->addr; + const struct sys_reg_desc *r; + u64 id =3D kvm_one_reg_to_id(reg); + u64 val; + int ret; + + r =3D id_to_sys_reg_desc(vcpu, id, table, num); + if (!r || sysreg_hidden(vcpu, r)) + return -ENOENT; + + if (r->get_user) { + ret =3D (r->get_user)(vcpu, r, &val); + } else { + val =3D __vcpu_sys_reg(vcpu, r->reg); + ret =3D 0; + } + + if (!ret) + ret =3D put_user(val, uaddr); + + return ret; +} + +int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *= reg, + const struct sys_reg_desc table[], unsigned int num) +{ + u64 __user *uaddr =3D (u64 __user *)(unsigned long)reg->addr; + const struct sys_reg_desc *r; + u64 id =3D kvm_one_reg_to_id(reg); + u64 val; + int ret; + + if (get_user(val, uaddr)) + return -EFAULT; + + r =3D id_to_sys_reg_desc(vcpu, id, table, num); + if (!r || sysreg_hidden(vcpu, r)) + return -ENOENT; + + if (sysreg_user_write_ignore(vcpu, r)) + return 0; + + if (r->set_user) { + ret =3D (r->set_user)(vcpu, r, val); + } else { + __vcpu_assign_sys_reg(vcpu, r->reg, val); + ret =3D 0; + } + + return ret; +} diff --git a/virt/kvm/arm64/trace.h b/virt/kvm/arm64/trace.h index 0814000b7749..d791ee4ea2bf 100644 --- a/virt/kvm/arm64/trace.h +++ b/virt/kvm/arm64/trace.h @@ -36,6 +36,40 @@ TRACE_EVENT(kvm_mmio_nisv, __entry->far, __entry->vcpu_pc) ); =20 +TRACE_EVENT(kvm_sys_access, + TP_PROTO(unsigned long vcpu_pc, struct sys_reg_params *params, const stru= ct sys_reg_desc *reg), + TP_ARGS(vcpu_pc, params, reg), + + TP_STRUCT__entry( + __field(unsigned long, vcpu_pc) + __field(bool, is_write) + __field(const char *, name) + __field(u8, Op0) + __field(u8, Op1) + __field(u8, CRn) + __field(u8, CRm) + __field(u8, Op2) + ), + + TP_fast_assign( + __entry->vcpu_pc =3D vcpu_pc; + __entry->is_write =3D params->is_write; + __entry->name =3D reg->name; + __entry->Op0 =3D reg->Op0; + __entry->Op0 =3D reg->Op0; + __entry->Op1 =3D reg->Op1; + __entry->CRn =3D reg->CRn; + __entry->CRm =3D reg->CRm; + __entry->Op2 =3D reg->Op2; + ), + + TP_printk("PC: %lx %s (%d,%d,%d,%d,%d) %s", + __entry->vcpu_pc, __entry->name ?: "UNKN", + __entry->Op0, __entry->Op1, __entry->CRn, + __entry->CRm, __entry->Op2, + str_write_read(__entry->is_write)) +); + #endif /* __KVM_ARM64_TRACE_H__ */ =20 /* This part must be outside protection */ --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 6A22C3F1AD3; Fri, 29 May 2026 16:01:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070498; cv=none; b=rxYTctvofrP173enTyWvP+xi+civrU7dTrAyJ+9yR9Owb5/TG6c1uF6kIznP4ZlLgzUGgY84BwKesNrnAI0gwlHR8M0/WQetNCsWAmNlu/cfRu4tjOCjWf2bFpe9dydMOzdvWQLHQPybdO9Y8ljK/VfyLyTCnGfeympwZ60/dSk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070498; c=relaxed/simple; bh=KlZQ4MSJqjnIvULwCaGerlpkjtfnusCPIghRGzijdGI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SaiPRNyFqM+Xa5yA1osK8X8MI6TLHvJ5fVfJVHeFt9aFWHJRn+RiMn+zeIs+ccgWiv93HvVkS9hVzsasmbifHuuUDgnUFolh7alOuiVC+zgY9zht5IYtkBUMSZJtNHfi3eYeeMsVmyEWjVt3vxeCdPwGdsbG7bFNhEIOCT4rN9g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=KjBCfBcD; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="KjBCfBcD" Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFn8hn1467755; Fri, 29 May 2026 15:56:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=+ZUv8cR1VqrVbTl3m Hf0T1bCgGPWY+ZTuBptjqVPGvU=; b=KjBCfBcDQDSaiBO0bgNBLT02rP+uhMES5 PE6oUpDzmJbapm1dT7iRxJxinaU6UbcawKYy3pSH4oWeCvRVrkHJkb5hbr8LQgbL fRRhM/t3MVRya13fFr7lBEBNuJkW2bhXGG9TYXCJ9iAoOrogpZz40aQkaN4OytJh 4q5uPmP/ldgr6fN56+quEzfANkmAmg0mMk87EwzVeGilYvw2GnUrx9hgNjEuiRS9 n+w6Ds8ztAlKLtcMk0dK/QN2wWMhe++ZLRa6iWVxlSPjC6YpAp09oSs7f27c5DGj Nk0pTsqIpyXWvRlxyWSfFqSzL7BCIJgjNV+gsFxSTN0kUc7FX87EA== Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee886mgkk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:20 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs56d016943; Fri, 29 May 2026 15:56:19 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgjrw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:19 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFuAMr49414438 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:10 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id ACD8320040; Fri, 29 May 2026 15:56:10 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 60B8E2004B; Fri, 29 May 2026 15:56:10 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:10 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 22/26] KVM: arm64: Refactor core reg handling Date: Fri, 29 May 2026 17:55:55 +0200 Message-ID: <20260529155601.2927240-23-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 31vsPhmURQS40ov7PA3eSqLGauBwurqn X-Authority-Analysis: v=2.4 cv=Z8Dc2nRA c=1 sm=1 tr=0 ts=6a19b724 cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=zUXWKsC1zW_jSfsg-zQA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfXy/4faeW9qaEW jHrAgLdULeegCw7f465TqGT2M//Q02j4eP+f1UPT34tgcBZyAGXhkJA35zCnXUQQ075gAW5WvKr bdoEyvU3qt6QALFYzfu6Ou5pOduHPVHsKuGkC6DyQdSfAhqD8VU57Hc4BPVfxrQRwId9ujp57Z0 1T+Od+20RwqJhNP25TcqC4kq2QYQExp+bZ9yd8HxkOAsabIw0X3DdljGY+QiLr6KYCVrdV6FNGT PR5xCeNPCE0L4gVVJcW2SgfhxaKNVVTOSfDpzKsW6iDjYTpRu3hkFTv88PIDWIeAWtwrKxFhw87 IMd/aM7JMcYSnzZd5vmHj0Xe0OONeSv/hujVHoU6daTqI+wZCLwg1GDBe1JZj5m+i2/Y2YAZpcA 5WfN7tgJyFxSxvs/rFTfyLTXqHuki8TVGpqgFvixSUzLiz54gMp7C8qnTNXHlMNH0QAJvGroBjs jHp/i8NDAU+rUa70kpg== X-Proofpoint-ORIG-GUID: 31vsPhmURQS40ov7PA3eSqLGauBwurqn X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 bulkscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 phishscore=0 suspectscore=0 adultscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Refactor sysreg core handling. Before this all core regs are identified with a memory address and reading/writing happened through accessing the data at this address. However, for arm64 on s390 not all core registers have a dedicated memory address. Refactor such that the address function does not return an address but actually does the read/write request. ELR_EL1 and SPSR_EL1 now use vcpu_read_sys_reg/vcpu_write_sys_reg accessor functions, allowing s390 to provide custom implementations. Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- virt/kvm/arm64/guest.c | 100 ++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 36 deletions(-) diff --git a/virt/kvm/arm64/guest.c b/virt/kvm/arm64/guest.c index 35ba03033b4c..11509382d594 100644 --- a/virt/kvm/arm64/guest.c +++ b/virt/kvm/arm64/guest.c @@ -65,69 +65,96 @@ static int core_reg_size_from_offset(const struct kvm_v= cpu *vcpu, u64 off) return size; } =20 -static void *core_reg_addr(struct kvm_vcpu *vcpu, const struct kvm_one_reg= *reg) +static int core_reg_rw(struct kvm_vcpu *vcpu, u64 reg_id, void *valp, bool= read) { - u64 off =3D core_reg_offset_from_id(reg->id); + u64 off =3D core_reg_offset_from_id(reg_id); int size =3D core_reg_size_from_offset(vcpu, off); + void *addr; =20 - if (size < 0) - return NULL; + if (size < 0 || (KVM_REG_SIZE(reg_id) !=3D size)) + return -EINVAL; =20 - if (KVM_REG_SIZE(reg->id) !=3D size) - return NULL; + switch (off) { + case KVM_REG_ARM_CORE_REG(elr_el1): + if (read) + *(u64 *)valp =3D vcpu_read_sys_reg(vcpu, ELR_EL1); + else + vcpu_write_sys_reg(vcpu, *(u64 *)valp, ELR_EL1); + return 0; + + case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_EL1]): + if (read) + *(u64 *)valp =3D vcpu_read_sys_reg(vcpu, SPSR_EL1); + else + vcpu_write_sys_reg(vcpu, *(u64 *)valp, SPSR_EL1); + return 0; + } =20 switch (off) { case KVM_REG_ARM_CORE_REG(regs.regs[0]) ... KVM_REG_ARM_CORE_REG(regs.regs[30]): off -=3D KVM_REG_ARM_CORE_REG(regs.regs[0]); off /=3D 2; - return &vcpu_gp_regs(vcpu)[off]; + addr =3D &vcpu_gp_regs(vcpu)[off]; + break; =20 case KVM_REG_ARM_CORE_REG(regs.sp): - return vcpu_sp_el0(vcpu); + addr =3D vcpu_sp_el0(vcpu); + break; =20 case KVM_REG_ARM_CORE_REG(regs.pc): - return vcpu_pc(vcpu); + addr =3D vcpu_pc(vcpu); + break; =20 case KVM_REG_ARM_CORE_REG(regs.pstate): - return vcpu_cpsr(vcpu); + addr =3D vcpu_cpsr(vcpu); + break; =20 case KVM_REG_ARM_CORE_REG(sp_el1): - return kvm_vcpu_get_sp_el1(vcpu); - - case KVM_REG_ARM_CORE_REG(elr_el1): - return __ctxt_sys_reg(&vcpu->arch.ctxt, ELR_EL1); - - case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_EL1]): - return __ctxt_sys_reg(&vcpu->arch.ctxt, SPSR_EL1); + addr =3D kvm_vcpu_get_sp_el1(vcpu); + break; =20 case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_ABT]): - return &vcpu->arch.ctxt.spsr_abt; + addr =3D &vcpu->arch.ctxt.spsr_abt; + break; =20 case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_UND]): - return &vcpu->arch.ctxt.spsr_und; + addr =3D &vcpu->arch.ctxt.spsr_und; + break; =20 case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_IRQ]): - return &vcpu->arch.ctxt.spsr_irq; + addr =3D &vcpu->arch.ctxt.spsr_irq; + break; =20 case KVM_REG_ARM_CORE_REG(spsr[KVM_SPSR_FIQ]): - return &vcpu->arch.ctxt.spsr_fiq; + addr =3D &vcpu->arch.ctxt.spsr_fiq; + break; =20 case KVM_REG_ARM_CORE_REG(fp_regs.vregs[0]) ... KVM_REG_ARM_CORE_REG(fp_regs.vregs[31]): off -=3D KVM_REG_ARM_CORE_REG(fp_regs.vregs[0]); off /=3D 4; - return kvm_vcpu_get_vreg(vcpu, off); + addr =3D kvm_vcpu_get_vreg(vcpu, off); + break; =20 case KVM_REG_ARM_CORE_REG(fp_regs.fpsr): - return kvm_vcpu_get_fpsr(vcpu); + addr =3D kvm_vcpu_get_fpsr(vcpu); + break; =20 case KVM_REG_ARM_CORE_REG(fp_regs.fpcr): - return kvm_vcpu_get_fpcr(vcpu); + addr =3D kvm_vcpu_get_fpcr(vcpu); + break; =20 default: - return NULL; + return -EINVAL; } + + if (read) + memcpy(valp, addr, size); + else + memcpy(addr, valp, size); + + return 0; } =20 int get_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) @@ -140,7 +167,9 @@ int get_core_reg(struct kvm_vcpu *vcpu, const struct kv= m_one_reg *reg) */ __u32 __user *uaddr =3D (__u32 __user *)(unsigned long)reg->addr; int nr_regs =3D sizeof(struct kvm_regs) / sizeof(__u32); - void *addr; + __uint128_t tmp; + void *valp =3D &tmp; + int ret; u32 off; =20 /* Our ID is an index into the kvm_regs struct. */ @@ -149,11 +178,12 @@ int get_core_reg(struct kvm_vcpu *vcpu, const struct = kvm_one_reg *reg) (off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >=3D nr_regs) return -ENOENT; =20 - addr =3D core_reg_addr(vcpu, reg); - if (!addr) - return -EINVAL; =20 - if (copy_to_user(uaddr, addr, KVM_REG_SIZE(reg->id))) + ret =3D core_reg_rw(vcpu, reg->id, valp, true); + if (ret) + return ret; + + if (copy_to_user(uaddr, valp, KVM_REG_SIZE(reg->id))) return -EFAULT; =20 return 0; @@ -164,7 +194,7 @@ int set_core_reg(struct kvm_vcpu *vcpu, const struct kv= m_one_reg *reg) __u32 __user *uaddr =3D (__u32 __user *)(unsigned long)reg->addr; int nr_regs =3D sizeof(struct kvm_regs) / sizeof(__u32); __uint128_t tmp; - void *valp =3D &tmp, *addr; + void *valp =3D &tmp; u64 off; int err =3D 0; =20 @@ -174,10 +204,6 @@ int set_core_reg(struct kvm_vcpu *vcpu, const struct k= vm_one_reg *reg) (off + (KVM_REG_SIZE(reg->id) / sizeof(__u32))) >=3D nr_regs) return -ENOENT; =20 - addr =3D core_reg_addr(vcpu, reg); - if (!addr) - return -EINVAL; - if (KVM_REG_SIZE(reg->id) > sizeof(tmp)) return -EINVAL; =20 @@ -220,7 +246,9 @@ int set_core_reg(struct kvm_vcpu *vcpu, const struct kv= m_one_reg *reg) } } =20 - memcpy(addr, valp, KVM_REG_SIZE(reg->id)); + err =3D core_reg_rw(vcpu, reg->id, valp, false); + if (err) + goto out; =20 if (*vcpu_cpsr(vcpu) & PSR_MODE32_BIT) { int i, nr_reg; --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 69B333F1ABF; Fri, 29 May 2026 16:01:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070499; cv=none; b=C6FaDSHGTUBjdeYffk0vLAF7dInB/8olVwZIjLURNnWEbqiZsQzwqVxICLWCRuWk0SemhQrLd1M/g0517DSZ+Q9vWLFTsKdWH69+pVRBthi+Oxogui8xDY4Xhd4887RMWhj/JdalLjW1URkBOj8aI1N5TPq1GegSLK33cRrY9sQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070499; c=relaxed/simple; bh=1qFcgdzfKutuRCefdcv49mhnpDe49vhaVF+lPt6wIPg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HkWlTos5o+uy3veESrXuVNcWrPDwj0de6te9FzwwyTH24bn/r9eGnIOQCdrHrOMsc0MRvY5oiySFO/UtE2px/EjlZyPoLuFm9ximqSzZNUC/HJ0Lq76EuABNtHI1Z5PgXbllimwpPReboerMaLNoaTQ6jS1UBW9QCAUASs+1q38= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=E0S/ccSw; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="E0S/ccSw" Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TF8fI81468200; Fri, 29 May 2026 15:56:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=GoxrwaGtqkwb0bP+i 25cRQ407cUzDdO4u3IWehcOzxc=; b=E0S/ccSwzZvm/dz4zxDQm/0DzhLlSaKos mO8V8FwVVRwtXJcgrZR6dgsmU6/Ief2eZkuly0Oad2ftcVP28eTwlu5TLpenucrx i9icXRcSKuHuCg188nX54NAspxSMbNhDQy1Atz24JsFyneaQMOUMAMuIxGNj8eG5 Td9g/m9Nl6s6GbfPTb2mI0N+KOS09+WO/5sGL7fC3Alk9ER2dRIeUBwnpApre152 i+CWb3gKuKS+9o/K8P3rHqmwmHV6QmxKLmbrfGWzEUk8eV+YrTzQOkcYwOW+cpDi N0BY08f8wv276zKL1iUxrfMVBH2ucPbpYsUqeY+8ftBaKt0jwJsSA== Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee886mgk8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:19 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs5Ek016940; Fri, 29 May 2026 15:56:18 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgjrk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:18 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFuBmF20906536 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:11 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 19DE22004B; Fri, 29 May 2026 15:56:11 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B95E420043; Fri, 29 May 2026 15:56:10 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:10 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 23/26] KVM: s390: arm64: Implement feature sanitisation Date: Fri, 29 May 2026 17:55:56 +0200 Message-ID: <20260529155601.2927240-24-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 9SvAY8Wj9EaNZfGFFir4G7VlwKfL-0t3 X-Authority-Analysis: v=2.4 cv=Z8Dc2nRA c=1 sm=1 tr=0 ts=6a19b723 cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=IwyvTvM2pio66WvHkYAA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfXy2KWNEm7t3zb uHtFibnIxTTygD1dhn7bMJXOoUpZ/bLBlXCmJm+UK3zTVjjnY17J5kCD3Di4ls73ntAJ7arai1p bFgpBKXkX8ObbQ8BVBgSCpac6DZGQYxtF9q97EhqYsp9bf9qa6VKrofLkKV2Z2Lx6/U50mbZbn3 Y6BhgKh0+psWAL/Q4fUnlb6wDijqKmSr0N/+StREPnIr/fnoZvJPRc2V8LXDyCX3nkbzwdJTdA/ /X6j8nZKVoAuYXc+aDOjtQspIC9rgkovVDiY/q1SpsupZV7mHJACIbAGxpKvomnpkee/aHuT3db MQAog5FDKSNcxSh3E7UckNFuqCrY1W2OpTO8GWSXoHWhKRdE9CIY19Bplq0bTHizDeBw2mUcuev 42Wy5eCbFbS5WNsjownIFOHn8GrT38pHywtaoEe7nElkPsYahPMmyLFzfa0UQQr6BKag3pO0aRL QXeaqFrkezwO3xf/GQA== X-Proofpoint-ORIG-GUID: 9SvAY8Wj9EaNZfGFFir4G7VlwKfL-0t3 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 bulkscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 phishscore=0 suspectscore=0 adultscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Implement feature detection and sanitization for arm64 KVM guests on s390. Query hardware capabilities using QAAF instruction and sanitize arm64 ID registers. Provide accessor functions for queried capabilities and integrate feature detection into module initialization sequence. Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- arch/s390/include/asm/kvm_feature.h | 111 ++++++++++++ arch/s390/include/asm/kvm_host_arm64.h | 2 +- arch/s390/include/asm/kvm_host_arm64_types.h | 3 +- arch/s390/include/asm/kvm_nested.h | 5 + arch/s390/kvm/arm64/Makefile | 1 + arch/s390/kvm/arm64/arm.c | 6 + arch/s390/kvm/arm64/feature.c | 170 +++++++++++++++++++ 7 files changed, 296 insertions(+), 2 deletions(-) create mode 100644 arch/s390/include/asm/kvm_feature.h create mode 100644 arch/s390/kvm/arm64/feature.c diff --git a/arch/s390/include/asm/kvm_feature.h b/arch/s390/include/asm/kv= m_feature.h new file mode 100644 index 000000000000..dda99c3b09af --- /dev/null +++ b/arch/s390/include/asm/kvm_feature.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __S390_KVM_ARM64_FEATURE_H__ +#define __S390_KVM_ARM64_FEATURE_H__ + +#include +#include +#include + +#include + +int __init kvm_arm_host_detect_features(void); + +/** + * kvm_sae_supported_sd_formats() - Retrieve supported SAE SD formats + * + * Return: Bitmap of supported SAE state description formats. + */ +static inline u32 kvm_sae_supported_sd_formats(void) +{ + extern struct qaaf_qmc_block __qaaf_qmp; + + return __qaaf_qmp.ssdf; +} + +/** + * kvm_sae_supported_sa_formats() - Retrieve supported SAE SA formats + * + * Return: Bitmap of supported SAE save area formats. + */ +static inline u32 kvm_sae_supported_sa_formats(void) +{ + extern struct qaaf_qmc_block __qaaf_qmp; + + return __qaaf_qmp.ssaf; +} + +/** + * kvm_sae_max_vcpus() - Retrieve maximum supported vcpus + * + * Return: Max number of vCPUs supported by the SAE instruction/the machine + * as indicated by QAAF, not necessarily that supported by the host softwa= re. + */ +static inline u16 kvm_sae_max_vcpus(void) +{ + extern struct qaaf_qmc_block __qaaf_qmp; + + /* QAAF QMP reports the max id not the max num */ + return __qaaf_qmp.maxncpu + 1; +} + +/** + * kvm_sae_irptc() - Retrieve supported SAE IRPTCs + * + * Return: Bitmap of supported SAE IRPTCs. + */ +static inline u64 kvm_sae_irptc(void) +{ + extern struct qaaf_qmc_block __qaaf_qmp; + + return __qaaf_qmp.regs[QAAF_IRPTC]; +} + +/**=20 + * kvm_arm_host_sys_reg_by_name() - Get the value of a sys register + * + * @id - ARM (ID-)register name + * + * Get the value of a sys register describing the host configuration. + * The returned value indicates support by the machine (HW/FW) + * after some sanitisation. Equivalent to arm64's read_sanitised_ftr_reg, + * See `enum qaaf_regs` for supported registers. Use the ARM register name + * without the QAAF_REG_ prefix as defined in the qaaf_regs enum. + * + * Example: + * kvm_arm_host_sys_reg_by_name(ID_AA64PFR0_EL1) + * + * Return: Sanitised HW value of the specified register + */ +#define kvm_arm_host_sys_reg_by_name(id) kvm_arm_host_sys_reg_by_id(SYS_##= id) + +/**=20 + * kvm_arm_host_sys_reg_by_id() - Get the value of a sys register + * + * @id - ARM sysreg id + * + * Get the value of a sys register describing the host configuration. + * The returned value indicates support by the machine (HW/FW) + * after some sanitisation. Equivalent to arm64's read_sanitised_ftr_reg, + * See `enum qaaf_regs` for supported registers. + * + * Example: + * kvm_arm_host_sys_reg_by_id(SYS_ID_AA64PFR0_EL1) + * + * Return: Sanitised HW value of the specified register + */ +u64 kvm_arm_host_sys_reg_by_id(u32 id); + +#define kvm_arm_host_has_feat(id, fld, limit) \ + id_has_feat(kvm_arm_host_sys_reg_by_name(id), id, fld, limit) + +#define kvm_has_fpmr(k) \ + (kvm_has_feat((k), ID_AA64PFR2_EL1, FPMR, IMP)) + +#define kvm_has_s1poe(k) \ + (kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP)) + +#define kvm_vcpu_has_pmu(_v) false +#define kvm_has_mte(_k) false + +#endif /* __S390_KVM_ARM64_FEATURE_H__*/ diff --git a/arch/s390/include/asm/kvm_host_arm64.h b/arch/s390/include/asm= /kvm_host_arm64.h index fcbe510cb868..f62daff3303b 100644 --- a/arch/s390/include/asm/kvm_host_arm64.h +++ b/arch/s390/include/asm/kvm_host_arm64.h @@ -6,6 +6,7 @@ =20 #include #include +#include =20 #define vcpu_gp_regs(v) ((v)->arch.sae_block.gpr) =20 @@ -123,7 +124,6 @@ struct kvm_vcpu_stat { #define _vcpu_test_and_clear_flag(v, flagset, ...) \ __vcpu_test_and_clear_flag(&(v)->arch.flagset, __VA_ARGS__) =20 -#define kvm_has_mte(_kvm) false #define vcpu_has_sve(_vcpu) false #define vcpu_has_ptrauth(_vcpu) false =20 diff --git a/arch/s390/include/asm/kvm_host_arm64_types.h b/arch/s390/inclu= de/asm/kvm_host_arm64_types.h index 16f7018a1714..45fa360601fb 100644 --- a/arch/s390/include/asm/kvm_host_arm64_types.h +++ b/arch/s390/include/asm/kvm_host_arm64_types.h @@ -206,7 +206,8 @@ enum { /* 0x3f-0x41 reserved */ QAAF_REG_CNTFRQ_EL0 =3D 0x42, QAAF_REG_CTR_EL0 =3D 0x43, - /* 0x44-0x49 reserved */ + QAAF_REG_AIDR_EL1 =3D 0x44, + /* 0x43-0x49 reserved */ QAAF_IRPTC =3D 0x4a, /* 0x4b reserved */ QAAF_REG_ICH_VTR_EL2 =3D 0x4c, diff --git a/arch/s390/include/asm/kvm_nested.h b/arch/s390/include/asm/kvm= _nested.h index 7158932e718b..f075df33277f 100644 --- a/arch/s390/include/asm/kvm_nested.h +++ b/arch/s390/include/asm/kvm_nested.h @@ -10,4 +10,9 @@ static inline bool vcpu_has_nv(const struct kvm_vcpu *vcp= u) return false; } =20 +static inline u64 limit_nv_id_reg(struct kvm *kvm, u32 reg, u64 val) +{ + BUILD_BUG(); +} + #endif /* ASM_KVM_NESTED_H */ diff --git a/arch/s390/kvm/arm64/Makefile b/arch/s390/kvm/arm64/Makefile index d0aac34b8d2f..28deeb90efa9 100644 --- a/arch/s390/kvm/arm64/Makefile +++ b/arch/s390/kvm/arm64/Makefile @@ -9,6 +9,7 @@ ccflags-y +=3D -I $(src) -I$(srctree)/arch/s390/kvm/gmap -D= KVM_S390_ARM64 =20 kvm-arm64-obj :=3D \ arm.o \ + feature.o \ guest.o \ handle_exit.o \ inject_fault.o \ diff --git a/arch/s390/kvm/arm64/arm.c b/arch/s390/kvm/arm64/arm.c index 48418c46e451..dc0e070f8a62 100644 --- a/arch/s390/kvm/arm64/arm.c +++ b/arch/s390/kvm/arm64/arm.c @@ -701,6 +701,8 @@ u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, enum= vcpu_sysreg reg) =20 static int __init kvm_s390_arm64_init(void) { + int err =3D 0; + if (!sclp.has_aef) { pr_info("SAE is not available\n"); return -ENXIO; @@ -711,6 +713,10 @@ static int __init kvm_s390_arm64_init(void) return -ENXIO; } =20 + err =3D kvm_arm_host_detect_features(); + if (err) + return err; + return kvm_init_with_dev(sizeof(struct kvm_vcpu), 0, THIS_MODULE, KVM_DEV_NAME, MISC_DYNAMIC_MINOR); } diff --git a/arch/s390/kvm/arm64/feature.c b/arch/s390/kvm/arm64/feature.c new file mode 100644 index 000000000000..9a34c0866a2b --- /dev/null +++ b/arch/s390/kvm/arm64/feature.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +struct qaaf_qmc_block __qaaf_qmc; + +#define MASK_RESERVED(_qaafp, _id) \ + ({ \ + u64 *_reg =3D &((_qaafp)->regs[QAAF_REG_##_id]); \ + *_reg =3D (*_reg & ~_id##_RES0) | _id##_RES1; \ + }) + +#define QAAF_FIELD_MODIFY(_idp, _id_field, _val) \ + FIELD_MODIFY(_id_field##_MASK, _idp, _id_field##_##_val) + +#define MODIFY(_qaafp, _id, _field, _val) \ + QAAF_FIELD_MODIFY(&((_qaafp)->regs[QAAF_REG_##_id]), _id##_##_field, _val) + +int __init kvm_arm_host_detect_features(void) +{ + qaaf_qmc(&__qaaf_qmc); + + MASK_RESERVED(&__qaaf_qmc, ID_AA64ISAR0_EL1); + + MODIFY(&__qaaf_qmc, ID_AA64ISAR1_EL1, LS64, NI); + MASK_RESERVED(&__qaaf_qmc, ID_AA64ISAR1_EL1); + + MODIFY(&__qaaf_qmc, ID_AA64ISAR2_EL1, SYSINSTR_128, NI); + MODIFY(&__qaaf_qmc, ID_AA64ISAR2_EL1, SYSREG_128, NI); + MODIFY(&__qaaf_qmc, ID_AA64ISAR2_EL1, PAC_frac, NI); + MASK_RESERVED(&__qaaf_qmc, ID_AA64ISAR2_EL1); + + MASK_RESERVED(&__qaaf_qmc, ID_AA64ISAR3_EL1); + + MASK_RESERVED(&__qaaf_qmc, ID_AA64MMFR0_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_AA64MMFR1_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_AA64MMFR2_EL1); + + MODIFY(&__qaaf_qmc, ID_AA64MMFR3_EL1, Spec_FPACC, NI); + MODIFY(&__qaaf_qmc, ID_AA64MMFR3_EL1, ADERR, NI); + MODIFY(&__qaaf_qmc, ID_AA64MMFR3_EL1, SDERR, NI); + MODIFY(&__qaaf_qmc, ID_AA64MMFR3_EL1, ANERR, NI); + MODIFY(&__qaaf_qmc, ID_AA64MMFR3_EL1, SNERR, NI); + MODIFY(&__qaaf_qmc, ID_AA64MMFR3_EL1, MEC, NI); + MASK_RESERVED(&__qaaf_qmc, ID_AA64MMFR3_EL1); + + MODIFY(&__qaaf_qmc, ID_AA64MMFR4_EL1, SRMASK, NI); + MODIFY(&__qaaf_qmc, ID_AA64MMFR4_EL1, E3DSE, NI); + MODIFY(&__qaaf_qmc, ID_AA64MMFR4_EL1, RMEGDI, NI); + MODIFY(&__qaaf_qmc, ID_AA64MMFR4_EL1, FGWTE3, NI); + MODIFY(&__qaaf_qmc, ID_AA64MMFR4_EL1, ASID2, NI); + MASK_RESERVED(&__qaaf_qmc, ID_AA64MMFR4_EL1); + + MODIFY(&__qaaf_qmc, ID_AA64PFR0_EL1, SEL2, NI); + MODIFY(&__qaaf_qmc, ID_AA64PFR0_EL1, SVE, NI); + MASK_RESERVED(&__qaaf_qmc, ID_AA64PFR0_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_AA64PFR1_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_AA64PFR2_EL1); + + MODIFY(&__qaaf_qmc, ID_AA64DFR0_EL1, PMUVer, NI); + MASK_RESERVED(&__qaaf_qmc, ID_AA64DFR0_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_AA64DFR1_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_AA64DFR2_EL1); + + MASK_RESERVED(&__qaaf_qmc, ID_AA64AFR0_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_AA64AFR1_EL1); + + MASK_RESERVED(&__qaaf_qmc, ID_AA64ZFR0_EL1); + + MASK_RESERVED(&__qaaf_qmc, ID_AA64SMFR0_EL1); + + MASK_RESERVED(&__qaaf_qmc, ID_AA64FPFR0_EL1); + + MASK_RESERVED(&__qaaf_qmc, ID_PFR0_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_PFR1_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_PFR2_EL1); + + MASK_RESERVED(&__qaaf_qmc, ID_DFR0_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_DFR1_EL1); + + MASK_RESERVED(&__qaaf_qmc, ID_MMFR0_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_MMFR1_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_MMFR2_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_MMFR3_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_MMFR4_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_MMFR5_EL1); + + MASK_RESERVED(&__qaaf_qmc, ID_ISAR0_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_ISAR1_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_ISAR2_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_ISAR3_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_ISAR4_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_ISAR5_EL1); + MASK_RESERVED(&__qaaf_qmc, ID_ISAR6_EL1); + + MASK_RESERVED(&__qaaf_qmc, MVFR0_EL1); + MASK_RESERVED(&__qaaf_qmc, MVFR1_EL1); + MASK_RESERVED(&__qaaf_qmc, MVFR2_EL1); + + MASK_RESERVED(&__qaaf_qmc, CTR_EL0); + + MASK_RESERVED(&__qaaf_qmc, ICH_VTR_EL2); + + return 0; +} + +#define _qaaf_reg_case(id) case SYS_##id: return __qaaf_qmc.regs[QAAF_REG_= ##id] + +u64 kvm_arm_host_sys_reg_by_id(u32 id) +{ + switch (id) { + _qaaf_reg_case(MIDR_EL1); + _qaaf_reg_case(MPIDR_EL1); + _qaaf_reg_case(REVIDR_EL1); + _qaaf_reg_case(ID_PFR0_EL1); + _qaaf_reg_case(ID_PFR1_EL1); + _qaaf_reg_case(ID_DFR0_EL1); + _qaaf_reg_case(ID_AFR0_EL1); + _qaaf_reg_case(ID_MMFR0_EL1); + _qaaf_reg_case(ID_MMFR1_EL1); + _qaaf_reg_case(ID_MMFR2_EL1); + _qaaf_reg_case(ID_MMFR3_EL1); + _qaaf_reg_case(ID_ISAR0_EL1); + _qaaf_reg_case(ID_ISAR1_EL1); + _qaaf_reg_case(ID_ISAR2_EL1); + _qaaf_reg_case(ID_ISAR3_EL1); + _qaaf_reg_case(ID_ISAR4_EL1); + _qaaf_reg_case(ID_ISAR5_EL1); + _qaaf_reg_case(ID_MMFR4_EL1); + _qaaf_reg_case(ID_ISAR6_EL1); + _qaaf_reg_case(MVFR0_EL1); + _qaaf_reg_case(MVFR1_EL1); + _qaaf_reg_case(MVFR2_EL1); + _qaaf_reg_case(ID_PFR2_EL1); + _qaaf_reg_case(ID_DFR1_EL1); + _qaaf_reg_case(ID_MMFR5_EL1); + _qaaf_reg_case(ID_AA64PFR0_EL1); + _qaaf_reg_case(ID_AA64PFR1_EL1); + _qaaf_reg_case(ID_AA64PFR2_EL1); + _qaaf_reg_case(ID_AA64ZFR0_EL1); + _qaaf_reg_case(ID_AA64SMFR0_EL1); + _qaaf_reg_case(ID_AA64FPFR0_EL1); + _qaaf_reg_case(ID_AA64DFR0_EL1); + _qaaf_reg_case(ID_AA64DFR1_EL1); + _qaaf_reg_case(ID_AA64DFR2_EL1); + _qaaf_reg_case(ID_AA64AFR0_EL1); + _qaaf_reg_case(ID_AA64AFR1_EL1); + _qaaf_reg_case(ID_AA64ISAR0_EL1); + _qaaf_reg_case(ID_AA64ISAR1_EL1); + _qaaf_reg_case(ID_AA64ISAR2_EL1); + _qaaf_reg_case(ID_AA64ISAR3_EL1); + _qaaf_reg_case(ID_AA64MMFR0_EL1); + _qaaf_reg_case(ID_AA64MMFR1_EL1); + _qaaf_reg_case(ID_AA64MMFR2_EL1); + _qaaf_reg_case(ID_AA64MMFR3_EL1); + _qaaf_reg_case(ID_AA64MMFR4_EL1); + _qaaf_reg_case(CNTFRQ_EL0); + _qaaf_reg_case(CTR_EL0); + _qaaf_reg_case(AIDR_EL1); + _qaaf_reg_case(ICH_VTR_EL2); + _qaaf_reg_case(PMMIR_EL1); + _qaaf_reg_case(PMCR_EL0); + _qaaf_reg_case(PMCEID0_EL0); + _qaaf_reg_case(PMCEID1_EL0); + default: + WARN(true, "Unknown system register 0x%x\n", id); + return 0xbad1234bad; + } +} --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 D9E3743637D; Fri, 29 May 2026 15:57:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070229; cv=none; b=qvwCRIj17UVxSu6O5sIw7BkCwd6qzkOfnXp9Q4jsIkcixoSIawwb9TcnMRcNoNVMqwAbcWamgDR4fjYf/OG0yNjk5I87vX+uD/T661jrwE19aMH9G60dTloKYAWaRDZ72ERgPPsgmgAUnsfBzaee3brgHgX0RW5WPxkRXYJEaSw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070229; c=relaxed/simple; bh=Snpt7TSib1q6Sj8l4X5CXeC1HI+B3MJyIgfiNupQt2U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=V4ZlRlpitDOAtLfJobtToBY3//XZ8bo28/w7VrDUv/OUE9URFqi0H5QI/53PNY+38hL30xT4o+vlM4Ckv09K7YNMeTWzq1DgDS3PU4a2geQYwLpInenmnzpEC/TUZHyp+t2h0oEKt4PMMGCpxrnbkjTz5aXupeKEHt0wIW99FkA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=mLuAJGHg; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="mLuAJGHg" Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFAijr2418321; Fri, 29 May 2026 15:56:21 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=07zjaI064nmoh49b2 migjE+4CKaKKwfhbZQP8VBqk3c=; b=mLuAJGHgpPSISgqhOr7G+oUwXk/04R0JQ 1iNztFDaAMiygYJsLj0J0rFU0TI6Ogkmg4w9lk98tWHPf7IKJd5Xxgg2Bodnubpq /Pj9HHWnVhRRa+lqinuAv6vSVTf5G0ucLd/UmvtXXteWkUHYDlTJzNkC+Qwl9hM5 GZJ19pFaLkQSeV9jbI6F7O+rMVPsmq7l1wUbliU7a/IJEP2IUMur3a31DrvWM0CC yBwZJrLLgc8paCv1G6wEWPYe/3qVJKv8TtRnKtGD1a90K9HfIgZrnp5QnOC4DpG5 AmkpQjGJZMnlRfDK8d0fQE+kcPU0A06C+kHenXO3vyifuheY9Zd+w== Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee884vksu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:20 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs7Tm027776; Fri, 29 May 2026 15:56:18 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrc8jpj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:18 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFuBdY16187722 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:11 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 8C65120040; Fri, 29 May 2026 15:56:11 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 262042004E; Fri, 29 May 2026 15:56:11 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:11 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 24/26] KVM: s390: arm64: Implement sysreg handling Date: Fri, 29 May 2026 17:55:57 +0200 Message-ID: <20260529155601.2927240-25-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=L4MtheT8 c=1 sm=1 tr=0 ts=6a19b724 cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=VnNF1IyMAAAA:8 a=4AYil0YxhE6jXFOO_r0A:9 X-Proofpoint-ORIG-GUID: CQrKwnA0xXDswTaBjqlyDi65rdKTqCPp X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX8485wTThnZHv dmnM4ePGem6GKE/3sYko81gI+P9h4aOOC23d/311oLw70kEJPsFjqyyifxs7pj+Bxe4+6+drMD2 4DxHyiEK4T9RWfCG+kXg+yonrj9Ykbr7ZmNU7jqMR2aZ68LPtOykwLnjfdd/1agAZ60NiUvvNo0 /mYkOZvXiKp3ALtdizn/RuTVEVes7hz2oJp1PhQkDwbDuOIpdbrj3tOBhdTbeRxhhEOkSMNRzop 5nXtdcXNfse2p/6+oyL5t1ln1WFN/azcVRDFPlxJSguYm/QkTGQ4BkKPsUmlRiJcOt/fhEFOEBs RGbtoc9tLJlBl1xBIeAGcv16BxJ1iy5y4c1QaNXcYVM+BFFBRs9ijIHJw9d+oimH46EXlVp0Cpw HzBBj5+Tmz/pa7aJRtbszQYvWIoR1NefN/+yzVZiXVcRNkoquY/TPodDkkteMUckHyIh5rYasVU WJA1BMWtz+V9zU3fEuQ== X-Proofpoint-GUID: CQrKwnA0xXDswTaBjqlyDi65rdKTqCPp X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 suspectscore=0 clxscore=1015 malwarescore=0 bulkscore=0 impostorscore=0 adultscore=0 priorityscore=1501 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Add arm64 system register support for the s390 KVM backend, including register enumeration, userspace get/set handling, reset/finalization hooks, and vCPU run integration for trapped sysreg accesses. Co-developed-by: Andreas Grapentin Signed-off-by: Andreas Grapentin Co-developed-by: Nico Boehr Signed-off-by: Nico Boehr Co-developed-by: Nina Schoetterl-Glausch Signed-off-by: Nina Schoetterl-Glausch Signed-off-by: Steffen Eiden --- arch/arm64/kvm/Makefile | 1 - arch/s390/include/asm/kvm_emulate.h | 34 ++ arch/s390/include/asm/kvm_host_arm64.h | 2 +- arch/s390/kvm/arm64/Makefile | 1 + arch/s390/kvm/arm64/arm.c | 23 +- arch/s390/kvm/arm64/guest.c | 20 +- arch/s390/kvm/arm64/handle_exit.c | 1 + arch/s390/kvm/arm64/reset.c | 5 + arch/s390/kvm/arm64/sys_regs.c | 769 +++++++++++++++++++++++++ arch/s390/kvm/arm64/trace.h | 33 ++ virt/kvm/arm64/Makefile.kvm | 1 + 11 files changed, 875 insertions(+), 15 deletions(-) create mode 100644 arch/s390/kvm/arm64/sys_regs.c create mode 100644 arch/s390/kvm/arm64/trace.h diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index d55c7245aad9..5b4a8d002fc9 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -19,7 +19,6 @@ kvm-y +=3D arm.o mmu.o psci.o hypercalls.o pvtime.o \ guest.o debug.o reset.o sys_regs.o stacktrace.o \ vgic-sys-reg-v3.o fpsimd.o pkvm.o \ arch_timer.o trng.o vmid.o emulate-nested.o nested.o at.o \ - $(KVM_ARM64)/sys_regs.o \ vgic/vgic.o vgic/vgic-init.o \ vgic/vgic-irqfd.o vgic/vgic-v2.o \ vgic/vgic-v3.o vgic/vgic-v4.o \ diff --git a/arch/s390/include/asm/kvm_emulate.h b/arch/s390/include/asm/kv= m_emulate.h index 93b9e777b51e..5549d44fda18 100644 --- a/arch/s390/include/asm/kvm_emulate.h +++ b/arch/s390/include/asm/kvm_emulate.h @@ -12,6 +12,7 @@ =20 #include #include +#include =20 static __always_inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu) { @@ -84,6 +85,39 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) HCR_TID4 | HCR_TID5 | HCR_TIDCP; } =20 +static inline void vcpu_reset_hcrx(struct kvm_vcpu *vcpu) +{ + vcpu->arch.hcrx_elz =3D 0; + if (kvm_has_feat(vcpu->kvm, ID_AA64ISAR2_EL1, MOPS, IMP)) + vcpu->arch.hcrx_elz |=3D HCRX_EL2_MSCEn ; +} + +static inline void vcpu_reset_cptr(struct kvm_vcpu *vcpu) +{ + u64 cptr; + + /* we unconditionally have E2H, so disable traps to EL2 for FP and SVE, i= f enabled */ + cptr =3D CPACR_EL1_FPEN; + if (vcpu_has_sve(vcpu)) + cptr |=3D CPACR_EL1_ZEN; + vcpu_write_host_sys_reg(vcpu, cptr, SYS_CPTR_EL2); +} + +static inline void vcpu_reset_cnthctl(struct kvm_vcpu *vcpu) +{ + u64 cnthctl; + + /* we unconditionally have E2H, so disable traps to EL2 for physical time= r registers */ + cnthctl =3D (CNTHCTL_EL1PCEN | CNTHCTL_EL1PCTEN) << 10; + vcpu_write_host_sys_reg(vcpu, cnthctl, SYS_CNTHCTL_EL2); +} + +static inline void vcpu_reset_icc(struct kvm_vcpu *vcpu) +{ + /* ensure ICC_SRE_EL2.Enable =3D 1 so ICC_SRE_EL1 is handled in hardware = */ + vcpu_write_host_sys_reg(vcpu, 0xf, SYS_ICC_SRE_EL2); +} + static inline unsigned long vcpu_get_vsesr(struct kvm_vcpu *vcpu) { WARN(true, "not implemented, just feat RAS"); diff --git a/arch/s390/include/asm/kvm_host_arm64.h b/arch/s390/include/asm= /kvm_host_arm64.h index f62daff3303b..cc457d69621c 100644 --- a/arch/s390/include/asm/kvm_host_arm64.h +++ b/arch/s390/include/asm/kvm_host_arm64.h @@ -370,7 +370,7 @@ int __init kvm_sys_reg_table_init(void); =20 static inline u64 kvm_sanitised_host_ftr_reg(u32 id) { - return 0xbad1234bad; + return kvm_arm_host_sys_reg_by_id(id); } =20 #endif /* ASM_KVM_HOST_ARM64_H */ diff --git a/arch/s390/kvm/arm64/Makefile b/arch/s390/kvm/arm64/Makefile index 28deeb90efa9..bec24b60a071 100644 --- a/arch/s390/kvm/arm64/Makefile +++ b/arch/s390/kvm/arm64/Makefile @@ -15,6 +15,7 @@ kvm-arm64-obj :=3D \ inject_fault.o \ mmu.o \ reset.o \ + sys_regs.o \ =20 kvm-arm64-obj +=3D $(patsubst %.o,%-arm64.o,$(shared-arm64-obj)) kvm-arm64-obj +=3D $(patsubst %.o,%-arm64.o,$(kvm-y)) diff --git a/arch/s390/kvm/arm64/arm.c b/arch/s390/kvm/arm64/arm.c index dc0e070f8a62..88b66552cff0 100644 --- a/arch/s390/kvm/arm64/arm.c +++ b/arch/s390/kvm/arm64/arm.c @@ -14,6 +14,7 @@ =20 #include #include +#include =20 #include =20 @@ -227,6 +228,7 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu) { struct kvm *kvm =3D vcpu->kvm; + int ret; =20 if (!kvm_vcpu_initialized(vcpu)) return -ENOEXEC; @@ -237,6 +239,9 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu) if (likely(READ_ONCE(vcpu->pid))) return 0; =20 + ret =3D kvm_finalize_sys_regs(vcpu); + if (ret) + return ret; =20 mutex_lock(&kvm->arch.config_lock); set_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags); @@ -363,6 +368,9 @@ static void arm_vcpu_run(struct kvm_vcpu *vcpu) guest_enter_irqoff(); local_irq_enable(); =20 + vcpu_write_host_sys_reg(vcpu, vcpu->arch.hcr_elz, SYS_HCR_EL2); + vcpu_write_host_sys_reg(vcpu, vcpu->arch.hcrx_elz, SYS_HCRX_EL2); + vcpu_write_host_sys_reg(vcpu, vcpu->arch.mpidr, SYS_VMPIDR_EL2); //TODO i= mplement mpidr plumbing sae_block->icptr =3D 0; =20 sae64a(sae_block); @@ -690,15 +698,6 @@ long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, u= nsigned int ioctl, return -ENOIOCTLCMD; } =20 -void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, enum vcpu_sysreg r= eg) -{ -} - -u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg reg) -{ - return 0xbad12324bad; -} - static int __init kvm_s390_arm64_init(void) { int err =3D 0; @@ -717,6 +716,12 @@ static int __init kvm_s390_arm64_init(void) if (err) return err; =20 + err =3D kvm_sys_reg_table_init(); + if (err) { + kvm_info("Error initializing system register tables"); + return err; + } + return kvm_init_with_dev(sizeof(struct kvm_vcpu), 0, THIS_MODULE, KVM_DEV_NAME, MISC_DYNAMIC_MINOR); } diff --git a/arch/s390/kvm/arm64/guest.c b/arch/s390/kvm/arm64/guest.c index 893d48037292..3287059f89c7 100644 --- a/arch/s390/kvm/arm64/guest.c +++ b/arch/s390/kvm/arm64/guest.c @@ -2,6 +2,8 @@ #include #include =20 +#include + #include "guest.h" =20 const struct kvm_stats_desc kvm_vm_stats_desc[] =3D { @@ -42,12 +44,22 @@ const struct kvm_stats_header kvm_vcpu_stats_header =3D= { =20 int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) { - return copy_core_reg_indices(vcpu, uindices); + int ret; + + ret =3D copy_core_reg_indices(vcpu, uindices); + if (ret < 0) + return ret; + uindices +=3D ret; + + return kvm_arm_copy_sys_reg_indices(vcpu, uindices); } =20 unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) { - return num_core_regs(vcpu); + unsigned long num =3D num_core_regs(vcpu); + + num +=3D kvm_arm_num_sys_reg_descs(vcpu); + return num; } =20 int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) @@ -60,7 +72,7 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct k= vm_one_reg *reg) case KVM_REG_ARM_CORE: return get_core_reg(vcpu, reg); default: - return -EINVAL; + return kvm_arm_sys_reg_get_reg(vcpu, reg); } } =20 @@ -74,7 +86,7 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct k= vm_one_reg *reg) case KVM_REG_ARM_CORE: return set_core_reg(vcpu, reg); default: - return -EINVAL; + return kvm_arm_sys_reg_set_reg(vcpu, reg); } } =20 diff --git a/arch/s390/kvm/arm64/handle_exit.c b/arch/s390/kvm/arm64/handle= _exit.c index bccd644fb07c..53aa7f6c4745 100644 --- a/arch/s390/kvm/arm64/handle_exit.c +++ b/arch/s390/kvm/arm64/handle_exit.c @@ -47,6 +47,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu) exit_handle_fn arm_exit_handlers[] =3D { [0 ... ESR_ELx_EC_MAX] =3D kvm_handle_unknown_ec, [ESR_ELx_EC_HVC64] =3D handle_hvc, + [ESR_ELx_EC_SYS64] =3D kvm_handle_sys_reg, [ESR_ELx_EC_IABT_LOW] =3D kvm_handle_guest_abort, [ESR_ELx_EC_DABT_LOW] =3D kvm_handle_guest_abort, }; diff --git a/arch/s390/kvm/arm64/reset.c b/arch/s390/kvm/arm64/reset.c index b38b36c72c72..19404bfb85b6 100644 --- a/arch/s390/kvm/arm64/reset.c +++ b/arch/s390/kvm/arm64/reset.c @@ -33,9 +33,14 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu) vcpu_put(vcpu); =20 kvm_reset_vcpu_core_regs(vcpu); + kvm_reset_sys_regs(vcpu); =20 /* Reset special registers */ vcpu_reset_hcr(vcpu); + vcpu_reset_hcrx(vcpu); + vcpu_reset_cptr(vcpu); + vcpu_reset_cnthctl(vcpu); + vcpu_reset_icc(vcpu); =20 if (reset_state.reset) { *vcpu_pc(vcpu) =3D reset_state.pc; diff --git a/arch/s390/kvm/arm64/sys_regs.c b/arch/s390/kvm/arm64/sys_regs.c new file mode 100644 index 000000000000..0bcfdade8509 --- /dev/null +++ b/arch/s390/kvm/arm64/sys_regs.c @@ -0,0 +1,769 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define CREATE_TRACE_POINTS +#include "trace.h" + +#define SR_INVALID 0x8badf00d8badf00d + +enum sr_loc_attr { + SR_LOC_SAVE_AREA, /* Register on SA, loaded (on cpu) */ + SR_LOC_SPECIAL, /* Register in state description or Special care registe= r*/ + SR_LOC_INVALID, /* Register is unknown */ +}; + +struct sr_loc { + enum sr_loc_attr loc; +}; + +#define SREG_RANGE(NAME) __##NAME##_BEGIN__ + 1 ... __##NAME##_END__ - 1 +static __always_inline void locate_register(const struct kvm_vcpu *vcpu, + enum vcpu_sysreg reg, + struct sr_loc *loc) +{ + switch (reg) { + case SREG_RANGE(STATE_DESC): + case SREG_RANGE(SPECIAL): + loc->loc =3D SR_LOC_SPECIAL; + break; + case SREG_RANGE(SAVE_AREA): + loc->loc =3D SR_LOC_SAVE_AREA; + break; + default: + WARN(true, "%s wants to read invalid register %x", __func__, reg); + loc->loc =3D SR_LOC_INVALID; + } +} + +static __always_inline u64 read_special_sr(const struct kvm_vcpu *vcpu, + enum vcpu_sysreg reg) +{ + switch (reg) { + case CLIDR_EL1: return vcpu->arch.sys_reg_clidr_el1; + case CSSELR_EL1: return vcpu->arch.sys_reg_csselr_el1; + case MPIDR_EL1: return vcpu->arch.mpidr; + case CNTP_CTL_EL0: return vcpu->arch.sae_block.cntp_ctl; + case CNTV_CTL_EL0: return vcpu->arch.sae_block.cntv_ctl; + case CONTEXTIDR_EL1: return vcpu->arch.sae_block.contextidr_el1; + case SP_EL1: return vcpu->arch.sae_block.sp_el1; + default: + WARN(true, "%s wants to read non-special register %x", __func__, reg); + return SR_INVALID; + } +} + +static __always_inline u64 read_sr_from_vcpu(const struct kvm_vcpu *vcpu, + enum vcpu_sysreg reg) +{ + switch (reg) { + case ACTLR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_ACTLR_EL1); + case AFSR0_EL1: return _vcpu_read_sys_reg(vcpu, SYS_AFSR0_EL1); + case AFSR1_EL1: return _vcpu_read_sys_reg(vcpu, SYS_AFSR1_EL1); + case CNTFRQ_EL0: return _vcpu_read_sys_reg(vcpu, SYS_CNTFRQ_EL0); + case CNTP_CVAL_EL0: return _vcpu_read_sys_reg(vcpu, SYS_CNTP_CVAL_EL0); + case CNTV_CVAL_EL0: return _vcpu_read_sys_reg(vcpu, SYS_CNTV_CVAL_EL0); + case DISR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_DISR_EL1); + case MIDR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_MIDR_EL1); + case OSLSR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_OSLSR_EL1); + case PAR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_PAR_EL1); + case SCTLR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_SCTLR_EL1); + case CPACR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_CPACR_EL1); + case VBAR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_VBAR_EL1); + case SPSR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_SPSR_EL1); + case ELR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_ELR_EL1); + case ESR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_ESR_EL1); + case TCR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_TCR_EL1); + case MAIR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_MAIR_EL1); + case TTBR0_EL1: return _vcpu_read_sys_reg(vcpu, SYS_TTBR0_EL1); + case TTBR1_EL1: return _vcpu_read_sys_reg(vcpu, SYS_TTBR1_EL1); + case FAR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_FAR_EL1); + case TPIDR_EL0: return _vcpu_read_sys_reg(vcpu, SYS_TPIDR_EL0); + case TPIDR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_TPIDR_EL1); + case TPIDRRO_EL0: return _vcpu_read_sys_reg(vcpu, SYS_TPIDRRO_EL0); + case CNTKCTL_EL1: return _vcpu_read_sys_reg(vcpu, SYS_CNTKCTL_EL1); + case ZCR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_ZCR_EL1); + case SCXTNUM_EL0: return _vcpu_read_sys_reg(vcpu, SYS_SCXTNUM_EL0); + case SCXTNUM_EL1: return _vcpu_read_sys_reg(vcpu, SYS_SCXTNUM_EL1); + case APIBKEYLO_EL1: return _vcpu_read_sys_reg(vcpu, SYS_APIBKEYLO_EL1); + case APIBKEYHI_EL1: return _vcpu_read_sys_reg(vcpu, SYS_APIBKEYHI_EL1); + case APIAKEYLO_EL1: return _vcpu_read_sys_reg(vcpu, SYS_APIAKEYLO_EL1); + case APIAKEYHI_EL1: return _vcpu_read_sys_reg(vcpu, SYS_APIAKEYHI_EL1); + case APGAKEYLO_EL1: return _vcpu_read_sys_reg(vcpu, SYS_APGAKEYLO_EL1); + case APGAKEYHI_EL1: return _vcpu_read_sys_reg(vcpu, SYS_APGAKEYHI_EL1); + case APDBKEYLO_EL1: return _vcpu_read_sys_reg(vcpu, SYS_APDBKEYLO_EL1); + case APDBKEYHI_EL1: return _vcpu_read_sys_reg(vcpu, SYS_APDBKEYHI_EL1); + case APDAKEYLO_EL1: return _vcpu_read_sys_reg(vcpu, SYS_APDAKEYLO_EL1); + case APDAKEYHI_EL1: return _vcpu_read_sys_reg(vcpu, SYS_APDAKEYHI_EL1); + case MDSCR_EL1: return _vcpu_read_sys_reg(vcpu, SYS_MDSCR_EL1); + default: + WARN(true, "%s: failed to resolve %x", __func__, reg); + return SR_INVALID; + } +} + +u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg reg) +{ + struct sr_loc loc =3D {}; + + locate_register(vcpu, reg, &loc); + + if (unlikely(loc.loc =3D=3D SR_LOC_INVALID)) { + WARN(true, "%s: failed to locate %u", __func__, reg); + return SR_INVALID; + } + + if (loc.loc =3D=3D SR_LOC_SPECIAL) + return read_special_sr(vcpu, reg); + + return read_sr_from_vcpu(vcpu, reg); +} + +static __always_inline void write_special_sr(struct kvm_vcpu *vcpu, u64 va= l, + enum vcpu_sysreg reg) +{ + switch (reg) { + case CLIDR_EL1: vcpu->arch.sys_reg_clidr_el1 =3D val; break; + case CSSELR_EL1: vcpu->arch.sys_reg_csselr_el1 =3D val; break; + case MPIDR_EL1: vcpu->arch.mpidr =3D val; break; + case CNTP_CTL_EL0: vcpu->arch.sae_block.cntp_ctl =3D val; break; + case CNTV_CTL_EL0: vcpu->arch.sae_block.cntv_ctl =3D val; break; + case CONTEXTIDR_EL1: vcpu->arch.sae_block.contextidr_el1 =3D val; break; + case SP_EL1: vcpu->arch.sae_block.sp_el1 =3D val; break; + default: + WARN(true, "%s wants to write non-special register %x", __func__, reg); + } +} + +static __always_inline void write_sr_to_vcpu(struct kvm_vcpu *vcpu, u64 va= l, + enum vcpu_sysreg reg) +{ + switch (reg) { + case ACTLR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_ACTLR_EL1); break; + case AFSR0_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_AFSR0_EL1); break; + case AFSR1_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_AFSR1_EL1); break; + case CNTFRQ_EL0: _vcpu_write_sys_reg(vcpu, val, SYS_CNTFRQ_EL0); break; + case CNTP_CVAL_EL0: _vcpu_write_sys_reg(vcpu, val, SYS_CNTP_CVAL_EL0); br= eak; + case CNTV_CVAL_EL0: _vcpu_write_sys_reg(vcpu, val, SYS_CNTV_CVAL_EL0); br= eak; + case DISR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_DISR_EL1); break; + case MIDR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_MIDR_EL1); break; + case PAR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_PAR_EL1); break; + case OSLAR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_OSLAR_EL1); break; + case SCTLR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_SCTLR_EL1); break; + case CPACR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_CPACR_EL1); break; + case VBAR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_VBAR_EL1); break; + case SPSR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_SPSR_EL1); break; + case ELR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_ELR_EL1); break; + case ESR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_ESR_EL1); break; + case TCR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_TCR_EL1); break; + case MAIR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_MAIR_EL1); break; + case TTBR0_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_TTBR0_EL1); break; + case TTBR1_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_TTBR1_EL1); break; + case FAR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_FAR_EL1); break; + case TPIDR_EL0: _vcpu_write_sys_reg(vcpu, val, SYS_TPIDR_EL0); break; + case TPIDR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_TPIDR_EL1); break; + case TPIDRRO_EL0: _vcpu_write_sys_reg(vcpu, val, SYS_TPIDRRO_EL0); break; + case CNTKCTL_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_CNTKCTL_EL1); break; + case ZCR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_ZCR_EL1); break; + case SCXTNUM_EL0: _vcpu_write_sys_reg(vcpu, val, SYS_SCXTNUM_EL0); break; + case SCXTNUM_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_SCXTNUM_EL1); break; + case APIBKEYLO_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_APIBKEYLO_EL1); br= eak; + case APIBKEYHI_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_APIBKEYHI_EL1); br= eak; + case APIAKEYLO_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_APIAKEYLO_EL1); br= eak; + case APIAKEYHI_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_APIAKEYHI_EL1); br= eak; + case APGAKEYLO_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_APGAKEYLO_EL1); br= eak; + case APGAKEYHI_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_APGAKEYHI_EL1); br= eak; + case APDBKEYLO_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_APDBKEYLO_EL1); br= eak; + case APDBKEYHI_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_APDBKEYHI_EL1); br= eak; + case APDAKEYLO_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_APDAKEYLO_EL1); br= eak; + case APDAKEYHI_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_APDAKEYHI_EL1); br= eak; + case MDSCR_EL1: _vcpu_write_sys_reg(vcpu, val, SYS_MDSCR_EL1); break; + default: + WARN(true, "%s: failed to resolve %x", __func__, reg); + } +} + +void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, enum vcpu_sysreg r= eg) +{ + struct sr_loc loc =3D {}; + + locate_register(vcpu, reg, &loc); + + if (unlikely(loc.loc =3D=3D SR_LOC_INVALID)) { + WARN(true, "%s: failed to locate %u", __func__, reg); + return; + } + + if (loc.loc =3D=3D SR_LOC_SPECIAL) { + write_special_sr(vcpu, val, reg); + return; + } + + write_sr_to_vcpu(vcpu, val, reg); +} + +u64 vcpu_read_host_sys_reg(const struct kvm_vcpu *vcpu, int reg) +{ + switch (reg) { + case SYS_ICH_LR0_EL2: return vcpu->arch.sae_block.ic_regs.ich_lrn_el2[0]; + case SYS_ICH_LR1_EL2: return vcpu->arch.sae_block.ic_regs.ich_lrn_el2[1]; + case SYS_ICH_LR2_EL2: return vcpu->arch.sae_block.ic_regs.ich_lrn_el2[2]; + case SYS_ICH_LR3_EL2: return vcpu->arch.sae_block.ic_regs.ich_lrn_el2[3]; + case SYS_ICH_HCR_EL2: return vcpu->arch.sae_block.ic_regs.ich_hcr_el2; + case SYS_ICH_AP0R0_EL2: return vcpu->arch.sae_block.ic_regs.ich_ap0r0_el2; + case SYS_ICH_AP1R0_EL2: return vcpu->arch.sae_block.ic_regs.ich_ap1r0_el2; + case SYS_ICH_VMCR_EL2: return vcpu->arch.sae_block.ic_regs.ich_vmcr_el2; + case SYS_VSESR_EL2: return _vcpu_read_sys_reg(vcpu, SYS_VSESR_EL2); + case SYS_HCR_EL2: return _vcpu_read_sys_reg(vcpu, SYS_HCR_EL2); + case SYS_CPTR_EL2: return _vcpu_read_sys_reg(vcpu, SYS_CPTR_EL2); + case SYS_MDCR_EL2: return _vcpu_read_sys_reg(vcpu, SYS_MDCR_EL2); + case SYS_HCRX_EL2: return _vcpu_read_sys_reg(vcpu, SYS_HCRX_EL2); + case SYS_HFGRTR_EL2: return _vcpu_read_sys_reg(vcpu, SYS_HFGRTR_EL2); + case SYS_HFGWTR_EL2: return _vcpu_read_sys_reg(vcpu, SYS_HFGWTR_EL2); + case SYS_HDFGWTR_EL2: return _vcpu_read_sys_reg(vcpu, SYS_HDFGWTR_EL2); + case SYS_HDFGRTR_EL2: return _vcpu_read_sys_reg(vcpu, SYS_HDFGRTR_EL2); + case SYS_HFGITR_EL2: return _vcpu_read_sys_reg(vcpu, SYS_HFGITR_EL2); + case SYS_CNTHCTL_EL2: return _vcpu_read_sys_reg(vcpu, SYS_CNTHCTL_EL2); + case SYS_ICC_SRE_EL2: return _vcpu_read_sys_reg(vcpu, SYS_ICC_SRE_EL2); + case SYS_VMPIDR_EL2: return _vcpu_read_sys_reg(vcpu, SYS_VMPIDR_EL2); + default: + WARN(true, "%s wants to read non-host register %x", __func__, reg); + return SR_INVALID; + } +} + +void vcpu_write_host_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg) +{ + switch (reg) { + case SYS_ICH_LR0_EL2: vcpu->arch.sae_block.ic_regs.ich_lrn_el2[0] =3D val= ; break; + case SYS_ICH_LR1_EL2: vcpu->arch.sae_block.ic_regs.ich_lrn_el2[1] =3D val= ; break; + case SYS_ICH_LR2_EL2: vcpu->arch.sae_block.ic_regs.ich_lrn_el2[2] =3D val= ; break; + case SYS_ICH_LR3_EL2: vcpu->arch.sae_block.ic_regs.ich_lrn_el2[3] =3D val= ; break; + case SYS_ICH_HCR_EL2: vcpu->arch.sae_block.ic_regs.ich_hcr_el2 =3D val; = break; + case SYS_ICH_AP0R0_EL2: vcpu->arch.sae_block.ic_regs.ich_ap0r0_el2 =3D va= l; break; + case SYS_ICH_AP1R0_EL2: vcpu->arch.sae_block.ic_regs.ich_ap1r0_el2 =3D va= l; break; + case SYS_ICH_VMCR_EL2: vcpu->arch.sae_block.ic_regs.ich_vmcr_el2 =3D val;= break; + case SYS_VSESR_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_VSESR_EL2); break; + case SYS_HCR_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_HCR_EL2); break; + case SYS_CPTR_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_CPTR_EL2); break; + case SYS_MDCR_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_MDCR_EL2); break; + case SYS_HCRX_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_HCRX_EL2); break; + case SYS_HFGRTR_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_HFGRTR_EL2); bre= ak; + case SYS_HFGWTR_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_HFGWTR_EL2); bre= ak; + case SYS_HDFGWTR_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_HDFGWTR_EL2); br= eak; + case SYS_HDFGRTR_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_HDFGRTR_EL2); br= eak; + case SYS_HFGITR_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_HFGITR_EL2); bre= ak; + case SYS_CNTHCTL_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_CNTHCTL_EL2); br= eak; + case SYS_ICC_SRE_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_ICC_SRE_EL2); br= eak; + case SYS_VMPIDR_EL2: _vcpu_write_sys_reg(vcpu, val, SYS_VMPIDR_EL2); bre= ak; + default: + WARN(true, "%s wants to write non-host register %x", __func__, reg); + } +} + +static int set_id_aa64dfr0_el1(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, + u64 val) +{ + u8 debugver =3D SYS_FIELD_GET(ID_AA64DFR0_EL1, DebugVer, val); + u8 pmuver =3D SYS_FIELD_GET(ID_AA64DFR0_EL1, PMUVer, val); + + if (pmuver =3D=3D ID_AA64DFR0_EL1_PMUVer_IMP_DEF) + return -EINVAL; + + /* + * ID_AA64DFR0_EL1.DebugVer is one of those awkward fields with a + * nonzero minimum safe value. + */ + if (debugver < ID_AA64DFR0_EL1_DebugVer_IMP) + return -EINVAL; + + return set_id_reg(vcpu, rd, val); +} + +static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, u64 user_val) +{ + /* Fail the guest's request to disable the AA64 ISA at EL{0,1,2} */ + if (!FIELD_GET(ID_AA64PFR0_EL1_EL0, user_val) || + !FIELD_GET(ID_AA64PFR0_EL1_EL1, user_val) || + (vcpu_has_nv(vcpu) && !FIELD_GET(ID_AA64PFR0_EL1_EL2, user_val))) + return -EINVAL; + + return set_id_reg(vcpu, rd, user_val); +} + +int arm64_check_features(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, + u64 val) +{ + u32 id =3D reg_to_encoding(rd); + u64 host_val; + u64 old_val; + + /* + * This is a very minimal implementation to sanitise only the craziest + * shenanigans we could get from userspace. The final goal is to share + * the sanitisation with arm as well but this needs access to arm + * (core) kernel code for which there is no suitable solution yet. TODO + */ + + /* + * If the register is RAZ we know the only safe value is 0. + */ + if (sysreg_visible_as_raz(vcpu, rd)) + return val ? -E2BIG : 0; + + host_val =3D kvm_arm_host_sys_reg_by_id(id); + + switch (id) { + case SYS_ID_AA64MMFR0_EL1: + /* Forbid PRANGE values we do not know about */ + if (SYS_FIELD_GET(ID_AA64MMFR0_EL1, PARANGE, host_val) > + ID_AA64MMFR0_EL1_PARANGE_56) + return -E2BIG; + break; + case SYS_CTR_EL0: + /* forbid upgrading from VIPT to PIPT */ + old_val =3D read_id_reg(vcpu, rd); + if (SYS_FIELD_GET(CTR_EL0, L1Ip, old_val) =3D=3D CTR_EL0_L1Ip_VIPT && + SYS_FIELD_GET(CTR_EL0, L1Ip, val) =3D=3D CTR_EL0_L1Ip_PIPT) + return -E2BIG; + break; + } + return 0; +} + +static u64 __ro_after_init boot_cpu_midr_val; +static u64 __ro_after_init boot_cpu_revidr_val; +static u64 __ro_after_init boot_cpu_aidr_val; + +static void init_imp_id_regs(void) +{ + boot_cpu_midr_val =3D kvm_arm_host_sys_reg_by_name(MIDR_EL1); + boot_cpu_revidr_val =3D kvm_arm_host_sys_reg_by_name(REVIDR_EL1); + boot_cpu_aidr_val =3D 0xC0FFEE; // TODO qaaf support needed. +} + +u64 reset_imp_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) +{ + switch (reg_to_encoding(r)) { + case SYS_MIDR_EL1: + return boot_cpu_midr_val; + case SYS_REVIDR_EL1: + return boot_cpu_revidr_val; + case SYS_AIDR_EL1: + return boot_cpu_aidr_val; + default: + KVM_BUG_ON(1, vcpu->kvm); + return 0; + } +} + +bool access_imp_id_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p, + const struct sys_reg_desc *r) +{ + if (p->is_write) + return write_to_read_only(vcpu, p, r); + + /* + * Return the VM-scoped implementation ID register values if userspace + * has made them writable. + */ + if (test_bit(KVM_ARCH_FLAG_WRITABLE_IMP_ID_REGS, &vcpu->kvm->arch.flags)) + return access_id_reg(vcpu, p, r); + + switch (reg_to_encoding(r)) { + case SYS_REVIDR_EL1: + p->regval =3D boot_cpu_revidr_val; //no old api to conform to? + break; + case SYS_AIDR_EL1: + p->regval =3D boot_cpu_aidr_val; + break; + default: + WARN_ON_ONCE(1); + } + + return true; +} + +static int get_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,= u64 *val) +{ + *val =3D vcpu->arch.mpidr; + return 0; +} + +static int set_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,= u64 val) +{ + vcpu->arch.mpidr =3D val; + return 0; +} + +static u64 reset_midr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) +{ + _vcpu_write_sys_reg(vcpu, boot_cpu_midr_val, SYS_MIDR_EL1); + return boot_cpu_midr_val; +} + +static u64 reset_oslsr_el1(struct kvm_vcpu *vcpu, const struct sys_reg_des= c *r) +{ + u64 oslsr =3D r->val; + + set_oslsr_el1(vcpu, r, oslsr); + return oslsr; +} + +static int arch_timer_set_user(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, + u64 val) +{ + switch (reg_to_encoding(rd)) { + case SYS_CNTVCT_EL0: + vcpu->arch.sae_block.gpto =3D ptff_qagto(val); + return 0; + case SYS_CNTPCT_EL0: + return 0; + } + + __vcpu_assign_sys_reg(vcpu, rd->reg, val); + return 0; +} + +static int arch_timer_get_user(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd, + u64 *val) +{ + switch (reg_to_encoding(rd)) { + case SYS_CNTVCT_EL0: + *val =3D ptff_qagpt(vcpu->arch.sae_block.gpto); + break; + case SYS_CNTPCT_EL0: + *val =3D ptff_qagpt(vcpu->arch.sae_block.gpto); + break; + default: + *val =3D __vcpu_sys_reg(vcpu, rd->reg); + } + + return 0; +} + +#define TIMER_REG(name) { \ + SYS_DESC(SYS_##name), \ + .reset =3D reset_val, \ + .reg =3D name, \ + .get_user =3D arch_timer_get_user, \ + .set_user =3D arch_timer_set_user, \ +} + +/* + * Architected system registers. + * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2 + */ +static const struct sys_reg_desc sys_reg_descs[] =3D { + /* Op0 =3D 2 */ + { SYS_DESC(SYS_OSLAR_EL1), trap_oslar_el1 }, + { SYS_DESC(SYS_OSLSR_EL1), trap_oslsr_el1, reset_oslsr_el1, OSLSR_EL1, + OSLSR_EL1_OSLM_IMPLEMENTED, NULL, set_oslsr_el1 }, + + /* Op0 =3D 3 */ + /* Op1 =3D 0 */ + /* CRn =3D 0 */ + /* CRm =3D 0 */ + + //should not trap, right? + { SYS_DESC(SYS_MIDR_EL1), NULL, reset_midr, 0, GENMASK_ULL(31, 0), + get_id_reg, set_imp_id_reg }, + { SYS_DESC(SYS_MPIDR_EL1), NULL, reset_mpidr, MPIDR_EL1, 0, get_mpidr, + set_mpidr }, + IMPLEMENTATION_ID(REVIDR_EL1, GENMASK_ULL(63, 0)), + + /* + * ID regs: all ID_SANITISED() entries here must have corresponding + * entries in arm64_ftr_regs[]. + */ + + /* AArch64 mappings of the AArch32 ID registers */ + /* CRm=3D1 */ + ID_HIDDEN(ID_PFR0_EL1), + ID_HIDDEN(ID_PFR1_EL1), + ID_HIDDEN(ID_DFR0_EL1), + ID_HIDDEN(ID_AFR0_EL1), + ID_HIDDEN(ID_MMFR0_EL1), + ID_HIDDEN(ID_MMFR1_EL1), + ID_HIDDEN(ID_MMFR2_EL1), + ID_HIDDEN(ID_MMFR3_EL1), + + /* CRm=3D2 */ + ID_HIDDEN(ID_ISAR0_EL1), + ID_HIDDEN(ID_ISAR1_EL1), + ID_HIDDEN(ID_ISAR2_EL1), + ID_HIDDEN(ID_ISAR3_EL1), + ID_HIDDEN(ID_ISAR4_EL1), + ID_HIDDEN(ID_ISAR5_EL1), + ID_HIDDEN(ID_MMFR4_EL1), + ID_HIDDEN(ID_ISAR6_EL1), + + /* CRm=3D3 */ + ID_HIDDEN(MVFR0_EL1), + ID_HIDDEN(MVFR1_EL1), + ID_HIDDEN(MVFR2_EL1), + ID_UNALLOCATED(3, 3), + ID_HIDDEN(ID_PFR2_EL1), + ID_HIDDEN(ID_DFR1_EL1), + ID_HIDDEN(ID_MMFR5_EL1), + ID_UNALLOCATED(3, 7), + + /* AArch64 ID registers */ + /* CRm=3D4 */ + ID_FILTERED(ID_AA64PFR0_EL1, id_aa64pfr0_el1, + ~(ID_AA64PFR0_EL1_AMU | ID_AA64PFR0_EL1_MPAM | + ID_AA64PFR0_EL1_SVE | ID_AA64PFR0_EL1_RAS | + ID_AA64PFR0_EL1_GIC | ID_AA64PFR0_EL1_AdvSIMD | + ID_AA64PFR0_EL1_FP)), + ID_WRITABLE(ID_AA64PFR1_EL1, + ~(ID_AA64PFR1_EL1_PFAR | ID_AA64PFR1_EL1_DF2 | + 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 | + ID_AA64PFR1_EL1_SME | ID_AA64PFR1_EL1_RES0 | + ID_AA64PFR1_EL1_MPAM_frac | ID_AA64PFR1_EL1_RAS_frac | + ID_AA64PFR1_EL1_MTE)), + ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR), + ID_UNALLOCATED(4, 3), + ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0), + ID_HIDDEN(ID_AA64SMFR0_EL1), + ID_UNALLOCATED(4, 6), + ID_WRITABLE(ID_AA64FPFR0_EL1, ~ID_AA64FPFR0_EL1_RES0), + + /* CRm=3D5 */ + /* + * Prior to FEAT_Debugv8.9, the architecture defines context-aware + * breakpoints (CTX_CMPs) as the highest numbered breakpoints (BRPs). + * KVM does not trap + emulate the breakpoint registers, and as such + * cannot support a layout that misaligns with the underlying hardware. + * While it may be possible to describe a subset that aligns with + * hardware, just prevent changes to BRPs and CTX_CMPs altogether for + * simplicity. + * + * See DDI0487K.a, section D2.8.3 Breakpoint types and linking + * of breakpoints for more details. + */ + ID_FILTERED(ID_AA64DFR0_EL1, id_aa64dfr0_el1, + ID_AA64DFR0_EL1_DoubleLock_MASK | + ID_AA64DFR0_EL1_WRPs_MASK | + ID_AA64DFR0_EL1_PMUVer_MASK | + ID_AA64DFR0_EL1_DebugVer_MASK), + ID_SANITISED(ID_AA64DFR1_EL1), + ID_UNALLOCATED(5, 2), + ID_UNALLOCATED(5, 3), + ID_HIDDEN(ID_AA64AFR0_EL1), + ID_HIDDEN(ID_AA64AFR1_EL1), + ID_UNALLOCATED(5, 6), + ID_UNALLOCATED(5, 7), + + /* CRm=3D6 */ + ID_WRITABLE(ID_AA64ISAR0_EL1, ~ID_AA64ISAR0_EL1_RES0), + ID_WRITABLE(ID_AA64ISAR1_EL1, + ~(ID_AA64ISAR1_EL1_GPI | ID_AA64ISAR1_EL1_GPA | + ID_AA64ISAR1_EL1_API | ID_AA64ISAR1_EL1_APA)), + ID_WRITABLE(ID_AA64ISAR2_EL1, + ~(ID_AA64ISAR2_EL1_RES0 | ID_AA64ISAR2_EL1_APA3 | + ID_AA64ISAR2_EL1_GPA3)), + ID_WRITABLE(ID_AA64ISAR3_EL1, + (ID_AA64ISAR3_EL1_FPRCVT | ID_AA64ISAR3_EL1_FAMINMAX)), + ID_UNALLOCATED(6, 4), + ID_UNALLOCATED(6, 5), + ID_UNALLOCATED(6, 6), + ID_UNALLOCATED(6, 7), + + /* CRm=3D7 */ + ID_FILTERED(ID_AA64MMFR0_EL1, id_aa64mmfr0_el1, + ~(ID_AA64MMFR0_EL1_RES0 | ID_AA64MMFR0_EL1_ASIDBITS)), + ID_WRITABLE(ID_AA64MMFR1_EL1, + ~(ID_AA64MMFR1_EL1_RES0 | ID_AA64MMFR1_EL1_HCX | + ID_AA64MMFR1_EL1_TWED | ID_AA64MMFR1_EL1_XNX | + ID_AA64MMFR1_EL1_VH | ID_AA64MMFR1_EL1_VMIDBits)), + ID_WRITABLE(ID_AA64MMFR2_EL1, + ~(ID_AA64MMFR2_EL1_RES0 | ID_AA64MMFR2_EL1_EVT | + ID_AA64MMFR2_EL1_FWB | ID_AA64MMFR2_EL1_IDS | + ID_AA64MMFR2_EL1_NV | ID_AA64MMFR2_EL1_CCIDX)), + ID_WRITABLE(ID_AA64MMFR3_EL1, + (ID_AA64MMFR3_EL1_TCRX | ID_AA64MMFR3_EL1_S1PIE | + ID_AA64MMFR3_EL1_S1POE)), + ID_WRITABLE(ID_AA64MMFR4_EL1, ID_AA64MMFR4_EL1_NV_frac), + ID_UNALLOCATED(7, 5), + ID_UNALLOCATED(7, 6), + ID_UNALLOCATED(7, 7), + + /* CRn =3D 1 */ + { SYS_DESC(SYS_SCTLR_EL1), NULL, reset_val, SCTLR_EL1, 0x00C50078 }, + { SYS_DESC(SYS_CPACR_EL1), NULL, reset_val, CPACR_EL1, 0 }, + + /* CRn =3D 2 */ + { SYS_DESC(SYS_TTBR0_EL1), access_rw, reset_val, TTBR0_EL1, 0 }, + { SYS_DESC(SYS_TTBR1_EL1), access_rw, reset_val, TTBR1_EL1, 0 }, + { SYS_DESC(SYS_TCR_EL1), access_rw, reset_val, TCR_EL1, 0 }, + + { SYS_DESC(SYS_PMMIR_EL1), trap_raz_wi }, + /* CRn =3D 10 */ + { SYS_DESC(SYS_MAIR_EL1), NULL, reset_unknown, MAIR_EL1 }, + + /* CRn =3D 12 */ + { SYS_DESC(SYS_VBAR_EL1), access_rw, reset_val, VBAR_EL1, 0 }, + + /* CRn =3D 13 */ + { SYS_DESC(SYS_TPIDR_EL1), NULL, reset_unknown, TPIDR_EL1 }, + + /* Op1 =3D 1 */ + /* CRn =3D 0 */ + /* CRm =3D 0 */ + { SYS_DESC(SYS_CCSIDR_EL1), access_ccsidr }, + { SYS_DESC(SYS_CLIDR_EL1), access_clidr, reset_clidr, CLIDR_EL1, + ~CLIDR_EL1_RES0, .set_user =3D set_clidr }, + IMPLEMENTATION_ID(AIDR_EL1, GENMASK_ULL(63, 0)), + { SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 }, + ID_FILTERED(CTR_EL0, ctr_el0, + CTR_EL0_DIC_MASK | CTR_EL0_IDC_MASK | + CTR_EL0_DminLine_MASK | CTR_EL0_L1Ip_MASK | + CTR_EL0_IminLine_MASK), + + { SYS_DESC(SYS_CNTFRQ_EL0), NULL, reset_val, CNTFRQ_EL0, 0x3B9ACA00 }, + { SYS_DESC(SYS_CNTVCT_EL0), .get_user =3D arch_timer_get_user, + .set_user =3D arch_timer_set_user }, + TIMER_REG(CNTP_CTL_EL0), + TIMER_REG(CNTP_CVAL_EL0), + TIMER_REG(CNTV_CTL_EL0), + TIMER_REG(CNTV_CVAL_EL0), + +}; + +/* + * kvm_handle_sys_reg -- handles a system instruction or mrs/msr instructi= on + * trap on a guest execution + * @vcpu: The VCPU pointer + */ +int kvm_handle_sys_reg(struct kvm_vcpu *vcpu) +{ + const struct sys_reg_desc *desc =3D NULL; + struct sys_reg_params params; + unsigned long esr =3D kvm_vcpu_get_esr(vcpu); + int Rt =3D kvm_vcpu_sys_get_rt(vcpu); + + trace_kvm_handle_sys_reg(esr); + + params =3D esr_sys64_to_params(esr); + params.regval =3D vcpu_get_reg(vcpu, Rt); + + /* System registers have Op0=3D=3D{2,3}, as per DDI487 J.a C5.1.2 */ + if (params.Op0 =3D=3D 2 || params.Op0 =3D=3D 3) + desc =3D find_reg(¶ms, sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); + else + WARN(true, "system instruction handling not supported"); + + if (!desc) { + if (!(params.Op0 =3D=3D 3 && (params.CRn & 0b1011) =3D=3D 0b1011)) + print_sys_reg_msg(¶ms, + "Unsupported guest access at: %lx\n", + *vcpu_pc(vcpu)); + kvm_inject_undefined(vcpu); + return 1; + } else { + perform_access(vcpu, ¶ms, desc); + } + + /* Read from system register? */ + if (!params.is_write && + (params.Op0 =3D=3D 2 || params.Op0 =3D=3D 3)) + vcpu_set_reg(vcpu, Rt, params.regval); + + return 1; +} + +void kvm_reset_sys_regs(struct kvm_vcpu *vcpu) +{ + struct kvm *kvm =3D vcpu->kvm; + unsigned long i; + + for (i =3D 0; i < ARRAY_SIZE(sys_reg_descs); i++) { + const struct sys_reg_desc *r =3D &sys_reg_descs[i]; + + if (!r->reset) + continue; + + if (is_vm_ftr_id_reg(reg_to_encoding(r))) { + reset_vm_ftr_id_reg(vcpu, r); + /* + * Even VM only regs are stored in the save area of the vcpu + * and need a meaningful initial value. Call reset because of this. + */ + r->reset(vcpu, r); + } else if (is_vcpu_ftr_id_reg(reg_to_encoding(r))) { + reset_vcpu_ftr_id_reg(vcpu, r); + } else { + r->reset(vcpu, r); + } + } + set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags); +} + +int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, + const struct kvm_one_reg *reg) +{ + return __kvm_arm_sys_reg_get_reg(vcpu, reg, ARRAY_SIZE(sys_reg_descs), + sys_reg_descs); +} + +int __init kvm_sys_reg_table_init(void) +{ + init_imp_id_regs(); + + bool valid =3D check_sysreg_table(sys_reg_descs, + ARRAY_SIZE(sys_reg_descs), false); + + if (!valid) + return -EINVAL; + + return 0; +} + +unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu) +{ + return __kvm_arm_num_sys_reg_descs(vcpu, ARRAY_SIZE(sys_reg_descs), + sys_reg_descs); +} + +int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindic= es) +{ + return __kvm_arm_copy_sys_reg_indices(vcpu, uindices,=20 + ARRAY_SIZE(sys_reg_descs), + sys_reg_descs); +} + +int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, + const struct kvm_one_reg *reg) +{ + return __kvm_arm_sys_reg_set_reg(vcpu, reg, ARRAY_SIZE(sys_reg_descs), + sys_reg_descs); +} + +/* + * Perform last adjustments to the ID registers that are implied by the + * configuration outside of the ID regs themselves, as well as any + * initialisation that directly depend on these ID registers (such as + * RES0/RES1 behaviours). This is not the place to configure traps though. + * + * Because this can be called once per CPU, changes must be idempotent. + */ +int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu) +{ + /* TODO GIC finalization */ + return 0; +} diff --git a/arch/s390/kvm/arm64/trace.h b/arch/s390/kvm/arm64/trace.h new file mode 100644 index 000000000000..015f380207ab --- /dev/null +++ b/arch/s390/kvm/arm64/trace.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#if !defined(_TRACE_ARM64_KVM_S390_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_ARM64_KVM_S390_H + +#include + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kvm + +TRACE_EVENT(kvm_handle_sys_reg, + TP_PROTO(unsigned long esr), + TP_ARGS(esr), + + TP_STRUCT__entry( + __field(unsigned long, esr) + ), + + TP_fast_assign( + __entry->esr =3D esr; + ), + + TP_printk("ESR 0x%08lx", __entry->esr) +); + +#endif /* _TRACE_ARM64_KVM_S390_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ../../arch/s390/kvm/arm64 +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace + +/* This part must be outside protection */ +#include diff --git a/virt/kvm/arm64/Makefile.kvm b/virt/kvm/arm64/Makefile.kvm index c5e1db570a09..9a3df2446b8b 100644 --- a/virt/kvm/arm64/Makefile.kvm +++ b/virt/kvm/arm64/Makefile.kvm @@ -10,4 +10,5 @@ shared-arm64-obj :=3D \ $(KVM_ARM64)/handle_exit.o \ $(KVM_ARM64)/mmio.o \ $(KVM_ARM64)/reset.o \ + $(KVM_ARM64)/sys_regs.o \ =20 --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (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 8021942EED7; Fri, 29 May 2026 15:56:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070218; cv=none; b=fTh1hxANzJKj94aCRjwB4rzd/T3qk+elUR0ukCbRaOXKOKsCCffkKI+BEjZPfwys7AwhTevY5ln7l68pWIOQQI6pyVMLnZC6Sabb4NMbdm78TIG9OXux6oBJxIYZu9IEe4BLC1B0jxVhrtNaaZknL73RGpqIV0SJDfYpXa8PSAw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070218; c=relaxed/simple; bh=0m8cxs8YoSeIpo3ErhzD67MbuJNGxraHXhAfroFyrUw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jx/90HgJ4aV15w8kOVgkxrJoBU9vxP4tqUDtolgD6xhBjdolMGoSYDM2UVIuCjgig2hZnRNiLbLd13KwRbEl70Lv2XCOKHinHEsES88Vnlhalhg2Pf3GHXud6gecAfCyGwXME/iLFuc/gR7yI06Y+q8PAVnVKEzz2krpEa2/+M4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=Xh/CPvls; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="Xh/CPvls" Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TFFto82776289; Fri, 29 May 2026 15:56:21 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=anDf/gvctOkuN5DgG yLL9jz1QpXwOjJXmrZUSy7fjno=; b=Xh/CPvlskTKCAz1CkS2LF+s9SXXJLj899 /wHz8nW3EGGBed3v2/lgm5rK33SWi4PPlzE3T8CqU+hLnb84ZIl2/n3l+2kmZ+bg djCcBYMSWai72mhROGi7Hcs+IrsAegggiW+tqH8b+jI5rhkjXtIEcEwrWrbUpRis qYJQcNuIu5dZVprbDBE+mbOROmOl6nUNirXOYzHVEtoL0qX5q4EyiOYICEkfNoMd dI7ENqqKS3KZeFQQXN5/SkDnGlyJrvO1xMbOs8TOsYtZWEO5GJUt60wg9EeWpSsg IsRoS2NjQlqp78udeadGwEWy7Nh7XA/zMgSV3YDgkBjgqENDeoMZw== Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee889m2f1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:21 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs8EA027824; Fri, 29 May 2026 15:56:20 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4edjrc8jq6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:20 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFuCIT49349002 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:12 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EA1C020040; Fri, 29 May 2026 15:56:11 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 93FC620043; Fri, 29 May 2026 15:56:11 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:11 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 25/26] KVM: s390: arm64: Implement exception injection Date: Fri, 29 May 2026 17:55:58 +0200 Message-ID: <20260529155601.2927240-26-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: mkBwToMnPdxn7Agaz6M9EECNczw32dy4 X-Proofpoint-GUID: mkBwToMnPdxn7Agaz6M9EECNczw32dy4 X-Authority-Analysis: v=2.4 cv=XqfK/1F9 c=1 sm=1 tr=0 ts=6a19b725 cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=Ga-kB53fOd7CXy6K7RwA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfX+SnYZ3wGhZDo 1pMmghK3pGWmPQdM8X7EQJx2k3c9hkkgARPOB21fYK3KXmntr+/HT7iUwAf5kDr6tX6v+vb9SxI 1rvGF3IGU76oEdSrvcwSUij9YxrELfBY5dKluXMN/LX6uyxPTK4Z9TCuHDWTpIp5hkGQsHB3LDG VqbP8He9wXCUbSyMOQuADSHWQC0mBBjrCYeqT0Wa5AXs0Rcu/uH+PtqAmefuqqRPVTBi3Syguqu DDeKV+wYWPUoqXiJ7C47G/DRyGubZZY2GZJRDWLJpONYZ8aGxmdZyXo5K6xjNs+eOsEzqd/VWAu 3+Y224gcnfxKpoNBMkcH6wyU82NfNBGTz4gSW2OfoB6KU7tA87pMfTYiYTkMtsY9mi7u2X9b0nD 20cbqpqd+bY93FeGOubs6Ma52X1glkr27rh2RREo4wvTJndDeHah7bQve/7RAO9mrH+hnAL7u+f 45DEORUxoFFY6kAryfw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 impostorscore=0 adultscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 bulkscore=0 suspectscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Add exception injection support for s390 KVM arm64 architecture. This implements the core exception entry mechanism and fault injection functions needed for proper guest exception handling. Co-developed-by: Andreas Grapentin Signed-off-by: Andreas Grapentin Signed-off-by: Steffen Eiden --- arch/s390/include/asm/kvm_host_arm64.h | 2 + arch/s390/kvm/arm64/Makefile | 1 + arch/s390/kvm/arm64/arm.c | 15 +--- arch/s390/kvm/arm64/exception.c | 105 +++++++++++++++++++++++++ arch/s390/kvm/arm64/inject_fault.c | 72 ++++++++++++++++- 5 files changed, 182 insertions(+), 13 deletions(-) create mode 100644 arch/s390/kvm/arm64/exception.c diff --git a/arch/s390/include/asm/kvm_host_arm64.h b/arch/s390/include/asm= /kvm_host_arm64.h index cc457d69621c..34d131b36e70 100644 --- a/arch/s390/include/asm/kvm_host_arm64.h +++ b/arch/s390/include/asm/kvm_host_arm64.h @@ -373,4 +373,6 @@ static inline u64 kvm_sanitised_host_ftr_reg(u32 id) return kvm_arm_host_sys_reg_by_id(id); } =20 +void kvm_adjust_pc(struct kvm_vcpu *vcpu); + #endif /* ASM_KVM_HOST_ARM64_H */ diff --git a/arch/s390/kvm/arm64/Makefile b/arch/s390/kvm/arm64/Makefile index bec24b60a071..9d6b7d5bf588 100644 --- a/arch/s390/kvm/arm64/Makefile +++ b/arch/s390/kvm/arm64/Makefile @@ -9,6 +9,7 @@ ccflags-y +=3D -I $(src) -I$(srctree)/arch/s390/kvm/gmap -D= KVM_S390_ARM64 =20 kvm-arm64-obj :=3D \ arm.o \ + exception.o \ feature.o \ guest.o \ handle_exit.o \ diff --git a/arch/s390/kvm/arm64/arm.c b/arch/s390/kvm/arm64/arm.c index 88b66552cff0..c62e50002628 100644 --- a/arch/s390/kvm/arm64/arm.c +++ b/arch/s390/kvm/arm64/arm.c @@ -350,19 +350,11 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm= _irq_level *irq_level, return 0; } =20 -static void adjust_pc(struct kvm_vcpu *vcpu) -{ - if (vcpu_get_flag(vcpu, INCREMENT_PC)) { - kvm_skip_instr(vcpu); - vcpu_clear_flag(vcpu, INCREMENT_PC); - } -} - static void arm_vcpu_run(struct kvm_vcpu *vcpu) { struct kvm_sae_block *sae_block =3D &vcpu->arch.sae_block; =20 - adjust_pc(vcpu); + kvm_adjust_pc(vcpu); =20 local_irq_disable(); guest_enter_irqoff(); @@ -457,8 +449,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) =20 kvm_sigset_deactivate(vcpu); out: - if (unlikely(vcpu_get_flag(vcpu, INCREMENT_PC))) - adjust_pc(vcpu); + if (unlikely(vcpu_get_flag(vcpu, PENDING_EXCEPTION) || + vcpu_get_flag(vcpu, INCREMENT_PC))) + kvm_adjust_pc(vcpu); =20 save_vx_regs(vcpu->arch.ctxt.vregs); kernel_fpu_end(&fpu_save, KERNEL_FPC | KERNEL_VXR); diff --git a/arch/s390/kvm/arm64/exception.c b/arch/s390/kvm/arm64/exceptio= n.c new file mode 100644 index 000000000000..871e4e2c710a --- /dev/null +++ b/arch/s390/kvm/arm64/exception.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include + +#include + +/* + * 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. + * The EL passed to this function *must* be a non-secure, privileged mode = with + * bit 0 being set (PSTATE.SP =3D=3D 1). + * + * When an exception is taken, most PSTATE fields are left unchanged in the + * handler. However, some are explicitly overridden (e.g. M[4:0]). Luckily= all + * of the inherited bits have the same position in the AArch64/AArch32 SPS= R_ELx + * layouts, so we don't need to shuffle these for exceptions from AArch32 = EL0. + * + * For the SPSR_ELx layout for AArch64, see ARM DDI 0487E.a page C5-429. + * For the SPSR_ELx layout for AArch32, see ARM DDI 0487E.a page C5-426. + * + * Here we manipulate the fields in order of the AArch64 SPSR_ELx layout, = from + * MSB to LSB. + */ +static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_= mode, + enum exception_type type) +{ + unsigned long sctlr, vbar, old_pstate, new, mode; + u64 exc_offset; + + old_pstate =3D *vcpu_cpsr(vcpu); + mode =3D old_pstate & (PSR_MODE_MASK | PSR_MODE32_BIT); + + if (mode =3D=3D target_mode) + exc_offset =3D CURRENT_EL_SP_ELx_VECTOR; + else if ((mode | PSR_MODE_THREAD_BIT) =3D=3D target_mode) + exc_offset =3D CURRENT_EL_SP_EL0_VECTOR; + else if (!(mode & PSR_MODE32_BIT)) + exc_offset =3D LOWER_EL_AArch64_VECTOR; + else + exc_offset =3D LOWER_EL_AArch32_VECTOR; + + switch (target_mode) { + case PSR_MODE_EL1h: + vbar =3D vcpu_read_sys_reg(vcpu, VBAR_EL1); + sctlr =3D vcpu_read_sys_reg(vcpu, SCTLR_EL1); + vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL1); + vcpu_write_sys_reg(vcpu, old_pstate, SPSR_EL1); + break; + default: + panic("Unknown PSR Mode: 0x%lx.", target_mode); + } + + *vcpu_pc(vcpu) =3D vbar + exc_offset + type; + + new =3D 0; + + new |=3D (old_pstate & PSR_N_BIT); + new |=3D (old_pstate & PSR_Z_BIT); + new |=3D (old_pstate & PSR_C_BIT); + new |=3D (old_pstate & PSR_V_BIT); + new |=3D (old_pstate & PSR_DIT_BIT); + new |=3D (old_pstate & PSR_PAN_BIT); + + if (!(sctlr & SCTLR_EL1_SPAN)) + new |=3D PSR_PAN_BIT; + + if (sctlr & SCTLR_ELx_DSSBS) + new |=3D PSR_SSBS_BIT; + + new |=3D PSR_D_BIT; + new |=3D PSR_A_BIT; + new |=3D PSR_I_BIT; + new |=3D PSR_F_BIT; + + new |=3D target_mode; + + *vcpu_cpsr(vcpu) =3D new; +} + +static void kvm_inject_exception(struct kvm_vcpu *vcpu) +{ + switch (vcpu_get_flag(vcpu, EXCEPT_MASK)) { + case unpack_vcpu_flag(EXCEPT_AA64_EL1_SYNC): + enter_exception64(vcpu, PSR_MODE_EL1h, except_type_sync); + break; + } +} + +/* + * Adjust the guest PC (and potentially exception state) depending on + * flags provided by the emulation code. + */ +void kvm_adjust_pc(struct kvm_vcpu *vcpu) +{ + if (vcpu_get_flag(vcpu, PENDING_EXCEPTION)) { + kvm_inject_exception(vcpu); + vcpu_clear_flag(vcpu, PENDING_EXCEPTION); + vcpu_clear_flag(vcpu, EXCEPT_MASK); + } else if (vcpu_get_flag(vcpu, INCREMENT_PC)) { + kvm_skip_instr(vcpu); + vcpu_clear_flag(vcpu, INCREMENT_PC); + } +} diff --git a/arch/s390/kvm/arm64/inject_fault.c b/arch/s390/kvm/arm64/injec= t_fault.c index 650c041efde2..0216ffbd62ab 100644 --- a/arch/s390/kvm/arm64/inject_fault.c +++ b/arch/s390/kvm/arm64/inject_fault.c @@ -2,6 +2,42 @@ =20 #include =20 +#define exception_esr_elx(__vcpu) ESR_EL1 +#define exception_far_elx(__vcpu) FAR_EL1 + +static void pend_sync_exception(struct kvm_vcpu *vcpu) +{ + kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC); +} + +static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned lon= g addr) +{ + unsigned long cpsr =3D *vcpu_cpsr(vcpu); + bool is_aarch32 =3D vcpu_mode_is_32bit(vcpu); + u64 esr =3D 0; + + if (kvm_vcpu_abt_iss1tw(vcpu)) + esr |=3D ESR_ELx_FSC_SEA_TTW(kvm_vcpu_abt_gltl(vcpu)); + else + esr |=3D ESR_ELx_FSC_EXTABT; + + pend_sync_exception(vcpu); + + if (kvm_vcpu_trap_il_is32bit(vcpu)) + esr |=3D ESR_ELx_IL; + + if (is_aarch32 || (cpsr & PSR_MODE_MASK) =3D=3D PSR_MODE_EL0t) + esr |=3D (ESR_ELx_EC_IABT_LOW << ESR_ELx_EC_SHIFT); + else + esr |=3D (ESR_ELx_EC_IABT_CUR << ESR_ELx_EC_SHIFT); + + if (!is_iabt) + esr |=3D ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT; + + vcpu_write_sys_reg(vcpu, addr, ESR_EL1); + vcpu_write_sys_reg(vcpu, esr, FAR_EL1); +} + /** * kvm_inject_undefined - inject an undefined instruction into the guest * @vcpu: The vCPU in which to inject the exception @@ -11,11 +47,43 @@ */ void kvm_inject_undefined(struct kvm_vcpu *vcpu) { - /* Stub until s390 supports arm64 sysregs TODO sysregs*/ + u64 esr =3D (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT); + + pend_sync_exception(vcpu); + + /* + * Build an unknown exception, depending on the instruction + * set. + */ + if (kvm_vcpu_trap_il_is32bit(vcpu)) + esr |=3D ESR_ELx_IL; + + vcpu_write_sys_reg(vcpu, esr, exception_esr_elx(vcpu)); +} + +static void __kvm_inject_sea(struct kvm_vcpu *vcpu, bool iabt, u64 addr) +{ + inject_abt64(vcpu, iabt, addr); } =20 int kvm_inject_sea(struct kvm_vcpu *vcpu, bool iabt, u64 addr) { - /* Stub until s390 supports arm64 sysregs TODO sysregs*/ + lockdep_assert_held(&vcpu->mutex); + + __kvm_inject_sea(vcpu, iabt, addr); return 1; } + +void kvm_inject_size_fault(struct kvm_vcpu *vcpu) +{ + unsigned long addr, esr; + + addr =3D kvm_vcpu_get_fault_ipa(vcpu); + addr |=3D FAR_TO_FIPA_OFFSET(kvm_vcpu_get_hfar(vcpu)); + + __kvm_inject_sea(vcpu, kvm_vcpu_trap_is_iabt(vcpu), addr); + + esr =3D vcpu_read_sys_reg(vcpu, exception_esr_elx(vcpu)); + esr &=3D ~GENMASK_ULL(5, 0); + vcpu_write_sys_reg(vcpu, esr, exception_esr_elx(vcpu)); +} --=20 2.53.0 From nobody Mon Jun 8 10:56:39 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (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 A6814403E8C; Fri, 29 May 2026 15:56:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070204; cv=none; b=REhrACZnU9ZR4wYmCXWq/UiQ9aGWhpKZLXp//S0i6k1C0+cLBT5VzCD8ZR8Ip75OjVdRkzzUQvpAGa+f+J4tyiEFCObCk1h2NRT+O4UGaMMRrdZOUoZaw1D7jhPEMkxy11kGHOsMfjCmRlEXQeFL7SIXDKsP50FLL5XN3oaeqNs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780070204; c=relaxed/simple; bh=2T0IcOBvlQduoOdEXyL/k5QW4zteu4afOmlAgQcmdMA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BFUt0dVpURDqzATP0DDwokdQa5RKjnJckC6fdCHPUp1ywrSCji4TqyG/kwAYiO72i0Cd4yn0al+wG2QwN2N0Tbm+AOIIljDRTfrSdbpUvmMF3XBN5Vbqv/LEZN23OEmLOwKgoenvoaV7Vhe1vpI1hM8b8UUp/ZGno3cufAw4WkE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=VrIdGcOw; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="VrIdGcOw" Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64TF4tJ11467789; Fri, 29 May 2026 15:56:19 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=65ZPjGgfujvTG2FNZ towcxEFcacc9WDSb9CSpbn8UaE=; b=VrIdGcOw2TW//fI640IuF96wP4YN7VLPU 9ljjCj5/SUMds5oxleVfMRfIr0nwC49/syiF4xtubaH3k9gpfRx7SjgkNg3c6Hiv ErM0vIk+D2feXYFATvvFZ+wYjKG6lT7emiuycU1uBQANhRM/dQqjGOAAwaFXAAjK 1ClQoEq08GG4UwxWRm8brebvLikkrC8Uab5xfbVZIRrNQ194fu+GU8nsvhgMq9GP LS751ORizJ3CmSK7RvAIC6ulWZ4OMCQNHaoNE/VgwA+oGnGHbwvrwVIdk1RZejzT NtnfOkp9FW/SeB1AwNnHM6LkBZKvkroGLHhvWje97dcpstHvIASpQ== Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4ee886mgjy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:19 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 64TFs7ar009677; Fri, 29 May 2026 15:56:18 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4edjrbgkwq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 May 2026 15:56:18 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 64TFuCP549349006 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 May 2026 15:56:12 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5051720040; Fri, 29 May 2026 15:56:12 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 023C12004B; Fri, 29 May 2026 15:56:12 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.87.85.9]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 29 May 2026 15:56:11 +0000 (GMT) From: Steffen Eiden To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org Cc: Alexander Gordeev , Andreas Grapentin , Arnd Bergmann , Catalin Marinas , Christian Borntraeger , Claudio Imbrenda , David Hildenbrand , Friedrich Welter , Gautam Gala , Hariharan Mari , Heiko Carstens , Hendrik Brueckner , Ilya Leoshkevich , Janosch Frank , Joey Gouly , Marc Zyngier , Nico Boehr , Nina Schoetterl-Glausch , Oliver Upton , Paolo Bonzini , Suzuki K Poulose , Sven Schnelle , Ulrich Weigand , Vasily Gorbik , Will Deacon , Zenghui Yu Subject: [PATCH v1 26/26] KVM: s390: arm64: Finalize page fault handling Date: Fri, 29 May 2026 17:55:59 +0200 Message-ID: <20260529155601.2927240-27-seiden@linux.ibm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260529155601.2927240-1-seiden@linux.ibm.com> References: <20260529155601.2927240-1-seiden@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: qdGqNpQsC3UYpGpvAk8HeorvrvLc47VH X-Authority-Analysis: v=2.4 cv=Z8Dc2nRA c=1 sm=1 tr=0 ts=6a19b723 cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=NGcC8JguVDcA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=LtHRyupC2uTP9dkk8LUA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTI5MDE1NiBTYWx0ZWRfXx3wbluWa3lB6 rnxFykGocU5+j9Wla02dXZFABY6qgxxpQtelKlJIA1zq/r+5dkk33gFCssPqPaqmn6mm5uIOquu y0yEznA2FwBjT2S35mf5TMExYrEMLlCezCINd8Tk+DMPK9YhVI6SFCMDMt6aBDu3bPg3OinGneK CBNSR9iTAWCWJFm3VhGwd+tj7YiycPZqoLsTzhIdtPJUPJKRlNKasI5EQsHFWRKrrmDXC6dGUch 2Jqd7BTS0acQYinl2K27BMjQy77m7IOPvqooH4hxyFFi6BhPhmozLFO0ud7+zjIAJySreoBCNmi ApGgsg1hZpBDsRwIsnTUDdzESnFIwwkEy87uUZ9mP0zp26ol8XhBhQD7PvR7NKl5ffIY2ijXsxm xR7VvXmZHugNWOg66kXF5E1ep50oIl55lKHzaNn4wKE6W0UgQpiGQ6bzse6V5T/QIxel2nRDfRL 3HK55T8PQmmdeKORCVQ== X-Proofpoint-ORIG-GUID: qdGqNpQsC3UYpGpvAk8HeorvrvLc47VH X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-05-29_04,2026-05-28_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 bulkscore=0 impostorscore=0 priorityscore=1501 malwarescore=0 phishscore=0 suspectscore=0 adultscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605210000 definitions=main-2605290156 Content-Type: text/plain; charset="utf-8" Complete the page fault handling implementation by replacing temporary error returns with proper ARM64 exception injection. Signed-off-by: Steffen Eiden --- arch/s390/kvm/arm64/mmu.c | 62 ++++++++++++++++++++++----------- include/kvm/arm64/kvm_feature.h | 3 ++ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/arch/s390/kvm/arm64/mmu.c b/arch/s390/kvm/arm64/mmu.c index 8759cbafbaff..4224503276fb 100644 --- a/arch/s390/kvm/arm64/mmu.c +++ b/arch/s390/kvm/arm64/mmu.c @@ -31,12 +31,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, gpa_t = fault_ipa, ret =3D kvm_s390_faultin_gfn(vcpu, NULL, &f); if (ret <=3D 0) return ret; - if (ret =3D=3D PGM_ADDRESSING) + if (ret =3D=3D PGM_ADDRESSING) { /* - * Without the relevant sysregs we cannot do anything for now. - * Go back to userspace with an error. TODO sysreg handling + * There is no page with the requested address. Inject size fault + * which is the closest arm match to PGM-addressing */ - return -ENOEXEC; + kvm_inject_size_fault(vcpu); + return 1; + } KVM_BUG_ON(ret, vcpu->kvm); return -EINVAL; } @@ -69,6 +71,27 @@ static int kvm_handle_pic(struct kvm_vcpu *vcpu, bool *t= ranslation) return 0; } =20 +static u32 kvm_get_pa_bits(struct kvm *kvm) +{ + u32 id_parange =3D get_idreg_field_enum(kvm, ID_AA64MMFR0_EL1, PARANGE); + + switch (id_parange) { + case ID_AA64MMFR0_EL1_PARANGE_32: return 32; + case ID_AA64MMFR0_EL1_PARANGE_36: return 36; + case ID_AA64MMFR0_EL1_PARANGE_40: return 40; + case ID_AA64MMFR0_EL1_PARANGE_42: return 42; + case ID_AA64MMFR0_EL1_PARANGE_44: return 44; + case ID_AA64MMFR0_EL1_PARANGE_48: return 48; + case ID_AA64MMFR0_EL1_PARANGE_52: return 52; + case ID_AA64MMFR0_EL1_PARANGE_56: return 56; + } + /* + * Future values must be higher than we know already. + * See ARM DDI 0487C.a. Return a safe limit. + */ + return ID_AA64MMFR0_EL1_PARANGE_48; +} + int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) { struct kvm_memory_slot *memslot; @@ -98,16 +121,17 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) } =20 if (translation) { - /* - * For both cases: - * Without the relevant sysregs we cannot do anything for now. - * Go back to userspace with an error. TODO sysreg handling - */ - if (fault_ipa >=3D BIT_ULL(get_kvm_ipa_limit())) - return -ENOEXEC; + /* Beyond sanitised PA range (which is the IPA limit) */ + if (fault_ipa >=3D BIT_ULL(kvm_get_pa_bits(vcpu->kvm))) { + kvm_inject_size_fault(vcpu); + return 1; + } =20 - if (fault_ipa >=3D kvm_phys_size(vcpu->kvm)) - return -ENOEXEC; + /* Falls between the IPA range and the PA range? */ + if (fault_ipa >=3D kvm_phys_size(vcpu->kvm)) { + fault_ipa |=3D kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0); + return kvm_inject_sea(vcpu, is_iabt, fault_ipa); + } } =20 idx =3D srcu_read_lock(&vcpu->kvm->srcu); @@ -123,18 +147,14 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) * The guest has put either its instructions or its page-tables * somewhere it shouldn't have. Userspace won't be able to do * anything about this (there's no syndrome for a start). - * - * Without the relevant sysregs we cannot do anything for now. - * Go back to userspace with an error. TODO sysreg handling */ - if (is_iabt) + if (is_iabt) { + ret =3D kvm_inject_sea_iabt(vcpu, kvm_vcpu_get_hfar(vcpu)); goto out_unlock; + } =20 if (kvm_vcpu_abt_iss1tw(vcpu)) { - /* - * Without the relevant sysregs we cannot do anything for now. - * Go back to userspace with an error. TODO sysreg handling - */ + ret =3D kvm_inject_sea_dabt(vcpu, kvm_vcpu_get_hfar(vcpu)); goto out_unlock; } =20 diff --git a/include/kvm/arm64/kvm_feature.h b/include/kvm/arm64/kvm_featur= e.h index 945abbbf1aa8..193c9ca7045f 100644 --- a/include/kvm/arm64/kvm_feature.h +++ b/include/kvm/arm64/kvm_feature.h @@ -47,6 +47,9 @@ =20 #define kvm_has_feat_enum(kvm, ...) __kvm_has_feat_enum(kvm, __VA_ARGS__) =20 +#define get_idreg_field_enum(kvm, id, fld) \ + SYS_FIELD_GET(id, fld, kvm_read_vm_id_reg((kvm), SYS_##id)) + /* Check for a given level of PAuth support */ #define kvm_has_pauth(k, l) \ ({ \ --=20 2.53.0