Re: [RFC PATCH 4/5] arm64: mm: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef

2021-12-03 Thread Catalin Marinas
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

2021-12-03 Thread Emil Renner Berthing
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

2021-12-03 Thread Russell King (Oracle)
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.

2021-12-03 Thread Veronika Kabatova
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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

2021-12-03 Thread Amit Daniel Kachhap
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