From: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
To: Ralf Baechle <ralf@linux-mips.org>, <linux-mips@linux-mips.org>
Subject: [PATCH 03/10] MIPS: init: ensure bootmem does not corrupt reserved memory
Date: Wed, 23 Nov 2016 14:43:45 +0100 [thread overview]
Message-ID: <1479908632-30392-4-git-send-email-marcin.nowakowski@imgtec.com> (raw)
In-Reply-To: <1479908632-30392-1-git-send-email-marcin.nowakowski@imgtec.com>
Current init code initialises bootmem allocator with all of the low
memory that it assumes is available, but does not check for reserved
memory block, which can lead to corruption of data that may be stored
there.
Move bootmem's allocation map to a location that does not cross any
reserved regions
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 71 insertions(+), 3 deletions(-)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 8ebad24..64b38d4 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -153,6 +153,35 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add
add_memory_region(start, size, BOOT_MEM_RAM);
}
+bool __init memory_region_available(phys_addr_t start, phys_addr_t size)
+{
+ int i;
+ bool in_ram = false, free = true;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ phys_addr_t start_, end_;
+
+ start_ = boot_mem_map.map[i].addr;
+ end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size;
+
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RAM:
+ if (start >= start_ && start + size <= end_)
+ in_ram = true;
+ break;
+ case BOOT_MEM_RESERVED:
+ if ((start >= start_ && start < end_) ||
+ (start < start_ && start + size >= start_))
+ free = false;
+ break;
+ default:
+ continue;
+ }
+ }
+
+ return in_ram && free;
+}
+
static void __init print_memory_map(void)
{
int i;
@@ -332,11 +361,19 @@ static void __init bootmem_init(void)
#else /* !CONFIG_SGI_IP27 */
+static unsigned long __init bootmap_bytes(unsigned long pages)
+{
+ unsigned long bytes = DIV_ROUND_UP(pages, 8);
+
+ return ALIGN(bytes, sizeof(long));
+}
+
static void __init bootmem_init(void)
{
unsigned long reserved_end;
unsigned long mapstart = ~0UL;
unsigned long bootmap_size;
+ bool bootmap_valid = false;
int i;
/*
@@ -430,11 +467,42 @@ static void __init bootmem_init(void)
#endif
/*
- * Initialize the boot-time allocator with low memory only.
+ * check that mapstart doesn't overlap with any of
+ * memory regions that have been reserved through eg. DTB
*/
- bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart,
- min_low_pfn, max_low_pfn);
+ bootmap_size = bootmap_bytes(max_low_pfn - min_low_pfn);
+
+ bootmap_valid = memory_region_available(PFN_PHYS(mapstart),
+ bootmap_size);
+ for (i = 0; i < boot_mem_map.nr_map && !bootmap_valid; i++) {
+ unsigned long mapstart_addr;
+
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RESERVED:
+ mapstart_addr = PFN_ALIGN(boot_mem_map.map[i].addr +
+ boot_mem_map.map[i].size);
+ if (PHYS_PFN(mapstart_addr) < mapstart)
+ break;
+
+ bootmap_valid = memory_region_available(mapstart_addr,
+ bootmap_size);
+ if (bootmap_valid)
+ mapstart = PHYS_PFN(mapstart_addr);
+ break;
+ default:
+ break;
+ }
+ }
+ if (!bootmap_valid)
+ panic("No memory area to place a bootmap bitmap");
+
+ /*
+ * Initialize the boot-time allocator with low memory only.
+ */
+ if (bootmap_size != init_bootmem_node(NODE_DATA(0), mapstart,
+ min_low_pfn, max_low_pfn))
+ panic("Unexpected memory size required for bootmap");
for (i = 0; i < boot_mem_map.nr_map; i++) {
unsigned long start, end;
--
2.7.4
WARNING: multiple messages have this Message-ID (diff)
From: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
To: Ralf Baechle <ralf@linux-mips.org>, linux-mips@linux-mips.org
Subject: [PATCH 03/10] MIPS: init: ensure bootmem does not corrupt reserved memory
Date: Wed, 23 Nov 2016 14:43:45 +0100 [thread overview]
Message-ID: <1479908632-30392-4-git-send-email-marcin.nowakowski@imgtec.com> (raw)
Message-ID: <20161123134345.Ofs4id-BZhveHPrrxt3hoGD3mBi16e7oWbFAXAHFy_A@z> (raw)
In-Reply-To: <1479908632-30392-1-git-send-email-marcin.nowakowski@imgtec.com>
Current init code initialises bootmem allocator with all of the low
memory that it assumes is available, but does not check for reserved
memory block, which can lead to corruption of data that may be stored
there.
Move bootmem's allocation map to a location that does not cross any
reserved regions
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 71 insertions(+), 3 deletions(-)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 8ebad24..64b38d4 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -153,6 +153,35 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add
add_memory_region(start, size, BOOT_MEM_RAM);
}
+bool __init memory_region_available(phys_addr_t start, phys_addr_t size)
+{
+ int i;
+ bool in_ram = false, free = true;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ phys_addr_t start_, end_;
+
+ start_ = boot_mem_map.map[i].addr;
+ end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size;
+
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RAM:
+ if (start >= start_ && start + size <= end_)
+ in_ram = true;
+ break;
+ case BOOT_MEM_RESERVED:
+ if ((start >= start_ && start < end_) ||
+ (start < start_ && start + size >= start_))
+ free = false;
+ break;
+ default:
+ continue;
+ }
+ }
+
+ return in_ram && free;
+}
+
static void __init print_memory_map(void)
{
int i;
@@ -332,11 +361,19 @@ static void __init bootmem_init(void)
#else /* !CONFIG_SGI_IP27 */
+static unsigned long __init bootmap_bytes(unsigned long pages)
+{
+ unsigned long bytes = DIV_ROUND_UP(pages, 8);
+
+ return ALIGN(bytes, sizeof(long));
+}
+
static void __init bootmem_init(void)
{
unsigned long reserved_end;
unsigned long mapstart = ~0UL;
unsigned long bootmap_size;
+ bool bootmap_valid = false;
int i;
/*
@@ -430,11 +467,42 @@ static void __init bootmem_init(void)
#endif
/*
- * Initialize the boot-time allocator with low memory only.
+ * check that mapstart doesn't overlap with any of
+ * memory regions that have been reserved through eg. DTB
*/
- bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart,
- min_low_pfn, max_low_pfn);
+ bootmap_size = bootmap_bytes(max_low_pfn - min_low_pfn);
+
+ bootmap_valid = memory_region_available(PFN_PHYS(mapstart),
+ bootmap_size);
+ for (i = 0; i < boot_mem_map.nr_map && !bootmap_valid; i++) {
+ unsigned long mapstart_addr;
+
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RESERVED:
+ mapstart_addr = PFN_ALIGN(boot_mem_map.map[i].addr +
+ boot_mem_map.map[i].size);
+ if (PHYS_PFN(mapstart_addr) < mapstart)
+ break;
+
+ bootmap_valid = memory_region_available(mapstart_addr,
+ bootmap_size);
+ if (bootmap_valid)
+ mapstart = PHYS_PFN(mapstart_addr);
+ break;
+ default:
+ break;
+ }
+ }
+ if (!bootmap_valid)
+ panic("No memory area to place a bootmap bitmap");
+
+ /*
+ * Initialize the boot-time allocator with low memory only.
+ */
+ if (bootmap_size != init_bootmem_node(NODE_DATA(0), mapstart,
+ min_low_pfn, max_low_pfn))
+ panic("Unexpected memory size required for bootmap");
for (i = 0; i < boot_mem_map.nr_map; i++) {
unsigned long start, end;
--
2.7.4
next prev parent reply other threads:[~2016-11-23 13:45 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 01/10] MIPS: do not request resources for crashkernel if one isn't defined Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 02/10] MIPS: init: ensure reserved memory regions are not added to bootmem Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski [this message]
2016-11-23 13:43 ` [PATCH 03/10] MIPS: init: ensure bootmem does not corrupt reserved memory Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 04/10] MIPS: use early_init_fdt_reserve_self to protect DTB location Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 05/10] MIPS: platform: allow for DTB to be moved during kernel relocation Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 06/10] MIPS: relocate: optionally relocate the DTB Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 07/10] MIPS: fix mem=X@Y commandline processing Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 08/10] MIPS: kexec: do not reserve invalid crashkernel memory on boot Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 09/10] MIPS: kexec: add debug info about the new kexec'ed image Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 10/10] MIPS: generic/kexec: add support for a DTB passed in a separate buffer Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
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=1479908632-30392-4-git-send-email-marcin.nowakowski@imgtec.com \
--to=marcin.nowakowski@imgtec.com \
--cc=linux-mips@linux-mips.org \
--cc=ralf@linux-mips.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