From mboxrd@z Thu Jan 1 00:00:00 1970 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 29EBD23A0 for ; Fri, 24 Jan 2025 09:53:11 +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=1737712394; cv=none; b=l9xVb1ihcIXGo7SEwvyp7Qn6EOfPFbs4seFDw9BJbgUC82CoilS5xwkfeCTA/MUxeFRptvC2M2wgsTkL75qpeWTdcMzRDM2f5JST7w4QkGEZrsO0zydRfcDwybnNLUhOL9hYZq7Sn6DmFP3Ntu1Spc2mlcBMSdy2tcHsGhsU1FM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737712394; c=relaxed/simple; bh=ZJrnAbUkX6sbecWr5xOMdm0LOdqvNClq5tC4UzP0Zfc=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=T+ofkSluaE/kzwy2pwJn4t7+/UX6nRp0JUwq1jmZ5tHRqXcKB3CU2S1utK1kD28WSb4HdNkj7p6gaUiFX0pdUZatyndomYzKBWqL8xseRc4Ok2rJAb6/n68C9e3Xzq75IiXbquwAjLHHWZuqyqalbh6hgn4sAgn/maZAiHbmRR0= 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=Z6hSTUb/; 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="Z6hSTUb/" Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 50O924pK008603; Fri, 24 Jan 2025 09:52:55 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pp1; bh=bud1wW fO7+4Arp8pphbcMjwsTwJvsTKZjY4VR5FForM=; b=Z6hSTUb/n8pKiGWHxnPU7h GetLTDKad+Nykyb4v7YRQwqosl7GqlSFldYjmbkPr6zT8T1u8v2owSPk20U5XBAy T8IEeji30tGTz5lxyThFrXQlrGJXJKb9gp3JZRdjX/SCK43qDyFBXzeINIU3NjkI vudB+yBCbDkImsmX6PURzNIwpGav23vGyuGiJ2gskHV9XABGJGHGM7I08qj56jjc wnFWfRATkXrp6T5+e4G4Z7f2sAu+T8WvFbwjEG93hRy8SwCuHNrdGO6axCisH+zj EAefwKi6uvNwHVB9b/yuaukhA60KpxPoh5atChHl/FmIAg+2nsnJpsbjQHtBdZGA == 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 44c1pyts3t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Jan 2025 09:52:55 +0000 (GMT) Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.18.1.2/8.18.1.2) with ESMTP id 50O7979G019252; Fri, 24 Jan 2025 09:52:54 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 448pmsu02e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 24 Jan 2025 09:52:54 +0000 Received: from smtpav04.fra02v.mail.ibm.com (smtpav04.fra02v.mail.ibm.com [10.20.54.103]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 50O9qpVH19136982 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 24 Jan 2025 09:52:51 GMT Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 23ABF2021B; Fri, 24 Jan 2025 09:52:51 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id F2CC32021A; Fri, 24 Jan 2025 09:52:48 +0000 (GMT) Received: from [9.43.1.43] (unknown [9.43.1.43]) by smtpav04.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 24 Jan 2025 09:52:48 +0000 (GMT) Message-ID: <755825bb-4153-44ce-8c1d-7c011fac4b7d@linux.ibm.com> Date: Fri, 24 Jan 2025 15:22:48 +0530 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2 6/6] crash: option to let arch decide mem range is usable To: Sourabh Jain , linuxppc-dev@lists.ozlabs.org Cc: Andrew Morton , Baoquan he , Madhavan Srinivasan , Mahesh Salgaonkar , Michael Ellerman , kexec@lists.infradead.org, linux-kernel@vger.kernel.org References: <20250121115442.1278458-1-sourabhjain@linux.ibm.com> <20250121115442.1278458-7-sourabhjain@linux.ibm.com> Content-Language: en-US From: Hari Bathini In-Reply-To: <20250121115442.1278458-7-sourabhjain@linux.ibm.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: wZ9Enu0n3GX7Nh5dBjXOK_8sYRA5U05T X-Proofpoint-GUID: wZ9Enu0n3GX7Nh5dBjXOK_8sYRA5U05T X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-01-24_03,2025-01-23_01,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 phishscore=0 mlxlogscore=999 bulkscore=0 lowpriorityscore=0 spamscore=0 mlxscore=0 priorityscore=1501 adultscore=0 impostorscore=0 malwarescore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501240068 Hi Sourabh, On 21/01/25 5:24 pm, Sourabh Jain wrote: > On PowerPC, the memory reserved for the crashkernel can contain > components like RTAS, TCE, OPAL, etc., which should be avoided when > loading kexec segments into crashkernel memory. Due to these special > components, PowerPC has its own set of functions to locate holes in the > crashkernel memory for loading kexec segments for kdump. However, for > loading kexec segments in the kexec case, PowerPC uses generic functions > to locate holes. > > So, let's use generic functions to locate memory holes for kdump on > PowerPC by adding an arch hook to handle such special regions while > loading kexec segments, and remove the PowerPC functions to locate > holes. > > Cc: Andrew Morton > Cc: Baoquan he > Cc: Hari Bathini > Cc: Madhavan Srinivasan > Cc: Mahesh Salgaonkar > Cc: Michael Ellerman > Cc: kexec@lists.infradead.org > Cc: linux-kernel@vger.kernel.org > Signed-off-by: Sourabh Jain > --- > arch/powerpc/include/asm/kexec.h | 6 +- > arch/powerpc/kexec/file_load_64.c | 259 ++---------------------------- > include/linux/kexec.h | 9 ++ > kernel/kexec_file.c | 12 ++ > 4 files changed, 34 insertions(+), 252 deletions(-) > > diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h > index 64741558071f..5e4680f9ff35 100644 > --- a/arch/powerpc/include/asm/kexec.h > +++ b/arch/powerpc/include/asm/kexec.h > @@ -95,8 +95,10 @@ int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, unsigned long > int arch_kimage_file_post_load_cleanup(struct kimage *image); > #define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup > > -int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf); > -#define arch_kexec_locate_mem_hole arch_kexec_locate_mem_hole > +int arch_check_excluded_range(struct kimage *image, unsigned long start, > + unsigned long end); > +#define arch_check_excluded_range arch_check_excluded_range > + > > int load_crashdump_segments_ppc64(struct kimage *image, > struct kexec_buf *kbuf); > diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c > index dc65c1391157..e7ef8b2a2554 100644 > --- a/arch/powerpc/kexec/file_load_64.c > +++ b/arch/powerpc/kexec/file_load_64.c > @@ -49,201 +49,18 @@ const struct kexec_file_ops * const kexec_file_loaders[] = { > NULL > }; > > -/** > - * __locate_mem_hole_top_down - Looks top down for a large enough memory hole > - * in the memory regions between buf_min & buf_max > - * for the buffer. If found, sets kbuf->mem. > - * @kbuf: Buffer contents and memory parameters. > - * @buf_min: Minimum address for the buffer. > - * @buf_max: Maximum address for the buffer. > - * > - * Returns 0 on success, negative errno on error. > - */ > -static int __locate_mem_hole_top_down(struct kexec_buf *kbuf, > - u64 buf_min, u64 buf_max) > -{ > - int ret = -EADDRNOTAVAIL; > - phys_addr_t start, end; > - u64 i; > - > - for_each_mem_range_rev(i, &start, &end) { > - /* > - * memblock uses [start, end) convention while it is > - * [start, end] here. Fix the off-by-one to have the > - * same convention. > - */ > - end -= 1; > - > - if (start > buf_max) > - continue; > - > - /* Memory hole not found */ > - if (end < buf_min) > - break; > - > - /* Adjust memory region based on the given range */ > - if (start < buf_min) > - start = buf_min; > - if (end > buf_max) > - end = buf_max; > - > - start = ALIGN(start, kbuf->buf_align); > - if (start < end && (end - start + 1) >= kbuf->memsz) { > - /* Suitable memory range found. Set kbuf->mem */ > - kbuf->mem = ALIGN_DOWN(end - kbuf->memsz + 1, > - kbuf->buf_align); > - ret = 0; > - break; > - } > - } > - > - return ret; > -} > - > -/** > - * locate_mem_hole_top_down_ppc64 - Skip special memory regions to find a > - * suitable buffer with top down approach. > - * @kbuf: Buffer contents and memory parameters. > - * @buf_min: Minimum address for the buffer. > - * @buf_max: Maximum address for the buffer. > - * @emem: Exclude memory ranges. > - * > - * Returns 0 on success, negative errno on error. > - */ > -static int locate_mem_hole_top_down_ppc64(struct kexec_buf *kbuf, > - u64 buf_min, u64 buf_max, > - const struct crash_mem *emem) > +int arch_check_excluded_range(struct kimage *image, unsigned long start, > + unsigned long end) > { > - int i, ret = 0, err = -EADDRNOTAVAIL; > - u64 start, end, tmin, tmax; > - > - tmax = buf_max; > - for (i = (emem->nr_ranges - 1); i >= 0; i--) { > - start = emem->ranges[i].start; > - end = emem->ranges[i].end; > - > - if (start > tmax) > - continue; > - > - if (end < tmax) { > - tmin = (end < buf_min ? buf_min : end + 1); > - ret = __locate_mem_hole_top_down(kbuf, tmin, tmax); > - if (!ret) > - return 0; > - } > - > - tmax = start - 1; > - > - if (tmax < buf_min) { > - ret = err; > - break; > - } > - ret = 0; > - } > - > - if (!ret) { > - tmin = buf_min; > - ret = __locate_mem_hole_top_down(kbuf, tmin, tmax); > - } > - return ret; > -} > - > -/** > - * __locate_mem_hole_bottom_up - Looks bottom up for a large enough memory hole > - * in the memory regions between buf_min & buf_max > - * for the buffer. If found, sets kbuf->mem. > - * @kbuf: Buffer contents and memory parameters. > - * @buf_min: Minimum address for the buffer. > - * @buf_max: Maximum address for the buffer. > - * > - * Returns 0 on success, negative errno on error. > - */ > -static int __locate_mem_hole_bottom_up(struct kexec_buf *kbuf, > - u64 buf_min, u64 buf_max) > -{ > - int ret = -EADDRNOTAVAIL; > - phys_addr_t start, end; > - u64 i; > - > - for_each_mem_range(i, &start, &end) { > - /* > - * memblock uses [start, end) convention while it is > - * [start, end] here. Fix the off-by-one to have the > - * same convention. > - */ > - end -= 1; > - > - if (end < buf_min) > - continue; > - > - /* Memory hole not found */ > - if (start > buf_max) > - break; > - > - /* Adjust memory region based on the given range */ > - if (start < buf_min) > - start = buf_min; > - if (end > buf_max) > - end = buf_max; > - > - start = ALIGN(start, kbuf->buf_align); > - if (start < end && (end - start + 1) >= kbuf->memsz) { > - /* Suitable memory range found. Set kbuf->mem */ > - kbuf->mem = start; > - ret = 0; > - break; > - } > - } > - > - return ret; > -} > - > -/** > - * locate_mem_hole_bottom_up_ppc64 - Skip special memory regions to find a > - * suitable buffer with bottom up approach. > - * @kbuf: Buffer contents and memory parameters. > - * @buf_min: Minimum address for the buffer. > - * @buf_max: Maximum address for the buffer. > - * @emem: Exclude memory ranges. > - * > - * Returns 0 on success, negative errno on error. > - */ > -static int locate_mem_hole_bottom_up_ppc64(struct kexec_buf *kbuf, > - u64 buf_min, u64 buf_max, > - const struct crash_mem *emem) > -{ > - int i, ret = 0, err = -EADDRNOTAVAIL; > - u64 start, end, tmin, tmax; > - > - tmin = buf_min; > - for (i = 0; i < emem->nr_ranges; i++) { > - start = emem->ranges[i].start; > - end = emem->ranges[i].end; > - > - if (end < tmin) > - continue; > - > - if (start > tmin) { > - tmax = (start > buf_max ? buf_max : start - 1); > - ret = __locate_mem_hole_bottom_up(kbuf, tmin, tmax); > - if (!ret) > - return 0; > - } > - > - tmin = end + 1; > + struct crash_mem *emem; > + int i; > > - if (tmin > buf_max) { > - ret = err; > - break; > - } > - ret = 0; > - } > + emem = image->arch.exclude_ranges; > + for (i = 0; i < emem->nr_ranges; i++) > + if (start < emem->ranges[i].end && end > emem->ranges[i].start) > + return 1; > > - if (!ret) { > - tmax = buf_max; > - ret = __locate_mem_hole_bottom_up(kbuf, tmin, tmax); > - } > - return ret; > + return 0; > } > > #ifdef CONFIG_CRASH_DUMP > @@ -1004,64 +821,6 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt, struct crash_mem > return ret; > } > > -/** > - * arch_kexec_locate_mem_hole - Skip special memory regions like rtas, opal, > - * tce-table, reserved-ranges & such (exclude > - * memory ranges) as they can't be used for kexec > - * segment buffer. Sets kbuf->mem when a suitable > - * memory hole is found. > - * @kbuf: Buffer contents and memory parameters. > - * > - * Assumes minimum of PAGE_SIZE alignment for kbuf->memsz & kbuf->buf_align. > - * > - * Returns 0 on success, negative errno on error. > - */ > -int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf) > -{ > - struct crash_mem **emem; > - u64 buf_min, buf_max; > - int ret; > - > - /* Look up the exclude ranges list while locating the memory hole */ > - emem = &(kbuf->image->arch.exclude_ranges); > - if (!(*emem) || ((*emem)->nr_ranges == 0)) { > - pr_warn("No exclude range list. Using the default locate mem hole method\n"); > - return kexec_locate_mem_hole(kbuf); > - } > - > - buf_min = kbuf->buf_min; > - buf_max = kbuf->buf_max; > - /* Segments for kdump kernel should be within crashkernel region */ > - if (IS_ENABLED(CONFIG_CRASH_DUMP) && kbuf->image->type == KEXEC_TYPE_CRASH) { > - buf_min = (buf_min < crashk_res.start ? > - crashk_res.start : buf_min); > - buf_max = (buf_max > crashk_res.end ? > - crashk_res.end : buf_max); > - } > - > - if (buf_min > buf_max) { > - pr_err("Invalid buffer min and/or max values\n"); > - return -EINVAL; > - } > - > - if (kbuf->top_down) > - ret = locate_mem_hole_top_down_ppc64(kbuf, buf_min, buf_max, > - *emem); > - else > - ret = locate_mem_hole_bottom_up_ppc64(kbuf, buf_min, buf_max, > - *emem); > - > - /* Add the buffer allocated to the exclude list for the next lookup */ > - if (!ret) { > - add_mem_range(emem, kbuf->mem, kbuf->memsz); > - sort_memory_ranges(*emem, true); > - } else { > - pr_err("Failed to locate memory buffer of size %lu\n", > - kbuf->memsz); > - } > - return ret; > -} > - > /** > * arch_kexec_kernel_image_probe - Does additional handling needed to setup > * kexec segments. > diff --git a/include/linux/kexec.h b/include/linux/kexec.h > index f0e9f8eda7a3..407f8b0346aa 100644 > --- a/include/linux/kexec.h > +++ b/include/linux/kexec.h > @@ -205,6 +205,15 @@ static inline int arch_kimage_file_post_load_cleanup(struct kimage *image) > } > #endif > > +#ifndef arch_check_excluded_range > +static inline int arch_check_excluded_range(struct kimage *image, > + unsigned long start, > + unsigned long end) > +{ > + return 0; > +} > +#endif > + > #ifdef CONFIG_KEXEC_SIG > #ifdef CONFIG_SIGNED_PE_FILE_VERIFICATION > int kexec_kernel_verify_pe_sig(const char *kernel, unsigned long kernel_len); > diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c > index 3eedb8c226ad..fba686487e3b 100644 > --- a/kernel/kexec_file.c > +++ b/kernel/kexec_file.c > @@ -464,6 +464,12 @@ static int locate_mem_hole_top_down(unsigned long start, unsigned long end, > continue; > } > > + /* Make sure this does not conflict with exclude range */ > + if (arch_check_excluded_range(image, temp_start, temp_end)) { > + temp_start = temp_start - PAGE_SIZE; > + continue; > + } > + > /* We found a suitable memory range */ > break; > } while (1); > @@ -498,6 +504,12 @@ static int locate_mem_hole_bottom_up(unsigned long start, unsigned long end, > continue; > } > > + /* Make sure this does not conflict with exclude range */ > + if (arch_check_excluded_range(image, temp_start, temp_end)) { > + temp_start = temp_start + PAGE_SIZE; > + continue; > + } > + > /* We found a suitable memory range */ > break; > } while (1); Please split this arch-independent patch and have it as a preceding patch. Arch-specific changes can go in a separate patch. - Hari