All of lore.kernel.org
 help / color / mirror / Atom feed
From: bwalle@suse.de (Bernhard Walle)
To: kexec@lists.infradead.org, vgoyal@redhat.com
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] Limit E820 map and /proc/iomem for mem parameter on x86-64
Date: Tue, 10 Jun 2008 23:53:25 +0200	[thread overview]
Message-ID: <20080610215325.GA20673@suse.de> (raw)

This patch tries to unify the behaviour of i386 and x86-64 when parsing
the memory (mem/memmap) parameter of the kernel command line:

On i386, the view was limited (i.e. the actual view was presented).
On x86-64, the view was full (i.e. the BIOS view was presented).

This patch moves the limit_regions() function and the print_memory_map()
function to a new file e820.c, shared between the two x86 flavours. Then
it adds calls to limit_regions() in 64 bit code.

I gave the patch a bit testing. However, it's not for merging, it's just
to get early feedback to see if that goes into the right direction.


Signed-off-by: Bernhard Walle <bwalle@suse.de>

---
 arch/x86/kernel/Makefile   |    2 -
 arch/x86/kernel/e820.c     |   75 +++++++++++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/e820_32.c  |   60 +-----------------------------------
 arch/x86/kernel/e820_64.c  |    4 ++
 arch/x86/kernel/setup_32.c |    4 +-
 include/asm-x86/e820.h     |    4 ++
 6 files changed, 88 insertions(+), 61 deletions(-)

--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -22,7 +22,7 @@ obj-y			+= setup_$(BITS).o i8259_$(BITS)
 obj-$(CONFIG_X86_32)	+= sys_i386_32.o i386_ksyms_32.o
 obj-$(CONFIG_X86_64)	+= sys_x86_64.o x8664_ksyms_64.o
 obj-$(CONFIG_X86_64)	+= syscall_64.o vsyscall_64.o setup64.o
-obj-y			+= bootflag.o e820_$(BITS).o
+obj-y			+= bootflag.o e820_$(BITS).o e820.o
 obj-y			+= pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
 obj-y			+= alternative.o i8253.o pci-nommu.o
 obj-$(CONFIG_X86_64)	+= bugs_64.o
--- /dev/null
+++ b/arch/x86/kernel/e820.c
@@ -0,0 +1,75 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/ioport.h>
+#include <linux/string.h>
+#include <linux/kexec.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/pfn.h>
+#include <linux/uaccess.h>
+#include <linux/suspend.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/e820.h>
+#include <asm/setup.h>
+
+void __init limit_regions(struct e820map *e820, unsigned long long size)
+{
+	unsigned long long current_addr;
+	int i;
+
+	print_memory_map(e820, "limit_regions start");
+	for (i = 0; i < e820->nr_map; i++) {
+		current_addr = e820->map[i].addr + e820->map[i].size;
+		if (current_addr < size)
+			continue;
+
+		if (e820->map[i].type != E820_RAM)
+			continue;
+
+		if (e820->map[i].addr >= size) {
+			/*
+			 * This region starts past the end of the
+			 * requested size, skip it completely.
+			 */
+			e820->nr_map = i;
+		} else {
+			e820->nr_map = i + 1;
+			e820->map[i].size -= current_addr - size;
+		}
+		print_memory_map(e820, "limit_regions endfor");
+		return;
+	}
+	print_memory_map(e820, "limit_regions endfunc");
+}
+
+void __init print_memory_map(struct e820map *e820, char *who)
+{
+	int i;
+
+	for (i = 0; i < e820->nr_map; i++) {
+		printk(" %s: %016Lx - %016Lx ", who,
+			e820->map[i].addr,
+			e820->map[i].addr + e820->map[i].size);
+		switch (e820->map[i].type) {
+		case E820_RAM:	printk("(usable)\n");
+				break;
+		case E820_RESERVED:
+				printk("(reserved)\n");
+				break;
+		case E820_ACPI:
+				printk("(ACPI data)\n");
+				break;
+		case E820_NVS:
+				printk("(ACPI NVS)\n");
+				break;
+		default:	printk("type %u\n", e820->map[i].type);
+				break;
+		}
+	}
+}
+
+
--- a/arch/x86/kernel/e820_32.c
+++ b/arch/x86/kernel/e820_32.c
@@ -584,62 +584,6 @@ void __init e820_register_memory(void)
 		pci_mem_start, gapstart, gapsize);
 }
 
