Re: [RFC PATCH 4/5] arm64: mm: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
On Fri, Dec 03, 2021 at 01:11:56PM +0800, Jisheng Zhang wrote: > Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE" > by a check for "IS_ENABLED(CONFIG_BLK_DEV_INITRD)", to simplify the > code and increase compile coverage. > > Signed-off-by: Jisheng Zhang As long as it still compiles: Acked-by: Catalin Marinas ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [RFC PATCH 5/5] arm: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
Hi Jisheng, On Fri, 3 Dec 2021 at 06:22, Jisheng Zhang wrote: > Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE" > by a check for "IS_ENABLED(CONFIG_BLK_DEV_INITRD)", to simplify the The patch looks fine, but I think you mean IS_ENABLED(CONFIG_KEXEC_CORE) here, not CONFIG_BLK_DEV_INITRD. /Emil > code and increase compile coverage. > > Signed-off-by: Jisheng Zhang > --- > arch/arm/kernel/setup.c | 7 +++ > 1 file changed, 3 insertions(+), 4 deletions(-) > > diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c > index 284a80c0b6e1..f9a054a344c0 100644 > --- a/arch/arm/kernel/setup.c > +++ b/arch/arm/kernel/setup.c > @@ -973,7 +973,6 @@ static int __init init_machine_late(void) > } > late_initcall(init_machine_late); > > -#ifdef CONFIG_KEXEC > /* > * The crash region must be aligned to 128MB to avoid > * zImage relocating below the reserved region. > @@ -1001,6 +1000,9 @@ static void __init reserve_crashkernel(void) > unsigned long long total_mem; > int ret; > > + if (!IS_ENABLED(CONFIG_KEXEC_CORE)) > + return; > + > total_mem = get_total_mem(); > ret = parse_crashkernel(boot_command_line, total_mem, > _size, _base); > @@ -1056,9 +1058,6 @@ static void __init reserve_crashkernel(void) > insert_resource(_resource, _boot_res); > } > } > -#else > -static inline void reserve_crashkernel(void) {} > -#endif /* CONFIG_KEXEC */ > > void __init hyp_mode_check(void) > { > -- > 2.34.1 > > > ___ > linux-riscv mailing list > linux-ri...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: [RFC PATCH 5/5] arm: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
On Fri, Dec 03, 2021 at 01:11:57PM +0800, Jisheng Zhang wrote: > Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE" > by a check for "IS_ENABLED(CONFIG_BLK_DEV_INITRD)", to simplify the > code and increase compile coverage. > > Signed-off-by: Jisheng Zhang Reviewed-by: Russell King (Oracle) -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last! ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
Re: Compile error ppc64le: Cannot find symbol for section 11: .text.unlikely.
On Wed, Dec 1, 2021 at 3:20 AM Coiby Xu wrote: > > On Wed, Nov 24, 2021 at 09:47:43PM +0800, Baoquan He wrote: > >On 11/24/21 at 01:47pm, Veronika Kabatova wrote: > >> Hi, > >> > >> for a while we've been seen the following error when compiling > >> the mainline kernel with gcc 11.2 and binutils 2.37: > >> > >> 00:02:32 Cannot find symbol for section 11: .text.unlikely. > >> 00:02:32 kernel/kexec_file.o: failed > >> 00:02:32 make[3]: *** [scripts/Makefile.build:287: kernel/kexec_file.o] > >> Error 1 > >> 00:02:32 make[3]: *** Deleting file 'kernel/kexec_file.o' > >> 00:02:32 make[2]: *** [Makefile:1846: kernel] Error 2 > >> 00:02:32 make[2]: *** Waiting for unfinished jobs > >> > >> The error only happens with ppc64le. I've tested this with cross > >> compilation, but the only reference to the error I found suggests > >> the same happens with the native compiles as well: > >> > >> https://github.com/groeck/linux-build-test/commit/142cbefbc0d37962c9a6c7f28ee415ecd5fd1e98 > >> > >> In case it matters, the config used is the Fedora config with > >> kselftest options enabled, which you can grab from > >> > >> https://gitlab.com/redhat/red-hat-ci-tools/kernel/cki-internal-pipelines/cki-trusted-contributors/-/jobs/1760752896/artifacts/raw/artifacts/kernel-mainline.kernel.org-ppc64le-e4e737bb5c170df6135a127739a9e6148ee3da82.config > >> > >> > >> I've reached out to the Fedora compiler folks and Nick Clifton > >> suggested this is a problem with the kernel: > >> > >> This message comes from the recordmcount tool, which is part of the > >> kernel > >> sources: > >> > >> linux/scripts/recordmcount.[ch] > >> > >> It appears to be triggered when a compiler update causes code to be > >> rearranged. The problem has been reported before in various forums, > >> but in particular I found this reference: > >> > >> https://lore.kernel.org/lkml/20201204165742.3815221-2-a...@kernel.org/ > >> > >> The point of which to me at least is that this is a kernel issue > >> rather than > >> a compiler issue. Ie there must be some weak symbols in kexec_file.o > >> file > >> which need to be moved elsewhere. > > > >It could be arch_kexec_kernel_verify_sig() in kernel/kexec_file.c which > >is __weak, but not implemented in any ARCH. If true, this has been > >pointed out by Eric in one patch thread from Coiby. > > > >[PATCH v3 1/3] kexec: clean up arch_kexec_kernel_verify_sig > >http://lkml.kernel.org/r/20211018083137.338757-2-c...@redhat.com > > > >Maybe Coiby can fetch above config file and run the test to check. > > "[PATCH v3 1/3] kexec: clean up arch_kexec_kernel_verify_sig" alone > would fix the error. If I turn arch_kexec_apply_relocations{_add,} into > static function, the error would be gone. As attached is the patch would > make this error disappear. > Thank you! I can confirm the attached patch fixes the problem. Veronika > However, s390 and x86 have its own implementation of > arch_kexec_apply_relocations_add. This makes it looks like to be gcc's > issue. > > > > > >Thanks > >Baoquan > > > > -- > Best regards, > Coiby ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 13/14] s390/crash_dump: Use the new interface copy_oldmem_page_buf
The current interface copy_oldmem_page() passes user pointer without __user annotation and hence does unnecessary user/kernel pointer conversions during its implementation. Use the interface copy_oldmem_page_buf() to avoid this issue. Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger CC: Alexander Gordeev Cc: linux-s390 Signed-off-by: Amit Daniel Kachhap --- arch/s390/kernel/crash_dump.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 785d54c9350c..b1f8a908e8ca 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -214,8 +214,8 @@ static int copy_oldmem_user(void __user *dst, void *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_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) { void *src; int rc; @@ -223,10 +223,10 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, if (!csize) return 0; src = (void *) (pfn << PAGE_SHIFT) + offset; - if (userbuf) - rc = copy_oldmem_user((void __force __user *) buf, src, csize); + if (ubuf) + rc = copy_oldmem_user((void __user *) ubuf, src, csize); else - rc = copy_oldmem_kernel((void *) buf, src, csize); + rc = copy_oldmem_kernel((void *) kbuf, src, csize); return rc; } @@ -261,7 +261,7 @@ static int remap_oldmem_pfn_range_kdump(struct vm_area_struct *vma, * Remap "oldmem" for zfcp/nvme dump * * We only map available memory above HSA size. Memory below HSA size - * is read on demand using the copy_oldmem_page() function. + * is read on demand using the copy_oldmem_page_buf() function. */ static int remap_oldmem_pfn_range_zfcpdump(struct vm_area_struct *vma, unsigned long from, -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 14/14] fs/proc/vmcore: Remove the unused old interface copy_oldmem_page
As all archs have upgraded to use the new interface copy_oldmem_page_buf() so remove the unused copy_oldmem_page. Also remove the weak definitions. Cc: Dave Young Cc: Baoquan He Cc: Vivek Goyal Cc: kexec Cc: linux-fsdevel Signed-off-by: Amit Daniel Kachhap --- fs/proc/vmcore.c | 14 -- include/linux/crash_dump.h | 2 -- 2 files changed, 16 deletions(-) diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index d01b85c043dd..1edababe4bde 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -244,20 +244,6 @@ copy_oldmem_page_encrypted(unsigned long pfn, char __user *ubuf, char *kbuf, return copy_oldmem_page_buf(pfn, ubuf, kbuf, csize, offset); } -ssize_t __weak -copy_oldmem_page_buf(unsigned long pfn, char __user *ubuf, char *kbuf, -size_t csize, unsigned long offset) -{ - return -EOPNOTSUPP; -} - -ssize_t __weak -copy_oldmem_page(unsigned long pfn, char *ubuf, size_t csize, -unsigned long offset, int userbuf) -{ - return -EOPNOTSUPP; -} - /* * Copy to either kernel or user space buffer */ diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index 725c4e053ecf..e897bdc0b7bf 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -24,8 +24,6 @@ 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_buf(unsigned long pfn, char __user *ubuf, char *kbuf, size_t csize, unsigned long offset); -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 12/14] ia64/crash_dump: Use the new interface copy_oldmem_page_buf
The current interface copy_oldmem_page() passes user pointer without __user annotation and hence does unnecessary user/kernel pointer conversions during its implementation. Use the interface copy_oldmem_page_buf() to avoid this issue. Cc: linux-ia64 Signed-off-by: Amit Daniel Kachhap --- arch/ia64/kernel/crash_dump.c | 25 + 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/arch/ia64/kernel/crash_dump.c b/arch/ia64/kernel/crash_dump.c index 0ed3c3dee4cd..1aea8dbe06de 100644 --- a/arch/ia64/kernel/crash_dump.c +++ b/arch/ia64/kernel/crash_dump.c @@ -15,37 +15,38 @@ #include /** - * copy_oldmem_page - copy one page from "oldmem" + * copy_oldmem_page_buf - 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) + * @ubuf: target user memory pointer for the copy; use copy_to_user() if this + * pointer is not NULL + * @kbuf: target kernel memory pointer for the copy; use memcpy() if this + * pointer is not NULL * @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. + * Copy a page from "oldmem" into the buffer pointed by either @ubuf or @kbuf. + * 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) +copy_oldmem_page_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) { void *vaddr; if (!csize) return 0; vaddr = __va(pfn
[RFC PATCH 08/14] mips/crash_dump: Use the new interface copy_oldmem_page_buf
The current interface copy_oldmem_page() passes user pointer without __user annotation and hence does unnecessary user/kernel pointer conversions during its implementation. Use the interface copy_oldmem_page_buf() to avoid this issue. Cc: Thomas Bogendoerfer Cc: linux-mips Signed-off-by: Amit Daniel Kachhap --- arch/mips/kernel/crash_dump.c | 24 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c index 2e50f55185a6..f2406b868a27 100644 --- a/arch/mips/kernel/crash_dump.c +++ b/arch/mips/kernel/crash_dump.c @@ -3,20 +3,20 @@ #include /** - * copy_oldmem_page - copy one page from "oldmem" + * copy_oldmem_page_buf - 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) + * @ubuf: target user memory pointer for the copy; use copy_to_user() if this + * pointer is not NULL + * @kbuf: target kernel memory pointer for the copy; use memcpy() if this + * pointer is not NULL * @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. + * Copy a page from "oldmem" into buffer pointed by either @ubuf or @kbuf. 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_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) { void *vaddr; @@ -25,10 +25,10 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, vaddr = kmap_local_pfn(pfn); - if (!userbuf) { - memcpy(buf, vaddr + offset, csize); + if (kbuf) { + memcpy(kbuf, vaddr + offset, csize); } else { - if (copy_to_user(buf, vaddr + offset, csize)) + if (copy_to_user(ubuf, vaddr + offset, csize)) csize = -EFAULT; } -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 10/14] riscv/crash_dump: Use the new interface copy_oldmem_page_buf
The current interface copy_oldmem_page() passes user pointer without __user annotation and hence does unnecessary user/kernel pointer conversions during its implementation. Use the interface copy_oldmem_page_buf() to avoid this issue. Cc: Paul Walmsley Cc: Palmer Dabbelt Cc: Albert Ou Cc: linux-riscv Signed-off-by: Amit Daniel Kachhap --- arch/riscv/kernel/crash_dump.c | 25 + 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/arch/riscv/kernel/crash_dump.c b/arch/riscv/kernel/crash_dump.c index 86cc0ada5752..3a8fadcd1278 100644 --- a/arch/riscv/kernel/crash_dump.c +++ b/arch/riscv/kernel/crash_dump.c @@ -9,20 +9,21 @@ #include /** - * copy_oldmem_page() - copy one page from old kernel memory + * copy_oldmem_page_buf() - copy one page from old kernel memory * @pfn: page frame number to be copied - * @buf: buffer where the copied page is placed + * @ubuf: user buffer where the copied page is placed; use copy_to_user() if + * this pointer is not NULL + * @kbuf: kernel buffer where the copied page is placed; use memcpy() if this + * pointer is not NULL * @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. + * This function copies one page from old kernel memory into the buffer pointed + * by either @ubuf or @kbuf. 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_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) { void *vaddr; @@ -33,13 +34,13 @@ 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)) { + if (ubuf) { + if (copy_to_user(ubuf, vaddr + offset, csize)) { memunmap(vaddr); return -EFAULT; } } else - memcpy(buf, vaddr + offset, csize); + memcpy(kbuf, vaddr + offset, csize); memunmap(vaddr); return csize; -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 11/14] powerpc/crash_dump: Use the new interface copy_oldmem_page_buf
The current interface copy_oldmem_page() passes user pointer without __user annotation and hence does unnecessary user/kernel pointer conversions during its implementation. Use the interface copy_oldmem_page_buf() to avoid this issue. Cc: Michael Ellerman CC: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: linuxppc Signed-off-by: Amit Daniel Kachhap --- arch/powerpc/kernel/crash_dump.c | 33 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 5693e1c67c2b..a1c8a3a11694 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -68,33 +68,34 @@ 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) +static size_t copy_oldmem_vaddr(void *vaddr, char __user *ubuf, char *kbuf, + size_t csize, unsigned long offset) { - if (userbuf) { - if (copy_to_user((char __user *)buf, (vaddr + offset), csize)) + if (ubuf) { + if (copy_to_user(ubuf, (vaddr + offset), csize)) return -EFAULT; } else - memcpy(buf, (vaddr + offset), csize); + memcpy(kbuf, (vaddr + offset), csize); return csize; } /** - * copy_oldmem_page - copy one page from "oldmem" + * copy_oldmem_page_buf - 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) + * @ubuf: target user memory address for the copy; use copy_to_user() if this + * address is present + * @kbuf: target kernel memory address for the copy; use memcpy() if this + * address is present * @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. + * Copy a page from "oldmem" into buffer pointed by either @ubuf or @kbuf. 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_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) { void *vaddr; phys_addr_t paddr; @@ -107,10 +108,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_oldmem_vaddr(vaddr, ubuf, kbuf, csize, offset); } else { vaddr = ioremap_cache(paddr, PAGE_SIZE); - csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); + csize = copy_oldmem_vaddr(vaddr, ubuf, kbuf, csize, offset); iounmap(vaddr); } -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 09/14] sh/crash_dump: Use the new interface copy_oldmem_page_buf
The current interface copy_oldmem_page() passes user pointer without __user annotation and hence does unnecessary user/kernel pointer conversions during its implementation. Use the interface copy_oldmem_page_buf() to avoid this issue. Cc: Yoshinori Sato Cc: Rich Felker CC: linux-sh Signed-off-by: Amit Daniel Kachhap --- arch/sh/kernel/crash_dump.c | 25 + 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c index 5b41b59698c1..a80dedf1ace5 100644 --- a/arch/sh/kernel/crash_dump.c +++ b/arch/sh/kernel/crash_dump.c @@ -11,20 +11,21 @@ #include /** - * copy_oldmem_page - copy one page from "oldmem" + * copy_oldmem_page_buf - 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) + * @ubuf: target user memory pointer for the copy; use copy_to_user() if this + * pointer is not NULL + * @kbuf: target kernel memory pointer for the copy; use memcpy() if this + * pointer is not NULL * @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. + * Copy a page from "oldmem" into the buffer pointed by either @ubuf or @kbuf. + * 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_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) { void __iomem *vaddr; @@ -33,13 +34,13 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE); - if (userbuf) { - if (copy_to_user((void __user *)buf, (vaddr + offset), csize)) { + if (ubuf) { + if (copy_to_user(ubuf, (vaddr + offset), csize)) { iounmap(vaddr); return -EFAULT; } } else - memcpy(buf, (vaddr + offset), csize); + memcpy(kbuf, (vaddr + offset), csize); iounmap(vaddr); return csize; -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 07/14] arm/crash_dump: Use the new interface copy_oldmem_page_buf
The current interface copy_oldmem_page() passes user pointer without __user annotation and hence does unnecessary user/kernel pointer conversions during its implementation. Implement the interface copy_oldmem_page_buf() to avoid this issue. Cc: Russell King Cc: linux-arm-kernel Signed-off-by: Amit Daniel Kachhap --- arch/arm/kernel/crash_dump.c | 21 ++--- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/arch/arm/kernel/crash_dump.c b/arch/arm/kernel/crash_dump.c index 53cb92435392..bb0395ab9f98 100644 --- a/arch/arm/kernel/crash_dump.c +++ b/arch/arm/kernel/crash_dump.c @@ -16,20 +16,19 @@ #include /** - * copy_oldmem_page() - copy one page from old kernel memory + * copy_oldmem_page_buf() - copy one page from old kernel memory * @pfn: page frame number to be copied - * @buf: buffer where the copied page is placed + * @ubuf: user buffer where the copied page is placed + * @kbuf: kernel 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. + * either @ubuf or @kbuf. 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_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) { void *vaddr; @@ -40,13 +39,13 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, if (!vaddr) return -ENOMEM; - if (userbuf) { - if (copy_to_user(buf, vaddr + offset, csize)) { + if (ubuf) { + if (copy_to_user(ubuf, vaddr + offset, csize)) { iounmap(vaddr); return -EFAULT; } } else { - memcpy(buf, vaddr + offset, csize); + memcpy(kbuf, vaddr + offset, csize); } iounmap(vaddr); -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 05/14] x86/crash_dump_32: Use the new interface copy_oldmem_page_buf
The current interface copy_oldmem_page() passes user pointer without __user annotation and hence does unnecessary user/kernel pointer conversions during its implementation. Implement the interface copy_oldmem_page_buf() to avoid this issue. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x86 Signed-off-by: Amit Daniel Kachhap --- arch/x86/kernel/crash_dump_32.c | 24 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c index 5fcac46aaf6b..9932cd62ded1 100644 --- a/arch/x86/kernel/crash_dump_32.c +++ b/arch/x86/kernel/crash_dump_32.c @@ -30,20 +30,20 @@ static inline bool is_crashed_pfn_valid(unsigned long pfn) } /** - * copy_oldmem_page - copy one page from "oldmem" + * copy_oldmem_page_buf - 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) + * @ubuf: target user memory pointer for the copy; use copy_to_user() if this + * pointer is not NULL + * @kbuf: target kernel memory pointer for the copy; use memcpy() if this + * pointer is not NULL * @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. + * Copy a page from "oldmem" into the buffer pointed by either @ubuf or @kbuf. + * 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_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) { void *vaddr; @@ -55,10 +55,10 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, vaddr = kmap_local_pfn(pfn); - if (!userbuf) { - memcpy(buf, vaddr + offset, csize); + if (!ubuf) { + memcpy(kbuf, vaddr + offset, csize); } else { - if (copy_to_user(buf, vaddr + offset, csize)) + if (copy_to_user(ubuf, vaddr + offset, csize)) csize = -EFAULT; } -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 06/14] arm64/crash_dump: Use the new interface copy_oldmem_page_buf
The current interface copy_oldmem_page() passes user pointer without __user annotation and hence does unnecessary user/kernel pointer conversions during its implementation. Implement the interface copy_oldmem_page_buf() to avoid this issue. Cc: Catalin Marinas Cc: Will Deacon Cc: linux-arm-kernel Signed-off-by: Amit Daniel Kachhap --- arch/arm64/kernel/crash_dump.c | 21 ++--- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/arch/arm64/kernel/crash_dump.c b/arch/arm64/kernel/crash_dump.c index 58303a9ec32c..ec9d5c80726c 100644 --- a/arch/arm64/kernel/crash_dump.c +++ b/arch/arm64/kernel/crash_dump.c @@ -14,20 +14,19 @@ #include /** - * copy_oldmem_page() - copy one page from old kernel memory + * copy_oldmem_page_buf() - copy one page from old kernel memory * @pfn: page frame number to be copied - * @buf: buffer where the copied page is placed + * @ubuf: user buffer where the copied page is placed + * @kbuf: kernel 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. + * either @ubuf or @kbuf. 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_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) { void *vaddr; @@ -38,13 +37,13 @@ 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)) { + if (ubuf) { + if (copy_to_user(ubuf, vaddr + offset, csize)) { memunmap(vaddr); return -EFAULT; } } else { - memcpy(buf, vaddr + offset, csize); + memcpy(kbuf, vaddr + offset, csize); } memunmap(vaddr); -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 00/14] fs/proc/vmcore: Remove unnecessary user pointer conversions
Hi, This series aims to restructure the external interfaces as well internal code used in fs/proc/vmcore.c by removing the interchangeable use of user and kernel pointers. This unnecessary conversion may obstruct the tools such as sparse in generating meaningful results. This also simplifies the things by keeping the user and kernel pointers separate during propagation. The external interfaces such as copy_oldmem_page, copy_oldmem_page_encrypted and read_from_oldmem are used across different architectures. The goal here is to update one architecture at a time and hence there is an extra cleanup done in the end to remove the intermediaries. In this series, an extra user pointer is added as a parameter to all the above functions instead of an union as there were disagreement in earlier ideas of using universal pointer [1,2]. This series is posted as RFC so as to find out an acceptable way of handling this use case. This series is based on v5.16-rc3 and is compile tested for modified architectures and boot tested in qemu for all architectures except ia64. Note: This patch series breaks the crash dump functionality after patch 3 and is restored after each arch implements its own copy_oldmem_page_buf() interface. Thanks, Amit Daniel [1]: https://lore.kernel.org/lkml/20200624162901.1814136-2-...@lst.de/ [2]: https://lore.kernel.org/lkml/CAHk-=wit9enePELG=-hnlsr0ny5bucfnjqaqwoftuydgr1p...@mail.gmail.com/ Amit Daniel Kachhap (14): fs/proc/vmcore: Update read_from_oldmem() for user pointer fs/proc/vmcore: Update copy_oldmem_page_encrypted() for user buffer fs/proc/vmcore: Update copy_oldmem_page() for user buffer x86/crash_dump_64: Use the new interface copy_oldmem_page_buf x86/crash_dump_32: Use the new interface copy_oldmem_page_buf arm64/crash_dump: Use the new interface copy_oldmem_page_buf arm/crash_dump: Use the new interface copy_oldmem_page_buf mips/crash_dump: Use the new interface copy_oldmem_page_buf sh/crash_dump: Use the new interface copy_oldmem_page_buf riscv/crash_dump: Use the new interface copy_oldmem_page_buf powerpc/crash_dump: Use the new interface copy_oldmem_page_buf ia64/crash_dump: Use the new interface copy_oldmem_page_buf s390/crash_dump: Use the new interface copy_oldmem_page_buf fs/proc/vmcore: Remove the unused old interface copy_oldmem_page arch/arm/kernel/crash_dump.c | 21 arch/arm64/kernel/crash_dump.c | 21 arch/ia64/kernel/crash_dump.c| 25 +- arch/mips/kernel/crash_dump.c| 24 - arch/powerpc/kernel/crash_dump.c | 33 +++-- arch/riscv/kernel/crash_dump.c | 25 +- arch/s390/kernel/crash_dump.c| 12 ++--- arch/sh/kernel/crash_dump.c | 25 +- arch/x86/kernel/crash_dump_32.c | 24 - arch/x86/kernel/crash_dump_64.c | 48 +- fs/proc/vmcore.c | 85 +--- include/linux/crash_dump.h | 23 + 12 files changed, 189 insertions(+), 177 deletions(-) -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 01/14] fs/proc/vmcore: Update read_from_oldmem() for user pointer
The exported interface read_from_oldmem() passes user pointer without __user annotation and does unnecessary user/kernel pointer conversions during the pointer propagation. Hence it is modified to have a new parameter for user pointer. Also a helper macro read_from_oldmem_to_kernel is added for clear readability from callsite when calling read_from_oldmem() for copying to kernel buffer. There are several internal functions used here such as read_vmcore(), __read_vmcore(), copy_to() and vmcoredd_copy_dumps() which are re-structured to avoid the unnecessary user/kernel pointer conversions. x86_64 crash dump is also modified to use this new interface. No functionality change intended. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Young Cc: Baoquan He Cc: Vivek Goyal Cc: x86 Cc: kexec Cc: linux-fsdevel Signed-off-by: Amit Daniel Kachhap --- arch/x86/kernel/crash_dump_64.c | 4 +- fs/proc/vmcore.c| 88 +++-- include/linux/crash_dump.h | 12 +++-- 3 files changed, 60 insertions(+), 44 deletions(-) diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c index a7f617a3981d..6433513ef43a 100644 --- a/arch/x86/kernel/crash_dump_64.c +++ b/arch/x86/kernel/crash_dump_64.c @@ -74,6 +74,6 @@ ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char *buf, size_t csize, ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) { - return read_from_oldmem(buf, count, ppos, 0, - cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)); + return read_from_oldmem_to_kernel(buf, count, ppos, + cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)); } diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 509f85148fee..39b4353bd37c 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -70,6 +70,14 @@ static bool vmcore_cb_unstable; /* Whether the vmcore has been opened once. */ static bool vmcore_opened; +#define ptr_add(utarget, ktarget, size)\ +({ \ + if (utarget)\ + utarget += size;\ + else\ + ktarget += size;\ +}) + void register_vmcore_cb(struct vmcore_cb *cb) { down_write(_cb_rwsem); @@ -132,9 +140,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) +ssize_t read_from_oldmem(char __user *ubuf, char *kbuf, size_t count, +u64 *ppos, bool encrypted) { unsigned long pfn, offset; size_t nr_bytes; @@ -156,19 +163,27 @@ 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)) + if (kbuf) + memset(kbuf, 0, nr_bytes); + else if (clear_user(ubuf, nr_bytes)) tmp = -EFAULT; } else { - if (encrypted) - tmp = copy_oldmem_page_encrypted(pfn, buf, + if (encrypted && ubuf) + tmp = copy_oldmem_page_encrypted(pfn, +(__force char *)ubuf, +nr_bytes, +offset, 1); + else if (encrypted && kbuf) + tmp = copy_oldmem_page_encrypted(pfn, +kbuf, nr_bytes, -offset, -userbuf); +offset, 0); + else if (ubuf) + tmp = copy_oldmem_page(pfn, (__force char *)ubuf, + nr_bytes, offset, 1); else - tmp = copy_oldmem_page(pfn, buf, nr_bytes, - offset, userbuf); + tmp = copy_oldmem_page(pfn, kbuf, nr_bytes, + offset, 0); } if (tmp
[RFC PATCH 02/14] fs/proc/vmcore: Update copy_oldmem_page_encrypted() for user buffer
The exported interface copy_oldmem_page_encrypted() passes user pointer without __user annotation and does unnecessary user/kernel pointer conversions during the pointer propagation. Hence it is modified to have a new parameter for user pointer. The other similar interface copy_oldmem_page() will be updated in the subsequent patches. x86_64 crash dump is also modified to use this modified interface. No functionality change intended. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Young Cc: Baoquan He Cc: Vivek Goyal Cc: x86 Cc: kexec Cc: linux-fsdevel Signed-off-by: Amit Daniel Kachhap --- arch/x86/kernel/crash_dump_64.c | 12 +--- fs/proc/vmcore.c| 24 +++- include/linux/crash_dump.h | 6 +++--- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c index 6433513ef43a..99cd505628fa 100644 --- a/arch/x86/kernel/crash_dump_64.c +++ b/arch/x86/kernel/crash_dump_64.c @@ -66,10 +66,16 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, * 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(unsigned long pfn, char __user *ubuf, + char *kbuf, size_t csize, + unsigned long offset) { - return __copy_oldmem_page(pfn, buf, csize, offset, userbuf, true); + if (ubuf) + return __copy_oldmem_page(pfn, (__force char *)ubuf, csize, + offset, 1, true); + else + return __copy_oldmem_page(pfn, kbuf, csize, + offset, 0, 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 39b4353bd37c..fa4492ef6124 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -168,16 +168,10 @@ ssize_t read_from_oldmem(char __user *ubuf, char *kbuf, size_t count, else if (clear_user(ubuf, nr_bytes)) tmp = -EFAULT; } else { - if (encrypted && ubuf) - tmp = copy_oldmem_page_encrypted(pfn, -(__force char *)ubuf, -nr_bytes, -offset, 1); - else if (encrypted && kbuf) - tmp = copy_oldmem_page_encrypted(pfn, -kbuf, -nr_bytes, -offset, 0); + if (encrypted) + tmp = copy_oldmem_page_encrypted(pfn, ubuf, +kbuf, nr_bytes, +offset); else if (ubuf) tmp = copy_oldmem_page(pfn, (__force char *)ubuf, nr_bytes, offset, 1); @@ -247,10 +241,14 @@ 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) +copy_oldmem_page_encrypted(unsigned long pfn, char __user *ubuf, char *kbuf, + size_t csize, unsigned long offset) { - return copy_oldmem_page(pfn, buf, csize, offset, userbuf); + if (ubuf) + return copy_oldmem_page(pfn, (__force char *)ubuf, csize, + offset, 1); + else + return copy_oldmem_page(pfn, kbuf, csize, offset, 0); } /* diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index eb0ed423ccc8..36a7f08f4ad2 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -26,9 +26,9 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma, 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); +extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, + char __user *ubuf,
[RFC PATCH 03/14] fs/proc/vmcore: Update copy_oldmem_page() for user buffer
The exported interface copy_oldmem_page passes user pointer without __user annotation and does unnecessary user/kernel pointer conversions during the pointer propagation. Hence it is modified to have a new parameter for user pointer. However instead of updating it directly a new interface copy_oldmem_page_buf() is added as copy_oldmem_page() is used across different archs. This old interface copy_oldmem_page() will be deleted after all the archs are modified to use the new interface. The weak implementation of both copy_oldmem_page() and copy_oldmem_page_buf() are added temporarily to keep the kernel building for the subsequent patches. As a consequence, crash dump is temporarily broken for the archs till the patch where it implements its own copy_oldmem_page_buf(). Cc: Dave Young Cc: Baoquan He Cc: Vivek Goyal Cc: kexec Cc: linux-fsdevel Signed-off-by: Amit Daniel Kachhap --- fs/proc/vmcore.c | 27 +-- include/linux/crash_dump.h | 3 +++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index fa4492ef6124..d01b85c043dd 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -172,12 +172,9 @@ ssize_t read_from_oldmem(char __user *ubuf, char *kbuf, size_t count, tmp = copy_oldmem_page_encrypted(pfn, ubuf, kbuf, nr_bytes, offset); - else if (ubuf) - tmp = copy_oldmem_page(pfn, (__force char *)ubuf, - nr_bytes, offset, 1); else - tmp = copy_oldmem_page(pfn, kbuf, nr_bytes, - offset, 0); + tmp = copy_oldmem_page_buf(pfn, ubuf, kbuf, + nr_bytes, offset); } if (tmp < 0) { up_read(_cb_rwsem); @@ -244,11 +241,21 @@ ssize_t __weak copy_oldmem_page_encrypted(unsigned long pfn, char __user *ubuf, char *kbuf, size_t csize, unsigned long offset) { - if (ubuf) - return copy_oldmem_page(pfn, (__force char *)ubuf, csize, - offset, 1); - else - return copy_oldmem_page(pfn, kbuf, csize, offset, 0); + return copy_oldmem_page_buf(pfn, ubuf, kbuf, csize, offset); +} + +ssize_t __weak +copy_oldmem_page_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) +{ + return -EOPNOTSUPP; +} + +ssize_t __weak +copy_oldmem_page(unsigned long pfn, char *ubuf, size_t csize, +unsigned long offset, int userbuf) +{ + return -EOPNOTSUPP; } /* diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index 36a7f08f4ad2..725c4e053ecf 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -26,6 +26,9 @@ extern int remap_oldmem_pfn_range(struct vm_area_struct *vma, extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, unsigned long, int); +extern ssize_t copy_oldmem_page_buf(unsigned long pfn, char __user *ubuf, + char *kbuf, size_t csize, + unsigned long offset); extern ssize_t copy_oldmem_page_encrypted(unsigned long pfn, char __user *ubuf, char *kbuf, size_t csize, unsigned long offset); -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
[RFC PATCH 04/14] x86/crash_dump_64: Use the new interface copy_oldmem_page_buf
The current interface copy_oldmem_page() passes user pointer without __user annotation and hence does unnecessary user/kernel pointer conversions during its implementation. Implement the interface copy_oldmem_page_buf() to avoid this issue. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: Dave Hansen Cc: x86 Signed-off-by: Amit Daniel Kachhap --- arch/x86/kernel/crash_dump_64.c | 44 +++-- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c index 99cd505628fa..7a6fa797260f 100644 --- a/arch/x86/kernel/crash_dump_64.c +++ b/arch/x86/kernel/crash_dump_64.c @@ -12,9 +12,9 @@ #include #include -static ssize_t __copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, - unsigned long offset, int userbuf, - bool encrypted) +static ssize_t __copy_oldmem_page(unsigned long pfn, char __user *ubuf, + char *kbuf, size_t csize, + unsigned long offset, bool encrypted) { void *vaddr; @@ -29,13 +29,13 @@ 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)) { + if (ubuf) { + if (copy_to_user(ubuf, vaddr + offset, csize)) { iounmap((void __iomem *)vaddr); return -EFAULT; } } else - memcpy(buf, vaddr + offset, csize); + memcpy(kbuf, vaddr + offset, csize); set_iounmap_nonlazy(); iounmap((void __iomem *)vaddr); @@ -43,39 +43,35 @@ static ssize_t __copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, } /** - * copy_oldmem_page - copy one page of memory + * copy_oldmem_page_buf - 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) + * @ubuf: target user memory pointer for the copy; use copy_to_user() if this + * pointer is not NULL + * @kbuf: target kernel memory pointer for the copy; use memcpy() if this + * pointer is not NULL * @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. + * Copy a page from the old kernel's memory into the buffer pointed either by + * @ubuf or @kbuf. 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_buf(unsigned long pfn, char __user *ubuf, char *kbuf, +size_t csize, unsigned long offset) { - return __copy_oldmem_page(pfn, buf, csize, offset, userbuf, false); + return __copy_oldmem_page(pfn, ubuf, kbuf, 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 + * copy_oldmem_page_encrypted - same as copy_oldmem_page_buf() 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 __user *ubuf, char *kbuf, size_t csize, unsigned long offset) { - if (ubuf) - return __copy_oldmem_page(pfn, (__force char *)ubuf, csize, - offset, 1, true); - else - return __copy_oldmem_page(pfn, kbuf, csize, - offset, 0, true); + return __copy_oldmem_page(pfn, ubuf, kbuf, csize, offset, true); } ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) -- 2.17.1 ___ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec