LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] x86: access to efi reserved memory type
@ 2008-11-06 21:22 Cliff Wickman
  0 siblings, 0 replies; 5+ messages in thread
From: Cliff Wickman @ 2008-11-06 21:22 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo

From: Cliff Wickman <cpw@sgi.com>

Give drivers addresses of memory type EFI_RESERVED_TYPE.
This supports drivers that use vendor-specific memory, available
only to special devices.

The walk() function scans the EFI memory map and does a callback to a
specified function for each memory area of a specified type.
efi_memmap_walk_reserved() provides a scan for type EFI_RESERVED_TYPE.

(an earlier version of this patch had proposed a new EFI type, but
 EFI_RESERVED_TYPE should be sufficient, given that the firmware follows
 the standard and does not use such memory for its own purposes)

A UV driver will be posted to the community in the future that will use
these routines.

Diffed against 2.6.27-rc6

Signed-off-by: Cliff Wickman <cpw@sgi.com>
---
 arch/x86/kernel/efi.c |   36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

Index: linux/arch/x86/kernel/efi.c
===================================================================
--- linux.orig/arch/x86/kernel/efi.c
+++ linux/arch/x86/kernel/efi.c
@@ -572,3 +572,39 @@ u64 efi_mem_attributes(unsigned long phy
 	}
 	return 0;
 }
+
+static void
+walk(efi_freemem_callback_t callback, void *arg, int type)
+{
+	efi_memory_desc_t *md;
+	void *p;
+	int size;
+
+	/*
+	 * memmap.map is zeroed in efi_enter_virtual_mode()
+	 * but we can use the physical address (phys_map)
+	 */
+	size = memmap.nr_map*memmap.desc_size;
+	for (p = memmap.phys_map; p < memmap.phys_map+size;
+						p += memmap.desc_size) {
+		md = (efi_memory_desc_t *)__va(p);
+		if (md->type != type)
+			continue;
+		if ((*callback)(md->phys_addr,
+		     md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1,
+		     arg) < 0)
+			return;
+	}
+}
+
+/*
+ * Walk the EFI memory map and call "callback" once for each EFI memory
+ * descriptor of type EFI_RESERVED_TYPE.
+ */
+void
+efi_memmap_walk_reserved(efi_freemem_callback_t callback, void *arg)
+{
+	walk(callback, arg, EFI_RESERVED_TYPE);
+}
+
+EXPORT_SYMBOL(efi_memmap_walk_reserved);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] x86: access to efi reserved memory type
@ 2009-03-24 19:48 Cliff Wickman
  0 siblings, 0 replies; 5+ messages in thread
From: Cliff Wickman @ 2009-03-24 19:48 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo, hpa

From: Cliff Wickman <cpw@sgi.com>

This patch allows a driver to find the addresses of a specified memory type.

This supports drivers that use vendor-specific memory, available
only to special devices. An upcoming example being a UV driver that
will allow users to map in and access extremely large areas of memory
that are beyond the processor's address range.

The efi_mapped_type() function provides starting/ending addresses of
any EFI memory range of a specified type.
To be used like this to find all such ranges:
     start = 0;
     end = HIGH_VALUE;
     while ((ret_start = efi_mapped_type(start, end, EFI_RESERVED_TYPE,
             &ret_end)) != HIGH_VALUE) {
         [ process ret_start and ret_end ]
         start = ret_end;
     }

The UV driver mentioned above will be posted to the community in the future.

An earlier version of this patch raised some objections because
1) it used a callback method, and 2) it interfaced to just the EFI table
and not the e820 table.
The callback method has been replaced with an iterative one.
But use of the e820 table here is a bit problematic.  That is because the
e820 table is limited in size (128 entries). The BIOS can make a virtually
unlimited number of EFI_RESERVED_TYPE entries. Then those entries can
be merged into the e820 table with a "add_efi_memmap" boot line option.
But there seems to be no way around requiring that option for a given
architecture, as the acpi tables are not available to test for machine
type until after efi_init().
Hence our desire to give the driver access to the EFI table.

Tested on 2.6.29-rc7 (and previous versions) running on a
UV hardware simulator.

Diffed against 2.6.29-rc7

Signed-off-by: Cliff Wickman <cpw@sgi.com>
---
 arch/x86/kernel/efi.c |   36 ++++++++++++++++++++++++++++++++++++
 include/linux/efi.h   |    2 +-
 2 files changed, 37 insertions(+), 1 deletion(-)

Index: linux/arch/x86/kernel/efi.c
===================================================================
--- linux.orig/arch/x86/kernel/efi.c
+++ linux/arch/x86/kernel/efi.c
@@ -572,3 +572,39 @@ u64 efi_mem_attributes(unsigned long phy
 	}
 	return 0;
 }
+
+/*
+ * This function returns the start (and end) of any range lying within the
+ * range <start,end> of a given type.
+ * Returns 0xffffffffffffffff if there is no such range of that type.
+ */
+u64
+efi_mapped_type(u64 start, u64 end, unsigned type, u64 *returned_end)
+{
+	int size;
+	u64 range_end;
+	efi_memory_desc_t *md;
+	void *p;
+
+	if (returned_end == NULL)
+		return 0xffffffffffffffffUL;
+
+	/*
+	 * memmap.map is zeroed in efi_enter_virtual_mode()
+	 * but we can use the physical address (phys_map)
+	 */
+	size = memmap.nr_map*memmap.desc_size;
+	for (p = memmap.phys_map; p < memmap.phys_map+size;
+						p += memmap.desc_size) {
+		md = (efi_memory_desc_t *)__va(p);
+		if (md->type != type)
+			continue;
+		range_end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+		if (md->phys_addr >= end || range_end <= start)
+			continue;
+		*returned_end = range_end;
+		return md->phys_addr;
+	}
+	return 0xffffffffffffffffUL;
+}
+EXPORT_SYMBOL_GPL(efi_mapped_type);
Index: linux/include/linux/efi.h
===================================================================
--- linux.orig/include/linux/efi.h
+++ linux/include/linux/efi.h
@@ -291,7 +291,7 @@ efi_guid_unparse(efi_guid_t *guid, char 
 extern void efi_init (void);
 extern void *efi_get_pal_addr (void);
 extern void efi_map_pal_code (void);
-extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
+extern u64 efi_mapped_type(u64 start, u64 end, unsigned type, u64 *returned_end);
 extern void efi_gettimeofday (struct timespec *ts);
 extern void efi_enter_virtual_mode (void);	/* switch EFI to virtual mode, if possible */
 extern u64 efi_get_iobase (void);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] x86: access to efi reserved memory type
  2009-03-08 22:51 ` H. Peter Anvin
@ 2009-03-09 13:16   ` Robin Holt
  0 siblings, 0 replies; 5+ messages in thread
From: Robin Holt @ 2009-03-09 13:16 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Cliff Wickman, linux-kernel, mingo

On Sun, Mar 08, 2009 at 03:51:20PM -0700, H. Peter Anvin wrote:
> Cliff Wickman wrote:
...
> > The walk() function scans the EFI memory map and does a callback to a
> > specified function for each memory area of a specified type.
> > efi_memmap_walk_reserved() provides a scan for type EFI_RESERVED_TYPE.
> >  (an earlier version of this patch had proposed a new EFI type, but
> >   EFI_RESERVED_TYPE should be sufficient, given that the firmware follows
> >   the standard and does not use such memory for its own purposes)
...
> In particular, I really want to know why a plain platform device is
> insufficient, and look for a better solution than this, using the
> generic memory map interfaces rather than something EFI-specific.

For the driver Cliff is referring to, we are attempting to provide EFI
reserved memory to a special hardware (drivers/misc/sgi-gru) device
which is capable of handling pages up to 1TB in size.  Additionally, a
previously posted xpmem driver could make those pages available via
Numalink to other SSIs connected to the same fabric.

Excuse my ignorance, but what do you mean by a "plain platform device"?
By generic memory map interfaces, are you proposing we use order based
allocations?  If so, how do you propose we zero these 1TB (worst case)
size pages.  Our current estimate is this will take approx 20 minutes,
but newer processors might shorten that.  What assurances can we get on
these large pages not getting fragmented and therefore becoming useless
and requiring a reboot to reclaim.

I believe we have a special case of memory needing to be reserved by
BIOS, passed to a special driver which can utilize the GRU for async
zero on allocation and to prevent unintended fragmentation.  I agree we
probably made a small mistake in our submission in that the patch set
which adds the EFI walk should have included the special purpose driver.
We will work to correct that.

Thanks,
Robin

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] x86: access to efi reserved memory type
  2009-03-06 17:46 Cliff Wickman
@ 2009-03-08 22:51 ` H. Peter Anvin
  2009-03-09 13:16   ` Robin Holt
  0 siblings, 1 reply; 5+ messages in thread
From: H. Peter Anvin @ 2009-03-08 22:51 UTC (permalink / raw)
  To: Cliff Wickman; +Cc: linux-kernel, mingo

