From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A31E4C4828D for ; Mon, 5 Feb 2024 17:27:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Subject:Cc:To: From:Date:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=1aXSAlFcT2smz2t0dAI50UZZrJpAsUPlAeYwBvges84=; b=v1dxF9J3YvtcjU Z7o0eiGv+JvopxT3gCGXNnZK37p57/92j2BGjZBEWgY79W7feqaYHoKxfgKtOV4eAparEI+rM04tF XH3EVTu120mIhKwsdIqd5W48RFgLAqdYEo4pqFR0C51b85s+g3vAbsESbeMn9PQkAupUfRe3h8JLl sKyKMh+KRmVmFxwtZX4zGhsECSfVFwdqgB1Qe7oixyAYauVUkrnRgK0Gkf0TTbXA/HwXAshTUNKq8 +O6WQxAPr/cUa3VMONQdv9K1SMIuKoyK4OOBIoFzq4al3BDpXwUM74CiN9nw//o0k2uXdM2DP41uX MqJO4sj+mxpXQKECE97Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rX2kk-0000000498o-2Wmu; Mon, 05 Feb 2024 17:27:30 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rX2kg-0000000496G-238Y for linux-arm-kernel@lists.infradead.org; Mon, 05 Feb 2024 17:27:29 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BC626DA7; Mon, 5 Feb 2024 09:28:06 -0800 (PST) Received: from e133380.arm.com (e133380.arm.com [10.1.197.58]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 0AA613F5A1; Mon, 5 Feb 2024 09:27:22 -0800 (PST) Date: Mon, 5 Feb 2024 17:27:20 +0000 From: Dave Martin To: linux-arm-kernel@lists.infradead.org Cc: Mark Brown , Will Deacon , Catalin Marinas , Oleg Nesterov , Al Viro , linux-kernel@vger.kernel.org, Doug Anderson Subject: [RFC PATCH] arm64/sve,sme: Refine scalable regset sizes at boot Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240205_092726_736386_7149B148 X-CRM114-Status: GOOD ( 19.23 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Since [1] and [2], the ptrace core has used the static values in struct user_regset to preallocate memory when reading a regset. This results in allocating excessive memory for SVE and related regsets which are not a fixed size, since the theoretical max size of those regsets was deliberately made huge in case of future expansion. In practice, the regsets can be smaller -- usually _much_ smaller. Since the max possible size of these regsets depends on how big the CPUs' registers actually are, clamp the affected regset sizes once the kernel has probed all boot-time CPUs. This doesn't make memory allocation failures impossible on the affected paths, but at least avoids stupidly large allocations. [1]: commit b4e9c9549f62 ("introduction of regset ->get() wrappers, switching ELF coredumps to those") [2]: commit 7717cb9bdd04 ("regset: new method and helpers for it") Reported-by: Douglas Anderson Link: https://lore.kernel.org/lkml/20240201171159.1.Id9ad163b60d21c9e56c2d686b0cc9083a8ba7924@changeid/ Signed-off-by: Dave Martin --- Only build-tested for now. If a short-term fix is needed, Mark Brown's patch [3] looks like the lower-risk option, but there seems to be outstanding discussion about whether this change will actually fix the issue reported above or just make it less likely to fire. See the Link above. This patch duplicates logic between the compiled-in regset->n values and those computed after boot. It might be better to compile in junk values, since they should never get used anyway... [3] https://lore.kernel.org/all/20240203-arm64-sve-ptrace-regset-size-v1-1-2c3ba1386b9e@kernel.org/ arch/arm64/include/asm/ptrace.h | 12 ++++++++++++ arch/arm64/kernel/fpsimd.c | 3 +++ arch/arm64/kernel/ptrace.c | 22 +++++++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 47ec58031f11..609b963a05e0 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -389,5 +389,17 @@ static inline void procedure_link_pointer_set(struct pt_regs *regs, extern unsigned long profile_pc(struct pt_regs *regs); +#ifdef CONFIG_ARM64_SVE +void __init arch_ptrace_sve_init(unsigned int vq_max); +#else +static inline void __init arch_ptrace_sve_init(unsigned int vq_max) { } +#endif + +#ifdef CONFIG_ARM64_SME +void __init arch_ptrace_sme_init(unsigned int vq_max); +#else +static inline void __init arch_ptrace_sme_init(unsigned int vq_max) { } +#endif + #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index a5dc6f764195..5c2f91f84c31 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -1189,6 +1189,7 @@ void __init sve_setup(void) pr_warn("%s: unvirtualisable vector lengths present\n", info->name); + arch_ptrace_sve_init(sve_vq_from_vl(info->max_vl)); sve_efi_setup(); } @@ -1309,6 +1310,8 @@ void __init sme_setup(void) info->max_vl); pr_info("SME: default vector length %u bytes per vector\n", get_sme_default_vl()); + + arch_ptrace_sme_init(sve_vq_from_vl(info->max_vl)); } #endif /* CONFIG_ARM64_SME */ diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index dc6cf0e37194..466a0eb93123 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -1441,7 +1442,7 @@ enum aarch64_regset { #endif }; -static const struct user_regset aarch64_regsets[] = { +static struct user_regset aarch64_regsets[] __ro_after_init = { [REGSET_GPR] = { .core_note_type = NT_PRSTATUS, .n = sizeof(struct user_pt_regs) / sizeof(u64), @@ -1596,6 +1597,25 @@ static const struct user_regset_view user_aarch64_view = { .regsets = aarch64_regsets, .n = ARRAY_SIZE(aarch64_regsets) }; +#ifdef CONFIG_ARM64_SVE +void __init arch_ptrace_sve_init(unsigned int vq_max) +{ + aarch64_regsets[REGSET_SVE].n = DIV_ROUND_UP( + SVE_PT_SIZE(vq_max, SVE_PT_REGS_SVE), SVE_VQ_BYTES); +} +#endif /* CONFIG_ARM64_SVE */ + +#ifdef CONFIG_ARM64_SME +void __init arch_ptrace_sme_init(unsigned int vq_max) +{ + aarch64_regsets[REGSET_SSVE].n = DIV_ROUND_UP( + SVE_PT_SIZE(vq_max, SVE_PT_REGS_SVE), SVE_VQ_BYTES); + + aarch64_regsets[REGSET_ZA].n = DIV_ROUND_UP( + ZA_PT_SIZE(vq_max), SVE_VQ_BYTES); +} +#endif /* CONFIG_ARM64_SME */ + #ifdef CONFIG_COMPAT enum compat_regset { REGSET_COMPAT_GPR, base-commit: 54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478 -- 2.34.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel