linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory
@ 2012-08-30 21:28 Josh Triplett
  2012-08-30 21:28 ` [PATCH 1/3] efi: Defer freeing boot services memory until after ACPI init Josh Triplett
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Josh Triplett @ 2012-08-30 21:28 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86, Len Brown,
	Matt Fleming, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi

The ACPI BGRT lets the OS access the BIOS logo image and its position on the
screen at boot time, allowing it to maintain that image on the screen until
ready to display something else, making boot more seamless.  This series fixes
support for accessing the boot logo image via the BGRT when the BIOS stores it
in EFI boot services memory, as recommended by the ACPI 5.0 spec.  Linux needs
to copy the image out of boot services memory before reclaiming boot services
memory.

The first patch refactors EFI initialization to defer freeing boot services
memory until later in the boot process, after we have ACPI available.  The
second patch adds a helper function to look up existing EFI boot services
mappings, to avoid re-mapping them.  The third patch moves BGRT initialization
to before the reclamation of boot services memory, copies the logo at that
point, and reworks the existing BGRT driver to use that existing copy.

Josh Triplett (3):
  efi: Defer freeing boot services memory until after ACPI init
  efi: Add a function to look up existing IO memory mappings
  efi: Fix the ACPI BGRT driver for images located in EFI boot services memory

 arch/x86/platform/efi/Makefile   |    1 +
 arch/x86/platform/efi/efi-bgrt.c |   76 ++++++++++++++++++++++++++++++++++++++
 arch/x86/platform/efi/efi.c      |   65 +++++++++++++++++++++++++-------
 drivers/acpi/Kconfig             |    4 +-
 drivers/acpi/bgrt.c              |   76 +++++---------------------------------
 include/linux/efi-bgrt.h         |   21 +++++++++++
 include/linux/efi.h              |    3 ++
 init/main.c                      |    7 ++++
 8 files changed, 171 insertions(+), 82 deletions(-)
 create mode 100644 arch/x86/platform/efi/efi-bgrt.c
 create mode 100644 include/linux/efi-bgrt.h

-- 
1.7.10.4

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

* [PATCH 1/3] efi: Defer freeing boot services memory until after ACPI init
  2012-08-30 21:28 [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory Josh Triplett
@ 2012-08-30 21:28 ` Josh Triplett
  2012-08-30 21:28 ` [PATCH 2/3] efi: Add a function to look up existing IO memory mappings Josh Triplett
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 11+ messages in thread
From: Josh Triplett @ 2012-08-30 21:28 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86, Len Brown,
	Matt Fleming, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi

Some new ACPI 5.0 tables reference resources stored in boot services
memory, so keep that memory around until we have ACPI and can extract
data from it.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
 arch/x86/platform/efi/efi.c |   31 ++++++++++++++++++-------------
 include/linux/efi.h         |    1 +
 init/main.c                 |    5 +++++
 3 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 92660eda..8af329f 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -419,10 +419,21 @@ void __init efi_reserve_boot_services(void)
 	}
 }
 
-static void __init efi_free_boot_services(void)
+void __init efi_unmap_memmap(void)
+{
+	if (memmap.map) {
+		early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
+		memmap.map = NULL;
+	}
+}
+
+void __init efi_free_boot_services(void)
 {
 	void *p;
 
+	if (!efi_native)
+		return;
+
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		efi_memory_desc_t *md = p;
 		unsigned long long start = md->phys_addr;
@@ -438,6 +449,8 @@ static void __init efi_free_boot_services(void)
 
 		free_bootmem_late(start, size);
 	}
+
+	efi_unmap_memmap();
 }
 
 static int __init efi_systab_init(void *phys)
@@ -787,8 +800,10 @@ void __init efi_enter_virtual_mode(void)
 	 * non-native EFI
 	 */
 
-	if (!efi_native)
-		goto out;
+	if (!efi_native) {
+		efi_unmap_memmap();
+		return;
+	}
 
 	/* Merge contiguous regions of the same type and attribute */
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
@@ -878,13 +893,6 @@ void __init efi_enter_virtual_mode(void)
 	}
 
 	/*
-	 * Thankfully, it does seem that no runtime services other than
-	 * SetVirtualAddressMap() will touch boot services code, so we can
-	 * get rid of it all at this point
-	 */
-	efi_free_boot_services();
-
-	/*
 	 * Now that EFI is in virtual mode, update the function
 	 * pointers in the runtime service table to the new virtual addresses.
 	 *
@@ -906,9 +914,6 @@ void __init efi_enter_virtual_mode(void)
 	if (__supported_pte_mask & _PAGE_NX)
 		runtime_code_page_mkexec();
 
-out:
-	early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
-	memmap.map = NULL;
 	kfree(new_memmap);
 }
 
diff --git a/include/linux/efi.h b/include/linux/efi.h
index ec45ccd..00ec70f 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -496,6 +496,7 @@ extern void efi_map_pal_code (void);
 extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
 extern void efi_gettimeofday (struct timespec *ts);
 extern void efi_enter_virtual_mode (void);	/* switch EFI to virtual mode, if possible */
+extern void efi_free_boot_services(void);
 extern u64 efi_get_iobase (void);
 extern u32 efi_mem_type (unsigned long phys_addr);
 extern u64 efi_mem_attributes (unsigned long phys_addr);
diff --git a/init/main.c b/init/main.c
index b286730..391a291 100644
--- a/init/main.c
+++ b/init/main.c
@@ -631,6 +631,11 @@ asmlinkage void __init start_kernel(void)
 	acpi_early_init(); /* before LAPIC and SMP init */
 	sfi_init_late();
 
+#ifdef CONFIG_X86
+	if (efi_enabled)
+		efi_free_boot_services();
+#endif
+
 	ftrace_init();
 
 	/* Do the rest non-__init'ed, we're now alive */
-- 
1.7.10.4


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

* [PATCH 2/3] efi: Add a function to look up existing IO memory mappings
  2012-08-30 21:28 [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory Josh Triplett
  2012-08-30 21:28 ` [PATCH 1/3] efi: Defer freeing boot services memory until after ACPI init Josh Triplett
@ 2012-08-30 21:28 ` Josh Triplett
  2012-08-30 21:28 ` [PATCH 3/3] efi: Fix the ACPI BGRT driver for images located in EFI boot services memory Josh Triplett
  2012-09-04 14:27 ` [PATCH 0/3] Fix ACPI BGRT support " Matt Fleming
  3 siblings, 0 replies; 11+ messages in thread
From: Josh Triplett @ 2012-08-30 21:28 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86, Len Brown,
	Matt Fleming, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi

The EFI initialization creates virtual mappings for EFI boot services
memory, so if a driver wants to access EFI boot services memory, it
cannot call ioremap itself; doing so will trip the WARN about mapping
RAM twice.  Thus, a driver accessing EFI boot services memory must do so
via the existing mapping already created during EFI intiialization.
Since the EFI code already maintains a memory map for that memory, add a
function efi_lookup_mapped_addr to look up mappings in that memory map.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
 arch/x86/platform/efi/efi.c |   28 ++++++++++++++++++++++++++++
 include/linux/efi.h         |    1 +
 2 files changed, 29 insertions(+)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 8af329f..ae35cc8 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -777,6 +777,34 @@ static void __init runtime_code_page_mkexec(void)
 }
 
 /*
+ * We can't ioremap data in EFI boot services RAM, because we've already mapped
+ * it as RAM.  So, look it up in the existing EFI memory map instead.  Only
+ * callable after efi_enter_virtual_mode and before efi_free_boot_services.
+ */
+void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
+{
+	void *p;
+	if (WARN_ON(!memmap.map))
+		return NULL;
+	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+		efi_memory_desc_t *md = p;
+		u64 size = md->num_pages << EFI_PAGE_SHIFT;
+		u64 end = md->phys_addr + size;
+		if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
+		    md->type != EFI_BOOT_SERVICES_CODE &&
+		    md->type != EFI_BOOT_SERVICES_DATA)
+			continue;
+		if (!md->virt_addr)
+			continue;
+		if (phys_addr >= md->phys_addr && phys_addr < end) {
+			phys_addr += md->virt_addr - md->phys_addr;
+			return (__force void __iomem *)phys_addr;
+		}
+	}
+	return NULL;
+}
+
+/*
  * This function will switch the EFI runtime services to virtual mode.
  * Essentially, look through the EFI memmap and map every region that
  * has the runtime attribute bit set in its memory descriptor and update
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 00ec70f..0c11a58 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -496,6 +496,7 @@ extern void efi_map_pal_code (void);
 extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
 extern void efi_gettimeofday (struct timespec *ts);
 extern void efi_enter_virtual_mode (void);	/* switch EFI to virtual mode, if possible */
+extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
 extern void efi_free_boot_services(void);
 extern u64 efi_get_iobase (void);
 extern u32 efi_mem_type (unsigned long phys_addr);
-- 
1.7.10.4


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

* [PATCH 3/3] efi: Fix the ACPI BGRT driver for images located in EFI boot services memory
  2012-08-30 21:28 [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory Josh Triplett
  2012-08-30 21:28 ` [PATCH 1/3] efi: Defer freeing boot services memory until after ACPI init Josh Triplett
  2012-08-30 21:28 ` [PATCH 2/3] efi: Add a function to look up existing IO memory mappings Josh Triplett
@ 2012-08-30 21:28 ` Josh Triplett
  2012-09-04 14:27 ` [PATCH 0/3] Fix ACPI BGRT support " Matt Fleming
  3 siblings, 0 replies; 11+ messages in thread
From: Josh Triplett @ 2012-08-30 21:28 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86, Len Brown,
	Matt Fleming, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi

The ACPI BGRT driver accesses the BIOS logo image when it initializes.
However, ACPI 5.0 (which introduces the BGRT) recommends putting the
logo image in EFI boot services memory, so that the OS can reclaim that
memory.  Production systems follow this recommendation, breaking the
ACPI BGRT driver.

Move the bulk of the BGRT code to run during a new EFI late
initialization phase, which occurs after switching EFI to virtual mode,
and after initializing ACPI, but before freeing boot services memory.
Copy the BIOS logo image to kernel memory at that point, and make it
accessible to the BGRT driver.  Rework the existing ACPI BGRT driver to
act as a simple wrapper exposing that image (and the properties from the
BGRT) via sysfs.

Signed-off-by: Josh Triplett <josh@joshtriplett.org>
---
 arch/x86/platform/efi/Makefile   |    1 +
 arch/x86/platform/efi/efi-bgrt.c |   76 ++++++++++++++++++++++++++++++++++++++
 arch/x86/platform/efi/efi.c      |    6 +++
 drivers/acpi/Kconfig             |    4 +-
 drivers/acpi/bgrt.c              |   76 +++++---------------------------------
 include/linux/efi-bgrt.h         |   21 +++++++++++
 include/linux/efi.h              |    1 +
 init/main.c                      |    4 +-
 8 files changed, 119 insertions(+), 70 deletions(-)
 create mode 100644 arch/x86/platform/efi/efi-bgrt.c
 create mode 100644 include/linux/efi-bgrt.h

diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile
index 73b8be0..6db1cc4 100644
--- a/arch/x86/platform/efi/Makefile
+++ b/arch/x86/platform/efi/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_EFI) 		+= efi.o efi_$(BITS).o efi_stub_$(BITS).o
+obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o
diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c
new file mode 100644
index 0000000..f6a0c1b
--- /dev/null
+++ b/arch/x86/platform/efi/efi-bgrt.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2012 Intel Corporation
+ * Author: Josh Triplett <josh@joshtriplett.org>
+ *
+ * Based on the bgrt driver:
+ * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
+ * Author: Matthew Garrett
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/efi.h>
+#include <linux/efi-bgrt.h>
+
+struct acpi_table_bgrt *bgrt_tab;
+void *bgrt_image;
+size_t bgrt_image_size;
+
+struct bmp_header {
+	u16 id;
+	u32 size;
+} __packed;
+
+void efi_bgrt_init(void)
+{
+	acpi_status status;
+	void __iomem *image;
+	bool ioremapped = false;
+	struct bmp_header bmp_header;
+
+	if (acpi_disabled)
+		return;
+
+	status = acpi_get_table("BGRT", 0,
+	                        (struct acpi_table_header **)&bgrt_tab);
+	if (ACPI_FAILURE(status))
+		return;
+
+	if (bgrt_tab->version != 1)
+		return;
+	if (bgrt_tab->image_type != 0 || !bgrt_tab->image_address)
+		return;
+
+	image = efi_lookup_mapped_addr(bgrt_tab->image_address);
+	if (!image) {
+		image = ioremap(bgrt_tab->image_address, sizeof(bmp_header));
+		ioremapped = true;
+		if (!image)
+			return;
+	}
+
+	memcpy_fromio(&bmp_header, image, sizeof(bmp_header));
+	if (ioremapped)
+		iounmap(image);
+	bgrt_image_size = bmp_header.size;
+
+	bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL);
+	if (!bgrt_image)
+		return;
+
+	if (ioremapped) {
+		image = ioremap(bgrt_tab->image_address, bmp_header.size);
+		if (!image) {
+			kfree(bgrt_image);
+			bgrt_image = NULL;
+			return;
+		}
+	}
+
+	memcpy_fromio(bgrt_image, image, bgrt_image_size);
+	if (ioremapped)
+		iounmap(image);
+}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ae35cc8..0226585 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -31,6 +31,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/efi.h>
+#include <linux/efi-bgrt.h>
 #include <linux/export.h>
 #include <linux/bootmem.h>
 #include <linux/memblock.h>
@@ -745,6 +746,11 @@ void __init efi_init(void)
 #endif
 }
 
+void __init efi_late_init(void)
+{
+	efi_bgrt_init();
+}
+
 void __init efi_set_executable(efi_memory_desc_t *md, bool executable)
 {
 	u64 addr, npages;
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 8099895..119d58d 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -385,8 +385,8 @@ config ACPI_CUSTOM_METHOD
 	  to override that restriction).
 
 config ACPI_BGRT
-        tristate "Boottime Graphics Resource Table support"
-        default n
+	bool "Boottime Graphics Resource Table support"
+	depends on EFI
         help
 	  This driver adds support for exposing the ACPI Boottime Graphics
 	  Resource Table, which allows the operating system to obtain
diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c
index 6680df3..be60399 100644
--- a/drivers/acpi/bgrt.c
+++ b/drivers/acpi/bgrt.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
+ * Copyright 2012 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -11,20 +12,10 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/sysfs.h>
-#include <linux/io.h>
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
+#include <linux/efi-bgrt.h>
 
-static struct acpi_table_bgrt *bgrt_tab;
 static struct kobject *bgrt_kobj;
 
-struct bmp_header {
-	u16 id;
-	u32 size;
-} __attribute ((packed));
-
-static struct bmp_header bmp_header;
-
 static ssize_t show_version(struct device *dev,
 			    struct device_attribute *attr, char *buf)
 {
@@ -63,18 +54,7 @@ static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL);
 static ssize_t show_image(struct file *file, struct kobject *kobj,
 	       struct bin_attribute *attr, char *buf, loff_t off, size_t count)
 {
-	int size = attr->size;
-	void __iomem *image = attr->private;
-
-	if (off >= size) {
-		count = 0;
-	} else {
-		if (off + count > size)
-			count = size - off;
-
-		memcpy_fromio(buf, image+off, count);
-	}
-
+	memcpy(buf, attr->private + off, count);
 	return count;
 }
 
@@ -101,45 +81,18 @@ static struct attribute_group bgrt_attribute_group = {
 
 static int __init bgrt_init(void)
 {
-	acpi_status status;
 	int ret;
-	void __iomem *bgrt;
 
-	if (acpi_disabled)
-		return -ENODEV;
-
-	status = acpi_get_table("BGRT", 0,
-				(struct acpi_table_header **)&bgrt_tab);
-
-	if (ACPI_FAILURE(status))
+	if (!bgrt_image)
 		return -ENODEV;
 
 	sysfs_bin_attr_init(&image_attr);
-
-	bgrt = ioremap(bgrt_tab->image_address, sizeof(struct bmp_header));
-
-	if (!bgrt) {
-		ret = -EINVAL;
-		goto out_err;
-	}
-
-	memcpy_fromio(&bmp_header, bgrt, sizeof(bmp_header));
-	image_attr.size = bmp_header.size;
-	iounmap(bgrt);
-
-	image_attr.private = ioremap(bgrt_tab->image_address, image_attr.size);
-
-	if (!image_attr.private) {
-		ret = -EINVAL;
-		goto out_err;
-	}
-
+	image_attr.private = bgrt_image;
+	image_attr.size = bgrt_image_size;
 
 	bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
-	if (!bgrt_kobj) {
-		ret = -EINVAL;
-		goto out_iounmap;
-	}
+	if (!bgrt_kobj)
+		return -EINVAL;
 
 	ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group);
 	if (ret)
@@ -155,22 +108,11 @@ out_group:
 	sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
 out_kobject:
 	kobject_put(bgrt_kobj);
-out_iounmap:
-	iounmap(image_attr.private);
-out_err:
 	return ret;
 }
 
-static void __exit bgrt_exit(void)
-{
-	iounmap(image_attr.private);
-	sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
-	sysfs_remove_bin_file(bgrt_kobj, &image_attr);
-}
-
 module_init(bgrt_init);
-module_exit(bgrt_exit);
 
-MODULE_AUTHOR("Matthew Garrett");
+MODULE_AUTHOR("Matthew Garrett, Josh Triplett <josh@joshtriplett.org>");
 MODULE_DESCRIPTION("BGRT boot graphic support");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/efi-bgrt.h b/include/linux/efi-bgrt.h
new file mode 100644
index 0000000..051b21f
--- /dev/null
+++ b/include/linux/efi-bgrt.h
@@ -0,0 +1,21 @@
+#ifndef _LINUX_EFI_BGRT_H
+#define _LINUX_EFI_BGRT_H
+
+#ifdef CONFIG_ACPI_BGRT
+
+#include <linux/acpi.h>
+
+void efi_bgrt_init(void);
+
+/* The BGRT data itself; only valid if bgrt_image != NULL. */
+extern void *bgrt_image;
+extern size_t bgrt_image_size;
+extern struct acpi_table_bgrt *bgrt_tab;
+
+#else /* !CONFIG_ACPI_BGRT */
+
+static inline void efi_bgrt_init(void) {}
+
+#endif /* !CONFIG_ACPI_BGRT */
+
+#endif /* _LINUX_EFI_BGRT_H */
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 0c11a58..ab239c6 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -496,6 +496,7 @@ extern void efi_map_pal_code (void);
 extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
 extern void efi_gettimeofday (struct timespec *ts);
 extern void efi_enter_virtual_mode (void);	/* switch EFI to virtual mode, if possible */
+extern void efi_late_init(void);
 extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
 extern void efi_free_boot_services(void);
 extern u64 efi_get_iobase (void);
diff --git a/init/main.c b/init/main.c
index 391a291..f9de550 100644
--- a/init/main.c
+++ b/init/main.c
@@ -632,8 +632,10 @@ asmlinkage void __init start_kernel(void)
 	sfi_init_late();
 
 #ifdef CONFIG_X86
-	if (efi_enabled)
+	if (efi_enabled) {
+		efi_late_init();
 		efi_free_boot_services();
+	}
 #endif
 
 	ftrace_init();
-- 
1.7.10.4


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

* Re: [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory
  2012-08-30 21:28 [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory Josh Triplett
                   ` (2 preceding siblings ...)
  2012-08-30 21:28 ` [PATCH 3/3] efi: Fix the ACPI BGRT driver for images located in EFI boot services memory Josh Triplett
@ 2012-09-04 14:27 ` Matt Fleming
  2012-09-04 17:59   ` Josh Triplett
  3 siblings, 1 reply; 11+ messages in thread
From: Matt Fleming @ 2012-09-04 14:27 UTC (permalink / raw)
  To: Josh Triplett
  Cc: linux-kernel, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
	Len Brown, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi, linux-efi

On Thu, 2012-08-30 at 14:28 -0700, Josh Triplett wrote:
> The ACPI BGRT lets the OS access the BIOS logo image and its position on the
> screen at boot time, allowing it to maintain that image on the screen until
> ready to display something else, making boot more seamless.  This series fixes
> support for accessing the boot logo image via the BGRT when the BIOS stores it
> in EFI boot services memory, as recommended by the ACPI 5.0 spec.  Linux needs
> to copy the image out of boot services memory before reclaiming boot services
> memory.
> 
> The first patch refactors EFI initialization to defer freeing boot services
> memory until later in the boot process, after we have ACPI available.  The
> second patch adds a helper function to look up existing EFI boot services
> mappings, to avoid re-mapping them.  The third patch moves BGRT initialization
> to before the reclamation of boot services memory, copies the logo at that
> point, and reworks the existing BGRT driver to use that existing copy.

Since we always end up doing a copy anyway, is there no way we could
just copy the boot logo *without* deferring freeing the boot services
code, e.g. move the copy before we do SetVirtualAddressMap()? I wouldn't
be surprised if some implementations got really cranky if we accessed
boot services data after we installed a new virtual memory map.

Besides, if we can avoid moving the efi_free_boot_services() call we can
avoid littering init/main.c with more #ifdef CONFIG_X86 blocks.


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

* Re: [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory
  2012-09-04 14:27 ` [PATCH 0/3] Fix ACPI BGRT support " Matt Fleming
@ 2012-09-04 17:59   ` Josh Triplett
  2012-09-04 18:10     ` H. Peter Anvin
  2012-09-04 20:11     ` Matt Fleming
  0 siblings, 2 replies; 11+ messages in thread
From: Josh Triplett @ 2012-09-04 17:59 UTC (permalink / raw)
  To: Matt Fleming
  Cc: linux-kernel, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
	Len Brown, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi, linux-efi

On Tue, Sep 04, 2012 at 03:27:20PM +0100, Matt Fleming wrote:
> On Thu, 2012-08-30 at 14:28 -0700, Josh Triplett wrote:
> > The ACPI BGRT lets the OS access the BIOS logo image and its position on the
> > screen at boot time, allowing it to maintain that image on the screen until
> > ready to display something else, making boot more seamless.  This series fixes
> > support for accessing the boot logo image via the BGRT when the BIOS stores it
> > in EFI boot services memory, as recommended by the ACPI 5.0 spec.  Linux needs
> > to copy the image out of boot services memory before reclaiming boot services
> > memory.
> > 
> > The first patch refactors EFI initialization to defer freeing boot services
> > memory until later in the boot process, after we have ACPI available.  The
> > second patch adds a helper function to look up existing EFI boot services
> > mappings, to avoid re-mapping them.  The third patch moves BGRT initialization
> > to before the reclamation of boot services memory, copies the logo at that
> > point, and reworks the existing BGRT driver to use that existing copy.
> 
> Since we always end up doing a copy anyway, is there no way we could
> just copy the boot logo *without* deferring freeing the boot services
> code, e.g. move the copy before we do SetVirtualAddressMap()?

Unfortunately not.  We need enough of ACPI available to go read the
BGRT to know what to copy, so we need to defer freeing boot services
code until after we initialize ACPI (and thus everything ACPI needs,
which includes EFI since ACPI looks for root tables there).

> I wouldn't be surprised if some implementations got really cranky if
> we accessed boot services data after we installed a new virtual memory
> map.

Note that I've carefully accessed the boot services data *through* the
new virtual memory map, which should work fine.

> Besides, if we can avoid moving the efi_free_boot_services() call we can
> avoid littering init/main.c with more #ifdef CONFIG_X86 blocks.

Those seem easy enough to convert into appropriate always-available
stubs, if you'd like.  And I could move efi_free_boot_services() inside
efi_late_init(), too, keeping it an internal implementation detail of
EFI initialization.  Would that help?

- Josh Triplett

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

* Re: [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory
  2012-09-04 17:59   ` Josh Triplett
@ 2012-09-04 18:10     ` H. Peter Anvin
  2012-09-04 19:45       ` Josh Triplett
  2012-09-04 20:11     ` Matt Fleming
  1 sibling, 1 reply; 11+ messages in thread
From: H. Peter Anvin @ 2012-09-04 18:10 UTC (permalink / raw)
  To: Josh Triplett
  Cc: Matt Fleming, linux-kernel, Thomas Gleixner, Ingo Molnar, x86,
	Len Brown, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi, linux-efi

On 09/04/2012 10:59 AM, Josh Triplett wrote:
>
> Unfortunately not.  We need enough of ACPI available to go read the
> BGRT to know what to copy, so we need to defer freeing boot services
> code until after we initialize ACPI (and thus everything ACPI needs,
> which includes EFI since ACPI looks for root tables there).
>
>> I wouldn't be surprised if some implementations got really cranky if
>> we accessed boot services data after we installed a new virtual memory
>> map.
>
> Note that I've carefully accessed the boot services data *through* the
> new virtual memory map, which should work fine.
>

There are some platforms which have bugs in this area, so there are 
other reasons to defer freeing up boot memory until as late in the boot 
process as we can possibly get away with.

free_initmem() is presuambly the place that makes most sense.  This is 
EFI-specific but not x86-specific, let's not commingle those concepts, 
please...

	-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] 11+ messages in thread

* Re: [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory
  2012-09-04 18:10     ` H. Peter Anvin
@ 2012-09-04 19:45       ` Josh Triplett
  2012-09-04 20:24         ` H. Peter Anvin
  0 siblings, 1 reply; 11+ messages in thread
From: Josh Triplett @ 2012-09-04 19:45 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Matt Fleming, linux-kernel, Thomas Gleixner, Ingo Molnar, x86,
	Len Brown, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi, linux-efi

On Tue, Sep 04, 2012 at 11:10:54AM -0700, H. Peter Anvin wrote:
> On 09/04/2012 10:59 AM, Josh Triplett wrote:
> >
> >Unfortunately not.  We need enough of ACPI available to go read the
> >BGRT to know what to copy, so we need to defer freeing boot services
> >code until after we initialize ACPI (and thus everything ACPI needs,
> >which includes EFI since ACPI looks for root tables there).
> >
> >>I wouldn't be surprised if some implementations got really cranky if
> >>we accessed boot services data after we installed a new virtual memory
> >>map.
> >
> >Note that I've carefully accessed the boot services data *through* the
> >new virtual memory map, which should work fine.
> >
> 
> There are some platforms which have bugs in this area, so there are
> other reasons to defer freeing up boot memory until as late in the
> boot process as we can possibly get away with.
> 
> free_initmem() is presuambly the place that makes most sense.

You're suggesting a call from free_initmem() to
efi_free_boot_services()?  Or, from init_post() right before the call to
free_initmem()?

> This
> is EFI-specific but not x86-specific, let's not commingle those
> concepts, please...

init/main.c already calls the x86-specific efi_enter_virtual_mode
(defined in arch/x86/platform/efi/efi.c), and I split the call to the
x86-specific efi_free_boot_services out of that.  Neither of those
functions exists on non-x86 platforms, and thus I mirrored the #ifdef
currently wrapped around efi_enter_virtual_mode for the new call to
efi_free_boot_services.  While it might make sense for that code to
exist on non-x86 EFI platforms, it currently doesn't.  At best, I could
add static inline stubs to linux/efi.h for those functions to avoid the
ifdefs, but as far as I can tell the same issue applies to quite a few
more functions in efi.h.

Would you like me to add the static inline stubs for the couple of
functions called from init/main.c, or leave the #ifdefs?

- Josh Triplett

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

* Re: [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory
  2012-09-04 17:59   ` Josh Triplett
  2012-09-04 18:10     ` H. Peter Anvin
@ 2012-09-04 20:11     ` Matt Fleming
  1 sibling, 0 replies; 11+ messages in thread
From: Matt Fleming @ 2012-09-04 20:11 UTC (permalink / raw)
  To: Josh Triplett
  Cc: linux-kernel, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, x86,
	Len Brown, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi, linux-efi

On Tue, 2012-09-04 at 10:59 -0700, Josh Triplett wrote:
> On Tue, Sep 04, 2012 at 03:27:20PM +0100, Matt Fleming wrote:
> > On Thu, 2012-08-30 at 14:28 -0700, Josh Triplett wrote:
> > > The ACPI BGRT lets the OS access the BIOS logo image and its position on the
> > > screen at boot time, allowing it to maintain that image on the screen until
> > > ready to display something else, making boot more seamless.  This series fixes
> > > support for accessing the boot logo image via the BGRT when the BIOS stores it
> > > in EFI boot services memory, as recommended by the ACPI 5.0 spec.  Linux needs
> > > to copy the image out of boot services memory before reclaiming boot services
> > > memory.
> > > 
> > > The first patch refactors EFI initialization to defer freeing boot services
> > > memory until later in the boot process, after we have ACPI available.  The
> > > second patch adds a helper function to look up existing EFI boot services
> > > mappings, to avoid re-mapping them.  The third patch moves BGRT initialization
> > > to before the reclamation of boot services memory, copies the logo at that
> > > point, and reworks the existing BGRT driver to use that existing copy.
> > 
> > Since we always end up doing a copy anyway, is there no way we could
> > just copy the boot logo *without* deferring freeing the boot services
> > code, e.g. move the copy before we do SetVirtualAddressMap()?
> 
> Unfortunately not.  We need enough of ACPI available to go read the
> BGRT to know what to copy, so we need to defer freeing boot services
> code until after we initialize ACPI (and thus everything ACPI needs,
> which includes EFI since ACPI looks for root tables there).

Ah, right. It was also pointed out to me offline that some drivers have
been known to access boot services data even after
SetVirtualAddressMap(), so this deferring shouldn't be a problem.

> > I wouldn't be surprised if some implementations got really cranky if
> > we accessed boot services data after we installed a new virtual memory
> > map.
> 
> Note that I've carefully accessed the boot services data *through* the
> new virtual memory map, which should work fine.
> 
> > Besides, if we can avoid moving the efi_free_boot_services() call we can
> > avoid littering init/main.c with more #ifdef CONFIG_X86 blocks.
> 
> Those seem easy enough to convert into appropriate always-available
> stubs, if you'd like.  And I could move efi_free_boot_services() inside
> efi_late_init(), too, keeping it an internal implementation detail of
> EFI initialization.  Would that help?

Yeah, that would seem like a good solution.


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

* Re: [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory
  2012-09-04 19:45       ` Josh Triplett
@ 2012-09-04 20:24         ` H. Peter Anvin
  2012-09-04 20:29           ` Josh Triplett
  0 siblings, 1 reply; 11+ messages in thread
From: H. Peter Anvin @ 2012-09-04 20:24 UTC (permalink / raw)
  To: Josh Triplett
  Cc: Matt Fleming, linux-kernel, Thomas Gleixner, Ingo Molnar, x86,
	Len Brown, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi, linux-efi

On 09/04/2012 12:45 PM, Josh Triplett wrote:
>>
>> There are some platforms which have bugs in this area, so there are
>> other reasons to defer freeing up boot memory until as late in the
>> boot process as we can possibly get away with.
>>
>> free_initmem() is presuambly the place that makes most sense.
>
> You're suggesting a call from free_initmem() to
> efi_free_boot_services()?  Or, from init_post() right before the call to
> free_initmem()?
>

free_initmem() is arch-specific, so probably the latter.

>> This
>> is EFI-specific but not x86-specific, let's not commingle those
>> concepts, please...
>
> init/main.c already calls the x86-specific efi_enter_virtual_mode
> (defined in arch/x86/platform/efi/efi.c), and I split the call to the
> x86-specific efi_free_boot_services out of that.  Neither of those
> functions exists on non-x86 platforms, and thus I mirrored the #ifdef
> currently wrapped around efi_enter_virtual_mode for the new call to
> efi_free_boot_services.  While it might make sense for that code to
> exist on non-x86 EFI platforms, it currently doesn't.  At best, I could
> add static inline stubs to linux/efi.h for those functions to avoid the
> ifdefs, but as far as I can tell the same issue applies to quite a few
> more functions in efi.h.
>
> Would you like me to add the static inline stubs for the couple of
> functions called from init/main.c, or leave the #ifdefs?
>

I think that would really help clean things up.

	-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] 11+ messages in thread

