* x86: Add /sys/firmware/memmap @ 2008-06-25 19:57 Bernhard Walle 2008-06-25 19:57 ` [PATCH 1/2] " Bernhard Walle 2008-06-25 19:57 ` [PATCH 2/2] Use FIRMWARE_MEMMAP on x86/E820 Bernhard Walle 0 siblings, 2 replies; 24+ messages in thread From: Bernhard Walle @ 2008-06-25 19:57 UTC (permalink / raw) To: x86; +Cc: linux-kernel, vgoyal, kexec, yhlu.kernel, Bernhard Walle 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 <bwalle@suse.de> ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/2] Add /sys/firmware/memmap 2008-06-25 19:57 x86: Add /sys/firmware/memmap Bernhard Walle @ 2008-06-25 19:57 ` Bernhard Walle 2008-06-25 22:43 ` Vivek Goyal 2008-06-25 19:57 ` [PATCH 2/2] Use FIRMWARE_MEMMAP on x86/E820 Bernhard Walle 1 sibling, 1 reply; 24+ messages in thread From: Bernhard Walle @ 2008-06-25 19:57 UTC (permalink / raw) To: x86; +Cc: linux-kernel, vgoyal, kexec, yhlu.kernel, Bernhard Walle 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 <bwalle@suse.de> --- 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 <bwalle@suse.de> + * + * 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 <bwalle@suse.de> + * + * 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 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-25 19:57 ` [PATCH 1/2] " Bernhard Walle @ 2008-06-25 22:43 ` Vivek Goyal 2008-06-26 8:13 ` Mikael Pettersson 2008-06-26 8:15 ` Bernhard Walle 0 siblings, 2 replies; 24+ messages in thread From: Vivek Goyal @ 2008-06-25 22:43 UTC (permalink / raw) To: Bernhard Walle; +Cc: x86, linux-kernel, kexec, yhlu.kernel 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 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-25 22:43 ` Vivek Goyal @ 2008-06-26 8:13 ` Mikael Pettersson 2008-06-26 8:45 ` Bernhard Walle 2008-06-26 12:42 ` Vivek Goyal 2008-06-26 8:15 ` Bernhard Walle 1 sibling, 2 replies; 24+ messages in thread From: Mikael Pettersson @ 2008-06-26 8:13 UTC (permalink / raw) To: Vivek Goyal; +Cc: Bernhard Walle, x86, linux-kernel, kexec, yhlu.kernel 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. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 8:13 ` Mikael Pettersson @ 2008-06-26 8:45 ` Bernhard Walle 2008-06-26 9:11 ` Mikael Pettersson 2008-06-26 12:42 ` Vivek Goyal 1 sibling, 1 reply; 24+ messages in thread From: Bernhard Walle @ 2008-06-26 8:45 UTC (permalink / raw) To: Mikael Pettersson; +Cc: Vivek Goyal, x86, linux-kernel, kexec, yhlu.kernel * 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 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 8:45 ` Bernhard Walle @ 2008-06-26 9:11 ` Mikael Pettersson 2008-06-26 18:00 ` H. Peter Anvin 0 siblings, 1 reply; 24+ messages in thread From: Mikael Pettersson @ 2008-06-26 9:11 UTC (permalink / raw) To: Bernhard Walle Cc: Mikael Pettersson, Vivek Goyal, x86, linux-kernel, kexec, yhlu.kernel 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. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 9:11 ` Mikael Pettersson @ 2008-06-26 18:00 ` H. Peter Anvin 2008-06-26 18:18 ` Vivek Goyal 2008-06-26 18:23 ` Bernhard Walle 0 siblings, 2 replies; 24+ messages in thread From: H. Peter Anvin @ 2008-06-26 18:00 UTC (permalink / raw) To: Mikael Pettersson Cc: Bernhard Walle, Vivek Goyal, x86, linux-kernel, kexec, yhlu.kernel 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 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 18:00 ` H. Peter Anvin @ 2008-06-26 18:18 ` Vivek Goyal 2008-06-26 19:18 ` H. Peter Anvin 2008-06-26 18:23 ` Bernhard Walle 1 sibling, 1 reply; 24+ messages in thread From: Vivek Goyal @ 2008-06-26 18:18 UTC (permalink / raw) To: H. Peter Anvin Cc: Mikael Pettersson, Bernhard Walle, x86, linux-kernel, kexec, yhlu.kernel 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 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 18:18 ` Vivek Goyal @ 2008-06-26 19:18 ` H. Peter Anvin 0 siblings, 0 replies; 24+ messages in thread From: H. Peter Anvin @ 2008-06-26 19:18 UTC (permalink / raw) To: Vivek Goyal Cc: Mikael Pettersson, Bernhard Walle, x86, linux-kernel, kexec, yhlu.kernel 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 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 18:00 ` H. Peter Anvin 2008-06-26 18:18 ` Vivek Goyal @ 2008-06-26 18:23 ` Bernhard Walle 1 sibling, 0 replies; 24+ messages in thread From: Bernhard Walle @ 2008-06-26 18:23 UTC (permalink / raw) To: Mikael Pettersson Cc: H. Peter Anvin, Vivek Goyal, x86, linux-kernel, kexec, yhlu.kernel * "H. Peter Anvin" <hpa@kernel.org> [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 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 8:13 ` Mikael Pettersson 2008-06-26 8:45 ` Bernhard Walle @ 2008-06-26 12:42 ` Vivek Goyal 1 sibling, 0 replies; 24+ messages in thread From: Vivek Goyal @ 2008-06-26 12:42 UTC (permalink / raw) To: Mikael Pettersson; +Cc: Bernhard Walle, x86, linux-kernel, kexec, yhlu.kernel 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 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-25 22:43 ` Vivek Goyal 2008-06-26 8:13 ` Mikael Pettersson @ 2008-06-26 8:15 ` Bernhard Walle 1 sibling, 0 replies; 24+ messages in thread From: Bernhard Walle @ 2008-06-26 8:15 UTC (permalink / raw) To: Vivek Goyal; +Cc: x86, linux-kernel, kexec, yhlu.kernel * 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 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 2/2] Use FIRMWARE_MEMMAP on x86/E820 2008-06-25 19:57 x86: Add /sys/firmware/memmap Bernhard Walle 2008-06-25 19:57 ` [PATCH 1/2] " Bernhard Walle @ 2008-06-25 19:57 ` Bernhard Walle 1 sibling, 0 replies; 24+ messages in thread From: Bernhard Walle @ 2008-06-25 19:57 UTC (permalink / raw) To: x86; +Cc: linux-kernel, vgoyal, kexec, yhlu.kernel, Bernhard Walle 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 <bwalle@suse.de> --- 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 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* x86: Add /sys/firmware/memmap @ 2008-06-26 8:14 Bernhard Walle 2008-06-26 8:14 ` [PATCH 1/2] " Bernhard Walle 0 siblings, 1 reply; 24+ messages in thread From: Bernhard Walle @ 2008-06-26 8:14 UTC (permalink / raw) To: x86; +Cc: linux-kernel, kexec, yhlu.kernel, vgoyal, Bernhard Walle 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. Signed-off-by: Bernhard Walle <bwalle@suse.de> ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 8:14 x86: Add /sys/firmware/memmap Bernhard Walle @ 2008-06-26 8:14 ` Bernhard Walle 0 siblings, 0 replies; 24+ messages in thread From: Bernhard Walle @ 2008-06-26 8:14 UTC (permalink / raw) To: x86; +Cc: linux-kernel, kexec, yhlu.kernel, vgoyal, Bernhard Walle 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 <bwalle@suse.de> --- drivers/firmware/Kconfig | 4 + drivers/firmware/Makefile | 1 + drivers/firmware/memmap.c | 164 ++++++++++++++++++++++++++++++++++++++++++ include/linux/firmware-map.h | 63 ++++++++++++++++ 4 files changed, 232 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..1008737 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -26,6 +26,10 @@ 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 + def_bool y + depends on X86_64 || X86_32 + 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..998166a --- /dev/null +++ b/drivers/firmware/memmap.c @@ -0,0 +1,164 @@ +/* + * linux/drivers/firmware/memmap.c + * Copyright (C) 2008 SUSE LINUX Products GmbH + * by Bernhard Walle <bwalle@suse.de> + * + * 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> + +/* + * 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, + const char *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, + const char *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, + const char *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) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", entry->type); +} + +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..c6bd934 --- /dev/null +++ b/include/linux/firmware-map.h @@ -0,0 +1,63 @@ +/* + * include/linux/firmware-map.h: + * Copyright (C) 2008 SUSE LINUX Products GmbH + * by Bernhard Walle <bwalle@suse.de> + * + * 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> + + +/* + * 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.) */ + const char *type; /* type of the memory range */ + struct list_head list; /* entry for the linked list */ + struct kobject kobj; /* kobject for each entry */ +}; + +/** + * 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, + const char *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, + const char *type); + +#endif /* _LINUX_FIRMWARE_MAP_H */ -- 1.5.6 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* x86: Add /sys/firmware/memmap
@ 2008-06-26 20:19 Bernhard Walle
2008-06-26 20:19 ` [PATCH 1/2] " Bernhard Walle
0 siblings, 1 reply; 24+ messages in thread
From: Bernhard Walle @ 2008-06-26 20:19 UTC (permalink / raw)
To: x86; +Cc: kexec, linux-kernel, vgoyal, yhlu.kernel, gregkh, Bernhard Walle
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.
Change compared to previous commit:
1. Added Greg KH to Cc as suggested by H. Peter Anvin to review sysfs
structure.
2. Display the configuration option only if CONFIG_EMBEDDED is set.
If not, default to including the code in any case as it is not only
useful for kexec.
Please review!
Signed-off-by: Bernhard Walle <bwalle@suse.de>
^ permalink raw reply [flat|nested] 24+ messages in thread* [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 20:19 x86: " Bernhard Walle @ 2008-06-26 20:19 ` Bernhard Walle 2008-06-26 20:45 ` Vivek Goyal 2008-06-26 22:24 ` Greg KH 0 siblings, 2 replies; 24+ messages in thread From: Bernhard Walle @ 2008-06-26 20:19 UTC (permalink / raw) To: x86; +Cc: kexec, linux-kernel, vgoyal, yhlu.kernel, gregkh, Bernhard Walle 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 <bwalle@suse.de> --- drivers/firmware/Kconfig | 8 ++ drivers/firmware/Makefile | 1 + drivers/firmware/memmap.c | 164 ++++++++++++++++++++++++++++++++++++++++++ include/linux/firmware-map.h | 84 +++++++++++++++++++++ 4 files changed, 257 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..b9cea0e 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -26,6 +26,14 @@ 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 "Add firmware-provided memory map to sysfs" if EMBEDDED + default (X86_64 || X86_32) + help + Add the firmware-provided (unmodified) memory map to /sys/firmware/memmap. + That memory map is used for example by kexec to set up parameter area + for the next kernel, but can also be used for debugging purposes. + 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..998166a --- /dev/null +++ b/drivers/firmware/memmap.c @@ -0,0 +1,164 @@ +/* + * linux/drivers/firmware/memmap.c + * Copyright (C) 2008 SUSE LINUX Products GmbH + * by Bernhard Walle <bwalle@suse.de> + * + * 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> + +/* + * 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, + const char *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, + const char *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, + const char *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) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", entry->type); +} + +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..b2564a3 --- /dev/null +++ b/include/linux/firmware-map.h @@ -0,0 +1,84 @@ +/* + * include/linux/firmware-map.h: + * Copyright (C) 2008 SUSE LINUX Products GmbH + * by Bernhard Walle <bwalle@suse.de> + * + * 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> + + +/* + * 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.) */ + const char *type; /* type of the memory range */ + struct list_head list; /* entry for the linked list */ + struct kobject kobj; /* kobject for each entry */ +}; + +/* + * provide a dummy interface if CONFIG_FIRMWARE_MEMMAP is disabled + */ +#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, + const char *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, + const char *type); + +#else /* CONFIG_FIRMWARE_MEMMAP */ + +static inline int firmware_map_add(resource_size_t start, resource_size_t end, + const char *type) +{ + return 0; +} + +static inline int firmware_map_add_early(resource_size_t start, + resource_size_t end, const char *type) +{ + return 0; +} + +#endif /* CONFIG_FIRMWARE_MEMMAP */ + +#endif /* _LINUX_FIRMWARE_MAP_H */ -- 1.5.6 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 20:19 ` [PATCH 1/2] " Bernhard Walle @ 2008-06-26 20:45 ` Vivek Goyal 2008-06-26 22:24 ` Greg KH 1 sibling, 0 replies; 24+ messages in thread From: Vivek Goyal @ 2008-06-26 20:45 UTC (permalink / raw) To: Bernhard Walle; +Cc: x86, kexec, linux-kernel, yhlu.kernel, gregkh On Thu, Jun 26, 2008 at 10:19:01PM +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. > > 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 <bwalle@suse.de> > --- > drivers/firmware/Kconfig | 8 ++ > drivers/firmware/Makefile | 1 + > drivers/firmware/memmap.c | 164 ++++++++++++++++++++++++++++++++++++++++++ > include/linux/firmware-map.h | 84 +++++++++++++++++++++ > 4 files changed, 257 insertions(+), 0 deletions(-) > create mode 100644 drivers/firmware/memmap.c > create mode 100644 include/linux/firmware-map.h I think you also need to introduce some documentation about this new sysfs interface. Looks like in Documentation/ABI/ somewhere. Greg can tell more... Thanks Vivek ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 20:19 ` [PATCH 1/2] " Bernhard Walle 2008-06-26 20:45 ` Vivek Goyal @ 2008-06-26 22:24 ` Greg KH 2008-06-27 11:08 ` Bernhard Walle 1 sibling, 1 reply; 24+ messages in thread From: Greg KH @ 2008-06-26 22:24 UTC (permalink / raw) To: Bernhard Walle; +Cc: x86, kexec, linux-kernel, vgoyal, yhlu.kernel On Thu, Jun 26, 2008 at 10:19:01PM +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 Please provide new entries in Documentation/ABI/ for these new sysfs files with all of this information. > +/* > + * Firmware memory map entries > + */ > +LIST_HEAD(map_entries); Should this be static? > +int firmware_map_add(resource_size_t start, resource_size_t end, > + const char *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); Where is the kobject initialized properly? Ah, later on, that's scary... > +static struct kobj_type memmap_ktype = { > + .sysfs_ops = &memmap_attr_ops, > + .default_attrs = def_attrs, > +}; Do you really need your own kobj_type here? What you want is just a directory, and some attributes assigned to the kobject, can't you use the default kobject attributes for them? I'm not saying this is incorrect, it looks implemented properly, just curious. > +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) { So the list is supposed to be set up before this function is called? Is that because of early boot issues? You should document this somehow. > +/* > + * 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.) */ > + const char *type; /* type of the memory range */ > + struct list_head list; /* entry for the linked list */ > + struct kobject kobj; /* kobject for each entry */ > +}; Does this really need to be in the .h file? thanks, greg k-h ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-26 22:24 ` Greg KH @ 2008-06-27 11:08 ` Bernhard Walle 0 siblings, 0 replies; 24+ messages in thread From: Bernhard Walle @ 2008-06-27 11:08 UTC (permalink / raw) To: Greg KH; +Cc: x86, kexec, linux-kernel, vgoyal, yhlu.kernel Hi, * Greg KH [2008-06-26 15:24]: > > On Thu, Jun 26, 2008 at 10:19:01PM +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 > > Please provide new entries in Documentation/ABI/ for these new sysfs > files with all of this information. Yes, I planned that but wanted to get feedback first. It's in the next resend. > > +/* > > + * Firmware memory map entries > > + */ > > +LIST_HEAD(map_entries); > > Should this be static? Yes, thanks. > > +int firmware_map_add(resource_size_t start, resource_size_t end, > > + const char *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); > > Where is the kobject initialized properly? > > Ah, later on, that's scary... Ok, I moved initialisation to firmware_map_add_entry() and add it later with kobject_add(). > > +static struct kobj_type memmap_ktype = { > > + .sysfs_ops = &memmap_attr_ops, > > + .default_attrs = def_attrs, > > +}; > > Do you really need your own kobj_type here? What you want is just a > directory, and some attributes assigned to the kobject, can't you use > the default kobject attributes for them? > > I'm not saying this is incorrect, it looks implemented properly, just > curious. Well, since there are more than one directory with the same attributes, isn't using kobj_type easier here? > > +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) { > > So the list is supposed to be set up before this function is called? Is > that because of early boot issues? > > You should document this somehow. Yes, added a comment to firmware_map_add_early(), firmware_map_add() and before memmap_init(). > > +/* > > + * 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.) */ > > + const char *type; /* type of the memory range */ > > + struct list_head list; /* entry for the linked list */ > > + struct kobject kobj; /* kobject for each entry */ > > +}; > > Does this really need to be in the .h file? No, that was because I modified the API afterwards. Thanks for spotting that. Bernhard -- Bernhard Walle, SUSE LINUX Products GmbH, Architecture Development ^ permalink raw reply [flat|nested] 24+ messages in thread
* x86: Add /sys/firmware/memmap @ 2008-06-27 11:12 Bernhard Walle 2008-06-27 11:12 ` [PATCH 1/2] " Bernhard Walle 0 siblings, 1 reply; 24+ messages in thread From: Bernhard Walle @ 2008-06-27 11:12 UTC (permalink / raw) To: x86; +Cc: gregkh, kexec, yhlu.kernel, vgoyal, linux-kernel 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. Change compared to previous commit: 1. Comments from Greg KH. 2. Documentation. The patch has been tested on i386 and x86_64 with success. ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/2] Add /sys/firmware/memmap 2008-06-27 11:12 x86: " Bernhard Walle @ 2008-06-27 11:12 ` Bernhard Walle 2008-06-27 18:51 ` Dave Hansen ` (2 more replies) 0 siblings, 3 replies; 24+ messages in thread From: Bernhard Walle @ 2008-06-27 11:12 UTC (permalink / raw) To: x86; +Cc: gregkh, kexec, yhlu.kernel, vgoyal, linux-kernel, Bernhard Walle 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 <bwalle@suse.de> --- Documentation/ABI/testing/sysfs-firmware-memmap | 71 ++++++++ drivers/firmware/Kconfig | 10 + drivers/firmware/Makefile | 1 + drivers/firmware/memmap.c | 205 +++++++++++++++++++++++ include/linux/firmware-map.h | 74 ++++++++ 5 files changed, 361 insertions(+), 0 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-firmware-memmap create mode 100644 drivers/firmware/memmap.c create mode 100644 include/linux/firmware-map.h diff --git a/Documentation/ABI/testing/sysfs-firmware-memmap b/Documentation/ABI/testing/sysfs-firmware-memmap new file mode 100644 index 0000000..0d99ee6 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-memmap @@ -0,0 +1,71 @@ +What: /sys/firmware/memmap/ +Date: June 2008 +Contact: Bernhard Walle <bwalle@suse.de> +Description: + On all platforms, the firmware provides a memory map which the + kernel reads. The resources from that memory map are registered + in the kernel resource tree and exposed to userspace via + /proc/iomem (together with other resources). + + However, on most architectures that firmware-provided memory + map is modified afterwards by the kernel itself, either because + the kernel merges that memory map with other information or + just because the user overwrites that memory map via command + line. + + kexec needs the raw firmware-provided memory map to setup the + parameter segment of the kernel that should be booted with + kexec. Also, the raw memory map is useful for debugging. For + that reason, /sys/firmware/memmap is an interface that provides + the raw memory map to userspace. + + The structure is as follows: Under /sys/firmware/memmap there + are subdirectories with the number of the entry as their name: + + /sys/firmware/memmap/0 + /sys/firmware/memmap/1 + /sys/firmware/memmap/2 + /sys/firmware/memmap/3 + ... + + The maximum depends on the number of memory map entries provided + by the firmware. The order is just the order that the firmware + provides. + + Each directory contains three files: + + start : The start address (as hexadecimal number with the + '0x' prefix). + end : The end address, inclusive (regardless whether the + firmware provides inclusive or exclusive ranges). + type : Type of the entry as string. See below for a list of + valid types. + + So, for example: + + /sys/firmware/memmap/0/start + /sys/firmware/memmap/0/end + /sys/firmware/memmap/0/type + /sys/firmware/memmap/1/start + ... + + Currently following types exist: + + - System RAM + - ACPI Tables + - ACPI Non-volatile Storage + - reserved + + Following shell snippet can be used to display that memory + map in a human-readable format: + + -------------------- 8< ---------------------------------------- + #!/bin/bash + 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 ---------------------------------------- diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index dc2cec6..ebb9e51 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -26,6 +26,16 @@ 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 "Add firmware-provided memory map to sysfs" if EMBEDDED + default (X86_64 || X86_32) + help + Add the firmware-provided (unmodified) memory map to /sys/firmware/memmap. + That memory map is used for example by kexec to set up parameter area + for the next kernel, but can also be used for debugging purposes. + + See also Documentation/ABI/testing/sysfs-firmware-memmap. + 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..e23399c --- /dev/null +++ b/drivers/firmware/memmap.c @@ -0,0 +1,205 @@ +/* + * linux/drivers/firmware/memmap.c + * Copyright (C) 2008 SUSE LINUX Products GmbH + * by Bernhard Walle <bwalle@suse.de> + * + * 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> + +/* + * Data types ------------------------------------------------------------------ + */ + +/* + * 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.) */ + const char *type; /* type of the memory range */ + struct list_head list; /* entry for the linked list */ + struct kobject kobj; /* kobject for each entry */ +}; + +/* + * Forward declarations -------------------------------------------------------- + */ +static ssize_t memmap_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf); +static ssize_t start_show(struct firmware_map_entry *entry, char *buf); +static ssize_t end_show(struct firmware_map_entry *entry, char *buf); +static ssize_t type_show(struct firmware_map_entry *entry, char *buf); + +/* + * Static data ----------------------------------------------------------------- + */ + +struct memmap_attribute { + struct attribute attr; + ssize_t (*show)(struct firmware_map_entry *entry, char *buf); +}; + +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 +}; + +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, +}; + +/* + * Registration functions ------------------------------------------------------ + */ + +/* + * Firmware memory map entries + */ +static 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, + const char *type, + struct firmware_map_entry *entry) +{ + BUG_ON(start > end); + + entry->start = start; + entry->end = end; + entry->type = type; + INIT_LIST_HEAD(&entry->list); + kobject_init(&entry->kobj, &memmap_ktype); + + list_add_tail(&entry->list, &map_entries); + + return 0; +} + +/* + * See <linux/firmware-map.h> for documentation. + */ +int firmware_map_add(resource_size_t start, resource_size_t end, + const char *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); +} + +/* + * See <linux/firmware-map.h> for documentation. + */ +int __init firmware_map_add_early(resource_size_t start, resource_size_t end, + const char *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 ------------------------------------------------------------- + */ + +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) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", entry->type); +} + +#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); +} + +/* + * Initialises stuff and adds the entries in the map_entries list to + * sysfs. Important is that firmware_map_add() and firmware_map_add_early() + * must be called before late_initcall. + */ +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_add(&entry->kobj, 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..acbdbcc --- /dev/null +++ b/include/linux/firmware-map.h @@ -0,0 +1,74 @@ +/* + * include/linux/firmware-map.h: + * Copyright (C) 2008 SUSE LINUX Products GmbH + * by Bernhard Walle <bwalle@suse.de> + * + * 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> + +/* + * provide a dummy interface if CONFIG_FIRMWARE_MEMMAP is disabled + */ +#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. + * + * That function must be called before late_initcall. + * + * @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, + const char *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(). + * + * That function must be called before late_initcall. + * + * @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, + const char *type); + +#else /* CONFIG_FIRMWARE_MEMMAP */ + +static inline int firmware_map_add(resource_size_t start, resource_size_t end, + const char *type) +{ + return 0; +} + +static inline int firmware_map_add_early(resource_size_t start, + resource_size_t end, const char *type) +{ + return 0; +} + +#endif /* CONFIG_FIRMWARE_MEMMAP */ + +#endif /* _LINUX_FIRMWARE_MAP_H */ -- 1.5.6 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-27 11:12 ` [PATCH 1/2] " Bernhard Walle @ 2008-06-27 18:51 ` Dave Hansen 2008-06-27 20:56 ` Greg KH 2008-07-12 0:36 ` Andrew Morton 2 siblings, 0 replies; 24+ messages in thread From: Dave Hansen @ 2008-06-27 18:51 UTC (permalink / raw) To: Bernhard Walle; +Cc: x86, gregkh, kexec, yhlu.kernel, vgoyal, linux-kernel On Fri, 2008-06-27 at 13:12 +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 Could we give this a slightly different name? We have various 'mem_map' variables in the kernel, and this confused me on first glance. Could we just spell out 'memory_map'? -- Dave ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-27 11:12 ` [PATCH 1/2] " Bernhard Walle 2008-06-27 18:51 ` Dave Hansen @ 2008-06-27 20:56 ` Greg KH 2008-07-01 20:30 ` Bernhard Walle 2008-07-12 0:36 ` Andrew Morton 2 siblings, 1 reply; 24+ messages in thread From: Greg KH @ 2008-06-27 20:56 UTC (permalink / raw) To: Bernhard Walle; +Cc: x86, gregkh, kexec, yhlu.kernel, vgoyal, linux-kernel On Fri, Jun 27, 2008 at 01:12:54PM +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. > > 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 <bwalle@suse.de> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> x86 developers, feel free to add this to your tree, it looks fine to me. thanks, greg k-h ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-27 20:56 ` Greg KH @ 2008-07-01 20:30 ` Bernhard Walle 2008-07-01 20:33 ` Ingo Molnar 0 siblings, 1 reply; 24+ messages in thread From: Bernhard Walle @ 2008-07-01 20:30 UTC (permalink / raw) To: mingo; +Cc: x86, linux-kernel * Greg KH <gregkh@suse.de> [2008-06-27 13:56]: > > Acked-by: Greg Kroah-Hartman <gregkh@suse.de> > > x86 developers, feel free to add this to your tree, it looks fine to me. Ingo, any pending issues from your side that prevents merging in 'tip'? Bernhard -- Bernhard Walle, SUSE LINUX Products GmbH, Architecture Development ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-07-01 20:30 ` Bernhard Walle @ 2008-07-01 20:33 ` Ingo Molnar 0 siblings, 0 replies; 24+ messages in thread From: Ingo Molnar @ 2008-07-01 20:33 UTC (permalink / raw) To: Bernhard Walle; +Cc: x86, linux-kernel * Bernhard Walle <bwalle@suse.de> wrote: > * Greg KH <gregkh@suse.de> [2008-06-27 13:56]: > > > > Acked-by: Greg Kroah-Hartman <gregkh@suse.de> > > > > x86 developers, feel free to add this to your tree, it looks fine to me. > > Ingo, any pending issues from your side that prevents merging in > 'tip'? nope, no pending issues now that Greg has acked it - will create a topic for it tomorrow. Ingo ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 1/2] Add /sys/firmware/memmap 2008-06-27 11:12 ` [PATCH 1/2] " Bernhard Walle 2008-06-27 18:51 ` Dave Hansen 2008-06-27 20:56 ` Greg KH @ 2008-07-12 0:36 ` Andrew Morton 2 siblings, 0 replies; 24+ messages in thread From: Andrew Morton @ 2008-07-12 0:36 UTC (permalink / raw) To: Bernhard Walle; +Cc: x86, gregkh, kexec, yhlu.kernel, vgoyal, linux-kernel On Fri, 27 Jun 2008 13:12:54 +0200 Bernhard Walle <bwalle@suse.de> 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. > > 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. > > ... > > +/* > + * Firmware memory map entries > + */ > +static LIST_HEAD(map_entries); Alarm bells. Please add a comment explaining why no locking is needed for this. > +/** > + * 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. > + */ Busted kerneldoc. It should start with /** * firmware_map_add_entry - <stuff> > +static int firmware_map_add_entry(resource_size_t start, resource_size_t end, > + const char *type, > + struct firmware_map_entry *entry) > +{ > + BUG_ON(start > end); > + > + entry->start = start; > + entry->end = end; > + entry->type = type; > + INIT_LIST_HEAD(&entry->list); > + kobject_init(&entry->kobj, &memmap_ktype); > + > + list_add_tail(&entry->list, &map_entries); > + > + return 0; > +} > + > +/* > + * See <linux/firmware-map.h> for documentation. > + */ > +int firmware_map_add(resource_size_t start, resource_size_t end, > + const char *type) > +{ > + struct firmware_map_entry *entry; > + > + entry = kmalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC); > + WARN_ON(!entry); Actually, kmalloc() would have warned already. > + if (!entry) > + return -ENOMEM; > + > + return firmware_map_add_entry(start, end, type, entry); > +} > + > > ... > > +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); > +} Printing a resource_size_t needs a cast to `unsigned long long' to avoid printk warnings. > +static ssize_t type_show(struct firmware_map_entry *entry, char *buf) > +{ > + return snprintf(buf, PAGE_SIZE, "%s\n", entry->type); > +} > + > +#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); > +} > + > +/* > + * Initialises stuff and adds the entries in the map_entries list to > + * sysfs. Important is that firmware_map_add() and firmware_map_add_early() > + * must be called before late_initcall. Please update the comment to provide the reason why this is important. > + */ > +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; Actually, you can do if (WARN_ON(!memmap_kset)) return -ENOMEM; (multiple instances) > + list_for_each_entry(entry, &map_entries, list) { > + entry->kobj.kset = memmap_kset; > + kobject_add(&entry->kobj, NULL, "%d", i++); kobject_add() can fail. I'd suggest that you enable CONFIG_ENABLE_MUST_CHECK in your usualconfig. > + } > + > + return 0; > +} > +late_initcall(memmap_init); > + > > ... > > +/** > + * 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. > + * > + * That function must be called before late_initcall. > + * > + * @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, > + const char *type); More busted kernedoc (multiple instances) Please document C functions at the definition site, not in the header file. a) because otherwise the documentation gets splattered across different files (eg - static functions?) b) principle of least surprise: that's where people expect to find it. > +/** > + * Adds a firmware mapping entry. This function uses the bootmem allocator > + * for memory allocation. Use firmware_map_add() if you want to use kmalloc(). > + * > + * That function must be called before late_initcall. > + * > + * @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, > + const char *type); > + > +#else /* CONFIG_FIRMWARE_MEMMAP */ > + > +static inline int firmware_map_add(resource_size_t start, resource_size_t end, > + const char *type) > +{ > + return 0; > +} > + > +static inline int firmware_map_add_early(resource_size_t start, > + resource_size_t end, const char *type) > +{ > + return 0; > +} > + > +#endif /* CONFIG_FIRMWARE_MEMMAP */ > + > +#endif /* _LINUX_FIRMWARE_MAP_H */ ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2008-07-12 0:36 UTC | newest] Thread overview: 24+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-06-25 19:57 x86: Add /sys/firmware/memmap Bernhard Walle 2008-06-25 19:57 ` [PATCH 1/2] " Bernhard Walle 2008-06-25 22:43 ` Vivek Goyal 2008-06-26 8:13 ` Mikael Pettersson 2008-06-26 8:45 ` Bernhard Walle 2008-06-26 9:11 ` Mikael Pettersson 2008-06-26 18:00 ` H. Peter Anvin 2008-06-26 18:18 ` Vivek Goyal 2008-06-26 19:18 ` H. Peter Anvin 2008-06-26 18:23 ` Bernhard Walle 2008-06-26 12:42 ` Vivek Goyal 2008-06-26 8:15 ` Bernhard Walle 2008-06-25 19:57 ` [PATCH 2/2] Use FIRMWARE_MEMMAP on x86/E820 Bernhard Walle -- strict thread matches above, loose matches on Subject: below -- 2008-06-26 8:14 x86: Add /sys/firmware/memmap Bernhard Walle 2008-06-26 8:14 ` [PATCH 1/2] " Bernhard Walle 2008-06-26 20:19 x86: " Bernhard Walle 2008-06-26 20:19 ` [PATCH 1/2] " Bernhard Walle 2008-06-26 20:45 ` Vivek Goyal 2008-06-26 22:24 ` Greg KH 2008-06-27 11:08 ` Bernhard Walle 2008-06-27 11:12 x86: " Bernhard Walle 2008-06-27 11:12 ` [PATCH 1/2] " Bernhard Walle 2008-06-27 18:51 ` Dave Hansen 2008-06-27 20:56 ` Greg KH 2008-07-01 20:30 ` Bernhard Walle 2008-07-01 20:33 ` Ingo Molnar 2008-07-12 0:36 ` Andrew Morton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox