[Arm-dev] [PATCH 2/3] Add firmware update support with fwupdate tool

Fri Nov 18 01:30:30 UTC 2016
Duc Dang <dhdang at apm.com>

These patches are already upstream (v4.9-rc1).
The original series was posted by Ard Biesheuvel:
http://www.spinics.net/lists/arm-kernel/msg482982.html

Signed-off-by: Duc Dang <dhdang at apm.com>
---
 ...-drivers-to-reserve-boot-services-forever.patch | 112 +++++++++++++++++++++
 ...fi-esrt-add-missing-call-to-efi_esrt_init.patch |  48 +++++++++
 SOURCES/1025-efi-esrt-Don-t-preformat-name.patch   |  46 +++++++++
 ...t-Use-efi_mem_reserve-and-avoid-a-kmalloc.patch |  90 +++++++++++++++++
 ...e-memremap-not-ioremap-to-access-ESRT-tab.patch |  52 ++++++++++
 SPECS/kernel-aarch64.spec                          |  11 ++
 6 files changed, 359 insertions(+)
 create mode 100644 SOURCES/1023-efi-Allow-drivers-to-reserve-boot-services-forever.patch
 create mode 100644 SOURCES/1024-arm64-efi-esrt-add-missing-call-to-efi_esrt_init.patch
 create mode 100644 SOURCES/1025-efi-esrt-Don-t-preformat-name.patch
 create mode 100644 SOURCES/1026-efi-esrt-Use-efi_mem_reserve-and-avoid-a-kmalloc.patch
 create mode 100644 SOURCES/1027-efi-esrt-Use-memremap-not-ioremap-to-access-ESRT-tab.patch

