lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Tue, 24 Mar 2009 14:48:23 -0500
From:	Cliff Wickman <cpw@....com>
To:	linux-kernel@...r.kernel.org
Cc:	mingo@...e.hu, hpa@...or.com
Subject: [PATCH] x86: access to efi reserved memory type

From: Cliff Wickman <cpw@....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@....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);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