All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: mm-commits@vger.kernel.org, viro@zeniv.linux.org.uk,
	tongtiangen@huawei.com, naoya.horiguchi@nec.com,
	linmiaohe@huawei.com, brauner@kernel.org, axboe@kernel.dk,
	wangkefeng.wang@huawei.com, akpm@linux-foundation.org
Subject: + mm-hwpoison-coredump-support-recovery-from-dump_user_range.patch added to mm-unstable branch
Date: Thu, 13 Apr 2023 15:04:54 -0700	[thread overview]
Message-ID: <20230413220455.735FAC433EF@smtp.kernel.org> (raw)


The patch titled
     Subject: mm: hwpoison: coredump: support recovery from dump_user_range()
has been added to the -mm mm-unstable branch.  Its filename is
     mm-hwpoison-coredump-support-recovery-from-dump_user_range.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-hwpoison-coredump-support-recovery-from-dump_user_range.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: Kefeng Wang <wangkefeng.wang@huawei.com>
Subject: mm: hwpoison: coredump: support recovery from dump_user_range()
Date: Thu, 13 Apr 2023 12:13:36 +0800

The dump_user_range() is used to copy the user page to a coredump file,
but if a hardware memory error occurred during copy, which called from
__kernel_write_iter() in dump_user_range(), it crashes,

 CPU: 112 PID: 7014 Comm: mca-recover Not tainted 6.3.0-rc2 #425

 pc : __memcpy+0x110/0x260
 lr : _copy_from_iter+0x3bc/0x4c8
 ...
 Call trace:
  __memcpy+0x110/0x260
  copy_page_from_iter+0xcc/0x130
  pipe_write+0x164/0x6d8
  __kernel_write_iter+0x9c/0x210
  dump_user_range+0xc8/0x1d8
  elf_core_dump+0x308/0x368
  do_coredump+0x2e8/0xa40
  get_signal+0x59c/0x788
  do_signal+0x118/0x1f8
  do_notify_resume+0xf0/0x280
  el0_da+0x130/0x138
  el0t_64_sync_handler+0x68/0xc0
  el0t_64_sync+0x188/0x190

Generally, the '->write_iter' of file ops will use copy_page_from_iter()
and copy_page_from_iter_atomic(), change memcpy() to copy_mc_to_kernel()
in both of them to handle #MC during source read, which stop coredump
processing and kill the task instead of kernel panic, but the source
address may not always an user address, so introduce a new copy_mc flag in
struct iov_iter{} to indicate that the iter could do a safe memory copy,
also introduce the helpers to set/clear/check the flag, for now, it's only
used in coredump's dump_user_range(), but it could expand to any other
scenarios to fix the similar issue.

Link: https://lkml.kernel.org/r/20230413041336.26874-1-wangkefeng.wang@huawei.com
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Naoya Horiguchi <naoya.horiguchi@nec.com>
Cc: Tong Tiangen <tongtiangen@huawei.com>
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 fs/coredump.c       |    2 ++
 include/linux/uio.h |   26 ++++++++++++++++++++++++++
 lib/iov_iter.c      |   17 +++++++++++++++--
 3 files changed, 43 insertions(+), 2 deletions(-)