* Re: [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory
  2012-09-04 20:24         ` H. Peter Anvin
@ 2012-09-04 20:29           ` Josh Triplett
  0 siblings, 0 replies; 11+ messages in thread
From: Josh Triplett @ 2012-09-04 20:29 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Matt Fleming, linux-kernel, Thomas Gleixner, Ingo Molnar, x86,
	Len Brown, Olof Johansson, Matthew Garrett, David Howells,
	Rusty Russell, Jim Cromie, Peter Zijlstra, Pawel Moll,
	linux-acpi, linux-efi

On Tue, Sep 04, 2012 at 01:24:03PM -0700, H. Peter Anvin wrote:
> On 09/04/2012 12:45 PM, Josh Triplett wrote:
> >>
> >>There are some platforms which have bugs in this area, so there are
> >>other reasons to defer freeing up boot memory until as late in the
> >>boot process as we can possibly get away with.
> >>
> >>free_initmem() is presuambly the place that makes most sense.
> >
> >You're suggesting a call from free_initmem() to
> >efi_free_boot_services()?  Or, from init_post() right before the call to
> >free_initmem()?
> 
> free_initmem() is arch-specific, so probably the latter.

OK, will do.

> >>This
> >>is EFI-specific but not x86-specific, let's not commingle those
> >>concepts, please...
> >
> >init/main.c already calls the x86-specific efi_enter_virtual_mode
> >(defined in arch/x86/platform/efi/efi.c), and I split the call to the
> >x86-specific efi_free_boot_services out of that.  Neither of those
> >functions exists on non-x86 platforms, and thus I mirrored the #ifdef
> >currently wrapped around efi_enter_virtual_mode for the new call to
> >efi_free_boot_services.  While it might make sense for that code to
> >exist on non-x86 EFI platforms, it currently doesn't.  At best, I could
> >add static inline stubs to linux/efi.h for those functions to avoid the
> >ifdefs, but as far as I can tell the same issue applies to quite a few
> >more functions in efi.h.
> >
> >Would you like me to add the static inline stubs for the couple of
> >functions called from init/main.c, or leave the #ifdefs?
> >
> 
> I think that would really help clean things up.

Fair enough.  I'll send v2 shortly.

- Josh Triplett

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

end of thread, other threads:[~2012-09-04 20:29 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-30 21:28 [PATCH 0/3] Fix ACPI BGRT support for images located in EFI boot services memory Josh Triplett
2012-08-30 21:28 ` [PATCH 1/3] efi: Defer freeing boot services memory until after ACPI init Josh Triplett
2012-08-30 21:28 ` [PATCH 2/3] efi: Add a function to look up existing IO memory mappings Josh Triplett
2012-08-30 21:28 ` [PATCH 3/3] efi: Fix the ACPI BGRT driver for images located in EFI boot services memory Josh Triplett
2012-09-04 14:27 ` [PATCH 0/3] Fix ACPI BGRT support " Matt Fleming
2012-09-04 17:59   ` Josh Triplett
2012-09-04 18:10     ` H. Peter Anvin
2012-09-04 19:45       ` Josh Triplett
2012-09-04 20:24         ` H. Peter Anvin
2012-09-04 20:29           ` Josh Triplett
2012-09-04 20:11     ` Matt Fleming

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).