diff mbox series

[v5,RESEND,1/3] vmcore: Convert copy_oldmem_page() to take an iov_iter

Message ID 20220408090636.560886-2-bhe@redhat.com (mailing list archive)
State New, archived
Headers show
Series Convert vmcore to use an iov_iter | expand

Commit Message

Baoquan He April 8, 2022, 9:06 a.m. UTC
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>

Instead of passing in a 'buf' and 'userbuf' argument, pass in an iov_iter.
s390 needs more work to pass the iov_iter down further, or refactor,
but I'd be more comfortable if someone who can test on s390 did that work.

It's more convenient to convert the whole of read_from_oldmem() to
take an iov_iter at the same time, so rename it to read_from_oldmem_iter()
and add a temporary read_from_oldmem() wrapper that creates an iov_iter.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Baoquan He <bhe@redhat.com>
---
 arch/arm/kernel/crash_dump.c     | 27 +++-------------
 arch/arm64/kernel/crash_dump.c   | 29 +++--------------
 arch/ia64/kernel/crash_dump.c    | 32 +++----------------
 arch/mips/kernel/crash_dump.c    | 27 +++-------------
 arch/powerpc/kernel/crash_dump.c | 35 +++------------------
 arch/riscv/kernel/crash_dump.c   | 26 +++------------
 arch/s390/kernel/crash_dump.c    | 13 +++++---
 arch/sh/kernel/crash_dump.c      | 29 +++--------------
 arch/x86/kernel/crash_dump_32.c  | 29 +++--------------
 arch/x86/kernel/crash_dump_64.c  | 41 +++++++-----------------
 fs/proc/vmcore.c                 | 54 ++++++++++++++++++++------------
 include/linux/crash_dump.h       |  9 +++---
 12 files changed, 91 insertions(+), 260 deletions(-)

Comments

kernel test robot April 8, 2022, 1:17 p.m. UTC | #1
Hi Baoquan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on powerpc/next]
[also build test WARNING on s390/features linus/master v5.18-rc1 next-20220408]
[cannot apply to tip/x86/core hnaz-mm/master arm64/for-next/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/Convert-vmcore-to-use-an-iov_iter/20220408-170846
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: sh-randconfig-s032-20220408 (https://download.01.org/0day-ci/archive/20220408/202204082128.JKXXDGpa-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/intel-lab-lkp/linux/commit/a5e42962f5c0bea73aa382a2415094b4bd6c6c73
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Baoquan-He/Convert-vmcore-to-use-an-iov_iter/20220408-170846
        git checkout a5e42962f5c0bea73aa382a2415094b4bd6c6c73
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=sh SHELL=/bin/bash arch/sh/kernel/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> arch/sh/kernel/crash_dump.c:23:36: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   arch/sh/kernel/crash_dump.c:23:36: sparse:     expected void const *addr
   arch/sh/kernel/crash_dump.c:23:36: sparse:     got void [noderef] __iomem *

vim +23 arch/sh/kernel/crash_dump.c

    13	
    14	ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
    15				 size_t csize, unsigned long offset)
    16	{
    17		void  __iomem *vaddr;
    18	
    19		if (!csize)
    20			return 0;
    21	
    22		vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
  > 23		csize = copy_to_iter(vaddr + offset, csize, iter);
Baoquan He April 9, 2022, 1:02 a.m. UTC | #2
On 04/08/22 at 09:17pm, kernel test robot wrote:
> Hi Baoquan,
> 
> Thank you for the patch! Perhaps something to improve:
> 
> [auto build test WARNING on powerpc/next]
> [also build test WARNING on s390/features linus/master v5.18-rc1 next-20220408]
> [cannot apply to tip/x86/core hnaz-mm/master arm64/for-next/core]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/Convert-vmcore-to-use-an-iov_iter/20220408-170846
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
> config: sh-randconfig-s032-20220408 (https://download.01.org/0day-ci/archive/20220408/202204082128.JKXXDGpa-lkp@intel.com/config)
> compiler: sh4-linux-gcc (GCC) 11.2.0
> reproduce:
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross

Thanks for reporting this, do I need to try this on ppc system?

I tried on x86_64 system, for the 1st step, I got this:

[ ~]# wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
/root/bin/make.cross: No such file or directory

What else should I do to proceed?

Thanks
Baoquan

>         chmod +x ~/bin/make.cross
>         # apt-get install sparse
>         # sparse version: v0.6.4-dirty
>         # https://github.com/intel-lab-lkp/linux/commit/a5e42962f5c0bea73aa382a2415094b4bd6c6c73
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review Baoquan-He/Convert-vmcore-to-use-an-iov_iter/20220408-170846
>         git checkout a5e42962f5c0bea73aa382a2415094b4bd6c6c73
>         # save the config file to linux build tree
>         mkdir build_dir
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=sh SHELL=/bin/bash arch/sh/kernel/
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
> 
> 
> sparse warnings: (new ones prefixed by >>)
> >> arch/sh/kernel/crash_dump.c:23:36: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
>    arch/sh/kernel/crash_dump.c:23:36: sparse:     expected void const *addr
>    arch/sh/kernel/crash_dump.c:23:36: sparse:     got void [noderef] __iomem *
> 
> vim +23 arch/sh/kernel/crash_dump.c
> 
>     13	
>     14	ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
>     15				 size_t csize, unsigned long offset)
>     16	{
>     17		void  __iomem *vaddr;
>     18	
>     19		if (!csize)
>     20			return 0;
>     21	
>     22		vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
>   > 23		csize = copy_to_iter(vaddr + offset, csize, iter);
> 
> -- 
> 0-DAY CI Kernel Test Service
> https://01.org/lkp
>
Philip Li April 9, 2022, 1:24 a.m. UTC | #3
On Sat, Apr 09, 2022 at 09:02:29AM +0800, Baoquan He wrote:
> On 04/08/22 at 09:17pm, kernel test robot wrote:
> > Hi Baoquan,
> > 
> > Thank you for the patch! Perhaps something to improve:
> > 
> > [auto build test WARNING on powerpc/next]
> > [also build test WARNING on s390/features linus/master v5.18-rc1 next-20220408]
> > [cannot apply to tip/x86/core hnaz-mm/master arm64/for-next/core]
> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > And when submitting patch, we suggest to use '--base' as documented in
> > https://git-scm.com/docs/git-format-patch]
> > 
> > url:    https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/Convert-vmcore-to-use-an-iov_iter/20220408-170846
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
> > config: sh-randconfig-s032-20220408 (https://download.01.org/0day-ci/archive/20220408/202204082128.JKXXDGpa-lkp@intel.com/config)
> > compiler: sh4-linux-gcc (GCC) 11.2.0
> > reproduce:
> >         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> 
> Thanks for reporting this, do I need to try this on ppc system?
> 
> I tried on x86_64 system, for the 1st step, I got this:
> 
> [ ~]# wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> /root/bin/make.cross: No such file or directory
> 
> What else should I do to proceed?

not sure whether mkdir -p /root/bin works? I can reproduce this if i don't have ~/bin dir.

We will look into this to make reproduce step clearer.

> 
> Thanks
> Baoquan
> 
> >         chmod +x ~/bin/make.cross
> >         # apt-get install sparse
> >         # sparse version: v0.6.4-dirty
> >         # https://github.com/intel-lab-lkp/linux/commit/a5e42962f5c0bea73aa382a2415094b4bd6c6c73
> >         git remote add linux-review https://github.com/intel-lab-lkp/linux
> >         git fetch --no-tags linux-review Baoquan-He/Convert-vmcore-to-use-an-iov_iter/20220408-170846
> >         git checkout a5e42962f5c0bea73aa382a2415094b4bd6c6c73
> >         # save the config file to linux build tree
> >         mkdir build_dir
> >         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=sh SHELL=/bin/bash arch/sh/kernel/
> > 
> > If you fix the issue, kindly add following tag as appropriate
> > Reported-by: kernel test robot <lkp@intel.com>
> > 
> > 
> > sparse warnings: (new ones prefixed by >>)
> > >> arch/sh/kernel/crash_dump.c:23:36: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
> >    arch/sh/kernel/crash_dump.c:23:36: sparse:     expected void const *addr
> >    arch/sh/kernel/crash_dump.c:23:36: sparse:     got void [noderef] __iomem *
> > 
> > vim +23 arch/sh/kernel/crash_dump.c
> > 
> >     13	
> >     14	ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
> >     15				 size_t csize, unsigned long offset)
> >     16	{
> >     17		void  __iomem *vaddr;
> >     18	
> >     19		if (!csize)
> >     20			return 0;
> >     21	
> >     22		vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
> >   > 23		csize = copy_to_iter(vaddr + offset, csize, iter);
> > 
> > -- 
> > 0-DAY CI Kernel Test Service
> > https://01.org/lkp
> > 
> _______________________________________________
> kbuild-all mailing list -- kbuild-all@lists.01.org
> To unsubscribe send an email to kbuild-all-leave@lists.01.org
Matthew Wilcox April 9, 2022, 1:44 a.m. UTC | #4
On Sat, Apr 09, 2022 at 09:02:29AM +0800, Baoquan He wrote:
> I tried on x86_64 system, for the 1st step, I got this:
> 
> [ ~]# wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> /root/bin/make.cross: No such file or directory

... I don't think we need to reproduce it to see the problem.

> > sparse warnings: (new ones prefixed by >>)
> > >> arch/sh/kernel/crash_dump.c:23:36: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
> >    arch/sh/kernel/crash_dump.c:23:36: sparse:     expected void const *addr
> >    arch/sh/kernel/crash_dump.c:23:36: sparse:     got void [noderef] __iomem *
> > 
> > vim +23 arch/sh/kernel/crash_dump.c
> > 
> >     13	
> >     14	ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
> >     15				 size_t csize, unsigned long offset)
> >     16	{
> >     17		void  __iomem *vaddr;
> >     18	
> >     19		if (!csize)
> >     20			return 0;
> >     21	
> >     22		vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
> >   > 23		csize = copy_to_iter(vaddr + offset, csize, iter);

Unlike other architectures, sh4 does this by calling ioremap().
That gives us an __iomem qualified pointer, which it then warns about
passing to copy_to_iter().

There are a bunch of hacky things we could do to fix it, but for such an
unmaintained arch as sh, I'm inclined to do nothing.  We're more likely
to break something while fixing the warning.  Someone who knows the arch
can figure out what to do properly.
Baoquan He April 11, 2022, 12:32 a.m. UTC | #5
On 04/09/22 at 02:44am, Matthew Wilcox wrote:
> On Sat, Apr 09, 2022 at 09:02:29AM +0800, Baoquan He wrote:
> > I tried on x86_64 system, for the 1st step, I got this:
> > 
> > [ ~]# wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> > /root/bin/make.cross: No such file or directory
> 
> ... I don't think we need to reproduce it to see the problem.
> 
> > > sparse warnings: (new ones prefixed by >>)
> > > >> arch/sh/kernel/crash_dump.c:23:36: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
> > >    arch/sh/kernel/crash_dump.c:23:36: sparse:     expected void const *addr
> > >    arch/sh/kernel/crash_dump.c:23:36: sparse:     got void [noderef] __iomem *
> > > 
> > > vim +23 arch/sh/kernel/crash_dump.c
> > > 
> > >     13	
> > >     14	ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
> > >     15				 size_t csize, unsigned long offset)
> > >     16	{
> > >     17		void  __iomem *vaddr;
> > >     18	
> > >     19		if (!csize)
> > >     20			return 0;
> > >     21	
> > >     22		vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
> > >   > 23		csize = copy_to_iter(vaddr + offset, csize, iter);
> 
> Unlike other architectures, sh4 does this by calling ioremap().
> That gives us an __iomem qualified pointer, which it then warns about
> passing to copy_to_iter().
> 
> There are a bunch of hacky things we could do to fix it, but for such an
> unmaintained arch as sh, I'm inclined to do nothing.  We're more likely
> to break something while fixing the warning.  Someone who knows the arch
> can figure out what to do properly.

Checked code, this can be fixed by casting away __iomem when feeding
__iomem pointer into function which doesn't expect it. While seems the
lkp failed me again.


Subject: [PATCH] sh: cast away __iomem to remove sparse warning

This warning happened when __iomem pointer is passed into fucntion which
does expect it. casting away the __iomem can fix it.

Signed-off-by: Baoquan He <bhe@redhat.com>
---
 arch/sh/kernel/crash_dump.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c
index 19ce6a950aac..b45bb0b8a182 100644
--- a/arch/sh/kernel/crash_dump.c
+++ b/arch/sh/kernel/crash_dump.c
@@ -20,7 +20,7 @@ ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
 		return 0;
 
 	vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
-	csize = copy_to_iter(vaddr + offset, csize, iter);
+	csize = copy_to_iter((void __force *)vaddr + offset, csize, iter);
 	iounmap(vaddr);
 
 	return csize;
Matthew Wilcox April 11, 2022, 1:32 a.m. UTC | #6
On Mon, Apr 11, 2022 at 08:32:26AM +0800, Baoquan He wrote:
> On 04/09/22 at 02:44am, Matthew Wilcox wrote:
> > On Sat, Apr 09, 2022 at 09:02:29AM +0800, Baoquan He wrote:
> > > I tried on x86_64 system, for the 1st step, I got this:
> > > 
> > > [ ~]# wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> > > /root/bin/make.cross: No such file or directory
> > 
> > ... I don't think we need to reproduce it to see the problem.
> > 
> > > > sparse warnings: (new ones prefixed by >>)
> > > > >> arch/sh/kernel/crash_dump.c:23:36: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
> > > >    arch/sh/kernel/crash_dump.c:23:36: sparse:     expected void const *addr
> > > >    arch/sh/kernel/crash_dump.c:23:36: sparse:     got void [noderef] __iomem *
> > > > 
> > > > vim +23 arch/sh/kernel/crash_dump.c
> > > > 
> > > >     13	
> > > >     14	ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
> > > >     15				 size_t csize, unsigned long offset)
> > > >     16	{
> > > >     17		void  __iomem *vaddr;
> > > >     18	
> > > >     19		if (!csize)
> > > >     20			return 0;
> > > >     21	
> > > >     22		vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
> > > >   > 23		csize = copy_to_iter(vaddr + offset, csize, iter);
> > 
> > Unlike other architectures, sh4 does this by calling ioremap().
> > That gives us an __iomem qualified pointer, which it then warns about
> > passing to copy_to_iter().
> > 
> > There are a bunch of hacky things we could do to fix it, but for such an
> > unmaintained arch as sh, I'm inclined to do nothing.  We're more likely
> > to break something while fixing the warning.  Someone who knows the arch
> > can figure out what to do properly.
> 
> Checked code, this can be fixed by casting away __iomem when feeding
> __iomem pointer into function which doesn't expect it. While seems the
> lkp failed me again.

Sure, that's one of the hacky ways.  But the important thing is that
the _current_ code has a warning.  LKP only sends a nastygram because
we changed the line.  If the current maintainers of the SH architecture
haven't been bothered to fix it, I don't see why we should.

> Subject: [PATCH] sh: cast away __iomem to remove sparse warning
> 
> This warning happened when __iomem pointer is passed into fucntion which
> does expect it. casting away the __iomem can fix it.
> 
> Signed-off-by: Baoquan He <bhe@redhat.com>
> ---
>  arch/sh/kernel/crash_dump.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c
> index 19ce6a950aac..b45bb0b8a182 100644
> --- a/arch/sh/kernel/crash_dump.c
> +++ b/arch/sh/kernel/crash_dump.c
> @@ -20,7 +20,7 @@ ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
>  		return 0;
>  
>  	vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
> -	csize = copy_to_iter(vaddr + offset, csize, iter);
> +	csize = copy_to_iter((void __force *)vaddr + offset, csize, iter);
>  	iounmap(vaddr);
>  
>  	return csize;
> -- 
> 2.34.1
> 
> Hi Philipp,
> 
> I executed 'mkdir -p /root/bin', then can continue the next steps.
> However, the building failed with below message. I cloned linus's tree
> into the testing system. Then add remote
> https://github.com/intel-lab-lkp/linux. Forgive my stupidity on this. If
> I can test above code, I can merge it into patch in a new version.
> Otherwise, I will leave it alone as willy suggested.
> 
> [root@dell-pem710-02 linux]# wget https://download.01.org/0day-ci/archive/20220408/202204082128.JKXXDGpa-lkp@intel.com/config
> --2022-04-10 19:54:15--  https://download.01.org/0day-ci/archive/20220408/202204082128.JKXXDGpa-lkp@intel.com/config
> Resolving download.01.org (download.01.org)... 2600:1408:20:c90::4b21, 2600:1408:20:c9b::4b21, 23.208.55.108
> Connecting to download.01.org (download.01.org)|2600:1408:20:c90::4b21|:443... failed: Network is unreachable.
> Connecting to download.01.org (download.01.org)|2600:1408:20:c9b::4b21|:443... failed: Network is unreachable.
> Connecting to download.01.org (download.01.org)|23.208.55.108|:443... connected.
> HTTP request sent, awaiting response... 200 OK
> Length: 122058 (119K) [application/octet-stream]
> Saving to: ‘config’
> 
> config                            100%[============================================================>] 119.20K   769KB/s    in 0.2s    
> 
> 2022-04-10 19:54:16 (769 KB/s) - ‘config’ saved [122058/122058]
> 
> [root@dell-pem710-02 linux]# mv config .config
> [root@dell-pem710-02 linux]# COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=sh SHELL=/bin/bash arch/sh/kernel/
> Compiler will be installed in /root/0day
> make --keep-going CONFIG_OF_ALL_DTBS=y CONFIG_DTC=y CROSS_COMPILE=/root/0day/gcc-9.3.0-nolibc/sh4-linux/bin/sh4-linux- --jobs=32 C=1 CF=-fdiagnostic-prefix -D__CHECK_ENDIAN__ O=build_dir ARCH=sh SHELL=/bin/bash arch/sh/kernel/
> make[1]: Entering directory '/root/linux/build_dir'
>   SYNC    include/config/auto.conf.cmd
> ***
> *** The source tree is not clean, please run 'make ARCH=sh mrproper'
> *** in /root/linux
> ***
> make[2]: *** [../Makefile:574: outputmakefile] Error 1
>   HOSTCC  scripts/basic/fixdep
> make[2]: Target 'syncconfig' not remade because of errors.
> make[1]: *** [/root/linux/Makefile:722: include/config/auto.conf.cmd] Error 2
> make[1]: Failed to remake makefile 'include/config/auto.conf.cmd'.
> make[1]: Failed to remake makefile 'include/config/auto.conf'.
> ***
> *** The source tree is not clean, please run 'make ARCH=sh mrproper'
> *** in /root/linux
> ***
> make[1]: *** [/root/linux/Makefile:574: outputmakefile] Error 1
>   SYSHDR  arch/sh/include/generated/uapi/asm/unistd_32.h
>   SYSTBL  arch/sh/include/generated/asm/syscall_table.h
> Error: kernelrelease not valid - run 'make prepare' to update it
>   HOSTCC  scripts/dtc/dtc.o
>   HOSTCC  scripts/dtc/flattree.o
>   HOSTCC  scripts/dtc/fstree.o
>   HOSTCC  scripts/dtc/data.o
>   HOSTCC  scripts/dtc/treesource.o
>   HOSTCC  scripts/dtc/livetree.o
>   HOSTCC  scripts/dtc/srcpos.o
>   HOSTCC  scripts/dtc/checks.o
>   HOSTCC  scripts/dtc/util.o
>   LEX     scripts/dtc/dtc-lexer.lex.c
>   YACC    scripts/dtc/dtc-parser.tab.[ch]
>   HOSTCC  scripts/dtc/libfdt/fdt.o
>   HOSTCC  scripts/dtc/libfdt/fdt_ro.o
>   HOSTCC  scripts/dtc/libfdt/fdt_sw.o
>   HOSTCC  scripts/dtc/libfdt/fdt_wip.o
>   HOSTCC  scripts/dtc/libfdt/fdt_rw.o
>   HOSTCC  scripts/dtc/libfdt/fdt_strerror.o
>   HOSTCC  scripts/dtc/libfdt/fdt_empty_tree.o
>   HOSTCC  scripts/dtc/libfdt/fdt_addresses.o
>   HOSTCC  scripts/dtc/libfdt/fdt_overlay.o
>   HOSTCC  scripts/dtc/fdtoverlay.o
>   HOSTCC  scripts/dtc/dtc-lexer.lex.o
>   HOSTCC  scripts/dtc/dtc-parser.tab.o
>   HOSTLD  scripts/dtc/fdtoverlay
>   HOSTLD  scripts/dtc/dtc
> make[1]: Target 'arch/sh/kernel/' not remade because of errors.
> make[1]: Leaving directory '/root/linux/build_dir'
> make: *** [Makefile:219: __sub-make] Error 2
> make: Target 'arch/sh/kernel/' not remade because of errors.
> [root@dell-pem710-02 linux]# 
> 
> 
> 
> > 
>
Baoquan He April 11, 2022, 1:58 a.m. UTC | #7
On 04/11/22 at 02:32am, Matthew Wilcox wrote:
> On Mon, Apr 11, 2022 at 08:32:26AM +0800, Baoquan He wrote:
> > On 04/09/22 at 02:44am, Matthew Wilcox wrote:
> > > On Sat, Apr 09, 2022 at 09:02:29AM +0800, Baoquan He wrote:
> > > > I tried on x86_64 system, for the 1st step, I got this:
> > > > 
> > > > [ ~]# wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> > > > /root/bin/make.cross: No such file or directory
> > > 
> > > ... I don't think we need to reproduce it to see the problem.
> > > 
> > > > > sparse warnings: (new ones prefixed by >>)
> > > > > >> arch/sh/kernel/crash_dump.c:23:36: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
> > > > >    arch/sh/kernel/crash_dump.c:23:36: sparse:     expected void const *addr
> > > > >    arch/sh/kernel/crash_dump.c:23:36: sparse:     got void [noderef] __iomem *
> > > > > 
> > > > > vim +23 arch/sh/kernel/crash_dump.c
> > > > > 
> > > > >     13	
> > > > >     14	ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
> > > > >     15				 size_t csize, unsigned long offset)
> > > > >     16	{
> > > > >     17		void  __iomem *vaddr;
> > > > >     18	
> > > > >     19		if (!csize)
> > > > >     20			return 0;
> > > > >     21	
> > > > >     22		vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
> > > > >   > 23		csize = copy_to_iter(vaddr + offset, csize, iter);
> > > 
> > > Unlike other architectures, sh4 does this by calling ioremap().
> > > That gives us an __iomem qualified pointer, which it then warns about
> > > passing to copy_to_iter().
> > > 
> > > There are a bunch of hacky things we could do to fix it, but for such an
> > > unmaintained arch as sh, I'm inclined to do nothing.  We're more likely
> > > to break something while fixing the warning.  Someone who knows the arch
> > > can figure out what to do properly.
> > 
> > Checked code, this can be fixed by casting away __iomem when feeding
> > __iomem pointer into function which doesn't expect it. While seems the
> > lkp failed me again.
> 
> Sure, that's one of the hacky ways.  But the important thing is that
> the _current_ code has a warning.  LKP only sends a nastygram because
> we changed the line.  If the current maintainers of the SH architecture
> haven't been bothered to fix it, I don't see why we should.

Agree, it's an already existed drawback. Then I will leave it as is.

> 
> > Subject: [PATCH] sh: cast away __iomem to remove sparse warning
> > 
> > This warning happened when __iomem pointer is passed into fucntion which
> > does expect it. casting away the __iomem can fix it.
> > 
> > Signed-off-by: Baoquan He <bhe@redhat.com>
> > ---
> >  arch/sh/kernel/crash_dump.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c
> > index 19ce6a950aac..b45bb0b8a182 100644
> > --- a/arch/sh/kernel/crash_dump.c
> > +++ b/arch/sh/kernel/crash_dump.c
> > @@ -20,7 +20,7 @@ ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
> >  		return 0;
> >  
> >  	vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
> > -	csize = copy_to_iter(vaddr + offset, csize, iter);
> > +	csize = copy_to_iter((void __force *)vaddr + offset, csize, iter);
> >  	iounmap(vaddr);
> >  
> >  	return csize;
> > -- 
> > 2.34.1
> > 
> > Hi Philipp,
> > 
> > I executed 'mkdir -p /root/bin', then can continue the next steps.
> > However, the building failed with below message. I cloned linus's tree
> > into the testing system. Then add remote
> > https://github.com/intel-lab-lkp/linux. Forgive my stupidity on this. If
> > I can test above code, I can merge it into patch in a new version.
> > Otherwise, I will leave it alone as willy suggested.
> > 
> > [root@dell-pem710-02 linux]# wget https://download.01.org/0day-ci/archive/20220408/202204082128.JKXXDGpa-lkp@intel.com/config
> > --2022-04-10 19:54:15--  https://download.01.org/0day-ci/archive/20220408/202204082128.JKXXDGpa-lkp@intel.com/config
> > Resolving download.01.org (download.01.org)... 2600:1408:20:c90::4b21, 2600:1408:20:c9b::4b21, 23.208.55.108
> > Connecting to download.01.org (download.01.org)|2600:1408:20:c90::4b21|:443... failed: Network is unreachable.
> > Connecting to download.01.org (download.01.org)|2600:1408:20:c9b::4b21|:443... failed: Network is unreachable.
> > Connecting to download.01.org (download.01.org)|23.208.55.108|:443... connected.
> > HTTP request sent, awaiting response... 200 OK
> > Length: 122058 (119K) [application/octet-stream]
> > Saving to: ‘config’
> > 
> > config                            100%[============================================================>] 119.20K   769KB/s    in 0.2s    
> > 
> > 2022-04-10 19:54:16 (769 KB/s) - ‘config’ saved [122058/122058]
> > 
> > [root@dell-pem710-02 linux]# mv config .config
> > [root@dell-pem710-02 linux]# COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=sh SHELL=/bin/bash arch/sh/kernel/
> > Compiler will be installed in /root/0day
> > make --keep-going CONFIG_OF_ALL_DTBS=y CONFIG_DTC=y CROSS_COMPILE=/root/0day/gcc-9.3.0-nolibc/sh4-linux/bin/sh4-linux- --jobs=32 C=1 CF=-fdiagnostic-prefix -D__CHECK_ENDIAN__ O=build_dir ARCH=sh SHELL=/bin/bash arch/sh/kernel/
> > make[1]: Entering directory '/root/linux/build_dir'
> >   SYNC    include/config/auto.conf.cmd
> > ***
> > *** The source tree is not clean, please run 'make ARCH=sh mrproper'
> > *** in /root/linux
> > ***
> > make[2]: *** [../Makefile:574: outputmakefile] Error 1
> >   HOSTCC  scripts/basic/fixdep
> > make[2]: Target 'syncconfig' not remade because of errors.
> > make[1]: *** [/root/linux/Makefile:722: include/config/auto.conf.cmd] Error 2
> > make[1]: Failed to remake makefile 'include/config/auto.conf.cmd'.
> > make[1]: Failed to remake makefile 'include/config/auto.conf'.
> > ***
> > *** The source tree is not clean, please run 'make ARCH=sh mrproper'
> > *** in /root/linux
> > ***
> > make[1]: *** [/root/linux/Makefile:574: outputmakefile] Error 1
> >   SYSHDR  arch/sh/include/generated/uapi/asm/unistd_32.h
> >   SYSTBL  arch/sh/include/generated/asm/syscall_table.h
> > Error: kernelrelease not valid - run 'make prepare' to update it
> >   HOSTCC  scripts/dtc/dtc.o
> >   HOSTCC  scripts/dtc/flattree.o
> >   HOSTCC  scripts/dtc/fstree.o
> >   HOSTCC  scripts/dtc/data.o
> >   HOSTCC  scripts/dtc/treesource.o
> >   HOSTCC  scripts/dtc/livetree.o
> >   HOSTCC  scripts/dtc/srcpos.o
> >   HOSTCC  scripts/dtc/checks.o
> >   HOSTCC  scripts/dtc/util.o
> >   LEX     scripts/dtc/dtc-lexer.lex.c
> >   YACC    scripts/dtc/dtc-parser.tab.[ch]
> >   HOSTCC  scripts/dtc/libfdt/fdt.o
> >   HOSTCC  scripts/dtc/libfdt/fdt_ro.o
> >   HOSTCC  scripts/dtc/libfdt/fdt_sw.o
> >   HOSTCC  scripts/dtc/libfdt/fdt_wip.o
> >   HOSTCC  scripts/dtc/libfdt/fdt_rw.o
> >   HOSTCC  scripts/dtc/libfdt/fdt_strerror.o
> >   HOSTCC  scripts/dtc/libfdt/fdt_empty_tree.o
> >   HOSTCC  scripts/dtc/libfdt/fdt_addresses.o
> >   HOSTCC  scripts/dtc/libfdt/fdt_overlay.o
> >   HOSTCC  scripts/dtc/fdtoverlay.o
> >   HOSTCC  scripts/dtc/dtc-lexer.lex.o
> >   HOSTCC  scripts/dtc/dtc-parser.tab.o
> >   HOSTLD  scripts/dtc/fdtoverlay
> >   HOSTLD  scripts/dtc/dtc
> > make[1]: Target 'arch/sh/kernel/' not remade because of errors.
> > make[1]: Leaving directory '/root/linux/build_dir'
> > make: *** [Makefile:219: __sub-make] Error 2
> > make: Target 'arch/sh/kernel/' not remade because of errors.
> > [root@dell-pem710-02 linux]# 
> > 
> > 
> > 
> > > 
> > 
>
Christoph Hellwig April 13, 2022, 4:40 p.m. UTC | #8
Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>
diff mbox series

Patch

diff --git a/arch/arm/kernel/crash_dump.c b/arch/arm/kernel/crash_dump.c
index 53cb92435392..938bd932df9a 100644
--- a/arch/arm/kernel/crash_dump.c
+++ b/arch/arm/kernel/crash_dump.c
@@ -14,22 +14,10 @@ 
 #include <linux/crash_dump.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/uio.h>
 
-/**
- * copy_oldmem_page() - copy one page from old kernel memory
- * @pfn: page frame number to be copied
- * @buf: buffer where the copied page is placed
- * @csize: number of bytes to copy
- * @offset: offset in bytes into the page
- * @userbuf: if set, @buf is int he user address space
- *
- * This function copies one page from old kernel memory into buffer pointed by
- * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes
- * copied or negative error in case of failure.
- */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
-			 size_t csize, unsigned long offset,
-			 int userbuf)
+ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
+			 size_t csize, unsigned long offset)
 {
 	void *vaddr;
 
@@ -40,14 +28,7 @@  ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 	if (!vaddr)
 		return -ENOMEM;
 
-	if (userbuf) {
-		if (copy_to_user(buf, vaddr + offset, csize)) {
-			iounmap(vaddr);
-			return -EFAULT;
-		}
-	} else {
-		memcpy(buf, vaddr + offset, csize);
-	}
+	csize = copy_to_iter(vaddr + offset, csize, iter);
 
 	iounmap(vaddr);
 	return csize;
diff --git a/arch/arm64/kernel/crash_dump.c b/arch/arm64/kernel/crash_dump.c
index 58303a9ec32c..670e4ce81822 100644
--- a/arch/arm64/kernel/crash_dump.c
+++ b/arch/arm64/kernel/crash_dump.c
@@ -9,25 +9,11 @@ 
 #include <linux/crash_dump.h>
 #include <linux/errno.h>
 #include <linux/io.h>
-#include <linux/memblock.h>
-#include <linux/uaccess.h>
+#include <linux/uio.h>
 #include <asm/memory.h>
 
-/**
- * copy_oldmem_page() - copy one page from old kernel memory
- * @pfn: page frame number to be copied
- * @buf: buffer where the copied page is placed
- * @csize: number of bytes to copy
- * @offset: offset in bytes into the page
- * @userbuf: if set, @buf is in a user address space
- *
- * This function copies one page from old kernel memory into buffer pointed by
- * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes
- * copied or negative error in case of failure.
- */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
-			 size_t csize, unsigned long offset,
-			 int userbuf)
+ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
+			 size_t csize, unsigned long offset)
 {
 	void *vaddr;
 
@@ -38,14 +24,7 @@  ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 	if (!vaddr)
 		return -ENOMEM;
 
-	if (userbuf) {
-		if (copy_to_user((char __user *)buf, vaddr + offset, csize)) {
-			memunmap(vaddr);
-			return -EFAULT;
-		}
-	} else {
-		memcpy(buf, vaddr + offset, csize);
-	}
+	csize = copy_to_iter(vaddr + offset, csize, iter);
 
 	memunmap(vaddr);
 
diff --git a/arch/ia64/kernel/crash_dump.c b/arch/ia64/kernel/crash_dump.c
index 0ed3c3dee4cd..4ef68e2aa757 100644
--- a/arch/ia64/kernel/crash_dump.c
+++ b/arch/ia64/kernel/crash_dump.c
@@ -10,42 +10,18 @@ 
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/crash_dump.h>
-
+#include <linux/uio.h>
 #include <asm/page.h>
-#include <linux/uaccess.h>
 
-/**
- * copy_oldmem_page - copy one page from "oldmem"
- * @pfn: page frame number to be copied
- * @buf: target memory address for the copy; this can be in kernel address
- *	space or user address space (see @userbuf)
- * @csize: number of bytes to copy
- * @offset: offset in bytes into the page (based on pfn) to begin the copy
- * @userbuf: if set, @buf is in user address space, use copy_to_user(),
- *	otherwise @buf is in kernel address space, use memcpy().
- *
- * Copy a page from "oldmem". For this page, there is no pte mapped
- * in the current kernel. We stitch up a pte, similar to kmap_atomic.
- *
- * Calling copy_to_user() in atomic context is not desirable. Hence first
- * copying the data to a pre-allocated kernel page and then copying to user
- * space in non-atomic context.
- */
-ssize_t
-copy_oldmem_page(unsigned long pfn, char *buf,
-		size_t csize, unsigned long offset, int userbuf)
+ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
+		size_t csize, unsigned long offset)
 {
 	void  *vaddr;
 
 	if (!csize)
 		return 0;
 	vaddr = __va(pfn<<PAGE_SHIFT);
-	if (userbuf) {
-		if (copy_to_user(buf, (vaddr + offset), csize)) {
-			return -EFAULT;
-		}
-	} else
-		memcpy(buf, (vaddr + offset), csize);
+	csize = copy_to_iter(vaddr + offset, csize, iter);
 	return csize;
 }
 
diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c
index 2e50f55185a6..6e50f4902409 100644
--- a/arch/mips/kernel/crash_dump.c
+++ b/arch/mips/kernel/crash_dump.c
@@ -1,22 +1,10 @@ 
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/highmem.h>
 #include <linux/crash_dump.h>
+#include <linux/uio.h>
 
-/**
- * copy_oldmem_page - copy one page from "oldmem"
- * @pfn: page frame number to be copied
- * @buf: target memory address for the copy; this can be in kernel address
- *	space or user address space (see @userbuf)
- * @csize: number of bytes to copy
- * @offset: offset in bytes into the page (based on pfn) to begin the copy
- * @userbuf: if set, @buf is in user address space, use copy_to_user(),
- *	otherwise @buf is in kernel address space, use memcpy().
- *
- * Copy a page from "oldmem". For this page, there is no pte mapped
- * in the current kernel.
- */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
-			 size_t csize, unsigned long offset, int userbuf)
+ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
+			 size_t csize, unsigned long offset)
 {
 	void  *vaddr;
 
@@ -24,14 +12,7 @@  ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 		return 0;
 
 	vaddr = kmap_local_pfn(pfn);
-
-	if (!userbuf) {
-		memcpy(buf, vaddr + offset, csize);
-	} else {
-		if (copy_to_user(buf, vaddr + offset, csize))
-			csize = -EFAULT;
-	}
-
+	csize = copy_to_iter(vaddr + offset, csize, iter);
 	kunmap_local(vaddr);
 
 	return csize;
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 5693e1c67c2b..32b4a97f1b79 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -16,7 +16,7 @@ 
 #include <asm/kdump.h>
 #include <asm/prom.h>
 #include <asm/firmware.h>
-#include <linux/uaccess.h>
+#include <linux/uio.h>
 #include <asm/rtas.h>
 #include <asm/inst.h>
 
@@ -68,33 +68,8 @@  void __init setup_kdump_trampoline(void)
 }
 #endif /* CONFIG_NONSTATIC_KERNEL */
 
-static size_t copy_oldmem_vaddr(void *vaddr, char *buf, size_t csize,
-                               unsigned long offset, int userbuf)
-{
-	if (userbuf) {
-		if (copy_to_user((char __user *)buf, (vaddr + offset), csize))
-			return -EFAULT;
-	} else
-		memcpy(buf, (vaddr + offset), csize);
-
-	return csize;
-}
-
-/**
- * copy_oldmem_page - copy one page from "oldmem"
- * @pfn: page frame number to be copied
- * @buf: target memory address for the copy; this can be in kernel address
- *      space or user address space (see @userbuf)
- * @csize: number of bytes to copy
- * @offset: offset in bytes into the page (based on pfn) to begin the copy
- * @userbuf: if set, @buf is in user address space, use copy_to_user(),
- *      otherwise @buf is in kernel address space, use memcpy().
- *
- * Copy a page from "oldmem". For this page, there is no pte mapped
- * in the current kernel. We stitch up a pte, similar to kmap_atomic.
- */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
-			size_t csize, unsigned long offset, int userbuf)
+ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
+			size_t csize, unsigned long offset)
 {
 	void  *vaddr;
 	phys_addr_t paddr;
@@ -107,10 +82,10 @@  ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 
 	if (memblock_is_region_memory(paddr, csize)) {
 		vaddr = __va(paddr);
-		csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
+		csize = copy_to_iter(vaddr + offset, csize, iter);
 	} else {
 		vaddr = ioremap_cache(paddr, PAGE_SIZE);
-		csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
+		csize = copy_to_iter(vaddr + offset, csize, iter);
 		iounmap(vaddr);
 	}
 
diff --git a/arch/riscv/kernel/crash_dump.c b/arch/riscv/kernel/crash_dump.c
index 86cc0ada5752..ea2158cee97b 100644
--- a/arch/riscv/kernel/crash_dump.c
+++ b/arch/riscv/kernel/crash_dump.c
@@ -7,22 +7,10 @@ 
 
 #include <linux/crash_dump.h>
 #include <linux/io.h>
+#include <linux/uio.h>
 
-/**
- * copy_oldmem_page() - copy one page from old kernel memory
- * @pfn: page frame number to be copied
- * @buf: buffer where the copied page is placed
- * @csize: number of bytes to copy
- * @offset: offset in bytes into the page
- * @userbuf: if set, @buf is in a user address space
- *
- * This function copies one page from old kernel memory into buffer pointed by
- * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes
- * copied or negative error in case of failure.
- */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
-			 size_t csize, unsigned long offset,
-			 int userbuf)
+ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
+			 size_t csize, unsigned long offset)
 {
 	void *vaddr;
 
@@ -33,13 +21,7 @@  ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 	if (!vaddr)
 		return -ENOMEM;
 
-	if (userbuf) {
-		if (copy_to_user((char __user *)buf, vaddr + offset, csize)) {
-			memunmap(vaddr);
-			return -EFAULT;
-		}
-	} else
-		memcpy(buf, vaddr + offset, csize);
+	csize = copy_to_iter(vaddr + offset, csize, iter);
 
 	memunmap(vaddr);
 	return csize;
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index 69819b765250..a2c1c55daec0 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -15,6 +15,7 @@ 
 #include <linux/slab.h>
 #include <linux/memblock.h>
 #include <linux/elf.h>
+#include <linux/uio.h>
 #include <asm/asm-offsets.h>
 #include <asm/os_info.h>
 #include <asm/elf.h>
@@ -212,8 +213,8 @@  static int copy_oldmem_user(void __user *dst, unsigned long src, size_t count)
 /*
  * Copy one page from "oldmem"
  */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
-			 unsigned long offset, int userbuf)
+ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize,
+			 unsigned long offset)
 {
 	unsigned long src;
 	int rc;
@@ -221,10 +222,12 @@  ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
 	if (!csize)
 		return 0;
 	src = pfn_to_phys(pfn) + offset;
-	if (userbuf)
-		rc = copy_oldmem_user((void __force __user *) buf, src, csize);
+
+	/* XXX: pass the iov_iter down to a common function */
+	if (iter_is_iovec(iter))
+		rc = copy_oldmem_user(iter->iov->iov_base, src, csize);
 	else
-		rc = copy_oldmem_kernel((void *) buf, src, csize);
+		rc = copy_oldmem_kernel(iter->kvec->iov_base, src, csize);
 	return rc;
 }
 
diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c
index 5b41b59698c1..19ce6a950aac 100644
--- a/arch/sh/kernel/crash_dump.c
+++ b/arch/sh/kernel/crash_dump.c
@@ -8,23 +8,11 @@ 
 #include <linux/errno.h>
 #include <linux/crash_dump.h>
 #include <linux/io.h>
+#include <linux/uio.h>
 #include <linux/uaccess.h>
 
-/**
- * copy_oldmem_page - copy one page from "oldmem"
- * @pfn: page frame number to be copied
- * @buf: target memory address for the copy; this can be in kernel address
- *	space or user address space (see @userbuf)
- * @csize: number of bytes to copy
- * @offset: offset in bytes into the page (based on pfn) to begin the copy
- * @userbuf: if set, @buf is in user address space, use copy_to_user(),
- *	otherwise @buf is in kernel address space, use memcpy().
- *
- * Copy a page from "oldmem". For this page, there is no pte mapped
- * in the current kernel. We stitch up a pte, similar to kmap_atomic.
- */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
-                               size_t csize, unsigned long offset, int userbuf)
+ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
+			 size_t csize, unsigned long offset)
 {
 	void  __iomem *vaddr;
 
@@ -32,15 +20,8 @@  ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 		return 0;
 
 	vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
-
-	if (userbuf) {
-		if (copy_to_user((void __user *)buf, (vaddr + offset), csize)) {
-			iounmap(vaddr);
-			return -EFAULT;
-		}
-	} else
-	memcpy(buf, (vaddr + offset), csize);
-
+	csize = copy_to_iter(vaddr + offset, csize, iter);
 	iounmap(vaddr);
+
 	return csize;
 }
diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c
index 5fcac46aaf6b..5f4ae5476e19 100644
--- a/arch/x86/kernel/crash_dump_32.c
+++ b/arch/x86/kernel/crash_dump_32.c
@@ -10,8 +10,7 @@ 
 #include <linux/errno.h>
 #include <linux/highmem.h>
 #include <linux/crash_dump.h>
-
-#include <linux/uaccess.h>
+#include <linux/uio.h>
 
 static inline bool is_crashed_pfn_valid(unsigned long pfn)
 {
@@ -29,21 +28,8 @@  static inline bool is_crashed_pfn_valid(unsigned long pfn)
 #endif
 }
 
-/**
- * copy_oldmem_page - copy one page from "oldmem"
- * @pfn: page frame number to be copied
- * @buf: target memory address for the copy; this can be in kernel address
- *	space or user address space (see @userbuf)
- * @csize: number of bytes to copy
- * @offset: offset in bytes into the page (based on pfn) to begin the copy
- * @userbuf: if set, @buf is in user address space, use copy_to_user(),
- *	otherwise @buf is in kernel address space, use memcpy().
- *
- * Copy a page from "oldmem". For this page, there might be no pte mapped
- * in the current kernel.
- */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
-			 unsigned long offset, int userbuf)
+ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize,
+			 unsigned long offset)
 {
 	void  *vaddr;
 
@@ -54,14 +40,7 @@  ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
 		return -EFAULT;
 
 	vaddr = kmap_local_pfn(pfn);
-
-	if (!userbuf) {
-		memcpy(buf, vaddr + offset, csize);
-	} else {
-		if (copy_to_user(buf, vaddr + offset, csize))
-			csize = -EFAULT;
-	}
-
+	csize = copy_to_iter(vaddr + offset, csize, iter);
 	kunmap_local(vaddr);
 
 	return csize;
diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
index a7f617a3981d..f922d51c9d1f 100644
--- a/arch/x86/kernel/crash_dump_64.c
+++ b/arch/x86/kernel/crash_dump_64.c
@@ -8,12 +8,12 @@ 
 
 #include <linux/errno.h>
 #include <linux/crash_dump.h>
-#include <linux/uaccess.h>
+#include <linux/uio.h>
 #include <linux/io.h>
 #include <linux/cc_platform.h>
 
-static ssize_t __copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
-				  unsigned long offset, int userbuf,
+static ssize_t __copy_oldmem_page(struct iov_iter *iter, unsigned long pfn,
+				  size_t csize, unsigned long offset,
 				  bool encrypted)
 {
 	void  *vaddr;
@@ -29,47 +29,28 @@  static ssize_t __copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
 	if (!vaddr)
 		return -ENOMEM;
 
-	if (userbuf) {
-		if (copy_to_user((void __user *)buf, vaddr + offset, csize)) {
-			iounmap((void __iomem *)vaddr);
-			return -EFAULT;
-		}
-	} else
-		memcpy(buf, vaddr + offset, csize);
+	csize = copy_to_iter(vaddr + offset, csize, iter);
 
 	set_iounmap_nonlazy();
 	iounmap((void __iomem *)vaddr);
 	return csize;
 }
 
-/**
- * copy_oldmem_page - copy one page of memory
- * @pfn: page frame number to be copied
- * @buf: target memory address for the copy; this can be in kernel address
- *	space or user address space (see @userbuf)
- * @csize: number of bytes to copy
- * @offset: offset in bytes into the page (based on pfn) to begin the copy
- * @userbuf: if set, @buf is in user address space, use copy_to_user(),
- *	otherwise @buf is in kernel address space, use memcpy().
- *
- * Copy a page from the old kernel's memory. For this page, there is no pte
- * mapped in the current kernel. We stitch up a pte, similar to kmap_atomic.
- */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
-			 unsigned long offset, int userbuf)
+ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize,
+			 unsigned long offset)
 {
-	return __copy_oldmem_page(pfn, buf, csize, offset, userbuf, false);
+	return __copy_oldmem_page(iter, pfn, csize, offset, false);
 }
 
-/**
+/*
  * copy_oldmem_page_encrypted - same as copy_oldmem_page() above but ioremap the
  * memory with the encryption mask set to accommodate kdump on SME-enabled
  * machines.
  */
-ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
-				   unsigned long offset, int userbuf)
+ssize_t copy_oldmem_page_encrypted(struct iov_iter *iter, unsigned long pfn,
+				   size_t csize, unsigned long offset)
 {
-	return __copy_oldmem_page(pfn, buf, csize, offset, userbuf, true);
+	return __copy_oldmem_page(iter, pfn, csize, offset, true);
 }
 
 ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos)
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 6f1b8ddc6f7a..54dda2e19ed1 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -26,6 +26,7 @@ 
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
 #include <linux/uaccess.h>
+#include <linux/uio.h>
 #include <linux/cc_platform.h>
 #include <asm/io.h>
 #include "internal.h"
@@ -128,9 +129,8 @@  static int open_vmcore(struct inode *inode, struct file *file)
 }
 
 /* Reads a page from the oldmem device from given offset. */
-ssize_t read_from_oldmem(char *buf, size_t count,
-			 u64 *ppos, int userbuf,
-			 bool encrypted)
+static ssize_t read_from_oldmem_iter(struct iov_iter *iter, size_t count,
+			 u64 *ppos, bool encrypted)
 {
 	unsigned long pfn, offset;
 	size_t nr_bytes;
@@ -152,29 +152,23 @@  ssize_t read_from_oldmem(char *buf, size_t count,
 
 		/* If pfn is not ram, return zeros for sparse dump files */
 		if (!pfn_is_ram(pfn)) {
-			tmp = 0;
-			if (!userbuf)
-				memset(buf, 0, nr_bytes);
-			else if (clear_user(buf, nr_bytes))
-				tmp = -EFAULT;
+			tmp = iov_iter_zero(nr_bytes, iter);
 		} else {
 			if (encrypted)
-				tmp = copy_oldmem_page_encrypted(pfn, buf,
+				tmp = copy_oldmem_page_encrypted(iter, pfn,
 								 nr_bytes,
-								 offset,
-								 userbuf);
+								 offset);
 			else
-				tmp = copy_oldmem_page(pfn, buf, nr_bytes,
-						       offset, userbuf);
+				tmp = copy_oldmem_page(iter, pfn, nr_bytes,
+						       offset);
 		}
-		if (tmp < 0) {
+		if (tmp < nr_bytes) {
 			srcu_read_unlock(&vmcore_cb_srcu, idx);
-			return tmp;
+			return -EFAULT;
 		}
 
 		*ppos += nr_bytes;
 		count -= nr_bytes;
-		buf += nr_bytes;
 		read += nr_bytes;
 		++pfn;
 		offset = 0;
@@ -184,6 +178,27 @@  ssize_t read_from_oldmem(char *buf, size_t count,
 	return read;
 }
 
+ssize_t read_from_oldmem(char *buf, size_t count,
+			 u64 *ppos, int userbuf,
+			 bool encrypted)
+{
+	struct iov_iter iter;
+	struct iovec iov;
+	struct kvec kvec;
+
+	if (userbuf) {
+		iov.iov_base = (__force void __user *)buf;
+		iov.iov_len = count;
+		iov_iter_init(&iter, READ, &iov, 1, count);
+	} else {
+		kvec.iov_base = buf;
+		kvec.iov_len = count;
+		iov_iter_kvec(&iter, READ, &kvec, 1, count);
+	}
+
+	return read_from_oldmem_iter(&iter, count, ppos, encrypted);
+}
+
 /*
  * Architectures may override this function to allocate ELF header in 2nd kernel
  */
@@ -228,11 +243,10 @@  int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
 /*
  * Architectures which support memory encryption override this.
  */
-ssize_t __weak
-copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize,
-			   unsigned long offset, int userbuf)
+ssize_t __weak copy_oldmem_page_encrypted(struct iov_iter *iter,
+		unsigned long pfn, size_t csize, unsigned long offset)
 {
-	return copy_oldmem_page(pfn, buf, csize, offset, userbuf);
+	return copy_oldmem_page(iter, pfn, csize, offset);
 }
 
 /*
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
index 620821549b23..a1cf7d5c03c7 100644
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -24,11 +24,10 @@  extern int remap_oldmem_pfn_range(struct vm_area_struct *vma,
 				  unsigned long from, unsigned long pfn,
 				  unsigned long size, pgprot_t prot);
 
-extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
-						unsigned long, int);
-extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf,
-					  size_t csize, unsigned long offset,
-					  int userbuf);
+ssize_t copy_oldmem_page(struct iov_iter *i, unsigned long pfn, size_t csize,
+		unsigned long offset);
+ssize_t copy_oldmem_page_encrypted(struct iov_iter *iter, unsigned long pfn,
+				   size_t csize, unsigned long offset);
 
 void vmcore_cleanup(void);