Cliff Wickman wrote:
> From: Cliff Wickman <cpw@sgi.com>
> 
>  (this patch dates back to 2008-11-06
>     http://marc.info/?l=linux-kernel&m=122600658522471&w=2
>   but has never been applied.)
> 
> Give drivers addresses of memory type EFI_RESERVED_TYPE.
> This supports drivers that use vendor-specific memory, available
> only to special devices.
> 
> The walk() function scans the EFI memory map and does a callback to a
> specified function for each memory area of a specified type.
> efi_memmap_walk_reserved() provides a scan for type EFI_RESERVED_TYPE.
>  (an earlier version of this patch had proposed a new EFI type, but
>   EFI_RESERVED_TYPE should be sufficient, given that the firmware follows
>   the standard and does not use such memory for its own purposes)
> 
> A UV driver will be posted to the community in the future that will use
> these routines.
> 
> Tested on 2.6.29-rc7 (and many previous versions) running on a
> UV hardware simulator.
> 

I have multiple issues with this patch.

FIRST, this is identical to a platform driver.  I really don't
understand why it should need a special interface.

SECOND, the EFI-specific callback interface is just plain weird.

THIRD, saying "A UV driver will be posted to the community in the future
that will use these routines" is not exactly motivation.  At no point
are you technically justifying this code.

In particular, I really want to know why a plain platform device is
insufficient, and look for a better solution than this, using the
generic memory map interfaces rather than something EFI-specific.

	-hpa

-- 
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel.  I don't speak on their behalf.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] x86: access to efi reserved memory type
@ 2009-03-06 17:46 Cliff Wickman
  2009-03-08 22:51 ` H. Peter Anvin
  0 siblings, 1 reply; 5+ messages in thread
From: Cliff Wickman @ 2009-03-06 17:46 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo

From: Cliff Wickman <cpw@sgi.com>

 (this patch dates back to 2008-11-06
    http://marc.info/?l=linux-kernel&m=122600658522471&w=2
  but has never been applied.)

Give drivers addresses of memory type EFI_RESERVED_TYPE.
This supports drivers that use vendor-specific memory, available
only to special devices.

The walk() function scans the EFI memory map and does a callback to a
specified function for each memory area of a specified type.
efi_memmap_walk_reserved() provides a scan for type EFI_RESERVED_TYPE.
 (an earlier version of this patch had proposed a new EFI type, but
  EFI_RESERVED_TYPE should be sufficient, given that the firmware follows
  the standard and does not use such memory for its own purposes)

A UV driver will be posted to the community in the future that will use
these routines.

Tested on 2.6.29-rc7 (and many previous versions) running on a
UV hardware simulator.

Diffed against 2.6.29-rc7

Signed-off-by: Cliff Wickman <cpw@sgi.com>
---
 arch/x86/kernel/efi.c |   36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

Index: linux/arch/x86/kernel/efi.c
===================================================================
--- linux.orig/arch/x86/kernel/efi.c
+++ linux/arch/x86/kernel/efi.c
@@ -579,3 +579,39 @@ u64 efi_mem_attributes(unsigned long phy
 	}
 	return 0;
 }
+
+static void
+walk(efi_freemem_callback_t callback, void *arg, int type)
+{
+	efi_memory_desc_t *md;
+	void *p;
+	int size;
+
+	/*
+	 * memmap.map is zeroed in efi_enter_virtual_mode()
+	 * but we can use the physical address (phys_map)
+	 */
+	size = memmap.nr_map*memmap.desc_size;
+	for (p = memmap.phys_map; p < memmap.phys_map+size;
+						p += memmap.desc_size) {
+		md = (efi_memory_desc_t *)__va(p);
+		if (md->type != type)
+			continue;
+		if ((*callback)(md->phys_addr,
+		     md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1,
+		     arg) < 0)
+			return;
+	}
+}
+
+/*
+ * Walk the EFI memory map and call "callback" once for each EFI memory
+ * descriptor of type EFI_RESERVED_TYPE.
+ */
+void
+efi_memmap_walk_reserved(efi_freemem_callback_t callback, void *arg)
+{
+	walk(callback, arg, EFI_RESERVED_TYPE);
+}
+
+EXPORT_SYMBOL(efi_memmap_walk_reserved);

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-03-24 19:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-11-06 21:22 [PATCH] x86: access to efi reserved memory type Cliff Wickman
2009-03-06 17:46 Cliff Wickman
2009-03-08 22:51 ` H. Peter Anvin
2009-03-09 13:16   ` Robin Holt
2009-03-24 19:48 Cliff Wickman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).