-void __init print_memory_map(char *who)
-{
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		printk(" %s: %016Lx - %016Lx ", who,
-			e820.map[i].addr,
-			e820.map[i].addr + e820.map[i].size);
-		switch (e820.map[i].type) {
-		case E820_RAM:	printk("(usable)\n");
-				break;
-		case E820_RESERVED:
-				printk("(reserved)\n");
-				break;
-		case E820_ACPI:
-				printk("(ACPI data)\n");
-				break;
-		case E820_NVS:
-				printk("(ACPI NVS)\n");
-				break;
-		default:	printk("type %u\n", e820.map[i].type);
-				break;
-		}
-	}
-}
-
-void __init limit_regions(unsigned long long size)
-{
-	unsigned long long current_addr;
-	int i;
-
-	print_memory_map("limit_regions start");
-	for (i = 0; i < e820.nr_map; i++) {
-		current_addr = e820.map[i].addr + e820.map[i].size;
-		if (current_addr < size)
-			continue;
-
-		if (e820.map[i].type != E820_RAM)
-			continue;
-
-		if (e820.map[i].addr >= size) {
-			/*
-			 * This region starts past the end of the
-			 * requested size, skip it completely.
-			 */
-			e820.nr_map = i;
-		} else {
-			e820.nr_map = i + 1;
-			e820.map[i].size -= current_addr - size;
-		}
-		print_memory_map("limit_regions endfor");
-		return;
-	}
-	print_memory_map("limit_regions endfunc");
-}
-
 /*
  * This function checks if any part of the range <start,end> is mapped
  * with type.
@@ -729,7 +673,7 @@ static int __init parse_memmap(char *arg
 			start_at = memparse(arg+1, &arg);
 			add_memory_region(start_at, mem_size, E820_RESERVED);
 		} else {
-			limit_regions(mem_size);
+			limit_regions(&e820, mem_size);
 			user_defined_memmap = 1;
 		}
 	}
@@ -771,5 +715,5 @@ void __init update_e820(void)
 		return;
 	e820.nr_map = nr_map;
 	printk(KERN_INFO "modified physical RAM map:\n");
-	print_memory_map("modified");
+	print_memory_map(&e820, "modified");
 }
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -761,9 +761,12 @@ char * __init machine_specific_memory_se
 
 static int __init parse_memopt(char *p)
 {
+	printk(KERN_INFO "parse_memopt\n");
 	if (!p)
 		return -EINVAL;
 	end_user_pfn = memparse(p, &p);
+	limit_regions(&e820, end_user_pfn);
+
 	end_user_pfn >>= PAGE_SHIFT;
 	return 0;
 }
@@ -809,6 +812,7 @@ static int __init parse_memmap_opt(char
 		start_at = memparse(p+1, &p);
 		add_memory_region(start_at, mem_size, E820_RESERVED);
 	} else {
+		limit_regions(&e820, mem_size);
 		end_user_pfn = (mem_size >> PAGE_SHIFT);
 	}
 	return *p == '\0' ? 0 : -EINVAL;
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -787,7 +787,7 @@ void __init setup_arch(char **cmdline_p)
 	ARCH_SETUP
 
 	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
-	print_memory_map(memory_setup());
+	print_memory_map(&e820, memory_setup());
 
 	copy_edd();
 
@@ -809,7 +809,7 @@ void __init setup_arch(char **cmdline_p)
 
 	if (user_defined_memmap) {
 		printk(KERN_INFO "user-defined physical RAM map:\n");
-		print_memory_map("user");
+		print_memory_map(&e820, "user");
 	}
 
 	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
--- a/include/asm-x86/e820.h
+++ b/include/asm-x86/e820.h
@@ -20,6 +20,10 @@ struct e820map {
 	__u32 nr_map;
 	struct e820entry map[E820MAX];
 };
+
+void limit_regions(struct e820map *e820, unsigned long long size);
+void print_memory_map(struct e820map *e820, char *who);
+
 #endif /* __ASSEMBLY__ */
 
 #define ISA_START_ADDRESS	0xa0000

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

WARNING: multiple messages have this Message-ID (diff)
From: bwalle@suse.de (Bernhard Walle)
To: kexec@lists.infradead.org, vgoyal@redhat.com
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] Limit E820 map and /proc/iomem for mem parameter on x86-64
Date: Tue, 10 Jun 2008 23:53:25 +0200	[thread overview]
Message-ID: <20080610215325.GA20673@suse.de> (raw)