diff --git a/SOURCES/1023-efi-Allow-drivers-to-reserve-boot-services-forever.patch b/SOURCES/1023-efi-Allow-drivers-to-reserve-boot-services-forever.patch
new file mode 100644
index 0000000..44de0df
--- /dev/null
+++ b/SOURCES/1023-efi-Allow-drivers-to-reserve-boot-services-forever.patch
@@ -0,0 +1,112 @@
+From e8f60371bfbc8c5917b445dc2c5278065f21334d Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt at codeblueprint.co.uk>
+Date: Wed, 16 Nov 2016 17:09:50 -0600
+Subject: [PATCH 1023/1027] efi: Allow drivers to reserve boot services forever
+
+Today, it is not possible for drivers to reserve EFI boot services for
+access after efi_free_boot_services() has been called on x86. For
+ARM/arm64 it can be done simply by calling memblock_reserve().
+
+Having this ability for all three architectures is desirable for a
+couple of reasons,
+
+  1) It saves drivers copying data out of those regions
+  2) kexec reboot can now make use of things like ESRT
+
+Instead of using the standard memblock_reserve() which is insufficient
+to reserve the region on x86 (see efi_reserve_boot_services()), a new
+API is introduced in this patch; efi_mem_reserve().
+
+efi.memmap now always represents which EFI memory regions are
+available. On x86 the EFI boot services regions that have not been
+reserved via efi_mem_reserve() will be removed from efi.memmap during
+efi_free_boot_services().
+
+This has implications for kexec, since it is not possible for a newly
+kexec'd kernel to access the same boot services regions that the
+initial boot kernel had access to unless they are reserved by every
+kexec kernel in the chain.
+
+Tested-by: Dave Young <dyoung at redhat.com> [kexec/kdump]
+Tested-by: Ard Biesheuvel <ard.biesheuvel at linaro.org> [arm]
+Acked-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
+Cc: Leif Lindholm <leif.lindholm at linaro.org>
+Cc: Peter Jones <pjones at redhat.com>
+Cc: Borislav Petkov <bp at alien8.de>
+Cc: Mark Rutland <mark.rutland at arm.com>
+Signed-off-by: Matt Fleming <matt at codeblueprint.co.uk>
+
+[Apply from upstream commit 816e76129ed5fadd28e526c43397c79775194b5c
+for CentOS 7.3 AltArch, drop the changes for x86 platforms in
+arch/x86/platform/efi/quirks.c]
+Signed-off-by: Huy Duong <hduong at apm.com>
+Signed-off-by: Duc Dang <dhdang at apm.com>
+---
+ drivers/firmware/efi/efi.c | 31 ++++++++++++++++++++++++++++++-
+ include/linux/efi.h        |  1 +
+ 2 files changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index 2cd37da..5f3c096 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -24,7 +24,7 @@
+ #include <linux/of_fdt.h>
+ #include <linux/io.h>
+ #include <linux/platform_device.h>
+-
++#include <linux/memblock.h>
+ #include <asm/early_ioremap.h>
+ 
+ struct efi __read_mostly efi = {
+@@ -358,6 +358,35 @@ void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
+ 	return NULL;
+ }
+ 
++void __init __weak efi_arch_mem_reserve(phys_addr_t addr, u64 size) {}
++
++/**
++ * efi_mem_reserve - Reserve an EFI memory region
++ * @addr: Physical address to reserve
++ * @size: Size of reservation
++ *
++ * Mark a region as reserved from general kernel allocation and
++ * prevent it being released by efi_free_boot_services().
++ *
++ * This function should be called drivers once they've parsed EFI
++ * configuration tables to figure out where their data lives, e.g.
++ * efi_esrt_init().
++ */
++void __init efi_mem_reserve(phys_addr_t addr, u64 size)
++{
++	if (!memblock_is_region_reserved(addr, size))
++		memblock_reserve(addr, size);
++
++	/*
++	 * Some architectures (x86) reserve all boot services ranges
++	 * until efi_free_boot_services() because of buggy firmware
++	 * implementations. This means the above memblock_reserve() is
++	 * superfluous on x86 and instead what it needs to do is
++	 * ensure the @start, @size is not freed.
++	 */
++	efi_arch_mem_reserve(addr, size);
++}
++
+ static __initdata efi_config_table_type_t common_tables[] = {
+ 	{ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
+ 	{ACPI_TABLE_GUID, "ACPI", &efi.acpi},
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index 47be3ad..6cf8403 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -911,6 +911,7 @@ extern u64 efi_mem_attribute (unsigned long phys_addr, unsigned long size);
+ extern int __init efi_uart_console_only (void);
+ extern u64 efi_mem_desc_end(efi_memory_desc_t *md);
+ extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md);
++extern void efi_mem_reserve(phys_addr_t addr, u64 size);
+ extern void efi_initialize_iomem_resources(struct resource *code_resource,
+ 		struct resource *data_resource, struct resource *bss_resource);
+ extern void efi_get_time(struct timespec *now);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/1024-arm64-efi-esrt-add-missing-call-to-efi_esrt_init.patch b/SOURCES/1024-arm64-efi-esrt-add-missing-call-to-efi_esrt_init.patch
new file mode 100644
index 0000000..4944833
--- /dev/null
+++ b/SOURCES/1024-arm64-efi-esrt-add-missing-call-to-efi_esrt_init.patch
@@ -0,0 +1,48 @@
+From 1e6d164dc465e45ac59c1371ac57d649094d663f Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ard.biesheuvel at linaro.org>
+Date: Wed, 16 Nov 2016 17:25:54 -0600
+Subject: [PATCH 1024/1027] arm64/efi: esrt: add missing call to
+ efi_esrt_init()
+
+ESRT support is built by default for all architectures that define
+CONFIG_EFI. However, this support was not wired up yet for ARM/arm64,
+since efi_esrt_init() was never called. So add the missing call.
+
+Since efi_esrt_init() uses efi_mem_desc_lookup(), which in turn relies
+on efi.memmap having been assigned and populated completetely, add the
+missing assignments of efi.memmap and efi.memmap->nr_map.
+
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
+
+[Apply for CentOS 7.3 AltArch. Original patch is posted at
+http://www.spinics.net/lists/arm-kernel/msg482984.html,
+Matt Fleming queued an updated verison of this patch
+for v4.9 (https://patchwork.kernel.org/patch/9223967/)]
+Signed-off-by: Huy Duong <hduong at apm.com>
+Signed-off-by: Duc Dang <dhdang at apm.com>
+---
+ drivers/firmware/efi/arm-init.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
+index b21dbb5..68b176c 100644
+--- a/drivers/firmware/efi/arm-init.c
++++ b/drivers/firmware/efi/arm-init.c
+@@ -205,11 +205,14 @@ void __init efi_init(void)
+ 	memmap.map_end = memmap.map + params.mmap_size;
+ 	memmap.desc_size = params.desc_size;
+ 	memmap.desc_version = params.desc_ver;
++	memmap.nr_map = params.mmap_size / params.desc_size;
++	efi.memmap = &memmap;
+ 
+ 	if (uefi_init() < 0)
+ 		return;
+ 
+ 	reserve_regions();
++	efi_esrt_init();
+ 	early_memunmap(memmap.map, params.mmap_size);
+ 	memblock_mark_nomap(params.mmap & PAGE_MASK,
+ 			    PAGE_ALIGN(params.mmap_size +
+-- 
+1.8.3.1
+
diff --git a/SOURCES/1025-efi-esrt-Don-t-preformat-name.patch b/SOURCES/1025-efi-esrt-Don-t-preformat-name.patch
new file mode 100644
index 0000000..4a1b519
--- /dev/null
+++ b/SOURCES/1025-efi-esrt-Don-t-preformat-name.patch
@@ -0,0 +1,46 @@
+From 60de706977433c7e2a2c677a292747dfa258840e Mon Sep 17 00:00:00 2001
+From: Rasmus Villemoes <linux at rasmusvillemoes.dk>
+Date: Fri, 20 Nov 2015 11:30:17 +0100
+Subject: [PATCH 1025/1027] efi/esrt: Don't preformat name
+
+kobject_init_and_add takes a format string+args, so there's no reason
+to do this formatting in advance.
+
+Signed-off-by: Rasmus Villemoes <linux at rasmusvillemoes.dk>
+Cc: Peter Jones <pjones at redhat.com>
+Signed-off-by: Matt Fleming <matt at codeblueprint.co.uk>
+---
+ drivers/firmware/efi/esrt.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c
+index 22c5285..75feb3f 100644
+--- a/drivers/firmware/efi/esrt.c
++++ b/drivers/firmware/efi/esrt.c
+@@ -167,14 +167,11 @@ static struct kset *esrt_kset;
+ static int esre_create_sysfs_entry(void *esre, int entry_num)
+ {
+ 	struct esre_entry *entry;
+-	char name[20];
+ 
+ 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ 	if (!entry)
+ 		return -ENOMEM;
+ 
+-	sprintf(name, "entry%d", entry_num);
+-
+ 	entry->kobj.kset = esrt_kset;
+ 
+ 	if (esrt->fw_resource_version == 1) {
+@@ -182,7 +179,7 @@ static int esre_create_sysfs_entry(void *esre, int entry_num)
+ 
+ 		entry->esre.esre1 = esre;
+ 		rc = kobject_init_and_add(&entry->kobj, &esre1_ktype, NULL,
+-					  "%s", name);
++					  "entry%d", entry_num);
+ 		if (rc) {
+ 			kfree(entry);
+ 			return rc;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/1026-efi-esrt-Use-efi_mem_reserve-and-avoid-a-kmalloc.patch b/SOURCES/1026-efi-esrt-Use-efi_mem_reserve-and-avoid-a-kmalloc.patch
new file mode 100644
index 0000000..6d7d6c1
--- /dev/null
+++ b/SOURCES/1026-efi-esrt-Use-efi_mem_reserve-and-avoid-a-kmalloc.patch
@@ -0,0 +1,90 @@
+From 44acdab31a74c7ec482f4b0f332fe6c4c21d1dc6 Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt at codeblueprint.co.uk>
+Date: Tue, 1 Mar 2016 23:08:03 +0000
+Subject: [PATCH 1026/1027] efi/esrt: Use efi_mem_reserve() and avoid a
+ kmalloc()
+
+We can use the new efi_mem_reserve() API to mark the ESRT table as
+reserved forever and save ourselves the trouble of copying the data
+out into a kmalloc buffer.
+
+The added advantage is that now the ESRT driver will work across
+kexec reboot.
+
+Tested-by: Dave Young <dyoung at redhat.com> [kexec/kdump]
+Tested-by: Ard Biesheuvel <ard.biesheuvel at linaro.org> [arm]
+Acked-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
+Cc: Leif Lindholm <leif.lindholm at linaro.org>
+Cc: Peter Jones <pjones at redhat.com>
+Cc: Borislav Petkov <bp at alien8.de>
+Cc: Mark Rutland <mark.rutland at arm.com>
+Signed-off-by: Matt Fleming <matt at codeblueprint.co.uk>
+---
+ drivers/firmware/efi/esrt.c | 20 ++++----------------
+ 1 file changed, 4 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c
+index 75feb3f..b93cd11 100644
+--- a/drivers/firmware/efi/esrt.c
++++ b/drivers/firmware/efi/esrt.c
+@@ -235,7 +235,7 @@ static struct attribute_group esrt_attr_group = {
+ };
+ 
+ /*
+- * remap the table, copy it to kmalloced pages, and unmap it.
++ * remap the table, validate it, mark it reserved and unmap it.
+  */
+ void __init efi_esrt_init(void)
+ {
+@@ -335,7 +335,7 @@ void __init efi_esrt_init(void)
+ 
+ 	end = esrt_data + size;
+ 	pr_info("Reserving ESRT space from %pa to %pa.\n", &esrt_data, &end);
+-	memblock_reserve(esrt_data, esrt_data_size);
++	efi_mem_reserve(esrt_data, esrt_data_size);
+ 
+ 	pr_debug("esrt-init: loaded.\n");
+ err_memunmap:
+@@ -382,28 +382,18 @@ static void cleanup_entry_list(void)
+ static int __init esrt_sysfs_init(void)
+ {
+ 	int error;
+-	struct efi_system_resource_table __iomem *ioesrt;
+ 
+ 	pr_debug("esrt-sysfs: loading.\n");
+ 	if (!esrt_data || !esrt_data_size)
+ 		return -ENOSYS;
+ 
+-	ioesrt = ioremap(esrt_data, esrt_data_size);
+-	if (!ioesrt) {
++	esrt = ioremap(esrt_data, esrt_data_size);
++	if (!esrt) {
+ 		pr_err("ioremap(%pa, %zu) failed.\n", &esrt_data,
+ 		       esrt_data_size);
+ 		return -ENOMEM;
+ 	}
+ 
+-	esrt = kmalloc(esrt_data_size, GFP_KERNEL);
+-	if (!esrt) {
+-		pr_err("kmalloc failed. (wanted %zu bytes)\n", esrt_data_size);
+-		iounmap(ioesrt);
+-		return -ENOMEM;
+-	}
+-
+-	memcpy_fromio(esrt, ioesrt, esrt_data_size);
+-
+ 	esrt_kobj = kobject_create_and_add("esrt", efi_kobj);
+ 	if (!esrt_kobj) {
+ 		pr_err("Firmware table registration failed.\n");
+@@ -429,8 +419,6 @@ static int __init esrt_sysfs_init(void)
+ 	if (error)
+ 		goto err_cleanup_list;
+ 
+-	memblock_remove(esrt_data, esrt_data_size);
+-
+ 	pr_debug("esrt-sysfs: loaded.\n");
+ 
+ 	return 0;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/1027-efi-esrt-Use-memremap-not-ioremap-to-access-ESRT-tab.patch b/SOURCES/1027-efi-esrt-Use-memremap-not-ioremap-to-access-ESRT-tab.patch
new file mode 100644
index 0000000..11f1fca
--- /dev/null
+++ b/SOURCES/1027-efi-esrt-Use-memremap-not-ioremap-to-access-ESRT-tab.patch
@@ -0,0 +1,52 @@
+From 3dba40136c1ab16d48012dbd00e5f12681f13553 Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ard.biesheuvel at linaro.org>
+Date: Mon, 11 Jul 2016 21:00:45 +0200
+Subject: [PATCH 1027/1027] efi/esrt: Use memremap not ioremap to access ESRT
+ table in memory
+
+On ARM and arm64, ioremap() and memremap() are not interchangeable like
+on x86, and the use of ioremap() on ordinary RAM is typically flagged
+as an error if the memory region being mapped is also covered by the
+linear mapping, since that would lead to aliases with conflicting
+cacheability attributes.
+
+Since what we are dealing with is not an I/O region with side effects,
+using ioremap() here is arguably incorrect anyway, so let's replace
+it with memremap() instead.
+
+Acked-by: Peter Jones <pjones at redhat.com>
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
+Cc: Leif Lindholm <leif.lindholm at linaro.org>
+Cc: Mark Rutland <mark.rutland at arm.com>
+Signed-off-by: Matt Fleming <matt at codeblueprint.co.uk>
+---
+ drivers/firmware/efi/esrt.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c
+index b93cd11..1491407 100644
+--- a/drivers/firmware/efi/esrt.c
++++ b/drivers/firmware/efi/esrt.c
+@@ -16,6 +16,7 @@
+ #include <linux/device.h>
+ #include <linux/efi.h>
+ #include <linux/init.h>
++#include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/kobject.h>
+ #include <linux/list.h>
+@@ -387,9 +388,9 @@ static int __init esrt_sysfs_init(void)
+ 	if (!esrt_data || !esrt_data_size)
+ 		return -ENOSYS;
+ 
+-	esrt = ioremap(esrt_data, esrt_data_size);
++	esrt = memremap(esrt_data, esrt_data_size, MEMREMAP_WB);
+ 	if (!esrt) {
+-		pr_err("ioremap(%pa, %zu) failed.\n", &esrt_data,
++		pr_err("memremap(%pa, %zu) failed.\n", &esrt_data,
+ 		       esrt_data_size);
+ 		return -ENOMEM;
+ 	}
+-- 
+1.8.3.1
+
diff --git a/SPECS/kernel-aarch64.spec b/SPECS/kernel-aarch64.spec
index 2034cd0..6e7950b 100644
--- a/SPECS/kernel-aarch64.spec
+++ b/SPECS/kernel-aarch64.spec
@@ -347,6 +347,11 @@ Patch1019: 1019-i2c-designware-Implement-support-for-SMBus-block-rea.patch
 Patch1020: 1020-hwmon-xgene-access-mailbox-as-RAM.patch
 Patch1021: 1021-gpio-xgene-Enable-X-Gene-standby-GPIO-as-interrupt-c.patch
 Patch1022: 1022-genirq-Export-IRQ-functions-for-module-use.patch
+Patch1023: 1023-efi-Allow-drivers-to-reserve-boot-services-forever.patch
+Patch1024: 1024-arm64-efi-esrt-add-missing-call-to-efi_esrt_init.patch
+Patch1025: 1025-efi-esrt-Don-t-preformat-name.patch
+Patch1026: 1026-efi-esrt-Use-efi_mem_reserve-and-avoid-a-kmalloc.patch
+Patch1027: 1027-efi-esrt-Use-memremap-not-ioremap-to-access-ESRT-tab.patch
 
 # QDF2400 Patches
 Patch4000: 4000-arm64-Define-Qualcomm-Technologies-ARMv8-CPU.patch
@@ -704,6 +709,11 @@ git am %{PATCH1019}
 git am %{PATCH1020}
 git am %{PATCH1021}
 git am %{PATCH1022}
+git am %{PATCH1023}
+git am %{PATCH1024}
+git am %{PATCH1025}
+git am %{PATCH1026}
+git am %{PATCH1027}
 
 # Apply QDF2400 patches
 git am %{PATCH4000}
@@ -1483,6 +1493,7 @@ fi
 
 %changelog
 * Thu Nov 17 2016 Duc Dang <dhdang at apm.com> [4.5.0-18.el7]
+- Backport upstream patches to support fwupdate
 - Integrate upstream patch to add interrupt support for X-Gene Standby GPIO 
 
 * Thu Nov 10 2016 Duc Dang <dhdang at apm.com> [4.5.0-17.el7]
-- 
1.8.3.1