2008-06-25 19:56:38

by Bernhard Walle

[permalink] [raw]
Subject: x86: Add /sys/firmware/memmap

This patch series adds a new interface /sys/firmware/memmap
to export the BIOS (Firmware) provided memory map via sysfs
for usage with kexec.

While the first patch adds the generic interface, the second
patch implements that interface for E820 on x86. EFI is on the TODO
list, and other architectures can be added later.

This patch is RFC. It has been tested on x86-64 and i386 and
replaces my previous attemt that adds such an interface via
procfs.


Signed-off-by: Bernhard Walle <[email protected]>


2008-06-25 19:56:54

by Bernhard Walle

[permalink] [raw]
Subject: [PATCH 2/2] Use FIRMWARE_MEMMAP on x86/E820

This patch uses the /sys/firmware/memmap interface provided in the last patch
on the x86 architecture when E820 is used. The patch copies the E820
memory map very early, and registers the E820 map afterwards via
firmware_map_add_early().


Signed-off-by: Bernhard Walle <[email protected]>
---
arch/x86/kernel/e820.c | 36 ++++++++++++++++++++++++++++++++++++
include/asm-x86/e820.h | 2 ++
2 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 3771386..14f5a83 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -19,6 +19,7 @@
#include <linux/mm.h>
#include <linux/pfn.h>
#include <linux/suspend.h>
+#include <linux/firmware-map.h>

#include <asm/pgtable.h>
#include <asm/page.h>
@@ -27,7 +28,22 @@
#include <asm/setup.h>
#include <asm/trampoline.h>

+/*
+ * The e820 map is the map that gets modified e.g. with command line parameters
+ * and that is also registered with modifications in the kernel resource tree
+ * with the iomem_resource as parent.
+ *
+ * The e820_saved is directly saved after the BIOS-provided memory map is
+ * copied. It doesn't get modified afterwards. It's registered for the
+ * /sys/firmware/memmap interface.
+ *
+ * That memory map is not modified and is used as base for kexec. The kexec'd
+ * kernel should get the same memory map as the firmware provides. Then the
+ * user can e.g. boot the original kernel with mem=1G while still booting the
+ * next kernel with full memory.
+ */
struct e820map e820;
+struct e820map e820_saved;

/* For PCI or other memory-mapped resources */
unsigned long pci_mem_start = 0xaeedbabe;
@@ -1056,6 +1072,17 @@ void __init finish_e820_parsing(void)
}
}

+static inline enum firmware_map_type firmware_map_type_from_e820(int e820_type)
+{
+ switch (e820_type) {
+ case E820_RAM: return MAP_RAM;
+ case E820_ACPI: return MAP_ACPI;
+ case E820_RESERVED: return MAP_RESERVED;
+ case E820_NVS: return MAP_NVS;
+ default: return MAP_RESERVED;
+ }
+}
+
/*
* Mark e820 reserved areas as busy for the resource manager.
*/
@@ -1084,6 +1111,13 @@ void __init e820_reserve_resources(void)
insert_resource(&iomem_resource, res);
res++;
}
+
+ for (i = 0; i < e820_saved.nr_map; i++) {
+ struct e820entry *entry = &e820_saved.map[i];
+ firmware_map_add_early(entry->addr,
+ entry->addr + entry->size - 1,
+ firmware_map_type_from_e820(entry->type));
+ }
}

char *__init default_machine_specific_memory_setup(void)
@@ -1119,6 +1153,8 @@ char *__init default_machine_specific_memory_setup(void)
e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
}

+ memcpy(&e820_saved, &e820, sizeof(struct e820map));
+
/* In case someone cares... */
return who;
}
diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h
index 13a0a5f..607f940 100644
--- a/include/asm-x86/e820.h
+++ b/include/asm-x86/e820.h
@@ -56,7 +56,9 @@ struct e820map {
struct e820entry map[E820_X_MAX];
};

+/* see comment in arch/x86/kernel/e820.c */
extern struct e820map e820;
+extern struct e820map e820_saved;

extern int e820_any_mapped(u64 start, u64 end, unsigned type);
extern int e820_all_mapped(u64 start, u64 end, unsigned type);
--
1.5.4.5

2008-06-25 19:57:19

by Bernhard Walle

[permalink] [raw]
Subject: [PATCH 1/2] Add /sys/firmware/memmap

This patch adds /sys/firmware/memmap interface that represents the BIOS
(or Firmware) provided memory map. The tree looks like:

/sys/firmware/memmap/0/start (hex number)
end (hex number)
type (string)
... /1/start
end
type

With the following shell snippet one can print the memory map in the same form
the kernel prints itself when booting on x86 (the E820 map).

--------- 8< --------------------------
#!/bin/sh
cd /sys/firmware/memmap
for dir in * ; do
start=$(cat $dir/start)
end=$(cat $dir/end)
type=$(cat $dir/type)
printf "%016x-%016x (%s)\n" $start $[ $end +1] "$type"
done
--------- >8 --------------------------

That patch only provides the needed interface:

1. The sysfs interface.
2. The structure and enumeration definition.
3. The function firmware_map_add() and firmware_map_add_early()
that should be called from architecture code (E820/EFI, for
example) to add the contents to the interface.

If the kernel is compiled without CONFIG_FIRMWARE_MEMMAP, the interface does
nothing without cluttering the architecture-specific code with #ifdef's.

The purpose of the new interface is kexec: While /proc/iomem represents
the *used* memory map (e.g. modified via kernel parameters like 'memmap'
and 'mem'), the /sys/firmware/memmap tree represents the unmodified memory
map provided via the firmware. So kexec can:

- use the original memory map for rebooting,
- use the /proc/iomem for setting up the ELF core headers for kdump
case that should only represent the memory of the system.

The patch has been tested on i386 and x86_64.


Signed-off-by: Bernhard Walle <[email protected]>
---
drivers/firmware/Kconfig | 11 +++
drivers/firmware/Makefile | 1 +
drivers/firmware/memmap.c | 176 ++++++++++++++++++++++++++++++++++++++++++
include/linux/firmware-map.h | 100 ++++++++++++++++++++++++
4 files changed, 288 insertions(+), 0 deletions(-)
create mode 100644 drivers/firmware/memmap.c
create mode 100644 include/linux/firmware-map.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index dc2cec6..0f416fb 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -26,6 +26,17 @@ config EDD_OFF
kernel. Say N if you want EDD enabled by default. EDD can be dynamically set
using the kernel parameter 'edd={on|skipmbr|off}'.

+config FIRMWARE_MEMMAP
+ bool "Provide BIOS memory map in sysfs"
+ depends on X86_64 || X86_32
+ default y
+ help
+ Say Y if you want to provide the raw memory map in sysfs under
+ /sys/firmware/memmap/<number>/{start,end,type}.
+
+ This is useful for debugging, and required by kexec-tools to get an
+ unfiltered view that /proc/iomem cannot provide.
+
config EFI_VARS
tristate "EFI Variable Support via sysfs"
depends on EFI
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4c91471..1c3c173 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_DCDBAS) += dcdbas.o
obj-$(CONFIG_DMIID) += dmi-id.o
obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
+obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
new file mode 100644
index 0000000..d0de284
--- /dev/null
+++ b/drivers/firmware/memmap.c
@@ -0,0 +1,176 @@
+/*
+ * linux/drivers/firmware/memmap.c
+ * Copyright (C) 2008 SUSE LINUX Products GmbH
+ * by Bernhard Walle <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/firmware-map.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+
+/*
+ * String representation of enum firmware_map_type from
+ * <linux/firmware-map.h>.
+ */
+const char *type_to_string_map[] = {
+ "RAM", /* MAP_RAM */
+ "Reserved", /* MAP_RESERVED */
+ "ACPI Tables", /* MAP_ACPI */
+ "Non-volatile Storage", /* MAP_NVS */
+};
+
+/*
+ * Registration functions ------------------------------------------------------
+ */
+
+/*
+ * Firmware memory map entries
+ */
+LIST_HEAD(map_entries);
+
+/**
+ * Common implementation of firmware_map_add() and firmware_map_add_early()
+ * which expects a pre-allocated struct firmware_map_entry.
+ *
+ * @start: Start of the memory range.
+ * @end: End of the memory range (inclusive).
+ * @type: Type of the memory range.
+ * @entry: Pre-allocated (either kmalloc() or bootmem allocator), uninitialised
+ * entry.
+ */
+static int firmware_map_add_entry(resource_size_t start, resource_size_t end,
+ enum firmware_map_type type,
+ struct firmware_map_entry *entry)
+{
+ BUG_ON(start > end);
+
+ entry->start = start;
+ entry->end = end;
+ entry->type = type;
+ INIT_LIST_HEAD(&entry->list);
+
+ list_add_tail(&entry->list, &map_entries);
+
+ return 0;
+}
+
+int firmware_map_add(resource_size_t start, resource_size_t end,
+ enum firmware_map_type type)
+{
+ struct firmware_map_entry *entry;
+
+ entry = kmalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
+ WARN_ON(!entry);
+ if (!entry)
+ return -ENOMEM;
+
+ return firmware_map_add_entry(start, end, type, entry);
+}
+
+int firmware_map_add_early(resource_size_t start, resource_size_t end,
+ enum firmware_map_type type)
+{
+ struct firmware_map_entry *entry;
+
+ entry = alloc_bootmem_low(sizeof(struct firmware_map_entry));
+ WARN_ON(!entry);
+ if (!entry)
+ return -ENOMEM;
+
+ return firmware_map_add_entry(start, end, type, entry);
+}
+
+/*
+ * Sysfs functions
+ */
+
+struct memmap_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct firmware_map_entry *entry, char *buf);
+};
+
+static ssize_t start_show(struct firmware_map_entry *entry, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "0x%llx\n", entry->start);
+}
+
+static ssize_t end_show(struct firmware_map_entry *entry, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "0x%llx\n", entry->end);
+}
+
+static ssize_t type_show(struct firmware_map_entry *entry, char *buf)
+{
+ const char *str = type_to_string_map[entry->type];
+ return snprintf(buf, PAGE_SIZE, "%s\n", str);
+}
+
+struct memmap_attribute memmap_start_attr = __ATTR_RO(start);
+struct memmap_attribute memmap_end_attr = __ATTR_RO(end);
+struct memmap_attribute memmap_type_attr = __ATTR_RO(type);
+
+/*
+ * These are default attributes that are added for every memmap entry.
+ */
+static struct attribute *def_attrs[] = {
+ &memmap_start_attr.attr,
+ &memmap_end_attr.attr,
+ &memmap_type_attr.attr,
+ NULL
+};
+
+#define to_memmap_attr(_attr) container_of(_attr, struct memmap_attribute, attr)
+#define to_memmap_entry(obj) container_of(obj, struct firmware_map_entry, kobj)
+
+static ssize_t memmap_attr_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ struct firmware_map_entry *entry = to_memmap_entry(kobj);
+ struct memmap_attribute *memmap_attr = to_memmap_attr(attr);
+
+ return memmap_attr->show(entry, buf);
+}
+
+static struct sysfs_ops memmap_attr_ops = {
+ .show = memmap_attr_show,
+};
+
+static struct kobj_type memmap_ktype = {
+ .sysfs_ops = &memmap_attr_ops,
+ .default_attrs = def_attrs,
+};
+
+static int __init memmap_init(void)
+{
+ int i = 0;
+ struct firmware_map_entry *entry;
+ struct kset *memmap_kset;
+
+ memmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
+ WARN_ON(!memmap_kset);
+ if (!memmap_kset)
+ return -ENOMEM;
+
+ list_for_each_entry(entry, &map_entries, list) {
+ entry->kobj.kset = memmap_kset;
+ kobject_init_and_add(&entry->kobj, &memmap_ktype,
+ NULL, "%d", i++);
+ }
+
+ return 0;
+}
+late_initcall(memmap_init);
+
diff --git a/include/linux/firmware-map.h b/include/linux/firmware-map.h
new file mode 100644
index 0000000..64aff3d
--- /dev/null
+++ b/include/linux/firmware-map.h
@@ -0,0 +1,100 @@
+/*
+ * include/linux/firmware-map.h:
+ * Copyright (C) 2008 SUSE LINUX Products GmbH
+ * by Bernhard Walle <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _LINUX_FIRMWARE_MAP_H
+#define _LINUX_FIRMWARE_MAP_H
+
+#include <linux/list.h>
+#include <linux/kobject.h>
+
+/*
+ * Type used for memory maps provided by firmware. That must be some kind
+ * "superset" between all architectures. Most types are the same on each
+ * architectures, but for example ACPI only exists on x86 and ia64.
+ *
+ * If you add a new type here, make sure that you add them in
+ * drivers/firmware/memmap.c as type_to_string_map, too.
+ */
+enum firmware_map_type {
+ MAP_RAM, /* normal RAM */
+ MAP_RESERVED, /* reserved area */
+ MAP_ACPI, /* ACPI tables, only x86 and ia64 */
+ MAP_NVS /* non-volatile storage */
+};
+
+/*
+ * Firmware map entry. Because firmware memory maps are flat and not
+ * hierarchical, it's ok to organise them in a linked list. No parent
+ * information is necessary as for the resource tree.
+ */
+struct firmware_map_entry {
+ resource_size_t start; /* start of the memory range */
+ resource_size_t end; /* end of the memory range (incl.) */
+ enum firmware_map_type type; /* type of the memory range */
+ struct list_head list; /* entry for the linked list */
+ struct kobject kobj; /* kobject for each entry */
+};
+
+/*
+ * If the kernel is configured without CONFIG_FIRMWARE_MEMMAP, then
+ * the firmware_map_add() operation should do nothing.
+ */
+#ifdef CONFIG_FIRMWARE_MEMMAP
+
+/**
+ * Adds a firmware mapping entry. This function uses kmalloc() for memory
+ * allocation. Use firmware_map_add_early() if you want to use the bootmem
+ * allocator.
+ *
+ * @start: Start of the memory range.
+ * @end: End of the memory range (inclusive).
+ * @type: Type of the memory range.
+ *
+ * Returns 0 on success, or -ENOMEM if no memory could be allocated.
+ */
+int firmware_map_add(resource_size_t start, resource_size_t end,
+ enum firmware_map_type type);
+
+/**
+ * Adds a firmware mapping entry. This function uses the bootmem allocator
+ * for memory allocation. Use firmware_map_add() if you want to use kmalloc().
+ *
+ * @start: Start of the memory range.
+ * @end: End of the memory range (inclusive).
+ * @type: Type of the memory range.
+ *
+ * Returns 0 on success, or -ENOMEM if no memory could be allocated.
+ */
+int firmware_map_add_early(resource_size_t start, resource_size_t end,
+ enum firmware_map_type type);
+
+#else /* CONFIG_FIRMWARE_MEMMAP */
+
+static inline int firmware_map_add(resource_size_t start, resource_size_t end,
+ enum firmware_map_type type)
+{
+ return 0;
+}
+
+static inline int firmware_map_add_early(resource_size_t start,
+ resource_size_t end,
+ enum firmware_map_type type)
+{
+ return 0;
+}
+
+#endif /* CONFIG_FIRMWARE_MEMMAP */
+
+#endif /* _LINUX_FIRMWARE_MAP_H */
--
1.5.4.5

2008-06-25 22:44:30

by Vivek Goyal

[permalink] [raw]
Subject: Re: [PATCH 1/2] Add /sys/firmware/memmap

On Wed, Jun 25, 2008 at 09:57:05PM +0200, Bernhard Walle wrote:
> This patch adds /sys/firmware/memmap interface that represents the BIOS
> (or Firmware) provided memory map. The tree looks like:
>
> /sys/firmware/memmap/0/start (hex number)
> end (hex number)
> type (string)
> ... /1/start
> end
> type
>
> With the following shell snippet one can print the memory map in the same form
> the kernel prints itself when booting on x86 (the E820 map).
>
> --------- 8< --------------------------
> #!/bin/sh
> cd /sys/firmware/memmap
> for dir in * ; do
> start=$(cat $dir/start)
> end=$(cat $dir/end)
> type=$(cat $dir/type)
> printf "%016x-%016x (%s)\n" $start $[ $end +1] "$type"
> done
> --------- >8 --------------------------
>
> That patch only provides the needed interface:
>
> 1. The sysfs interface.
> 2. The structure and enumeration definition.
> 3. The function firmware_map_add() and firmware_map_add_early()
> that should be called from architecture code (E820/EFI, for
> example) to add the contents to the interface.
>
> If the kernel is compiled without CONFIG_FIRMWARE_MEMMAP, the interface does
> nothing without cluttering the architecture-specific code with #ifdef's.
>

Hi Bernhard,

Thanks for the patch. Couple of thoughts.

Do we really need another CONFIG option (CONFIG_FIRMWARE_MEMMAP)? To,
me this does not seem to be a big chunk of code at the same time I am
assuming that most of the people will use it (because of kexec). So
probably, it might not make lot of sense to put additional CONFIG option.

[..]
> +#include <linux/string.h>
> +#include <linux/firmware-map.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/types.h>
> +#include <linux/bootmem.h>
> +
> +/*
> + * String representation of enum firmware_map_type from
> + * <linux/firmware-map.h>.
> + */
> +const char *type_to_string_map[] = {
> + "RAM", /* MAP_RAM */
> + "Reserved", /* MAP_RESERVED */
> + "ACPI Tables", /* MAP_ACPI */
> + "Non-volatile Storage", /* MAP_NVS */
> +};
> +

How about leaving the decision of memory type on arch dependent code? How
about letting arch code pass you an string while adding entry and that
string will contain the type of memory. The way request_resource() is
implemented.

I think that would be easier and provide more flexibility to arch
dependent code. For example, I see so many additional memory types for
EFI code. It will be good to give EFI code flexibility that how does
he perceive a particular memory region and then let kexec-tools deal
with various memory types.

Thanks
Vivek

2008-06-26 08:15:22

by Bernhard Walle

[permalink] [raw]
Subject: Re: [PATCH 1/2] Add /sys/firmware/memmap

* Vivek Goyal [2008-06-25 18:43]:
>
> Thanks for the patch. Couple of thoughts.
>
> Do we really need another CONFIG option (CONFIG_FIRMWARE_MEMMAP)? To,
> me this does not seem to be a big chunk of code at the same time I am
> assuming that most of the people will use it (because of kexec). So
> probably, it might not make lot of sense to put additional CONFIG option.

Agreed.

> [..]
> > +#include <linux/string.h>
> > +#include <linux/firmware-map.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/types.h>
> > +#include <linux/bootmem.h>
> > +
> > +/*
> > + * String representation of enum firmware_map_type from
> > + * <linux/firmware-map.h>.
> > + */
> > +const char *type_to_string_map[] = {
> > + "RAM", /* MAP_RAM */
> > + "Reserved", /* MAP_RESERVED */
> > + "ACPI Tables", /* MAP_ACPI */
> > + "Non-volatile Storage", /* MAP_NVS */
> > +};
> > +
>
> How about leaving the decision of memory type on arch dependent code? How
> about letting arch code pass you an string while adding entry and that
> string will contain the type of memory. The way request_resource() is
> implemented.

Also agreed, see the resent patch.


Bernhard
--
Bernhard Walle, SUSE LINUX Products GmbH, Architecture Development

2008-06-26 08:36:55

by Mikael Pettersson

[permalink] [raw]
Subject: Re: [PATCH 1/2] Add /sys/firmware/memmap

Vivek Goyal writes:
> On Wed, Jun 25, 2008 at 09:57:05PM +0200, Bernhard Walle wrote:
> > This patch adds /sys/firmware/memmap interface that represents the BIOS
> > (or Firmware) provided memory map. The tree looks like:
> >
> > /sys/firmware/memmap/0/start (hex number)
> > end (hex number)
> > type (string)
> > ... /1/start
> > end
> > type
> >
> > With the following shell snippet one can print the memory map in the same form
> > the kernel prints itself when booting on x86 (the E820 map).
> >
> > --------- 8< --------------------------
> > #!/bin/sh
> > cd /sys/firmware/memmap
> > for dir in * ; do
> > start=$(cat $dir/start)
> > end=$(cat $dir/end)
> > type=$(cat $dir/type)
> > printf "%016x-%016x (%s)\n" $start $[ $end +1] "$type"
> > done
> > --------- >8 --------------------------
> >
> > That patch only provides the needed interface:
> >
> > 1. The sysfs interface.
> > 2. The structure and enumeration definition.
> > 3. The function firmware_map_add() and firmware_map_add_early()
> > that should be called from architecture code (E820/EFI, for
> > example) to add the contents to the interface.
> >
> > If the kernel is compiled without CONFIG_FIRMWARE_MEMMAP, the interface does
> > nothing without cluttering the architecture-specific code with #ifdef's.
> >
>
> Hi Bernhard,
>
> Thanks for the patch. Couple of thoughts.
>
> Do we really need another CONFIG option (CONFIG_FIRMWARE_MEMMAP)? To,
> me this does not seem to be a big chunk of code

It should be configurable. Whether it's done via CONFIG_KEXEC or its own
option I don't care.

> at the same time I am
> assuming that most of the people will use it (because of kexec). So
> probably, it might not make lot of sense to put additional CONFIG option.

I question that assumption. Even if (and that's a big if) "most"
people use kexec (I don't), Linux is not about forcing unwanted
stuff down peoples' throats, we allow knowledgeable users to tune
their kernels.

2008-06-26 08:45:26

by Bernhard Walle

[permalink] [raw]
Subject: Re: [PATCH 1/2] Add /sys/firmware/memmap

* Mikael Pettersson [2008-06-26 10:13]:
>
> Vivek Goyal writes:
> > On Wed, Jun 25, 2008 at 09:57:05PM +0200, Bernhard Walle wrote:
> > > This patch adds /sys/firmware/memmap interface that represents the BIOS
> > > (or Firmware) provided memory map. The tree looks like:
> > >
> > > /sys/firmware/memmap/0/start (hex number)
> > > end (hex number)
> > > type (string)
> > > ... /1/start
> > > end
> > > type
> > >
> > > With the following shell snippet one can print the memory map in the same form
> > > the kernel prints itself when booting on x86 (the E820 map).
> > >
> > > --------- 8< --------------------------
> > > #!/bin/sh
> > > cd /sys/firmware/memmap
> > > for dir in * ; do
> > > start=$(cat $dir/start)
> > > end=$(cat $dir/end)
> > > type=$(cat $dir/type)
> > > printf "%016x-%016x (%s)\n" $start $[ $end +1] "$type"
> > > done
> > > --------- >8 --------------------------
> > >
> > > That patch only provides the needed interface:
> > >
> > > 1. The sysfs interface.
> > > 2. The structure and enumeration definition.
> > > 3. The function firmware_map_add() and firmware_map_add_early()
> > > that should be called from architecture code (E820/EFI, for
> > > example) to add the contents to the interface.
> > >
> > > If the kernel is compiled without CONFIG_FIRMWARE_MEMMAP, the interface does
> > > nothing without cluttering the architecture-specific code with #ifdef's.
> > >
> >
> > Hi Bernhard,
> >
> > Thanks for the patch. Couple of thoughts.
> >
> > Do we really need another CONFIG option (CONFIG_FIRMWARE_MEMMAP)? To,
> > me this does not seem to be a big chunk of code
>
> It should be configurable. Whether it's done via CONFIG_KEXEC or its own
> option I don't care.

Ok, changed:

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 1008737..73fcc59 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -28,7 +28,7 @@ config EDD_OFF

config FIRMWARE_MEMMAP
def_bool y
- depends on X86_64 || X86_32
+ depends on (X86_64 || X86_32) && KEXEC

config EFI_VARS
tristate "EFI Variable Support via sysfs"

I will wait with resending the patch for other feedback.


Bernhard
--
Bernhard Walle, SUSE LINUX Products GmbH, Architecture Development

2008-06-26 09:13:30

by Mikael Pettersson

[permalink] [raw]
Subject: Re: [PATCH 1/2] Add /sys/firmware/memmap

Bernhard Walle writes:
> > It should be configurable. Whether it's done via CONFIG_KEXEC or its own
> > option I don't care.
>
> Ok, changed:
>
> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> index 1008737..73fcc59 100644
> --- a/drivers/firmware/Kconfig
> +++ b/drivers/firmware/Kconfig
> @@ -28,7 +28,7 @@ config EDD_OFF
>
> config FIRMWARE_MEMMAP
> def_bool y
> - depends on X86_64 || X86_32
> + depends on (X86_64 || X86_32) && KEXEC
>
> config EFI_VARS
> tristate "EFI Variable Support via sysfs"

Yep, thanks.

2008-06-26 13:02:50

by Vivek Goyal

[permalink] [raw]
Subject: Re: [PATCH 1/2] Add /sys/firmware/memmap

On Thu, Jun 26, 2008 at 10:13:23AM +0200, Mikael Pettersson wrote:
> Vivek Goyal writes:
> > On Wed, Jun 25, 2008 at 09:57:05PM +0200, Bernhard Walle wrote:
> > > This patch adds /sys/firmware/memmap interface that represents the BIOS
> > > (or Firmware) provided memory map. The tree looks like:
> > >
> > > /sys/firmware/memmap/0/start (hex number)
> > > end (hex number)
> > > type (string)
> > > ... /1/start
> > > end
> > > type
> > >
> > > With the following shell snippet one can print the memory map in the same form
> > > the kernel prints itself when booting on x86 (the E820 map).
> > >
> > > --------- 8< --------------------------
> > > #!/bin/sh
> > > cd /sys/firmware/memmap
> > > for dir in * ; do
> > > start=$(cat $dir/start)
> > > end=$(cat $dir/end)
> > > type=$(cat $dir/type)
> > > printf "%016x-%016x (%s)\n" $start $[ $end +1] "$type"
> > > done
> > > --------- >8 --------------------------
> > >
> > > That patch only provides the needed interface:
> > >
> > > 1. The sysfs interface.
> > > 2. The structure and enumeration definition.
> > > 3. The function firmware_map_add() and firmware_map_add_early()
> > > that should be called from architecture code (E820/EFI, for
> > > example) to add the contents to the interface.
> > >
> > > If the kernel is compiled without CONFIG_FIRMWARE_MEMMAP, the interface does
> > > nothing without cluttering the architecture-specific code with #ifdef's.
> > >
> >
> > Hi Bernhard,
> >
> > Thanks for the patch. Couple of thoughts.
> >
> > Do we really need another CONFIG option (CONFIG_FIRMWARE_MEMMAP)? To,
> > me this does not seem to be a big chunk of code
>
> It should be configurable. Whether it's done via CONFIG_KEXEC or its own
> option I don't care.
>

That's fine. I am just curious how does one decide whether a particular
functionality should have a separate CONFIG option or not.

I thought if a functionality is sufficiently big/significant (in terms of code
and in terms of memory allocation etc), then it is a good idea to put it
under a CONFIG option, in case people want to compile it out.

Just that looking at the patch, personally, I don't think that it makes
lot of sense to create a separate CONFIG option for this patch.

Thanks
Vivek

2008-06-26 18:07:51

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 1/2] Add /sys/firmware/memmap

Mikael Pettersson wrote:
> Bernhard Walle writes:
> > > It should be configurable. Whether it's done via CONFIG_KEXEC or its own
> > > option I don't care.
> >
> > Ok, changed:
> >
> > diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> > index 1008737..73fcc59 100644
> > --- a/drivers/firmware/Kconfig
> > +++ b/drivers/firmware/Kconfig
> > @@ -28,7 +28,7 @@ config EDD_OFF
> >
> > config FIRMWARE_MEMMAP
> > def_bool y
> > - depends on X86_64 || X86_32
> > + depends on (X86_64 || X86_32) && KEXEC
> >
> > config EFI_VARS
> > tristate "EFI Variable Support via sysfs"
>
> Yep, thanks.
>

Making this depend on KEXEC would be most unfortunate. This is valuable
information for finding all kinds of issues even in the absence of KEXEC.

I really don't see a point in making this configurable, except perhaps
under CONFIG_EMBEDDED.

-hpa

2008-06-26 18:24:20

by Bernhard Walle

[permalink] [raw]
Subject: Re: [PATCH 1/2] Add /sys/firmware/memmap

* "H. Peter Anvin" <[email protected]> [2008-06-26 11:00]:
>
> Making this depend on KEXEC would be most unfortunate. This is valuable
> information for finding all kinds of issues even in the absence of KEXEC.
>
> I really don't see a point in making this configurable, except perhaps
> under CONFIG_EMBEDDED.

Now we have all opinions about how making that interface
configurable. Mikael, should an option under CONFIG_EMBEDDED be
acceptable for you?

Then I can repost the patch, Cc Greg KH and see if the sysfs structure
would be ok for him.



Bernhard
--
Bernhard Walle, SUSE LINUX Products GmbH, Architecture Development

2008-06-26 18:25:28

by Vivek Goyal

[permalink] [raw]
Subject: Re: [PATCH 1/2] Add /sys/firmware/memmap

On Thu, Jun 26, 2008 at 11:00:16AM -0700, H. Peter Anvin wrote:
> Mikael Pettersson wrote:
>> Bernhard Walle writes:
>> > > It should be configurable. Whether it's done via CONFIG_KEXEC or its own
>> > > option I don't care.
>> > > Ok, changed:
>> > > diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
>> > index 1008737..73fcc59 100644
>> > --- a/drivers/firmware/Kconfig
>> > +++ b/drivers/firmware/Kconfig
>> > @@ -28,7 +28,7 @@ config EDD_OFF
>> > > config FIRMWARE_MEMMAP
>> > def_bool y
>> > - depends on X86_64 || X86_32
>> > + depends on (X86_64 || X86_32) && KEXEC
>> > > config EFI_VARS
>> > tristate "EFI Variable Support via sysfs"
>>
>> Yep, thanks.
>>
>
> Making this depend on KEXEC would be most unfortunate. This is valuable
> information for finding all kinds of issues even in the absence of KEXEC.
>

Agreed.

> I really don't see a point in making this configurable, except perhaps
> under CONFIG_EMBEDDED.

I think we should just not put this functionality under any CONFIG option.
If we put it under CONFIG_EMBEDDED, then even for using kexec, one
shall have to turn CONFIG_EMBEDDED on which probably does not make much
sense.

Thanks
Vivek

2008-06-26 19:22:40

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH 1/2] Add /sys/firmware/memmap

Vivek Goyal wrote:
>>>
>> Making this depend on KEXEC would be most unfortunate. This is valuable
>> information for finding all kinds of issues even in the absence of KEXEC.
>>
>
> Agreed.
>
>> I really don't see a point in making this configurable, except perhaps
>> under CONFIG_EMBEDDED.
>
> I think we should just not put this functionality under any CONFIG option.
> If we put it under CONFIG_EMBEDDED, then even for using kexec, one
> shall have to turn CONFIG_EMBEDDED on which probably does not make much
> sense.
>

Well, it should be *enabled* for !EMBEDDED.

-hpa