This patch tries to unify the behaviour of i386 and x86-64 when parsing
the memory (mem/memmap) parameter of the kernel command line:

On i386, the view was limited (i.e. the actual view was presented).
On x86-64, the view was full (i.e. the BIOS view was presented).

This patch moves the limit_regions() function and the print_memory_map()
function to a new file e820.c, shared between the two x86 flavours. Then
it adds calls to limit_regions() in 64 bit code.

I gave the patch a bit testing. However, it's not for merging, it's just
to get early feedback to see if that goes into the right direction.


Signed-off-by: Bernhard Walle <bwalle@suse.de>

---
 arch/x86/kernel/Makefile   |    2 -
 arch/x86/kernel/e820.c     |   75 +++++++++++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/e820_32.c  |   60 +-----------------------------------
 arch/x86/kernel/e820_64.c  |    4 ++
 arch/x86/kernel/setup_32.c |    4 +-
 include/asm-x86/e820.h     |    4 ++
 6 files changed, 88 insertions(+), 61 deletions(-)

--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -22,7 +22,7 @@ obj-y			+= setup_$(BITS).o i8259_$(BITS)
 obj-$(CONFIG_X86_32)	+= sys_i386_32.o i386_ksyms_32.o
 obj-$(CONFIG_X86_64)	+= sys_x86_64.o x8664_ksyms_64.o
 obj-$(CONFIG_X86_64)	+= syscall_64.o vsyscall_64.o setup64.o
-obj-y			+= bootflag.o e820_$(BITS).o
+obj-y			+= bootflag.o e820_$(BITS).o e820.o
 obj-y			+= pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
 obj-y			+= alternative.o i8253.o pci-nommu.o
 obj-$(CONFIG_X86_64)	+= bugs_64.o
--- /dev/null
+++ b/arch/x86/kernel/e820.c
@@ -0,0 +1,75 @@
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/ioport.h>
+#include <linux/string.h>
+#include <linux/kexec.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/pfn.h>
+#include <linux/uaccess.h>
+#include <linux/suspend.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/e820.h>
+#include <asm/setup.h>
+
+void __init limit_regions(struct e820map *e820, unsigned long long size)
+{
+	unsigned long long current_addr;
+	int i;
+
+	print_memory_map(e820, "limit_regions start");
+	for (i = 0; i < e820->nr_map; i++) {
+		current_addr = e820->map[i].addr + e820->map[i].size;
+		if (current_addr < size)
+			continue;
+
+		if (e820->map[i].type != E820_RAM)
+			continue;
+
+		if (e820->map[i].addr >= size) {
+			/*
+			 * This region starts past the end of the
+			 * requested size, skip it completely.
+			 */
+			e820->nr_map = i;
+		} else {
+			e820->nr_map = i + 1;
+			e820->map[i].size -= current_addr - size;
+		}
+		print_memory_map(e820, "limit_regions endfor");
+		return;
+	}
+	print_memory_map(e820, "limit_regions endfunc");
+}
+
+void __init print_memory_map(struct e820map *e820, char *who)
+{
+	int i;
+
+	for (i = 0; i < e820->nr_map; i++) {
+		printk(" %s: %016Lx - %016Lx ", who,
+			e820->map[i].addr,
+			e820->map[i].addr + e820->map[i].size);
+		switch (e820->map[i].type) {
+		case E820_RAM:	printk("(usable)\n");
+				break;
+		case E820_RESERVED:
+				printk("(reserved)\n");
+				break;
+		case E820_ACPI:
+				printk("(ACPI data)\n");
+				break;
+		case E820_NVS:
+				printk("(ACPI NVS)\n");
+				break;
+		default:	printk("type %u\n", e820->map[i].type);
+				break;
+		}
+	}
+}
+
+
--- a/arch/x86/kernel/e820_32.c
+++ b/arch/x86/kernel/e820_32.c
@@ -584,62 +584,6 @@ void __init e820_register_memory(void)
 		pci_mem_start, gapstart, gapsize);
 }
 