--- a/fs/coredump.c~mm-hwpoison-coredump-support-recovery-from-dump_user_range
+++ a/fs/coredump.c
@@ -882,7 +882,9 @@ static int dump_emit_page(struct coredum
 	pos = file->f_pos;
 	bvec_set_page(&bvec, page, PAGE_SIZE, 0);
 	iov_iter_bvec(&iter, ITER_SOURCE, &bvec, 1, PAGE_SIZE);
+	iov_iter_set_copy_mc(&iter);
 	n = __kernel_write_iter(cprm->file, &iter, &pos);
+	iov_iter_clear_copy_mc(&iter);
 	if (n != PAGE_SIZE)
 		return 0;
 	file->f_pos = pos;
--- a/include/linux/uio.h~mm-hwpoison-coredump-support-recovery-from-dump_user_range
+++ a/include/linux/uio.h
@@ -42,6 +42,7 @@ struct iov_iter_state {
 
 struct iov_iter {
 	u8 iter_type;
+	bool copy_mc;
 	bool nofault;
 	bool data_source;
 	bool user_backed;
@@ -126,6 +127,30 @@ static inline bool user_backed_iter(cons
 	return i->user_backed;
 }
 
+#ifdef CONFIG_ARCH_HAS_COPY_MC
+static inline void iov_iter_set_copy_mc(struct iov_iter *i)
+{
+	i->copy_mc = true;
+}
+
+static inline void iov_iter_clear_copy_mc(struct iov_iter *i)
+{
+	i->copy_mc = false;
+}
+
+static inline bool iov_iter_is_copy_mc(const struct iov_iter *i)
+{
+	return i->copy_mc;
+}
+#else
+static inline void iov_iter_set_copy_mc(struct iov_iter *i) { }
+static inline void iov_iter_clear_copy_mc(struct iov_iter *i) {}
+static inline bool iov_iter_is_copy_mc(const struct iov_iter *i)
+{
+	return false;
+}
+#endif
+
 /*
  * Total number of bytes covered by an iovec.
  *
@@ -360,6 +385,7 @@ static inline void iov_iter_ubuf(struct
 		.iter_type = ITER_UBUF,
 		.user_backed = true,
 		.data_source = direction,
+		.copy_mc = false,
 		.ubuf = buf,
 		.count = count
 	};
--- a/lib/iov_iter.c~mm-hwpoison-coredump-support-recovery-from-dump_user_range
+++ a/lib/iov_iter.c
@@ -434,6 +434,7 @@ void iov_iter_init(struct iov_iter *i, u
 	WARN_ON(direction & ~(READ | WRITE));
 	*i = (struct iov_iter) {
 		.iter_type = ITER_IOVEC,
+		.copy_mc = false,
 		.nofault = false,
 		.user_backed = true,
 		.data_source = direction,
@@ -630,6 +631,14 @@ size_t _copy_mc_to_iter(const void *addr
 EXPORT_SYMBOL_GPL(_copy_mc_to_iter);
 #endif /* CONFIG_ARCH_HAS_COPY_MC */
 
+static void *memcpy_from_iter(struct iov_iter *i, void *to, const void *from,
+				 size_t size)
+{
+       if (iov_iter_is_copy_mc(i))
+               return (void *)copy_mc_to_kernel(to, from, size);
+	return memcpy(to, from, size);
+}
+
 size_t _copy_from_iter(void *addr, size_t bytes, struct iov_iter *i)
 {
 	if (WARN_ON_ONCE(!i->data_source))
@@ -639,7 +648,7 @@ size_t _copy_from_iter(void *addr, size_
 		might_fault();
 	iterate_and_advance(i, bytes, base, len, off,
 		copyin(addr + off, base, len),
-		memcpy(addr + off, base, len)
+		memcpy_from_iter(i, addr + off, base, len)
 	)
 
 	return bytes;
@@ -862,7 +871,7 @@ size_t copy_page_from_iter_atomic(struct
 	}
 	iterate_and_advance(i, bytes, base, len, off,
 		copyin(p + off, base, len),
-		memcpy(p + off, base, len)
+		memcpy_from_iter(i, p + off, base, len)
 	)
 	kunmap_atomic(kaddr);
 	return bytes;
@@ -1043,6 +1052,7 @@ void iov_iter_kvec(struct iov_iter *i, u
 	WARN_ON(direction & ~(READ | WRITE));
 	*i = (struct iov_iter){
 		.iter_type = ITER_KVEC,
+		.copy_mc = false,
 		.data_source = direction,
 		.kvec = kvec,
 		.nr_segs = nr_segs,
@@ -1059,6 +1069,7 @@ void iov_iter_bvec(struct iov_iter *i, u
 	WARN_ON(direction & ~(READ | WRITE));
 	*i = (struct iov_iter){
 		.iter_type = ITER_BVEC,
+		.copy_mc = false,
 		.data_source = direction,
 		.bvec = bvec,
 		.nr_segs = nr_segs,
@@ -1105,6 +1116,7 @@ void iov_iter_xarray(struct iov_iter *i,
 	BUG_ON(direction & ~1);
 	*i = (struct iov_iter) {
 		.iter_type = ITER_XARRAY,
+		.copy_mc = false,
 		.data_source = direction,
 		.xarray = xarray,
 		.xarray_start = start,
@@ -1128,6 +1140,7 @@ void iov_iter_discard(struct iov_iter *i
 	BUG_ON(direction != READ);
 	*i = (struct iov_iter){
 		.iter_type = ITER_DISCARD,
+		.copy_mc = false,
 		.data_source = false,
 		.count = count,
 		.iov_offset = 0
_

Patches currently in -mm which might be from wangkefeng.wang@huawei.com are

mm-hwpoison-coredump-support-recovery-from-dump_user_range.patch


             reply	other threads:[~2023-04-13 22:04 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-13 22:04 Andrew Morton [this message]
  -- strict thread matches above, loose matches on Subject: below --
2023-04-18  1:03 + mm-hwpoison-coredump-support-recovery-from-dump_user_range.patch added to mm-unstable branch Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230413220455.735FAC433EF@smtp.kernel.org \
    --to=akpm@linux-foundation.org \
    --cc=axboe@kernel.dk \
    --cc=brauner@kernel.org \
    --cc=linmiaohe@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mm-commits@vger.kernel.org \
    --cc=naoya.horiguchi@nec.com \
    --cc=tongtiangen@huawei.com \
    --cc=viro@zeniv.linux.org.uk \
    --cc=wangkefeng.wang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.