Message ID | 20240130101802.23850-1-gaoshanliukou@163.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-44368-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1117450dyb; Tue, 30 Jan 2024 02:19:02 -0800 (PST) X-Google-Smtp-Source: AGHT+IFnPl3OgijZIn6wEeOnvH4nFSBBkuK3Vyq+xMJaAwB1sQfUG+LpBWKCcj2rOE0RrMHpfmGo X-Received: by 2002:a05:6402:1813:b0:55f:301b:14cd with SMTP id g19-20020a056402181300b0055f301b14cdmr1484354edy.25.1706609942419; Tue, 30 Jan 2024 02:19:02 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706609942; cv=pass; d=google.com; s=arc-20160816; b=KnHY6pp1efqqkAtU92O0uwqRazYEUd0D3+meXaHjPHUo2W9zjTuXp+OFDRbgheP2Qf bz9q7tIhd15qSEJd8EaKqlaB6/5lz7XsPkq+OC/Ug4q1nz0q0fgEbzKsUTfZsUi2+WG2 21P8vSpnIJl6+wn2ZWxe0Xa2YJJ4xAZWyj1kQYvKYWXVSH+9/6Uh9RdZ5II8zSrQYTLS zvZacYUOzyKr6hoO1iVbRkp3GWS8j1UedtrH5OPirhRsxITK3Azt9tCE4QUBpNn+CTZE pBXsLnAXaAZ/IKFbpGMnT3pnLoazBL4L/FhNVnifSfoWMCOQN7kEtT6tcrlCt5Rwu2bN k/rA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=e2FiQhU+RTDN+Ko8jTvok8WomqOu6UE1H2nRRf9t1x4=; fh=H4GV156ul+gyesFiEJsZZADNB2SjqVyKQdIjeeSPgtY=; b=tIpZtmmBPMa/HC6SRCDRnYrirQhWgBSXFw5tBjgjNPfA+MeFxOjp+E5ubydNjKrUkT A3FanRmZIOZhO7BhySCWiJrJotyczsC1cMqhZEfi3tt74Hsgju/YVjEvBlI8GCo6P9p4 9qNjlk7stysujDCj9xnnizlR6TUCO1SXHZhCldNx81tsoY98teK/jETmjqWx270GwV2e Ykkg0B/yFQ3IYuILDi8avT8lpJJhh8ggUVcag9qpnXecEkqQCddiO9dp+Ocan0hwrjhc UbTbQPV2KVcIKvgTk2gFCeKEzP4s3Mg2RhfhbYSID7eM7Ed9CMJNypU+R9XTFT6jpCWg 63Ng== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@163.com header.s=s110527 header.b=KeMGWHIh; arc=pass (i=1 spf=pass spfdomain=163.com dkim=pass dkdomain=163.com dmarc=pass fromdomain=163.com); spf=pass (google.com: domain of linux-kernel+bounces-44368-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-44368-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=163.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id et13-20020a056402378d00b0055ee69d459csi2347495edb.27.2024.01.30.02.19.02 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 02:19:02 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-44368-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@163.com header.s=s110527 header.b=KeMGWHIh; arc=pass (i=1 spf=pass spfdomain=163.com dkim=pass dkdomain=163.com dmarc=pass fromdomain=163.com); spf=pass (google.com: domain of linux-kernel+bounces-44368-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-44368-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=163.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 0D5221F21FBF for <ouuuleilei@gmail.com>; Tue, 30 Jan 2024 10:19:02 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4753160DFC; Tue, 30 Jan 2024 10:18:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="KeMGWHIh" Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.4]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2C73A60869 for <linux-kernel@vger.kernel.org>; Tue, 30 Jan 2024 10:18:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706609926; cv=none; b=gGbXfnliLKSyqcjq4lPwYpko/Z2tMaNIj/hdn1MFz/kmzgzfym7aXuVapl2fUJBsWmOIuoUOnETo1JVWBoe7Z0gAKXijsmozMrmc9SwPno9/0YSY3kZwinWRcnsbKBSRcrlyj9kDHX2WYZZVsi/VGmtYkgIHw1LJDiD45CgwfW8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706609926; c=relaxed/simple; bh=A2NG9B9N8tLHm4kxPliIEqFmb2Hcb8wx1Xa+E1oBSdo=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=c+1SSvYpzdzLub78b4ujW+J5zOXF1sWVoM8VfEiGIRTkkM9rFwMjeMU2eXo74cUUstHC1+GLzJAv+QN6Tag0i215BDjDxrnSvdgbC56falTVe8zYXc/aIxmneLVbXEqCwZuZAjULAmfXLxOzoqrSPxZJi5ssyqBNp8z7n2wFgwc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=KeMGWHIh; arc=none smtp.client-ip=220.197.31.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-Id:MIME-Version; bh=e2FiQ hU+RTDN+Ko8jTvok8WomqOu6UE1H2nRRf9t1x4=; b=KeMGWHIh8XxfVLcfvhOtc dOT6iWXTPXY23QTiiYUHoMVuxl9IslvBFGHrG1y92xB1WbzkThSRe4CBI0BzWo0a yip+SLLv21ScuCn5WfpmqNg1zAwYzmxK1TDaf7s/rpMVIfy9EspYkkrvpaD1ejxh 3BniyVxneyJVa+VNXHErlk= Received: from yangzhang2020.localdomain (unknown [60.24.209.222]) by gzga-smtp-mta-g0-0 (Coremail) with SMTP id _____wDXL2jmzLhlyCwHBg--.29538S2; Tue, 30 Jan 2024 18:18:20 +0800 (CST) From: "yang.zhang" <gaoshanliukou@163.com> To: ebiederm@xmission.com Cc: kexec@lists.infradead.org, linux-kernel@vger.kernel.org, "yang.zhang" <yang.zhang@hexintek.com> Subject: [PATCH] kexec: should use uchunk for user buffer increasing Date: Tue, 30 Jan 2024 18:18:02 +0800 Message-Id: <20240130101802.23850-1-gaoshanliukou@163.com> X-Mailer: git-send-email 2.25.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: _____wDXL2jmzLhlyCwHBg--.29538S2 X-Coremail-Antispam: 1Uf129KBjvdXoWrKw18ZFWrWr1DGr4xGFy3urg_yoWDtFb_Jw 1Iyw4DWr4UZw43Jw4DZrWIgry2yw4Uur4S9r1I9FW7Ar9Yyrs0grZ3trnagr4fGrZ3W3yx tF97J3WSvr1jqjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUvcSsGvfC2KfnxnUUI43ZEXa7IUnVbyJUUUUU== X-CM-SenderInfo: pjdr2x5dqox3xnrxqiywtou0bp/1tbiRAF18mVOBPed+QABs- X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789510226658079975 X-GMAIL-MSGID: 1789510226658079975 |
Series |
kexec: should use uchunk for user buffer increasing
|
|
Commit Message
yang.zhang
Jan. 30, 2024, 10:18 a.m. UTC
From: "yang.zhang" <yang.zhang@hexintek.com> Because of alignment requirement in kexec-tools, there is no problem for user buffer increasing when loading segments. But when coping, the step is uchunk, so we should use uchunk not mchunk. Signed-off-by: yang.zhang <yang.zhang@hexintek.com> --- kernel/kexec_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
Comments
On 01/30/24 at 06:18pm, yang.zhang wrote: > From: "yang.zhang" <yang.zhang@hexintek.com> > > Because of alignment requirement in kexec-tools, there is > no problem for user buffer increasing when loading segments. > But when coping, the step is uchunk, so we should use uchunk > not mchunk. In theory, ubytes is <= mbytes. So uchunk is always <= mchunk. If ubytes is exhausted, while there's still remaining mbytes, then uchunk is 0, there's still mchunk stepping forward. If I understand it correctly, this is a good catch. Not sure if Eric has comment on this to confirm. static int kimage_load_normal_segment(struct kimage *image, struct kexec_segment *segment) { ..... ptr += maddr & ~PAGE_MASK; mchunk = min_t(size_t, mbytes, PAGE_SIZE - (maddr & ~PAGE_MASK)); uchunk = min(ubytes, mchunk); .....} > > Signed-off-by: yang.zhang <yang.zhang@hexintek.com> > --- > kernel/kexec_core.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c > index d08fc7b5db97..2b8354313c85 100644 > --- a/kernel/kexec_core.c > +++ b/kernel/kexec_core.c > @@ -813,9 +813,9 @@ static int kimage_load_normal_segment(struct kimage *image, > ubytes -= uchunk; > maddr += mchunk; > if (image->file_mode) > - kbuf += mchunk; > + kbuf += uchunk; > else > - buf += mchunk; > + buf += uchunk; > mbytes -= mchunk; > > cond_resched(); > @@ -881,9 +881,9 @@ static int kimage_load_crash_segment(struct kimage *image, > ubytes -= uchunk; > maddr += mchunk; > if (image->file_mode) > - kbuf += mchunk; > + kbuf += uchunk; > else > - buf += mchunk; > + buf += uchunk; > mbytes -= mchunk; > > cond_resched(); > -- > 2.34.1 > > > _______________________________________________ > kexec mailing list > kexec@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/kexec >
Baoquan He <bhe@redhat.com> writes: > On 01/30/24 at 06:18pm, yang.zhang wrote: >> From: "yang.zhang" <yang.zhang@hexintek.com> >> >> Because of alignment requirement in kexec-tools, there is >> no problem for user buffer increasing when loading segments. >> But when coping, the step is uchunk, so we should use uchunk >> not mchunk. > > In theory, ubytes is <= mbytes. So uchunk is always <= mchunk. If ubytes > is exhausted, while there's still remaining mbytes, then uchunk is 0, > there's still mchunk stepping forward. If I understand it correctly, > this is a good catch. Not sure if Eric has comment on this to confirm. As far as I can read the code the proposed change is a noop. I agree it is more correct to not advance the pointers we read from, but since we never read from them after that point it does not matter. > > static int kimage_load_normal_segment(struct kimage *image, > struct kexec_segment *segment) > { > ...... > > ptr += maddr & ~PAGE_MASK; > mchunk = min_t(size_t, mbytes, > PAGE_SIZE - (maddr & ~PAGE_MASK)); > uchunk = min(ubytes, mchunk); > ......} If we are going to improve the code for clarity. We probably want to do something like: diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index d08fc7b5db97..1a8b8ce6bf15 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -800,22 +800,24 @@ static int kimage_load_normal_segment(struct kimage *image, PAGE_SIZE - (maddr & ~PAGE_MASK)); uchunk = min(ubytes, mchunk); - /* For file based kexec, source pages are in kernel memory */ - if (image->file_mode) - memcpy(ptr, kbuf, uchunk); - else - result = copy_from_user(ptr, buf, uchunk); + if (uchunk) { + /* For file based kexec, source pages are in kernel memory */ + if (image->file_mode) + memcpy(ptr, kbuf, uchunk); + else + result = copy_from_user(ptr, buf, uchunk); + ubytes -= uchunk; + if (image->file_mode) + kbuf += uchunk; + else + buf += uchunk; + } kunmap_local(ptr); if (result) { result = -EFAULT; goto out; } - ubytes -= uchunk; maddr += mchunk; - if (image->file_mode) - kbuf += mchunk; - else - buf += mchunk; mbytes -= mchunk; cond_resched(); And make it exceedingly clear that all of the copying and the rest only happens before uchunk goes to zero. Otherwise we are relying on a lot of operations becoming noops when uchunk goes to zero. Eric
On 02/05/24 at 06:27am, Eric W. Biederman wrote: > Baoquan He <bhe@redhat.com> writes: > > > On 01/30/24 at 06:18pm, yang.zhang wrote: > >> From: "yang.zhang" <yang.zhang@hexintek.com> > >> > >> Because of alignment requirement in kexec-tools, there is > >> no problem for user buffer increasing when loading segments. > >> But when coping, the step is uchunk, so we should use uchunk > >> not mchunk. > > > > In theory, ubytes is <= mbytes. So uchunk is always <= mchunk. If ubytes > > is exhausted, while there's still remaining mbytes, then uchunk is 0, > > there's still mchunk stepping forward. If I understand it correctly, > > this is a good catch. Not sure if Eric has comment on this to confirm. > > As far as I can read the code the proposed change is a noop. > > I agree it is more correct to not advance the pointers we read from, > but since we never read from them after that point it does not > matter. > > > > > static int kimage_load_normal_segment(struct kimage *image, > > struct kexec_segment *segment) > > { > > ...... > > > > ptr += maddr & ~PAGE_MASK; > > mchunk = min_t(size_t, mbytes, > > PAGE_SIZE - (maddr & ~PAGE_MASK)); > > uchunk = min(ubytes, mchunk); > > ......} > > If we are going to improve the code for clarity. We probably > want to do something like: > > diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c > index d08fc7b5db97..1a8b8ce6bf15 100644 > --- a/kernel/kexec_core.c > +++ b/kernel/kexec_core.c > @@ -800,22 +800,24 @@ static int kimage_load_normal_segment(struct kimage *image, > PAGE_SIZE - (maddr & ~PAGE_MASK)); > uchunk = min(ubytes, mchunk); > > - /* For file based kexec, source pages are in kernel memory */ > - if (image->file_mode) > - memcpy(ptr, kbuf, uchunk); > - else > - result = copy_from_user(ptr, buf, uchunk); > + if (uchunk) { > + /* For file based kexec, source pages are in kernel memory */ > + if (image->file_mode) > + memcpy(ptr, kbuf, uchunk); > + else > + result = copy_from_user(ptr, buf, uchunk); > + ubytes -= uchunk; > + if (image->file_mode) > + kbuf += uchunk; > + else > + buf += uchunk; > + } > kunmap_local(ptr); > if (result) { > result = -EFAULT; > goto out; > } > - ubytes -= uchunk; > maddr += mchunk; > - if (image->file_mode) > - kbuf += mchunk; > - else > - buf += mchunk; > mbytes -= mchunk; > > cond_resched(); > > And make it exceedingly clear that all of the copying and the rest > only happens before uchunk goes to zero. Otherwise we are relying > on a lot of operations becoming noops when uchunk goes to zero. ACK. This makes the code logic much clearer, thanks.
Thanks for your replies. Do you have plans to merge the improving code for clarity, or just keep them unchanged. At 2024-02-05 20:27:33, "Eric W. Biederman" <ebiederm@xmission.com> wrote: >Baoquan He <bhe@redhat.com> writes: > >> On 01/30/24 at 06:18pm, yang.zhang wrote: >>> From: "yang.zhang" <yang.zhang@hexintek.com> >>> >>> Because of alignment requirement in kexec-tools, there is >>> no problem for user buffer increasing when loading segments. >>> But when coping, the step is uchunk, so we should use uchunk >>> not mchunk. >> >> In theory, ubytes is <= mbytes. So uchunk is always <= mchunk. If ubytes >> is exhausted, while there's still remaining mbytes, then uchunk is 0, >> there's still mchunk stepping forward. If I understand it correctly, >> this is a good catch. Not sure if Eric has comment on this to confirm. > >As far as I can read the code the proposed change is a noop. > >I agree it is more correct to not advance the pointers we read from, >but since we never read from them after that point it does not >matter. > >> >> static int kimage_load_normal_segment(struct kimage *image, >> struct kexec_segment *segment) >> { >> ...... >> >> ptr += maddr & ~PAGE_MASK; >> mchunk = min_t(size_t, mbytes, >> PAGE_SIZE - (maddr & ~PAGE_MASK)); >> uchunk = min(ubytes, mchunk); >> ......} > >If we are going to improve the code for clarity. We probably >want to do something like: > >diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c >index d08fc7b5db97..1a8b8ce6bf15 100644 >--- a/kernel/kexec_core.c >+++ b/kernel/kexec_core.c >@@ -800,22 +800,24 @@ static int kimage_load_normal_segment(struct kimage *image, > PAGE_SIZE - (maddr & ~PAGE_MASK)); > uchunk = min(ubytes, mchunk); > >- /* For file based kexec, source pages are in kernel memory */ >- if (image->file_mode) >- memcpy(ptr, kbuf, uchunk); >- else >- result = copy_from_user(ptr, buf, uchunk); >+ if (uchunk) { >+ /* For file based kexec, source pages are in kernel memory */ >+ if (image->file_mode) >+ memcpy(ptr, kbuf, uchunk); >+ else >+ result = copy_from_user(ptr, buf, uchunk); >+ ubytes -= uchunk; >+ if (image->file_mode) >+ kbuf += uchunk; >+ else >+ buf += uchunk; >+ } > kunmap_local(ptr); > if (result) { > result = -EFAULT; > goto out; > } >- ubytes -= uchunk; > maddr += mchunk; >- if (image->file_mode) >- kbuf += mchunk; >- else >- buf += mchunk; > mbytes -= mchunk; > > cond_resched(); > >And make it exceedingly clear that all of the copying and the rest >only happens before uchunk goes to zero. Otherwise we are relying >on a lot of operations becoming noops when uchunk goes to zero. > >Eric
On 02/19/24 at 10:00am, yang.zhang wrote: > > > > Thanks for your replies. > Do you have plans to merge the improving code for clarity, or just keep them unchanged. You need post v2 to change those two places as Eric has demonstrated. Please CC Andrew when you post. > > At 2024-02-05 20:27:33, "Eric W. Biederman" <ebiederm@xmission.com> wrote: > >Baoquan He <bhe@redhat.com> writes: > > > >> On 01/30/24 at 06:18pm, yang.zhang wrote: > >>> From: "yang.zhang" <yang.zhang@hexintek.com> > >>> > >>> Because of alignment requirement in kexec-tools, there is > >>> no problem for user buffer increasing when loading segments. > >>> But when coping, the step is uchunk, so we should use uchunk > >>> not mchunk. > >> > >> In theory, ubytes is <= mbytes. So uchunk is always <= mchunk. If ubytes > >> is exhausted, while there's still remaining mbytes, then uchunk is 0, > >> there's still mchunk stepping forward. If I understand it correctly, > >> this is a good catch. Not sure if Eric has comment on this to confirm. > > > >As far as I can read the code the proposed change is a noop. > > > >I agree it is more correct to not advance the pointers we read from, > >but since we never read from them after that point it does not > >matter. > > > >> > >> static int kimage_load_normal_segment(struct kimage *image, > >> struct kexec_segment *segment) > >> { > >> ...... > >> > >> ptr += maddr & ~PAGE_MASK; > >> mchunk = min_t(size_t, mbytes, > >> PAGE_SIZE - (maddr & ~PAGE_MASK)); > >> uchunk = min(ubytes, mchunk); > >> ......} > > > >If we are going to improve the code for clarity. We probably > >want to do something like: > > > >diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c > >index d08fc7b5db97..1a8b8ce6bf15 100644 > >--- a/kernel/kexec_core.c > >+++ b/kernel/kexec_core.c > >@@ -800,22 +800,24 @@ static int kimage_load_normal_segment(struct kimage *image, > > PAGE_SIZE - (maddr & ~PAGE_MASK)); > > uchunk = min(ubytes, mchunk); > > > >- /* For file based kexec, source pages are in kernel memory */ > >- if (image->file_mode) > >- memcpy(ptr, kbuf, uchunk); > >- else > >- result = copy_from_user(ptr, buf, uchunk); > >+ if (uchunk) { > >+ /* For file based kexec, source pages are in kernel memory */ > >+ if (image->file_mode) > >+ memcpy(ptr, kbuf, uchunk); > >+ else > >+ result = copy_from_user(ptr, buf, uchunk); > >+ ubytes -= uchunk; > >+ if (image->file_mode) > >+ kbuf += uchunk; > >+ else > >+ buf += uchunk; > >+ } > > kunmap_local(ptr); > > if (result) { > > result = -EFAULT; > > goto out; > > } > >- ubytes -= uchunk; > > maddr += mchunk; > >- if (image->file_mode) > >- kbuf += mchunk; > >- else > >- buf += mchunk; > > mbytes -= mchunk; > > > > cond_resched(); > > > >And make it exceedingly clear that all of the copying and the rest > >only happens before uchunk goes to zero. Otherwise we are relying > >on a lot of operations becoming noops when uchunk goes to zero. > > > >Eric
Thanks, i would post v2 patch. Could you please provide the email address for andrew. At 2024-02-19 10:38:22, "Baoquan He" <bhe@redhat.com> wrote: >On 02/19/24 at 10:00am, yang.zhang wrote: >> >> >> >> Thanks for your replies. >> Do you have plans to merge the improving code for clarity, or just keep them unchanged. > >You need post v2 to change those two places as Eric has demonstrated. >Please CC Andrew when you post. > >> >> At 2024-02-05 20:27:33, "Eric W. Biederman" <ebiederm@xmission.com> wrote: >> >Baoquan He <bhe@redhat.com> writes: >> > >> >> On 01/30/24 at 06:18pm, yang.zhang wrote: >> >>> From: "yang.zhang" <yang.zhang@hexintek.com> >> >>> >> >>> Because of alignment requirement in kexec-tools, there is >> >>> no problem for user buffer increasing when loading segments. >> >>> But when coping, the step is uchunk, so we should use uchunk >> >>> not mchunk. >> >> >> >> In theory, ubytes is <= mbytes. So uchunk is always <= mchunk. If ubytes >> >> is exhausted, while there's still remaining mbytes, then uchunk is 0, >> >> there's still mchunk stepping forward. If I understand it correctly, >> >> this is a good catch. Not sure if Eric has comment on this to confirm. >> > >> >As far as I can read the code the proposed change is a noop. >> > >> >I agree it is more correct to not advance the pointers we read from, >> >but since we never read from them after that point it does not >> >matter. >> > >> >> >> >> static int kimage_load_normal_segment(struct kimage *image, >> >> struct kexec_segment *segment) >> >> { >> >> ...... >> >> >> >> ptr += maddr & ~PAGE_MASK; >> >> mchunk = min_t(size_t, mbytes, >> >> PAGE_SIZE - (maddr & ~PAGE_MASK)); >> >> uchunk = min(ubytes, mchunk); >> >> ......} >> > >> >If we are going to improve the code for clarity. We probably >> >want to do something like: >> > >> >diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c >> >index d08fc7b5db97..1a8b8ce6bf15 100644 >> >--- a/kernel/kexec_core.c >> >+++ b/kernel/kexec_core.c >> >@@ -800,22 +800,24 @@ static int kimage_load_normal_segment(struct kimage *image, >> > PAGE_SIZE - (maddr & ~PAGE_MASK)); >> > uchunk = min(ubytes, mchunk); >> > >> >- /* For file based kexec, source pages are in kernel memory */ >> >- if (image->file_mode) >> >- memcpy(ptr, kbuf, uchunk); >> >- else >> >- result = copy_from_user(ptr, buf, uchunk); >> >+ if (uchunk) { >> >+ /* For file based kexec, source pages are in kernel memory */ >> >+ if (image->file_mode) >> >+ memcpy(ptr, kbuf, uchunk); >> >+ else >> >+ result = copy_from_user(ptr, buf, uchunk); >> >+ ubytes -= uchunk; >> >+ if (image->file_mode) >> >+ kbuf += uchunk; >> >+ else >> >+ buf += uchunk; >> >+ } >> > kunmap_local(ptr); >> > if (result) { >> > result = -EFAULT; >> > goto out; >> > } >> >- ubytes -= uchunk; >> > maddr += mchunk; >> >- if (image->file_mode) >> >- kbuf += mchunk; >> >- else >> >- buf += mchunk; >> > mbytes -= mchunk; >> > >> > cond_resched(); >> > >> >And make it exceedingly clear that all of the copying and the rest >> >only happens before uchunk goes to zero. Otherwise we are relying >> >on a lot of operations becoming noops when uchunk goes to zero. >> > >> >Eric
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index d08fc7b5db97..2b8354313c85 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -813,9 +813,9 @@ static int kimage_load_normal_segment(struct kimage *image, ubytes -= uchunk; maddr += mchunk; if (image->file_mode) - kbuf += mchunk; + kbuf += uchunk; else - buf += mchunk; + buf += uchunk; mbytes -= mchunk; cond_resched(); @@ -881,9 +881,9 @@ static int kimage_load_crash_segment(struct kimage *image, ubytes -= uchunk; maddr += mchunk; if (image->file_mode) - kbuf += mchunk; + kbuf += uchunk; else - buf += mchunk; + buf += uchunk; mbytes -= mchunk; cond_resched();