linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Lianbo Jiang <lijiang@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: kexec@lists.infradead.org, tglx@linutronix.de, bp@alien8.de,
	mingo@redhat.com, x86@kernel.org, hpa@zytor.com,
	dyoung@redhat.com, bhe@redhat.com, k-hagio@ab.jp.nec.com
Subject: [PATCH 2/3] kexec: Improve the crash_exclude_mem_range() to handle the overlapping ranges
Date: Tue,  4 Aug 2020 12:49:32 +0800	[thread overview]
Message-ID: <20200804044933.1973-3-lijiang@redhat.com> (raw)
In-Reply-To: <20200804044933.1973-1-lijiang@redhat.com>

The crash_exclude_mem_range() can only handle one memory region one time.
It will fail the case in which the passed in area covers several memory
regions. In the case, it will only exclude the first region, then return,
but leave the later regions unsolved.

E.g in a NEC system with two usable RAM regions inside the low 1M:
...
BIOS-e820: [mem 0x0000000000000000-0x000000000003efff] usable
BIOS-e820: [mem 0x000000000003f000-0x000000000003ffff] reserved
BIOS-e820: [mem 0x0000000000040000-0x000000000009ffff] usable

It will only exclude the memory region [0, 0x3efff], the memory region
[0x40000, 0x9ffff] will still be added into /proc/vmcore, which may cause
the following failure when dumping the vmcore:

ioremap on RAM at 0x0000000000040000 - 0x0000000000040fff
WARNING: CPU: 0 PID: 665 at arch/x86/mm/ioremap.c:186 __ioremap_caller+0x2c7/0x2e0
...
RIP: 0010:__ioremap_caller+0x2c7/0x2e0
Code: 05 20 47 1c 01 48 09 c5 e9 93 fe ff ff 48 8d 54 24 28 48 8d 74 24 18 48 c7
      c7 85 e7 09 82 c6 05 b4 10 36 01 01 e8 32 91 04 00 <0f> 0b 45 31 ff e9 f3
      fe ff ff e8 2a 8e 04 00 66 2e 0f 1f 84 00 00
RSP: 0018:ffffc9000071fd60 EFLAGS: 00010286
RAX: 0000000000000000 RBX: 0000000000040000 RCX: 0000000000000000
RDX: ffff8880620268c0 RSI: ffff888062016a08 RDI: ffff888062016a08
RBP: 0000000000000000 R08: 0000000000000441 R09: 0000000000000048
R10: 0000000000000000 R11: ffffc9000071fc08 R12: 00007f794c343000
R13: 0000000000001000 R14: 0000000000000000 R15: 0000000000000000
FS:  00007f794c352800(0000) GS:ffff888062000000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f794c350000 CR3: 000000005df9c005 CR4: 00000000001606b0
Call Trace:
? __copy_oldmem_page.part.0+0x9c/0xb0
__copy_oldmem_page.part.0+0x9c/0xb0
read_from_oldmem.part.2+0xe2/0x140
read_vmcore+0xd8/0x2f0
proc_reg_read+0x39/0x60
vfs_read+0x91/0x140
ksys_read+0x4f/0xb0
do_syscall_64+0x5b/0x1a0
entry_SYSCALL_64_after_hwframe+0x65/0xca
cp: error reading '/proc/vmcore': Cannot allocate memory
kdump: saving vmcore failed

In order to solve this issue, let's extend the crash_exclude_mem_range()
to handle the overlapping ranges.

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
 kernel/kexec_file.c | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 09cc78df53c6..41616b6a80ad 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -1157,24 +1157,26 @@ int crash_exclude_mem_range(struct crash_mem *mem,
 			    unsigned long long mstart, unsigned long long mend)
 {
 	int i, j;
-	unsigned long long start, end;
+	unsigned long long start, end, p_start, p_end;
 	struct crash_mem_range temp_range = {0, 0};
 
 	for (i = 0; i < mem->nr_ranges; i++) {
 		start = mem->ranges[i].start;
 		end = mem->ranges[i].end;
+		p_start = mstart;
+		p_end = mend;
 
 		if (mstart > end || mend < start)
 			continue;
 
 		/* Truncate any area outside of range */
 		if (mstart < start)
-			mstart = start;
+			p_start = start;
 		if (mend > end)
-			mend = end;
+			p_end = end;
 
 		/* Found completely overlapping range */
-		if (mstart == start && mend == end) {
+		if (p_start == start && p_end == end) {
 			mem->ranges[i].start = 0;
 			mem->ranges[i].end = 0;
 			if (i < mem->nr_ranges - 1) {
@@ -1185,20 +1187,29 @@ int crash_exclude_mem_range(struct crash_mem *mem,
 					mem->ranges[j].end =
 							mem->ranges[j+1].end;
 				}
+
+				/*
+				 * Continue to check if there are another overlapping ranges
+				 * from the current position because of shifting the above
+				 * mem ranges.
+				 */
+				i--;
+				mem->nr_ranges--;
+				continue;
 			}
 			mem->nr_ranges--;
 			return 0;
 		}
 
-		if (mstart > start && mend < end) {
+		if (p_start > start && p_end < end) {
 			/* Split original range */
-			mem->ranges[i].end = mstart - 1;
-			temp_range.start = mend + 1;
+			mem->ranges[i].end = p_start - 1;
+			temp_range.start = p_end + 1;
 			temp_range.end = end;
-		} else if (mstart != start)
-			mem->ranges[i].end = mstart - 1;
+		} else if (p_start != start)
+			mem->ranges[i].end = p_start - 1;
 		else
-			mem->ranges[i].start = mend + 1;
+			mem->ranges[i].start = p_end + 1;
 		break;
 	}
 
-- 
2.17.1


  parent reply	other threads:[~2020-08-04  4:50 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-04  4:49 [PATCH 0/3] x86/kexec_file: Fix some corners bugs and improve the crash_exclude_mem_range() Lianbo Jiang
2020-08-04  4:49 ` [PATCH 1/3] x86/crash: Correct the address boundary of function parameters Lianbo Jiang
2020-08-06 17:10   ` [tip: x86/urgent] " tip-bot2 for Lianbo Jiang
2020-08-06 23:38   ` tip-bot2 for Lianbo Jiang
2020-08-04  4:49 ` Lianbo Jiang [this message]
2020-08-06 17:10   ` [tip: x86/urgent] kexec: Improve & fix crash_exclude_mem_range() to handle overlapping ranges tip-bot2 for Lianbo Jiang
2020-08-06 23:38   ` tip-bot2 for Lianbo Jiang
2020-08-04  4:49 ` [PATCH 3/3] kexec_file: correctly output debugging information for the PT_LOAD elf header Lianbo Jiang
2020-08-06 17:10   ` [tip: x86/urgent] kexec_file: Correctly output debugging information for the PT_LOAD ELF header tip-bot2 for Lianbo Jiang
2020-08-06 23:38   ` tip-bot2 for Lianbo Jiang
2020-08-05  6:36 ` [PATCH 0/3] x86/kexec_file: Fix some corners bugs and improve the crash_exclude_mem_range() Dave Young

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=20200804044933.1973-3-lijiang@redhat.com \
    --to=lijiang@redhat.com \
    --cc=bhe@redhat.com \
    --cc=bp@alien8.de \
    --cc=dyoung@redhat.com \
    --cc=hpa@zytor.com \
    --cc=k-hagio@ab.jp.nec.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).