-void __init print_memory_map(char *who)
-{
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		printk(" %s: %016Lx - %016Lx ", who,
-			e820.map[i].addr,
-			e820.map[i].addr + e820.map[i].size);
-		switch (e820.map[i].type) {
-		case E820_RAM:	printk("(usable)\n");
-				break;
-		case E820_RESERVED:
-				printk("(reserved)\n");
-				break;
-		case E820_ACPI:
-				printk("(ACPI data)\n");
-				break;
-		case E820_NVS:
-				printk("(ACPI NVS)\n");
-				break;
-		default:	printk("type %u\n", e820.map[i].type);
-				break;
-		}
-	}
-}
-
-void __init limit_regions(unsigned long long size)
-{
-	unsigned long long current_addr;
-	int i;
-
-	print_memory_map("limit_regions start");
-	for (i = 0; i < e820.nr_map; i++) {
-		current_addr = e820.map[i].addr + e820.map[i].size;
-		if (current_addr < size)
-			continue;
-
-		if (e820.map[i].type != E820_RAM)
-			continue;
-
-		if (e820.map[i].addr >= size) {
-			/*
-			 * This region starts past the end of the
-			 * requested size, skip it completely.
-			 */
-			e820.nr_map = i;
-		} else {
-			e820.nr_map = i + 1;
-			e820.map[i].size -= current_addr - size;
-		}
-		print_memory_map("limit_regions endfor");
-		return;
-	}
-	print_memory_map("limit_regions endfunc");
-}
-
 /*
  * This function checks if any part of the range <start,end> is mapped
  * with type.
@@ -729,7 +673,7 @@ static int __init parse_memmap(char *arg
 			start_at = memparse(arg+1, &arg);
 			add_memory_region(start_at, mem_size, E820_RESERVED);
 		} else {
-			limit_regions(mem_size);
+			limit_regions(&e820, mem_size);
 			user_defined_memmap = 1;
 		}
 	}
@@ -771,5 +715,5 @@ void __init update_e820(void)
 		return;
 	e820.nr_map = nr_map;
 	printk(KERN_INFO "modified physical RAM map:\n");
-	print_memory_map("modified");
+	print_memory_map(&e820, "modified");
 }
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -761,9 +761,12 @@ char * __init machine_specific_memory_se
 
 static int __init parse_memopt(char *p)
 {
+	printk(KERN_INFO "parse_memopt\n");
 	if (!p)
 		return -EINVAL;
 	end_user_pfn = memparse(p, &p);
+	limit_regions(&e820, end_user_pfn);
+
 	end_user_pfn >>= PAGE_SHIFT;
 	return 0;
 }
@@ -809,6 +812,7 @@ static int __init parse_memmap_opt(char
 		start_at = memparse(p+1, &p);
 		add_memory_region(start_at, mem_size, E820_RESERVED);
 	} else {
+		limit_regions(&e820, mem_size);
 		end_user_pfn = (mem_size >> PAGE_SHIFT);
 	}
 	return *p == '\0' ? 0 : -EINVAL;
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -787,7 +787,7 @@ void __init setup_arch(char **cmdline_p)
 	ARCH_SETUP
 
 	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
-	print_memory_map(memory_setup());
+	print_memory_map(&e820, memory_setup());
 
 	copy_edd();
 
@@ -809,7 +809,7 @@ void __init setup_arch(char **cmdline_p)
 
 	if (user_defined_memmap) {
 		printk(KERN_INFO "user-defined physical RAM map:\n");
-		print_memory_map("user");
+		print_memory_map(&e820, "user");
 	}
 
 	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
--- a/include/asm-x86/e820.h
+++ b/include/asm-x86/e820.h
@@ -20,6 +20,10 @@ struct e820map {
 	__u32 nr_map;
 	struct e820entry map[E820MAX];
 };
+
+void limit_regions(struct e820map *e820, unsigned long long size);
+void print_memory_map(struct e820map *e820, char *who);
+
 #endif /* __ASSEMBLY__ */
 
 #define ISA_START_ADDRESS	0xa0000

             reply	other threads:[~2008-06-10 21:52 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-10 21:53 Bernhard Walle [this message]
2008-06-10 21:53 ` [PATCH] Limit E820 map and /proc/iomem for mem parameter on x86-64 Bernhard Walle
2008-06-11 15:39 ` Vivek Goyal
2008-06-11 15:39   ` Vivek Goyal
2008-06-11 15:45   ` Bernhard Walle
2008-06-11 15:45     ` Bernhard Walle
2008-06-13  1:43 ` Yinghai Lu
2008-06-13  1:43   ` Yinghai Lu

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=20080610215325.GA20673@suse.de \
    --to=bwalle@suse.de \
    --cc=kexec@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=vgoyal@redhat.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.