linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] arm64 UEFI early FDT handling
@ 2015-05-11  6:41 Ard Biesheuvel
  2015-05-11  6:41 ` [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing Ard Biesheuvel
                   ` (7 more replies)
  0 siblings, 8 replies; 22+ messages in thread
From: Ard Biesheuvel @ 2015-05-11  6:41 UTC (permalink / raw)
  To: linux-arm-kernel

This is a followup to the "arm64: update/clarify/relax Image and FDT placement
rules" series I sent a while ago:
(http://article.gmane.org/gmane.linux.ports.arm.kernel/407148)

This has now been split in two series: this first series deals with the
early FDT handling, primarily in the context of UEFI, but not exclusively.

A number of minor issues exist in the early UEFI/FDT handling path, such as:
- the FDT placement by the stub may violate the arm64/linux boot protocol in
  some corner cases;
- when booting via UEFI, memreserve entries are removed from the device tree but
  the /reserved-memory node is not
- memory nodes are removed from the device tree in a way that is not officially
  supported by the libfdt API (i.e., you cannot delete nodes while traversing
  the tree)
- removal of memory nodes may discard annotations (such as NUMA topology) that
  should ideally be retained.

Patch #1 splits off the reservation of the FDT image from the reservation of the
memreserve entries and /reserved-memory node.

Patch #2 relaxes the boot protocol requirement on the placement of the FDT.

Patch #3 introduces an arm64 specific version of early_init_dt_add_memory_arch()
so that we can modify it later to ignore DT memory nodes if booting via UEFI.
Note that having this specific version is desirable for other reasons as well,
this is covered by the other followup series.

Patch #4 moves some UEFI+FDT init code around before making changes to it.

Patch #5 moves the UEFI initialization to before the early FDT scanning so we
know at that point whether we are booting via UEFI or not.

Patch #6 changes the UEFI init code so that memory nodes are simply ignored, so
that they don't have to be removed by the stub anymore.

Patch  #7 does the same as #6, but for memreserves and the /reserved-memory
node.

Patch #8 adapts the FDT placement logic used by the stub to take into account
the new relaxed rules.

Ard Biesheuvel (8):
  of/fdt: split off FDT self reservation from memreserve processing
  arm64: use fixmap region for permanent FDT mapping
  arm64: override early_init_dt_add_memory_arch()
  efi: move FDT handling to separate object file
  arm64/efi: move EFI init before early FDT processing
  arm64/efi: ignore DT memory nodes instead of removing them
  arm64/efi: ignore DT memreserve entries instead of removing them
  arm64/efi: adapt to relaxed FDT placement requirements

 Documentation/arm64/booting.txt         | 13 +++--
 arch/arm/mm/init.c                      |  1 +
 arch/arm64/include/asm/boot.h           | 14 ++++++
 arch/arm64/include/asm/efi.h            | 14 ++----
 arch/arm64/include/asm/fixmap.h         | 15 ++++++
 arch/arm64/include/asm/mmu.h            |  1 +
 arch/arm64/kernel/efi.c                 | 14 ++----
 arch/arm64/kernel/head.S                | 39 +--------------
 arch/arm64/kernel/setup.c               | 34 +++++--------
 arch/arm64/mm/Makefile                  |  2 +
 arch/arm64/mm/init.c                    | 35 +++++++++++++-
 arch/arm64/mm/mmu.c                     | 66 +++++++++++++++++++++++++
 arch/powerpc/kernel/prom.c              |  1 +
 drivers/firmware/efi/Makefile           |  2 +
 drivers/firmware/efi/efi-fdt.c          | 77 +++++++++++++++++++++++++++++
 drivers/firmware/efi/efi.c              | 86 ---------------------------------
 drivers/firmware/efi/libstub/arm-stub.c |  5 +-
 drivers/firmware/efi/libstub/efistub.h  |  1 -
 drivers/firmware/efi/libstub/fdt.c      | 51 ++++---------------
 drivers/of/fdt.c                        | 19 ++++++--
 include/linux/efi.h                     |  3 +-
 include/linux/of_fdt.h                  |  2 +
 22 files changed, 274 insertions(+), 221 deletions(-)
 create mode 100644 arch/arm64/include/asm/boot.h
 create mode 100644 drivers/firmware/efi/efi-fdt.c

-- 
1.9.1

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

* [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing
  2015-05-11  6:41 [PATCH 0/8] arm64 UEFI early FDT handling Ard Biesheuvel
@ 2015-05-11  6:41 ` Ard Biesheuvel
  2015-05-22 10:35   ` Catalin Marinas
  2015-05-11  6:41 ` [PATCH 2/8] arm64: use fixmap region for permanent FDT mapping Ard Biesheuvel
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: Ard Biesheuvel @ 2015-05-11  6:41 UTC (permalink / raw)
  To: linux-arm-kernel

This splits off the reservation of the memory occupied by the FDT
binary itself from the processing of the memory reservations it
contains. This is necessary because the physical address of the FDT,
which is needed to perform the reservation, may not be known to the
FDT driver core, i.e., it may be mapped outside the linear direct
mapping, in which case __pa() returns a bogus value.

Cc: Russell King <linux@arm.linux.org.uk>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm/mm/init.c         |  1 +
 arch/arm64/mm/init.c       |  1 +
 arch/powerpc/kernel/prom.c |  1 +
 drivers/of/fdt.c           | 19 ++++++++++++++-----
 include/linux/of_fdt.h     |  2 ++
 5 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index be92fa0f2f35..8a63b4cdc0f2 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -268,6 +268,7 @@ void __init arm_memblock_init(const struct machine_desc *mdesc)
 	if (mdesc->reserve)
 		mdesc->reserve();
 
+	early_init_fdt_reserve_self();
 	early_init_fdt_scan_reserved_mem();
 
 	/* reserve memory for DMA contiguous allocations */
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 597831bdddf3..89a05f467ffb 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -170,6 +170,7 @@ void __init arm64_memblock_init(void)
 		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
 #endif
 
+	early_init_fdt_reserve_self();
 	early_init_fdt_scan_reserved_mem();
 
 	/* 4GB maximum for 32-bit only capable devices */
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 308c5e15676b..51ea36f79307 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -573,6 +573,7 @@ static void __init early_reserve_mem_dt(void)
 	int len;
 	const __be32 *prop;
 
+	early_init_fdt_reserve_self();
 	early_init_fdt_scan_reserved_mem();
 
 	dt_root = of_get_flat_dt_root();
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index cde35c5d0191..f2dd23a32267 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -580,11 +580,6 @@ void __init early_init_fdt_scan_reserved_mem(void)
 	if (!initial_boot_params)
 		return;
 
-	/* Reserve the dtb region */
-	early_init_dt_reserve_memory_arch(__pa(initial_boot_params),
-					  fdt_totalsize(initial_boot_params),
-					  0);
-
 	/* Process header /memreserve/ fields */
 	for (n = 0; ; n++) {
 		fdt_get_mem_rsv(initial_boot_params, n, &base, &size);
@@ -598,6 +593,20 @@ void __init early_init_fdt_scan_reserved_mem(void)
 }
 
 /**
+ * early_init_fdt_reserve_self() - reserve the memory used by the FDT blob
+ */
+void __init early_init_fdt_reserve_self(void)
+{
+	if (!initial_boot_params)
+		return;
+
+	/* Reserve the dtb region */
+	early_init_dt_reserve_memory_arch(__pa(initial_boot_params),
+					  fdt_totalsize(initial_boot_params),
+					  0);
+}
+
+/**
  * of_scan_flat_dt - scan flattened tree blob and call callback on each.
  * @it: callback function
  * @data: context data pointer
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 587ee507965d..fd627a58068f 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -64,6 +64,7 @@ extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,
 extern int early_init_dt_scan_memory(unsigned long node, const char *uname,
 				     int depth, void *data);
 extern void early_init_fdt_scan_reserved_mem(void);
+extern void early_init_fdt_reserve_self(void);
 extern void early_init_dt_add_memory_arch(u64 base, u64 size);
 extern int early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size,
 					     bool no_map);
@@ -91,6 +92,7 @@ extern u64 fdt_translate_address(const void *blob, int node_offset);
 extern void of_fdt_limit_memory(int limit);
 #else /* CONFIG_OF_FLATTREE */
 static inline void early_init_fdt_scan_reserved_mem(void) {}
+static inline void early_init_fdt_reserve_self(void) {}
 static inline const char *of_flat_dt_get_machine_name(void) { return NULL; }
 static inline void unflatten_device_tree(void) {}
 static inline void unflatten_and_copy_device_tree(void) {}
-- 
1.9.1

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

* [PATCH 2/8] arm64: use fixmap region for permanent FDT mapping
  2015-05-11  6:41 [PATCH 0/8] arm64 UEFI early FDT handling Ard Biesheuvel
  2015-05-11  6:41 ` [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing Ard Biesheuvel
@ 2015-05-11  6:41 ` Ard Biesheuvel
  2015-06-01  9:53   ` Mark Rutland
  2015-05-11  6:41 ` [PATCH 3/8] arm64: override early_init_dt_add_memory_arch() Ard Biesheuvel
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: Ard Biesheuvel @ 2015-05-11  6:41 UTC (permalink / raw)
  To: linux-arm-kernel

Currently, the FDT blob needs to be in the same 512 MB region as
the kernel, so that it can be mapped into the kernel virtual memory
space very early on using a minimal set of statically allocated
translation tables.

Now that we have early fixmap support, we can relax this restriction,
by moving the permanent FDT mapping to the fixmap region instead.
This way, the FDT blob may be anywhere in memory.

This also moves the vetting of the FDT to mmu.c, since the early
init code in head.S does not handle mapping of the FDT anymore.
At the same time, fix up some comments in head.S that have gone stale.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 Documentation/arm64/booting.txt | 13 ++++----
 arch/arm64/include/asm/boot.h   | 14 +++++++++
 arch/arm64/include/asm/fixmap.h | 15 ++++++++++
 arch/arm64/include/asm/mmu.h    |  1 +
 arch/arm64/kernel/head.S        | 39 +-----------------------
 arch/arm64/kernel/setup.c       | 30 +++++++------------
 arch/arm64/mm/Makefile          |  2 ++
 arch/arm64/mm/init.c            |  1 -
 arch/arm64/mm/mmu.c             | 66 +++++++++++++++++++++++++++++++++++++++++
 9 files changed, 117 insertions(+), 64 deletions(-)
 create mode 100644 arch/arm64/include/asm/boot.h

diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
index f3c05b5f9f08..53f18e13d51c 100644
--- a/Documentation/arm64/booting.txt
+++ b/Documentation/arm64/booting.txt
@@ -45,11 +45,14 @@ sees fit.)
 
 Requirement: MANDATORY
 
-The device tree blob (dtb) must be placed on an 8-byte boundary within
-the first 512 megabytes from the start of the kernel image and must not
-cross a 2-megabyte boundary. This is to allow the kernel to map the
-blob using a single section mapping in the initial page tables.
-
+The device tree blob (dtb) must be placed on an 8-byte boundary and must
+not exceed 2 megabytes in size. Since the dtb will be mapped cacheable using
+blocks of up to 2 megabytes in size, it should not be placed within 2 megabytes
+of memreserves or other special carveouts that may be mapped with non-matching
+attributes.
+
+NOTE: versions prior to v4.2 also require that the DTB be placed within
+the 512 MB region starting at text_offset bytes below the kernel Image.
 
 3. Decompress the kernel image
 ------------------------------
diff --git a/arch/arm64/include/asm/boot.h b/arch/arm64/include/asm/boot.h
new file mode 100644
index 000000000000..81151b67b26b
--- /dev/null
+++ b/arch/arm64/include/asm/boot.h
@@ -0,0 +1,14 @@
+
+#ifndef __ASM_BOOT_H
+#define __ASM_BOOT_H
+
+#include <asm/sizes.h>
+
+/*
+ * arm64 requires the DTB to be 8 byte aligned and
+ * not exceed 2MB in size.
+ */
+#define MIN_FDT_ALIGN		8
+#define MAX_FDT_SIZE		SZ_2M
+
+#endif
diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index 95e6b6dcbe37..c0739187a920 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -17,6 +17,7 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/kernel.h>
+#include <asm/boot.h>
 #include <asm/page.h>
 
 /*
@@ -32,6 +33,20 @@
  */
 enum fixed_addresses {
 	FIX_HOLE,
+
+	/*
+	 * Reserve a virtual window for the FDT that is 2 MB larger than the
+	 * maximum supported size, and put it at the top of the fixmap region.
+	 * The additional space ensures that any FDT that does not exceed
+	 * MAX_FDT_SIZE can be mapped regardless of whether it crosses any
+	 * 2 MB alignment boundaries.
+	 *
+	 * Keep this at the top so it remains 2 MB aligned.
+	 */
+#define FIX_FDT_SIZE		(MAX_FDT_SIZE + SZ_2M)
+	FIX_FDT_END,
+	FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,
+
 	FIX_EARLYCON_MEM_BASE,
 	FIX_TEXT_POKE0,
 	__end_of_permanent_fixed_addresses,
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 3d311761e3c2..79fcfb048884 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -34,5 +34,6 @@ extern void init_mem_pgprot(void);
 extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
 			       unsigned long virt, phys_addr_t size,
 			       pgprot_t prot);
+extern void *fixmap_remap_fdt(phys_addr_t dt_phys);
 
 #endif
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 19f915e8f6e0..30cffc5e7402 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -237,8 +237,6 @@ ENTRY(stext)
 	bl	el2_setup			// Drop to EL1, w20=cpu_boot_mode
 	adrp	x24, __PHYS_OFFSET
 	bl	set_cpu_boot_mode_flag
-
-	bl	__vet_fdt
 	bl	__create_page_tables		// x25=TTBR0, x26=TTBR1
 	/*
 	 * The following calls CPU setup code, see arch/arm64/mm/proc.S for
@@ -270,24 +268,6 @@ preserve_boot_args:
 ENDPROC(preserve_boot_args)
 
 /*
- * Determine validity of the x21 FDT pointer.
- * The dtb must be 8-byte aligned and live in the first 512M of memory.
- */
-__vet_fdt:
-	tst	x21, #0x7
-	b.ne	1f
-	cmp	x21, x24
-	b.lt	1f
-	mov	x0, #(1 << 29)
-	add	x0, x0, x24
-	cmp	x21, x0
-	b.ge	1f
-	ret
-1:
-	mov	x21, #0
-	ret
-ENDPROC(__vet_fdt)
-/*
  * Macro to create a table entry to the next page.
  *
  *	tbl:	page table address
@@ -348,8 +328,7 @@ ENDPROC(__vet_fdt)
  * required to get the kernel running. The following sections are required:
  *   - identity mapping to enable the MMU (low address, TTBR0)
  *   - first few MB of the kernel linear mapping to jump to once the MMU has
- *     been enabled, including the FDT blob (TTBR1)
- *   - pgd entry for fixed mappings (TTBR1)
+ *     been enabled
  */
 __create_page_tables:
 	adrp	x25, idmap_pg_dir
@@ -439,22 +418,6 @@ __create_page_tables:
 	create_block_map x0, x7, x3, x5, x6
 
 	/*
-	 * Map the FDT blob (maximum 2MB; must be within 512MB of
-	 * PHYS_OFFSET).
-	 */
-	mov	x3, x21				// FDT phys address
-	and	x3, x3, #~((1 << 21) - 1)	// 2MB aligned
-	mov	x6, #PAGE_OFFSET
-	sub	x5, x3, x24			// subtract PHYS_OFFSET
-	tst	x5, #~((1 << 29) - 1)		// within 512MB?
-	csel	x21, xzr, x21, ne		// zero the FDT pointer
-	b.ne	1f
-	add	x5, x5, x6			// __va(FDT blob)
-	add	x6, x5, #1 << 21		// 2MB for the FDT blob
-	sub	x6, x6, #1			// inclusive range
-	create_block_map x0, x7, x3, x5, x6
-1:
-	/*
 	 * Since the page tables have been populated with non-cacheable
 	 * accesses (MMU disabled), invalidate the idmap and swapper page
 	 * tables again to remove any speculatively loaded cache lines.
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 74753132c3ac..770ae9dc5a75 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -105,18 +105,6 @@ static struct resource mem_res[] = {
 #define kernel_code mem_res[0]
 #define kernel_data mem_res[1]
 
-void __init early_print(const char *str, ...)
-{
-	char buf[256];
-	va_list ap;
-
-	va_start(ap, str);
-	vsnprintf(buf, sizeof(buf), str, ap);
-	va_end(ap);
-
-	printk("%s", buf);
-}
-
 /*
  * The recorded values of x0 .. x3 upon kernel entry.
  */
@@ -326,12 +314,14 @@ static void __init setup_processor(void)
 
 static void __init setup_machine_fdt(phys_addr_t dt_phys)
 {
-	if (!dt_phys || !early_init_dt_scan(phys_to_virt(dt_phys))) {
-		early_print("\n"
-			"Error: invalid device tree blob at physical address 0x%p (virtual address 0x%p)\n"
-			"The dtb must be 8-byte aligned and passed in the first 512MB of memory\n"
-			"\nPlease check your bootloader.\n",
-			dt_phys, phys_to_virt(dt_phys));
+	void *dt_virt = fixmap_remap_fdt(dt_phys);
+
+	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
+		pr_crit("\n"
+			"Error: invalid device tree blob@physical address %pa (virtual address 0x%p)\n"
+			"The dtb must be 8-byte aligned and must not exceed 2 MB in size\n"
+			"\nPlease check your bootloader.",
+			&dt_phys, dt_virt);
 
 		while (true)
 			cpu_relax();
@@ -374,8 +364,6 @@ void __init setup_arch(char **cmdline_p)
 {
 	setup_processor();
 
-	setup_machine_fdt(__fdt_pointer);
-
 	init_mm.start_code = (unsigned long) _text;
 	init_mm.end_code   = (unsigned long) _etext;
 	init_mm.end_data   = (unsigned long) _edata;
@@ -386,6 +374,8 @@ void __init setup_arch(char **cmdline_p)
 	early_fixmap_init();
 	early_ioremap_init();
 
+	setup_machine_fdt(__fdt_pointer);
+
 	parse_early_param();
 
 	/*
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index 773d37a14039..9d84feb41a16 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -4,3 +4,5 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_ARM64_PTDUMP)	+= dump.o
+
+CFLAGS_mmu.o			:= -I$(srctree)/scripts/dtc/libfdt/
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 89a05f467ffb..597831bdddf3 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -170,7 +170,6 @@ void __init arm64_memblock_init(void)
 		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
 #endif
 
-	early_init_fdt_reserve_self();
 	early_init_fdt_scan_reserved_mem();
 
 	/* 4GB maximum for 32-bit only capable devices */
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 5b8b664422d3..82d3435bf14f 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/libfdt.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/memblock.h>
@@ -643,3 +644,68 @@ void __set_fixmap(enum fixed_addresses idx,
 		flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
 	}
 }
+
+void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
+{
+	const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
+	pgprot_t prot = PAGE_KERNEL | PTE_RDONLY;
+	int granularity, size, offset;
+	void *dt_virt;
+
+	/*
+	 * Check whether the physical FDT address is set and meets the minimum
+	 * alignment requirement. Since we are relying on MIN_FDT_ALIGN to be
+	 * at least 8 bytes so that we can always access the size field of the
+	 * FDT header after mapping the first chunk, double check here if that
+	 * is indeed the case.
+	 */
+	BUILD_BUG_ON(MIN_FDT_ALIGN < 8);
+	if (!dt_phys || dt_phys % MIN_FDT_ALIGN)
+		return NULL;
+
+	/*
+	 * Make sure that the FDT region can be mapped without the need to
+	 * allocate additional translation table pages, so that it is safe
+	 * to call create_mapping() this early.
+	 *
+	 * On 64k pages, the FDT will be mapped using PTEs, so we need to
+	 * be in the same PMD as the rest of the fixmap.
+	 * On 4k pages, we'll use section mappings for the FDT so we only
+	 * have to be in the same PUD.
+	 */
+	BUILD_BUG_ON(dt_virt_base % SZ_2M);
+
+	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) {
+		BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PMD_SHIFT !=
+			     __fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT);
+
+		granularity = PAGE_SIZE;
+	} else {
+		BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PUD_SHIFT !=
+			     __fix_to_virt(FIX_BTMAP_BEGIN) >> PUD_SHIFT);
+
+		granularity = PMD_SIZE;
+	}
+
+	offset = dt_phys % granularity;
+	dt_virt = (void *)dt_virt_base + offset;
+
+	/* map the first chunk so we can read the size from the header */
+	create_mapping(round_down(dt_phys, granularity), dt_virt_base,
+		       granularity, prot);
+
+	if (fdt_check_header(dt_virt) != 0)
+		return NULL;
+
+	size = fdt_totalsize(dt_virt);
+	if (size > MAX_FDT_SIZE)
+		return NULL;
+
+	if (offset + size > granularity)
+		create_mapping(round_down(dt_phys, granularity), dt_virt_base,
+			       round_up(offset + size, granularity), prot);
+
+	memblock_reserve(dt_phys, size);
+
+	return dt_virt;
+}
-- 
1.9.1

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

* [PATCH 3/8] arm64: override early_init_dt_add_memory_arch()
  2015-05-11  6:41 [PATCH 0/8] arm64 UEFI early FDT handling Ard Biesheuvel
  2015-05-11  6:41 ` [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing Ard Biesheuvel
  2015-05-11  6:41 ` [PATCH 2/8] arm64: use fixmap region for permanent FDT mapping Ard Biesheuvel
@ 2015-05-11  6:41 ` Ard Biesheuvel
  2015-05-11  6:41 ` [PATCH 4/8] efi: move FDT handling to separate object file Ard Biesheuvel
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Ard Biesheuvel @ 2015-05-11  6:41 UTC (permalink / raw)
  To: linux-arm-kernel

Override the __weak early_init_dt_add_memory_arch() with our own
version. This allows us to relax the imposed restrictions at memory
discovery time, which is needed if we want to defer the assignment
of PHYS_OFFSET and make it independent of where the kernel Image
is placed in physical memory.

So copy the generic original, but only retain the check against
regions whose sizes become zero when clipped to page alignment.

For now, we will remove the range below PHYS_OFFSET explicitly
until we rework that logic in a subsequent patch. Any memory that
we will not be able to map due to insufficient size of the linear
region is also removed.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/mm/init.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 597831bdddf3..64480b65ef17 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -158,6 +158,15 @@ early_param("mem", early_mem);
 
 void __init arm64_memblock_init(void)
 {
+	/*
+	 * Remove the memory that we will not be able to cover
+	 * with the linear mapping.
+	 */
+	const s64 linear_region_size = -(s64)PAGE_OFFSET;
+
+	memblock_remove(0, memstart_addr);
+	memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
+
 	memblock_enforce_memory_limit(memory_limit);
 
 	/*
@@ -374,3 +383,19 @@ static int __init keepinitrd_setup(char *__unused)
 
 __setup("keepinitrd", keepinitrd_setup);
 #endif
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+	if (!PAGE_ALIGNED(base)) {
+		if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
+			pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
+				base, base + size);
+			return;
+		}
+		size -= PAGE_SIZE - (base & ~PAGE_MASK);
+		base = PAGE_ALIGN(base);
+	}
+	size &= PAGE_MASK;
+
+	memblock_add(base, size);
+}
-- 
1.9.1

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

* [PATCH 4/8] efi: move FDT handling to separate object file
  2015-05-11  6:41 [PATCH 0/8] arm64 UEFI early FDT handling Ard Biesheuvel
                   ` (2 preceding siblings ...)
  2015-05-11  6:41 ` [PATCH 3/8] arm64: override early_init_dt_add_memory_arch() Ard Biesheuvel
@ 2015-05-11  6:41 ` Ard Biesheuvel
  2015-05-26 18:15   ` Matt Fleming
  2015-05-11  6:41 ` [PATCH 5/8] arm64/efi: move EFI init before early FDT processing Ard Biesheuvel
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: Ard Biesheuvel @ 2015-05-11  6:41 UTC (permalink / raw)
  To: linux-arm-kernel

The EFI specific FDT handling is compiled conditionally, and is
logically independent of the rest of efi.o. So move it to a separate
file before making changes to it in subsequent patches.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/firmware/efi/Makefile  |  1 +
 drivers/firmware/efi/efi-fdt.c | 93 ++++++++++++++++++++++++++++++++++++++++++
 drivers/firmware/efi/efi.c     | 86 --------------------------------------
 3 files changed, 94 insertions(+), 86 deletions(-)
 create mode 100644 drivers/firmware/efi/efi-fdt.c

diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index d8be608a9f3b..9967dde52174 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_UEFI_CPER)			+= cper.o
 obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
 obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)	+= runtime-wrappers.o
 obj-$(CONFIG_EFI_STUB)			+= libstub/
+obj-$(CONFIG_EFI_PARAMS_FROM_FDT)	+= efi-fdt.o
diff --git a/drivers/firmware/efi/efi-fdt.c b/drivers/firmware/efi/efi-fdt.c
new file mode 100644
index 000000000000..f0e7ef2ae0e9
--- /dev/null
+++ b/drivers/firmware/efi/efi-fdt.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2013 - 2015 Linaro Ltd.
+ *
+ * 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/init.h>
+#include <linux/efi.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+
+#define UEFI_PARAM(name, prop, field)			   \
+	{						   \
+		{ name },				   \
+		{ prop },				   \
+		offsetof(struct efi_fdt_params, field),    \
+		FIELD_SIZEOF(struct efi_fdt_params, field) \
+	}
+
+static __initdata struct {
+	const char name[32];
+	const char propname[32];
+	int offset;
+	int size;
+} dt_params[] = {
+	UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
+	UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
+	UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
+	UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
+	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
+};
+
+struct param_info {
+	int verbose;
+	int found;
+	void *params;
+};
+
+static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
+				       int depth, void *data)
+{
+	struct param_info *info = data;
+	const void *prop;
+	void *dest;
+	u64 val;
+	int i, len;
+
+	if (depth != 1 || strcmp(uname, "chosen") != 0)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
+		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
+		if (!prop)
+			return 0;
+		dest = info->params + dt_params[i].offset;
+		info->found++;
+
+		val = of_read_number(prop, len / sizeof(u32));
+
+		if (dt_params[i].size == sizeof(u32))
+			*(u32 *)dest = val;
+		else
+			*(u64 *)dest = val;
+
+		if (info->verbose)
+			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
+				dt_params[i].size * 2, val);
+	}
+	return 1;
+}
+
+int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
+{
+	struct param_info info;
+	int ret;
+
+	pr_info("Getting EFI parameters from FDT:\n");
+
+	info.verbose = verbose;
+	info.found = 0;
+	info.params = params;
+
+	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
+	if (!info.found)
+		pr_info("UEFI not found.\n");
+	else if (!ret)
+		pr_err("Can't find '%s' in device tree!\n",
+		       dt_params[info.found].name);
+
+	return ret;
+}
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 3061bb8629dc..e546c3e4f127 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -20,8 +20,6 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/efi.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 
@@ -377,90 +375,6 @@ static int __init efi_load_efivars(void)
 device_initcall(efi_load_efivars);
 #endif
 
-#ifdef CONFIG_EFI_PARAMS_FROM_FDT
-
-#define UEFI_PARAM(name, prop, field)			   \
-	{						   \
-		{ name },				   \
-		{ prop },				   \
-		offsetof(struct efi_fdt_params, field),    \
-		FIELD_SIZEOF(struct efi_fdt_params, field) \
-	}
-
-static __initdata struct {
-	const char name[32];
-	const char propname[32];
-	int offset;
-	int size;
-} dt_params[] = {
-	UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
-	UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
-	UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
-	UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
-	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
-};
-
-struct param_info {
-	int verbose;
-	int found;
-	void *params;
-};
-
-static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
-				       int depth, void *data)
-{
-	struct param_info *info = data;
-	const void *prop;
-	void *dest;
-	u64 val;
-	int i, len;
-
-	if (depth != 1 || strcmp(uname, "chosen") != 0)
-		return 0;
-
-	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
-		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop)
-			return 0;
-		dest = info->params + dt_params[i].offset;
-		info->found++;
-
-		val = of_read_number(prop, len / sizeof(u32));
-
-		if (dt_params[i].size == sizeof(u32))
-			*(u32 *)dest = val;
-		else
-			*(u64 *)dest = val;
-
-		if (info->verbose)
-			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
-				dt_params[i].size * 2, val);
-	}
-	return 1;
-}
-
-int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
-{
-	struct param_info info;
-	int ret;
-
-	pr_info("Getting EFI parameters from FDT:\n");
-
-	info.verbose = verbose;
-	info.found = 0;
-	info.params = params;
-
-	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
-	if (!info.found)
-		pr_info("UEFI not found.\n");
-	else if (!ret)
-		pr_err("Can't find '%s' in device tree!\n",
-		       dt_params[info.found].name);
-
-	return ret;
-}
-#endif /* CONFIG_EFI_PARAMS_FROM_FDT */
-
 static __initdata char memory_type_name[][20] = {
 	"Reserved",
 	"Loader Code",
-- 
1.9.1

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

* [PATCH 5/8] arm64/efi: move EFI init before early FDT processing
  2015-05-11  6:41 [PATCH 0/8] arm64 UEFI early FDT handling Ard Biesheuvel
                   ` (3 preceding siblings ...)
  2015-05-11  6:41 ` [PATCH 4/8] efi: move FDT handling to separate object file Ard Biesheuvel
@ 2015-05-11  6:41 ` Ard Biesheuvel
  2015-05-11  6:41 ` [PATCH 6/8] arm64/efi: ignore DT memory nodes instead of removing them Ard Biesheuvel
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Ard Biesheuvel @ 2015-05-11  6:41 UTC (permalink / raw)
  To: linux-arm-kernel

The early FDT processing is responsible for enumerating the
DT memory nodes and installing them as memblocks. This should
only be done if we are not booting via EFI, but at this point,
we don't know yet if that is the case or not.

So move the EFI init to before the early FDT processing. This involves
making some changes to the way EFI discovers the locations of the
EFI system table and the memory map, since those values are retrieved
from the FDT as well. Instead the of_scan infrastructure, it now uses
libfdt directly to access the /chosen node.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/include/asm/efi.h   |  4 +--
 arch/arm64/kernel/efi.c        | 14 +++-----
 arch/arm64/kernel/setup.c      |  4 ++-
 drivers/firmware/efi/Makefile  |  1 +
 drivers/firmware/efi/efi-fdt.c | 74 +++++++++++++++++-------------------------
 include/linux/efi.h            |  3 +-
 6 files changed, 41 insertions(+), 59 deletions(-)

diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index ef572206f1c3..635101f36720 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -5,9 +5,9 @@
 #include <asm/neon.h>
 
 #ifdef CONFIG_EFI
-extern void efi_init(void);
+extern void efi_init_fdt(void *fdt);
 #else
-#define efi_init()
+#define efi_init_fdt(x)
 #endif
 
 #define efi_call_virt(f, ...)						\
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index ab21e0d58278..5369b4f96dd1 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -51,14 +51,7 @@ static struct mm_struct efi_mm = {
 	INIT_MM_CONTEXT(efi_mm)
 };
 
-static int uefi_debug __initdata;
-static int __init uefi_debug_setup(char *str)
-{
-	uefi_debug = 1;
-
-	return 0;
-}
-early_param("uefi_debug", uefi_debug_setup);
+static bool uefi_debug __initdata;
 
 static int __init is_normal_ram(efi_memory_desc_t *md)
 {
@@ -204,14 +197,15 @@ static __init void reserve_regions(void)
 	set_bit(EFI_MEMMAP, &efi.flags);
 }
 
-void __init efi_init(void)
+void __init efi_init_fdt(void *fdt)
 {
 	struct efi_fdt_params params;
 
 	/* Grab UEFI information placed in FDT by stub */
-	if (!efi_get_fdt_params(&params, uefi_debug))
+	if (!efi_get_fdt_params(fdt, &params))
 		return;
 
+	uefi_debug = params.verbose;
 	efi_system_table = params.system_table;
 
 	memblock_reserve(params.mmap & PAGE_MASK,
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 770ae9dc5a75..36ffd0a21a78 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -316,6 +316,9 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
 {
 	void *dt_virt = fixmap_remap_fdt(dt_phys);
 
+	if (dt_virt)
+		efi_init_fdt(dt_virt);
+
 	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
 		pr_crit("\n"
 			"Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
@@ -384,7 +387,6 @@ void __init setup_arch(char **cmdline_p)
 	 */
 	local_async_enable();
 
-	efi_init();
 	arm64_memblock_init();
 
 	/* Parse the ACPI tables for possible boot-time configuration */
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 9967dde52174..7b408a4cfc8a 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
 obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)	+= runtime-wrappers.o
 obj-$(CONFIG_EFI_STUB)			+= libstub/
 obj-$(CONFIG_EFI_PARAMS_FROM_FDT)	+= efi-fdt.o
+CFLAGS_efi-fdt.o			:= -I$(srctree)/scripts/dtc/libfdt/
diff --git a/drivers/firmware/efi/efi-fdt.c b/drivers/firmware/efi/efi-fdt.c
index f0e7ef2ae0e9..2e0e1a5a3fbb 100644
--- a/drivers/firmware/efi/efi-fdt.c
+++ b/drivers/firmware/efi/efi-fdt.c
@@ -8,8 +8,7 @@
 
 #include <linux/init.h>
 #include <linux/efi.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
 
 #define UEFI_PARAM(name, prop, field)			   \
 	{						   \
@@ -32,62 +31,47 @@ static __initdata struct {
 	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
 };
 
-struct param_info {
-	int verbose;
-	int found;
-	void *params;
-};
-
-static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
-				       int depth, void *data)
+bool __init efi_get_fdt_params(void *fdt, struct efi_fdt_params *params)
 {
-	struct param_info *info = data;
 	const void *prop;
-	void *dest;
-	u64 val;
-	int i, len;
+	int node, i;
+
+	pr_info("Getting EFI parameters from FDT:\n");
 
-	if (depth != 1 || strcmp(uname, "chosen") != 0)
-		return 0;
+	node = fdt_path_offset(fdt, "/chosen");
+	if (node < 0) {
+		pr_err("/chosen node not found!\n");
+		return false;
+	}
+
+	prop = fdt_getprop(fdt, node, "bootargs", NULL);
+	params->verbose = prop && strstr(prop, "uefi_debug");
 
 	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
-		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop)
-			return 0;
-		dest = info->params + dt_params[i].offset;
-		info->found++;
+		void *dest;
+		int len;
+		u64 val;
 
-		val = of_read_number(prop, len / sizeof(u32));
+		prop = fdt_getprop(fdt, node, dt_params[i].propname, &len);
+		if (!prop)
+			goto not_found;
+		dest = (void *)params + dt_params[i].offset;
 
 		if (dt_params[i].size == sizeof(u32))
-			*(u32 *)dest = val;
+			val = *(u32 *)dest = be32_to_cpup(prop);
 		else
-			*(u64 *)dest = val;
+			val = *(u64 *)dest = be64_to_cpup(prop);
 
-		if (info->verbose)
+		if (params->verbose)
 			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
 				dt_params[i].size * 2, val);
 	}
-	return 1;
-}
-
-int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
-{
-	struct param_info info;
-	int ret;
+	return true;
 
-	pr_info("Getting EFI parameters from FDT:\n");
-
-	info.verbose = verbose;
-	info.found = 0;
-	info.params = params;
-
-	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
-	if (!info.found)
+not_found:
+	if (i == 0)
 		pr_info("UEFI not found.\n");
-	else if (!ret)
-		pr_err("Can't find '%s' in device tree!\n",
-		       dt_params[info.found].name);
-
-	return ret;
+	else
+		pr_err("Can't find '%s' in device tree!\n", dt_params[i].name);
+	return false;
 }
diff --git a/include/linux/efi.h b/include/linux/efi.h
index af5be0368dec..c2be93d6156c 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -684,6 +684,7 @@ struct efi_fdt_params {
 	u32 mmap_size;
 	u32 desc_size;
 	u32 desc_ver;
+	bool verbose;
 };
 
 typedef struct {
@@ -886,7 +887,7 @@ 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);
 extern void efi_reserve_boot_services(void);
-extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose);
+extern bool efi_get_fdt_params(void *fdt, struct efi_fdt_params *params);
 extern struct efi_memory_map memmap;
 
 extern int efi_reboot_quirk_mode;
-- 
1.9.1

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

* [PATCH 6/8] arm64/efi: ignore DT memory nodes instead of removing them
  2015-05-11  6:41 [PATCH 0/8] arm64 UEFI early FDT handling Ard Biesheuvel
                   ` (4 preceding siblings ...)
  2015-05-11  6:41 ` [PATCH 5/8] arm64/efi: move EFI init before early FDT processing Ard Biesheuvel
@ 2015-05-11  6:41 ` Ard Biesheuvel
  2015-05-11 16:28   ` Ganapatrao Kulkarni
  2015-05-12 14:31   ` Leif Lindholm
  2015-05-11  6:41 ` [PATCH 7/8] arm64/efi: ignore DT memreserve entries " Ard Biesheuvel
  2015-05-11  6:42 ` [PATCH 8/8] arm64/efi: adapt to relaxed FDT placement requirements Ard Biesheuvel
  7 siblings, 2 replies; 22+ messages in thread
From: Ard Biesheuvel @ 2015-05-11  6:41 UTC (permalink / raw)
  To: linux-arm-kernel

There are two problems with the UEFI stub DT memory node removal
routine:
- it deletes nodes as it traverses the tree, which happens to work
  but is not supported, as deletion invalidates the node iterator;
- deleting memory nodes entirely may discard annotations in the form
  of additional properties on the nodes.

Now that the UEFI initialization has moved to an earlier stage, we can
actually just ignore any memblocks that are installed after we have
processed the UEFI memory map. This way, it is no longer necessary to
remove the nodes, so we can remove that logic from the stub as well.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/mm/init.c               |  7 +++++++
 drivers/firmware/efi/libstub/fdt.c | 24 +-----------------------
 2 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 64480b65ef17..95c239f43384 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -386,6 +386,13 @@ __setup("keepinitrd", keepinitrd_setup);
 
 void __init early_init_dt_add_memory_arch(u64 base, u64 size)
 {
+	/*
+	 * EFI_MEMMAP will be set /after/ UEFI has installed all memory based
+	 * on the content of the UEFI memory map.
+	 */
+	if (efi_enabled(EFI_MEMMAP))
+		return;
+
 	if (!PAGE_ALIGNED(base)) {
 		if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
 			pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index ef5d764e2a27..343e7992bd8f 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -24,7 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 			unsigned long map_size, unsigned long desc_size,
 			u32 desc_ver)
 {
-	int node, prev, num_rsv;
+	int node, num_rsv;
 	int status;
 	u32 fdt_val32;
 	u64 fdt_val64;
@@ -54,28 +54,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 		goto fdt_set_fail;
 
 	/*
-	 * Delete any memory nodes present. We must delete nodes which
-	 * early_init_dt_scan_memory may try to use.
-	 */
-	prev = 0;
-	for (;;) {
-		const char *type;
-		int len;
-
-		node = fdt_next_node(fdt, prev, NULL);
-		if (node < 0)
-			break;
-
-		type = fdt_getprop(fdt, node, "device_type", &len);
-		if (type && strncmp(type, "memory", len) == 0) {
-			fdt_del_node(fdt, node);
-			continue;
-		}
-
-		prev = node;
-	}
-
-	/*
 	 * Delete all memory reserve map entries. When booting via UEFI,
 	 * kernel will use the UEFI memory map to find reserved regions.
 	 */
-- 
1.9.1

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

* [PATCH 7/8] arm64/efi: ignore DT memreserve entries instead of removing them
  2015-05-11  6:41 [PATCH 0/8] arm64 UEFI early FDT handling Ard Biesheuvel
                   ` (5 preceding siblings ...)
  2015-05-11  6:41 ` [PATCH 6/8] arm64/efi: ignore DT memory nodes instead of removing them Ard Biesheuvel
@ 2015-05-11  6:41 ` Ard Biesheuvel
  2015-05-11  6:42 ` [PATCH 8/8] arm64/efi: adapt to relaxed FDT placement requirements Ard Biesheuvel
  7 siblings, 0 replies; 22+ messages in thread
From: Ard Biesheuvel @ 2015-05-11  6:41 UTC (permalink / raw)
  To: linux-arm-kernel

Now that the reservation of the FDT image itself is split off, we
can make the DT scanning of memreserves conditional on whether we
booted via UEFI and have its memory map available. This allows us
to drop deletion of these memreserves in the stub. It also fixes
the issue where the /reserved-memory/ node (which offers another
way of reserving memory ranges) was not being ignored under UEFI.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/mm/init.c               |  3 ++-
 drivers/firmware/efi/libstub/fdt.c | 11 +----------
 2 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 95c239f43384..a3469a436a73 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -179,7 +179,8 @@ void __init arm64_memblock_init(void)
 		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
 #endif
 
-	early_init_fdt_scan_reserved_mem();
+	if (!efi_enabled(EFI_MEMMAP))
+		early_init_fdt_scan_reserved_mem();
 
 	/* 4GB maximum for 32-bit only capable devices */
 	if (IS_ENABLED(CONFIG_ZONE_DMA))
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 343e7992bd8f..a7e87cd582f2 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -24,8 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 			unsigned long map_size, unsigned long desc_size,
 			u32 desc_ver)
 {
-	int node, num_rsv;
-	int status;
+	int node, status;
 	u32 fdt_val32;
 	u64 fdt_val64;
 
@@ -53,14 +52,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 	if (status != 0)
 		goto fdt_set_fail;
 
-	/*
-	 * Delete all memory reserve map entries. When booting via UEFI,
-	 * kernel will use the UEFI memory map to find reserved regions.
-	 */
-	num_rsv = fdt_num_mem_rsv(fdt);
-	while (num_rsv-- > 0)
-		fdt_del_mem_rsv(fdt, num_rsv);
-
 	node = fdt_subnode_offset(fdt, 0, "chosen");
 	if (node < 0) {
 		node = fdt_add_subnode(fdt, 0, "chosen");
-- 
1.9.1

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

* [PATCH 8/8] arm64/efi: adapt to relaxed FDT placement requirements
  2015-05-11  6:41 [PATCH 0/8] arm64 UEFI early FDT handling Ard Biesheuvel
                   ` (6 preceding siblings ...)
  2015-05-11  6:41 ` [PATCH 7/8] arm64/efi: ignore DT memreserve entries " Ard Biesheuvel
@ 2015-05-11  6:42 ` Ard Biesheuvel
  7 siblings, 0 replies; 22+ messages in thread
From: Ard Biesheuvel @ 2015-05-11  6:42 UTC (permalink / raw)
  To: linux-arm-kernel

With the relaxed FDT placement requirements in place, we can change
the allocation strategy used by the stub to put the FDT image higher
up in memory. At the same time, reduce the minimal alignment to 8 bytes,
and impose a 2 MB size limit, as per the new requirements.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/include/asm/efi.h            | 10 +++-------
 drivers/firmware/efi/libstub/arm-stub.c |  5 ++---
 drivers/firmware/efi/libstub/efistub.h  |  1 -
 drivers/firmware/efi/libstub/fdt.c      | 18 +++++++++---------
 4 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 635101f36720..43ea4ecbd361 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -1,6 +1,7 @@
 #ifndef _ASM_EFI_H
 #define _ASM_EFI_H
 
+#include <asm/boot.h>
 #include <asm/io.h>
 #include <asm/neon.h>
 
@@ -38,13 +39,8 @@ extern void efi_init_fdt(void *fdt);
 
 /* arch specific definitions used by the stub code */
 
-/*
- * AArch64 requires the DTB to be 8-byte aligned in the first 512MiB from
- * start of kernel and may not cross a 2MiB boundary. We set alignment to
- * 2MiB so we know it won't cross a 2MiB boundary.
- */
-#define EFI_FDT_ALIGN	SZ_2M   /* used by allocate_new_fdt_and_exit_boot() */
-#define MAX_FDT_OFFSET	SZ_512M
+#define EFI_FDT_ALIGN		MIN_FDT_ALIGN
+#define EFI_FDT_MAX_SIZE	MAX_FDT_SIZE
 
 #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
 
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index e29560e6b40b..4e5ac133d1dc 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -268,9 +268,8 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
 
 	new_fdt_addr = fdt_addr;
 	status = allocate_new_fdt_and_exit_boot(sys_table, handle,
-				&new_fdt_addr, dram_base + MAX_FDT_OFFSET,
-				initrd_addr, initrd_size, cmdline_ptr,
-				fdt_addr, fdt_size);
+				&new_fdt_addr, initrd_addr, initrd_size,
+				cmdline_ptr, fdt_addr, fdt_size);
 
 	/*
 	 * If all went well, we need to return the FDT address to the
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index e334a01cf92f..cf14dafc348a 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -35,7 +35,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
 					    void *handle,
 					    unsigned long *new_fdt_addr,
-					    unsigned long max_addr,
 					    u64 initrd_addr, u64 initrd_size,
 					    char *cmdline_ptr,
 					    unsigned long fdt_addr,
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index a7e87cd582f2..ab6ecb22bd6e 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -134,10 +134,6 @@ fdt_set_fail:
 	return EFI_LOAD_ERROR;
 }
 
-#ifndef EFI_FDT_ALIGN
-#define EFI_FDT_ALIGN EFI_PAGE_SIZE
-#endif
-
 /*
  * Allocate memory for a new FDT, then add EFI, commandline, and
  * initrd related fields to the FDT.  This routine increases the
@@ -155,7 +151,6 @@ fdt_set_fail:
 efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
 					    void *handle,
 					    unsigned long *new_fdt_addr,
-					    unsigned long max_addr,
 					    u64 initrd_addr, u64 initrd_size,
 					    char *cmdline_ptr,
 					    unsigned long fdt_addr,
@@ -192,8 +187,13 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
 	 */
 	new_fdt_size = fdt_size + EFI_PAGE_SIZE;
 	while (1) {
-		status = efi_high_alloc(sys_table, new_fdt_size, EFI_FDT_ALIGN,
-					new_fdt_addr, max_addr);
+		if (new_fdt_size > EFI_FDT_MAX_SIZE) {
+			pr_efi_err(sys_table, "FDT size exceeds EFI_FDT_MAX_SIZE.\n");
+			goto fail;
+		}
+		status = sys_table->boottime->allocate_pool(EFI_LOADER_DATA,
+							    new_fdt_size,
+							    (void **)new_fdt_addr);
 		if (status != EFI_SUCCESS) {
 			pr_efi_err(sys_table, "Unable to allocate memory for new device tree.\n");
 			goto fail;
@@ -227,7 +227,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
 			 * to get new one that reflects the free/alloc we do
 			 * on the device tree buffer.
 			 */
-			efi_free(sys_table, new_fdt_size, *new_fdt_addr);
+			sys_table->boottime->free_pool((void *)*new_fdt_addr);
 			sys_table->boottime->free_pool(memory_map);
 			new_fdt_size += EFI_PAGE_SIZE;
 		} else {
@@ -285,7 +285,7 @@ fail_free_mmap:
 	sys_table->boottime->free_pool(memory_map);
 
 fail_free_new_fdt:
-	efi_free(sys_table, new_fdt_size, *new_fdt_addr);
+	sys_table->boottime->free_pool((void *)*new_fdt_addr);
 
 fail:
 	sys_table->boottime->free_pool(runtime_map);
-- 
1.9.1

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

* [PATCH 6/8] arm64/efi: ignore DT memory nodes instead of removing them
  2015-05-11  6:41 ` [PATCH 6/8] arm64/efi: ignore DT memory nodes instead of removing them Ard Biesheuvel
@ 2015-05-11 16:28   ` Ganapatrao Kulkarni
  2015-05-12 14:31   ` Leif Lindholm
  1 sibling, 0 replies; 22+ messages in thread
From: Ganapatrao Kulkarni @ 2015-05-11 16:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 11, 2015 at 12:11 PM, Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
> There are two problems with the UEFI stub DT memory node removal
> routine:
> - it deletes nodes as it traverses the tree, which happens to work
>   but is not supported, as deletion invalidates the node iterator;
> - deleting memory nodes entirely may discard annotations in the form
>   of additional properties on the nodes.
>
> Now that the UEFI initialization has moved to an earlier stage, we can
> actually just ignore any memblocks that are installed after we have
> processed the UEFI memory map. This way, it is no longer necessary to
> remove the nodes, so we can remove that logic from the stub as well.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  arch/arm64/mm/init.c               |  7 +++++++
>  drivers/firmware/efi/libstub/fdt.c | 24 +-----------------------
>  2 files changed, 8 insertions(+), 23 deletions(-)
>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 64480b65ef17..95c239f43384 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -386,6 +386,13 @@ __setup("keepinitrd", keepinitrd_setup);
>
>  void __init early_init_dt_add_memory_arch(u64 base, u64 size)
>  {
> +       /*
> +        * EFI_MEMMAP will be set /after/ UEFI has installed all memory based
> +        * on the content of the UEFI memory map.
> +        */
> +       if (efi_enabled(EFI_MEMMAP))
> +               return;
> +
>         if (!PAGE_ALIGNED(base)) {
>                 if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
>                         pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
> diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
> index ef5d764e2a27..343e7992bd8f 100644
> --- a/drivers/firmware/efi/libstub/fdt.c
> +++ b/drivers/firmware/efi/libstub/fdt.c
> @@ -24,7 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>                         unsigned long map_size, unsigned long desc_size,
>                         u32 desc_ver)
>  {
> -       int node, prev, num_rsv;
> +       int node, num_rsv;
>         int status;
>         u32 fdt_val32;
>         u64 fdt_val64;
> @@ -54,28 +54,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>                 goto fdt_set_fail;
>
>         /*
> -        * Delete any memory nodes present. We must delete nodes which
> -        * early_init_dt_scan_memory may try to use.
> -        */
> -       prev = 0;
> -       for (;;) {
> -               const char *type;
> -               int len;
> -
> -               node = fdt_next_node(fdt, prev, NULL);
> -               if (node < 0)
> -                       break;
> -
> -               type = fdt_getprop(fdt, node, "device_type", &len);
> -               if (type && strncmp(type, "memory", len) == 0) {
> -                       fdt_del_node(fdt, node);
> -                       continue;
> -               }
> -
> -               prev = node;
> -       }
> -
> -       /*
>          * Delete all memory reserve map entries. When booting via UEFI,
>          * kernel will use the UEFI memory map to find reserved regions.
>          */
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Thanks Ard.
Tested this patch on my numa setup.

Tested-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>

thanks
Ganapat

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

* [PATCH 6/8] arm64/efi: ignore DT memory nodes instead of removing them
  2015-05-11  6:41 ` [PATCH 6/8] arm64/efi: ignore DT memory nodes instead of removing them Ard Biesheuvel
  2015-05-11 16:28   ` Ganapatrao Kulkarni
@ 2015-05-12 14:31   ` Leif Lindholm
  2015-05-12 15:01     ` Ard Biesheuvel
  1 sibling, 1 reply; 22+ messages in thread
From: Leif Lindholm @ 2015-05-12 14:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 11, 2015 at 08:41:58AM +0200, Ard Biesheuvel wrote:
> There are two problems with the UEFI stub DT memory node removal
> routine:
> - it deletes nodes as it traverses the tree, which happens to work
>   but is not supported, as deletion invalidates the node iterator;
> - deleting memory nodes entirely may discard annotations in the form
>   of additional properties on the nodes.
> 
> Now that the UEFI initialization has moved to an earlier stage, we can
> actually just ignore any memblocks that are installed after we have
> processed the UEFI memory map. This way, it is no longer necessary to
> remove the nodes, so we can remove that logic from the stub as well.

So ... I don't have an issue with this patch as such, but keeping the
memory nodes around for NUMA topology when the UEFI memory map is
the one being used for memblock leads to a spooky redefinition of what
that memory node _is_; it would now describe a region which may only
partially be populated with RAM.

/
    Leif

> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  arch/arm64/mm/init.c               |  7 +++++++
>  drivers/firmware/efi/libstub/fdt.c | 24 +-----------------------
>  2 files changed, 8 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 64480b65ef17..95c239f43384 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -386,6 +386,13 @@ __setup("keepinitrd", keepinitrd_setup);
>  
>  void __init early_init_dt_add_memory_arch(u64 base, u64 size)
>  {
> +	/*
> +	 * EFI_MEMMAP will be set /after/ UEFI has installed all memory based
> +	 * on the content of the UEFI memory map.
> +	 */
> +	if (efi_enabled(EFI_MEMMAP))
> +		return;
> +
>  	if (!PAGE_ALIGNED(base)) {
>  		if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
>  			pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
> diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
> index ef5d764e2a27..343e7992bd8f 100644
> --- a/drivers/firmware/efi/libstub/fdt.c
> +++ b/drivers/firmware/efi/libstub/fdt.c
> @@ -24,7 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>  			unsigned long map_size, unsigned long desc_size,
>  			u32 desc_ver)
>  {
> -	int node, prev, num_rsv;
> +	int node, num_rsv;
>  	int status;
>  	u32 fdt_val32;
>  	u64 fdt_val64;
> @@ -54,28 +54,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>  		goto fdt_set_fail;
>  
>  	/*
> -	 * Delete any memory nodes present. We must delete nodes which
> -	 * early_init_dt_scan_memory may try to use.
> -	 */
> -	prev = 0;
> -	for (;;) {
> -		const char *type;
> -		int len;
> -
> -		node = fdt_next_node(fdt, prev, NULL);
> -		if (node < 0)
> -			break;
> -
> -		type = fdt_getprop(fdt, node, "device_type", &len);
> -		if (type && strncmp(type, "memory", len) == 0) {
> -			fdt_del_node(fdt, node);
> -			continue;
> -		}
> -
> -		prev = node;
> -	}
> -
> -	/*
>  	 * Delete all memory reserve map entries. When booting via UEFI,
>  	 * kernel will use the UEFI memory map to find reserved regions.
>  	 */
> -- 
> 1.9.1
> 

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

* [PATCH 6/8] arm64/efi: ignore DT memory nodes instead of removing them
  2015-05-12 14:31   ` Leif Lindholm
@ 2015-05-12 15:01     ` Ard Biesheuvel
  0 siblings, 0 replies; 22+ messages in thread
From: Ard Biesheuvel @ 2015-05-12 15:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 12 May 2015 at 16:31, Leif Lindholm <leif.lindholm@linaro.org> wrote:
> On Mon, May 11, 2015 at 08:41:58AM +0200, Ard Biesheuvel wrote:
>> There are two problems with the UEFI stub DT memory node removal
>> routine:
>> - it deletes nodes as it traverses the tree, which happens to work
>>   but is not supported, as deletion invalidates the node iterator;
>> - deleting memory nodes entirely may discard annotations in the form
>>   of additional properties on the nodes.
>>
>> Now that the UEFI initialization has moved to an earlier stage, we can
>> actually just ignore any memblocks that are installed after we have
>> processed the UEFI memory map. This way, it is no longer necessary to
>> remove the nodes, so we can remove that logic from the stub as well.
>
> So ... I don't have an issue with this patch as such, but keeping the
> memory nodes around for NUMA topology when the UEFI memory map is
> the one being used for memblock leads to a spooky redefinition of what
> that memory node _is_; it would now describe a region which may only
> partially be populated with RAM.
>

How does that not apply to ACPI? It is still the responsibility of the
firmware to ensure that all information it supplies is consistent with
itself.

But I agree that we should carefully consider this interaction before
accepting any NUMA changes to the memnode bindings and implementation.

-- 
Ard.


>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>>  arch/arm64/mm/init.c               |  7 +++++++
>>  drivers/firmware/efi/libstub/fdt.c | 24 +-----------------------
>>  2 files changed, 8 insertions(+), 23 deletions(-)
>>
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index 64480b65ef17..95c239f43384 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -386,6 +386,13 @@ __setup("keepinitrd", keepinitrd_setup);
>>
>>  void __init early_init_dt_add_memory_arch(u64 base, u64 size)
>>  {
>> +     /*
>> +      * EFI_MEMMAP will be set /after/ UEFI has installed all memory based
>> +      * on the content of the UEFI memory map.
>> +      */
>> +     if (efi_enabled(EFI_MEMMAP))
>> +             return;
>> +
>>       if (!PAGE_ALIGNED(base)) {
>>               if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
>>                       pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
>> diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
>> index ef5d764e2a27..343e7992bd8f 100644
>> --- a/drivers/firmware/efi/libstub/fdt.c
>> +++ b/drivers/firmware/efi/libstub/fdt.c
>> @@ -24,7 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>>                       unsigned long map_size, unsigned long desc_size,
>>                       u32 desc_ver)
>>  {
>> -     int node, prev, num_rsv;
>> +     int node, num_rsv;
>>       int status;
>>       u32 fdt_val32;
>>       u64 fdt_val64;
>> @@ -54,28 +54,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>>               goto fdt_set_fail;
>>
>>       /*
>> -      * Delete any memory nodes present. We must delete nodes which
>> -      * early_init_dt_scan_memory may try to use.
>> -      */
>> -     prev = 0;
>> -     for (;;) {
>> -             const char *type;
>> -             int len;
>> -
>> -             node = fdt_next_node(fdt, prev, NULL);
>> -             if (node < 0)
>> -                     break;
>> -
>> -             type = fdt_getprop(fdt, node, "device_type", &len);
>> -             if (type && strncmp(type, "memory", len) == 0) {
>> -                     fdt_del_node(fdt, node);
>> -                     continue;
>> -             }
>> -
>> -             prev = node;
>> -     }
>> -
>> -     /*
>>        * Delete all memory reserve map entries. When booting via UEFI,
>>        * kernel will use the UEFI memory map to find reserved regions.
>>        */
>> --
>> 1.9.1
>>

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

* [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing
  2015-05-11  6:41 ` [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing Ard Biesheuvel
@ 2015-05-22 10:35   ` Catalin Marinas
  2015-06-01  7:56     ` Ard Biesheuvel
  0 siblings, 1 reply; 22+ messages in thread
From: Catalin Marinas @ 2015-05-22 10:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 11, 2015 at 08:41:53AM +0200, Ard Biesheuvel wrote:
> This splits off the reservation of the memory occupied by the FDT
> binary itself from the processing of the memory reservations it
> contains. This is necessary because the physical address of the FDT,
> which is needed to perform the reservation, may not be known to the
> FDT driver core, i.e., it may be mapped outside the linear direct
> mapping, in which case __pa() returns a bogus value.
> 
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Acked-by: Rob Herring <robh@kernel.org>
> Acked-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

For the arm64 part:

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

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

* [PATCH 4/8] efi: move FDT handling to separate object file
  2015-05-11  6:41 ` [PATCH 4/8] efi: move FDT handling to separate object file Ard Biesheuvel
@ 2015-05-26 18:15   ` Matt Fleming
  0 siblings, 0 replies; 22+ messages in thread
From: Matt Fleming @ 2015-05-26 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 11 May, at 08:41:56AM, Ard Biesheuvel wrote:
> The EFI specific FDT handling is compiled conditionally, and is
> logically independent of the rest of efi.o. So move it to a separate
> file before making changes to it in subsequent patches.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  drivers/firmware/efi/Makefile  |  1 +
>  drivers/firmware/efi/efi-fdt.c | 93 ++++++++++++++++++++++++++++++++++++++++++
>  drivers/firmware/efi/efi.c     | 86 --------------------------------------
>  3 files changed, 94 insertions(+), 86 deletions(-)
>  create mode 100644 drivers/firmware/efi/efi-fdt.c

Sorry for the delay,

Acked-by: Matt Fleming <matt.fleming@intel.com>

-- 
Matt Fleming, Intel Open Source Technology Center

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

* [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing
  2015-05-22 10:35   ` Catalin Marinas
@ 2015-06-01  7:56     ` Ard Biesheuvel
  2015-06-01  9:56       ` Mark Rutland
  0 siblings, 1 reply; 22+ messages in thread
From: Ard Biesheuvel @ 2015-06-01  7:56 UTC (permalink / raw)
  To: linux-arm-kernel

(snip non-LAKML CCs)

On 22 May 2015 at 12:35, Catalin Marinas <catalin.marinas@arm.com> wrote:
> On Mon, May 11, 2015 at 08:41:53AM +0200, Ard Biesheuvel wrote:
>> This splits off the reservation of the memory occupied by the FDT
>> binary itself from the processing of the memory reservations it
>> contains. This is necessary because the physical address of the FDT,
>> which is needed to perform the reservation, may not be known to the
>> FDT driver core, i.e., it may be mapped outside the linear direct
>> mapping, in which case __pa() returns a bogus value.
>>
>> Cc: Russell King <linux@arm.linux.org.uk>
>> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> Cc: Paul Mackerras <paulus@samba.org>
>> Acked-by: Rob Herring <robh@kernel.org>
>> Acked-by: Mark Rutland <mark.rutland@arm.com>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
> For the arm64 part:
>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>

Thanks Catalin,

Since there has been virtually no discussion about these patches, I
guess they have missed the window for being considered for inclusion
in v4.2

May I suggest that you at least consider these patches regarding the ID map

http://article.gmane.org/gmane.linux.ports.arm.kernel/411720
http://article.gmane.org/gmane.linux.ports.arm.kernel/411721

since they are self-contained and the first one does fix a potential
problem where the Image placement logic in the stub does not take the
512 MB alignment boundary into account. The second one is a trivial
cleanup.

Perhaps Mark can comment on the desirability to include the FDT
remapping patch (which depends on this 1/8).

http://article.gmane.org/gmane.linux.kernel.efi/5738

I don't have strong preference either way, although it would be good
to get some patches off my personal queue.

Regards,
Ard.

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

* [PATCH 2/8] arm64: use fixmap region for permanent FDT mapping
  2015-05-11  6:41 ` [PATCH 2/8] arm64: use fixmap region for permanent FDT mapping Ard Biesheuvel
@ 2015-06-01  9:53   ` Mark Rutland
  2015-06-01  9:55     ` Ard Biesheuvel
  0 siblings, 1 reply; 22+ messages in thread
From: Mark Rutland @ 2015-06-01  9:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Ard,

Sorry for the silence on this.

On Mon, May 11, 2015 at 07:41:54AM +0100, Ard Biesheuvel wrote:
> Currently, the FDT blob needs to be in the same 512 MB region as
> the kernel, so that it can be mapped into the kernel virtual memory
> space very early on using a minimal set of statically allocated
> translation tables.
> 
> Now that we have early fixmap support, we can relax this restriction,
> by moving the permanent FDT mapping to the fixmap region instead.
> This way, the FDT blob may be anywhere in memory.
> 
> This also moves the vetting of the FDT to mmu.c, since the early
> init code in head.S does not handle mapping of the FDT anymore.
> At the same time, fix up some comments in head.S that have gone stale.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

The patch looks good to me. I've just given this some testing loading
DTBs at weird offsets and large disances from the kernel, and that seems
to work, so:

Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Mark Rutland <mark.rutland@arm.com>

Thanks,
Mark.

> ---
>  Documentation/arm64/booting.txt | 13 ++++----
>  arch/arm64/include/asm/boot.h   | 14 +++++++++
>  arch/arm64/include/asm/fixmap.h | 15 ++++++++++
>  arch/arm64/include/asm/mmu.h    |  1 +
>  arch/arm64/kernel/head.S        | 39 +-----------------------
>  arch/arm64/kernel/setup.c       | 30 +++++++------------
>  arch/arm64/mm/Makefile          |  2 ++
>  arch/arm64/mm/init.c            |  1 -
>  arch/arm64/mm/mmu.c             | 66 +++++++++++++++++++++++++++++++++++++++++
>  9 files changed, 117 insertions(+), 64 deletions(-)
>  create mode 100644 arch/arm64/include/asm/boot.h
> 
> diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
> index f3c05b5f9f08..53f18e13d51c 100644
> --- a/Documentation/arm64/booting.txt
> +++ b/Documentation/arm64/booting.txt
> @@ -45,11 +45,14 @@ sees fit.)
> 
>  Requirement: MANDATORY
> 
> -The device tree blob (dtb) must be placed on an 8-byte boundary within
> -the first 512 megabytes from the start of the kernel image and must not
> -cross a 2-megabyte boundary. This is to allow the kernel to map the
> -blob using a single section mapping in the initial page tables.
> -
> +The device tree blob (dtb) must be placed on an 8-byte boundary and must
> +not exceed 2 megabytes in size. Since the dtb will be mapped cacheable using
> +blocks of up to 2 megabytes in size, it should not be placed within 2 megabytes
> +of memreserves or other special carveouts that may be mapped with non-matching
> +attributes.
> +
> +NOTE: versions prior to v4.2 also require that the DTB be placed within
> +the 512 MB region starting at text_offset bytes below the kernel Image.
> 
>  3. Decompress the kernel image
>  ------------------------------
> diff --git a/arch/arm64/include/asm/boot.h b/arch/arm64/include/asm/boot.h
> new file mode 100644
> index 000000000000..81151b67b26b
> --- /dev/null
> +++ b/arch/arm64/include/asm/boot.h
> @@ -0,0 +1,14 @@
> +
> +#ifndef __ASM_BOOT_H
> +#define __ASM_BOOT_H
> +
> +#include <asm/sizes.h>
> +
> +/*
> + * arm64 requires the DTB to be 8 byte aligned and
> + * not exceed 2MB in size.
> + */
> +#define MIN_FDT_ALIGN          8
> +#define MAX_FDT_SIZE           SZ_2M
> +
> +#endif
> diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
> index 95e6b6dcbe37..c0739187a920 100644
> --- a/arch/arm64/include/asm/fixmap.h
> +++ b/arch/arm64/include/asm/fixmap.h
> @@ -17,6 +17,7 @@
> 
>  #ifndef __ASSEMBLY__
>  #include <linux/kernel.h>
> +#include <asm/boot.h>
>  #include <asm/page.h>
> 
>  /*
> @@ -32,6 +33,20 @@
>   */
>  enum fixed_addresses {
>         FIX_HOLE,
> +
> +       /*
> +        * Reserve a virtual window for the FDT that is 2 MB larger than the
> +        * maximum supported size, and put it at the top of the fixmap region.
> +        * The additional space ensures that any FDT that does not exceed
> +        * MAX_FDT_SIZE can be mapped regardless of whether it crosses any
> +        * 2 MB alignment boundaries.
> +        *
> +        * Keep this at the top so it remains 2 MB aligned.
> +        */
> +#define FIX_FDT_SIZE           (MAX_FDT_SIZE + SZ_2M)
> +       FIX_FDT_END,
> +       FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,
> +
>         FIX_EARLYCON_MEM_BASE,
>         FIX_TEXT_POKE0,
>         __end_of_permanent_fixed_addresses,
> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
> index 3d311761e3c2..79fcfb048884 100644
> --- a/arch/arm64/include/asm/mmu.h
> +++ b/arch/arm64/include/asm/mmu.h
> @@ -34,5 +34,6 @@ extern void init_mem_pgprot(void);
>  extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
>                                unsigned long virt, phys_addr_t size,
>                                pgprot_t prot);
> +extern void *fixmap_remap_fdt(phys_addr_t dt_phys);
> 
>  #endif
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 19f915e8f6e0..30cffc5e7402 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -237,8 +237,6 @@ ENTRY(stext)
>         bl      el2_setup                       // Drop to EL1, w20=cpu_boot_mode
>         adrp    x24, __PHYS_OFFSET
>         bl      set_cpu_boot_mode_flag
> -
> -       bl      __vet_fdt
>         bl      __create_page_tables            // x25=TTBR0, x26=TTBR1
>         /*
>          * The following calls CPU setup code, see arch/arm64/mm/proc.S for
> @@ -270,24 +268,6 @@ preserve_boot_args:
>  ENDPROC(preserve_boot_args)
> 
>  /*
> - * Determine validity of the x21 FDT pointer.
> - * The dtb must be 8-byte aligned and live in the first 512M of memory.
> - */
> -__vet_fdt:
> -       tst     x21, #0x7
> -       b.ne    1f
> -       cmp     x21, x24
> -       b.lt    1f
> -       mov     x0, #(1 << 29)
> -       add     x0, x0, x24
> -       cmp     x21, x0
> -       b.ge    1f
> -       ret
> -1:
> -       mov     x21, #0
> -       ret
> -ENDPROC(__vet_fdt)
> -/*
>   * Macro to create a table entry to the next page.
>   *
>   *     tbl:    page table address
> @@ -348,8 +328,7 @@ ENDPROC(__vet_fdt)
>   * required to get the kernel running. The following sections are required:
>   *   - identity mapping to enable the MMU (low address, TTBR0)
>   *   - first few MB of the kernel linear mapping to jump to once the MMU has
> - *     been enabled, including the FDT blob (TTBR1)
> - *   - pgd entry for fixed mappings (TTBR1)
> + *     been enabled
>   */
>  __create_page_tables:
>         adrp    x25, idmap_pg_dir
> @@ -439,22 +418,6 @@ __create_page_tables:
>         create_block_map x0, x7, x3, x5, x6
> 
>         /*
> -        * Map the FDT blob (maximum 2MB; must be within 512MB of
> -        * PHYS_OFFSET).
> -        */
> -       mov     x3, x21                         // FDT phys address
> -       and     x3, x3, #~((1 << 21) - 1)       // 2MB aligned
> -       mov     x6, #PAGE_OFFSET
> -       sub     x5, x3, x24                     // subtract PHYS_OFFSET
> -       tst     x5, #~((1 << 29) - 1)           // within 512MB?
> -       csel    x21, xzr, x21, ne               // zero the FDT pointer
> -       b.ne    1f
> -       add     x5, x5, x6                      // __va(FDT blob)
> -       add     x6, x5, #1 << 21                // 2MB for the FDT blob
> -       sub     x6, x6, #1                      // inclusive range
> -       create_block_map x0, x7, x3, x5, x6
> -1:
> -       /*
>          * Since the page tables have been populated with non-cacheable
>          * accesses (MMU disabled), invalidate the idmap and swapper page
>          * tables again to remove any speculatively loaded cache lines.
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 74753132c3ac..770ae9dc5a75 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -105,18 +105,6 @@ static struct resource mem_res[] = {
>  #define kernel_code mem_res[0]
>  #define kernel_data mem_res[1]
> 
> -void __init early_print(const char *str, ...)
> -{
> -       char buf[256];
> -       va_list ap;
> -
> -       va_start(ap, str);
> -       vsnprintf(buf, sizeof(buf), str, ap);
> -       va_end(ap);
> -
> -       printk("%s", buf);
> -}
> -
>  /*
>   * The recorded values of x0 .. x3 upon kernel entry.
>   */
> @@ -326,12 +314,14 @@ static void __init setup_processor(void)
> 
>  static void __init setup_machine_fdt(phys_addr_t dt_phys)
>  {
> -       if (!dt_phys || !early_init_dt_scan(phys_to_virt(dt_phys))) {
> -               early_print("\n"
> -                       "Error: invalid device tree blob at physical address 0x%p (virtual address 0x%p)\n"
> -                       "The dtb must be 8-byte aligned and passed in the first 512MB of memory\n"
> -                       "\nPlease check your bootloader.\n",
> -                       dt_phys, phys_to_virt(dt_phys));
> +       void *dt_virt = fixmap_remap_fdt(dt_phys);
> +
> +       if (!dt_virt || !early_init_dt_scan(dt_virt)) {
> +               pr_crit("\n"
> +                       "Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
> +                       "The dtb must be 8-byte aligned and must not exceed 2 MB in size\n"
> +                       "\nPlease check your bootloader.",
> +                       &dt_phys, dt_virt);
> 
>                 while (true)
>                         cpu_relax();
> @@ -374,8 +364,6 @@ void __init setup_arch(char **cmdline_p)
>  {
>         setup_processor();
> 
> -       setup_machine_fdt(__fdt_pointer);
> -
>         init_mm.start_code = (unsigned long) _text;
>         init_mm.end_code   = (unsigned long) _etext;
>         init_mm.end_data   = (unsigned long) _edata;
> @@ -386,6 +374,8 @@ void __init setup_arch(char **cmdline_p)
>         early_fixmap_init();
>         early_ioremap_init();
> 
> +       setup_machine_fdt(__fdt_pointer);
> +
>         parse_early_param();
> 
>         /*
> diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
> index 773d37a14039..9d84feb41a16 100644
> --- a/arch/arm64/mm/Makefile
> +++ b/arch/arm64/mm/Makefile
> @@ -4,3 +4,5 @@ obj-y                           := dma-mapping.o extable.o fault.o init.o \
>                                    context.o proc.o pageattr.o
>  obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
>  obj-$(CONFIG_ARM64_PTDUMP)     += dump.o
> +
> +CFLAGS_mmu.o                   := -I$(srctree)/scripts/dtc/libfdt/
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 89a05f467ffb..597831bdddf3 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -170,7 +170,6 @@ void __init arm64_memblock_init(void)
>                 memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
>  #endif
> 
> -       early_init_fdt_reserve_self();
>         early_init_fdt_scan_reserved_mem();
> 
>         /* 4GB maximum for 32-bit only capable devices */
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 5b8b664422d3..82d3435bf14f 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -21,6 +21,7 @@
>  #include <linux/kernel.h>
>  #include <linux/errno.h>
>  #include <linux/init.h>
> +#include <linux/libfdt.h>
>  #include <linux/mman.h>
>  #include <linux/nodemask.h>
>  #include <linux/memblock.h>
> @@ -643,3 +644,68 @@ void __set_fixmap(enum fixed_addresses idx,
>                 flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
>         }
>  }
> +
> +void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
> +{
> +       const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
> +       pgprot_t prot = PAGE_KERNEL | PTE_RDONLY;
> +       int granularity, size, offset;
> +       void *dt_virt;
> +
> +       /*
> +        * Check whether the physical FDT address is set and meets the minimum
> +        * alignment requirement. Since we are relying on MIN_FDT_ALIGN to be
> +        * at least 8 bytes so that we can always access the size field of the
> +        * FDT header after mapping the first chunk, double check here if that
> +        * is indeed the case.
> +        */
> +       BUILD_BUG_ON(MIN_FDT_ALIGN < 8);
> +       if (!dt_phys || dt_phys % MIN_FDT_ALIGN)
> +               return NULL;
> +
> +       /*
> +        * Make sure that the FDT region can be mapped without the need to
> +        * allocate additional translation table pages, so that it is safe
> +        * to call create_mapping() this early.
> +        *
> +        * On 64k pages, the FDT will be mapped using PTEs, so we need to
> +        * be in the same PMD as the rest of the fixmap.
> +        * On 4k pages, we'll use section mappings for the FDT so we only
> +        * have to be in the same PUD.
> +        */
> +       BUILD_BUG_ON(dt_virt_base % SZ_2M);
> +
> +       if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) {
> +               BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PMD_SHIFT !=
> +                            __fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT);
> +
> +               granularity = PAGE_SIZE;
> +       } else {
> +               BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PUD_SHIFT !=
> +                            __fix_to_virt(FIX_BTMAP_BEGIN) >> PUD_SHIFT);
> +
> +               granularity = PMD_SIZE;
> +       }
> +
> +       offset = dt_phys % granularity;
> +       dt_virt = (void *)dt_virt_base + offset;
> +
> +       /* map the first chunk so we can read the size from the header */
> +       create_mapping(round_down(dt_phys, granularity), dt_virt_base,
> +                      granularity, prot);
> +
> +       if (fdt_check_header(dt_virt) != 0)
> +               return NULL;
> +
> +       size = fdt_totalsize(dt_virt);
> +       if (size > MAX_FDT_SIZE)
> +               return NULL;
> +
> +       if (offset + size > granularity)
> +               create_mapping(round_down(dt_phys, granularity), dt_virt_base,
> +                              round_up(offset + size, granularity), prot);
> +
> +       memblock_reserve(dt_phys, size);
> +
> +       return dt_virt;
> +}
> --
> 1.9.1
> 

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

* [PATCH 2/8] arm64: use fixmap region for permanent FDT mapping
  2015-06-01  9:53   ` Mark Rutland
@ 2015-06-01  9:55     ` Ard Biesheuvel
  0 siblings, 0 replies; 22+ messages in thread
From: Ard Biesheuvel @ 2015-06-01  9:55 UTC (permalink / raw)
  To: linux-arm-kernel

On 1 June 2015 at 11:53, Mark Rutland <mark.rutland@arm.com> wrote:
> Hi Ard,
>
> Sorry for the silence on this.
>
> On Mon, May 11, 2015 at 07:41:54AM +0100, Ard Biesheuvel wrote:
>> Currently, the FDT blob needs to be in the same 512 MB region as
>> the kernel, so that it can be mapped into the kernel virtual memory
>> space very early on using a minimal set of statically allocated
>> translation tables.
>>
>> Now that we have early fixmap support, we can relax this restriction,
>> by moving the permanent FDT mapping to the fixmap region instead.
>> This way, the FDT blob may be anywhere in memory.
>>
>> This also moves the vetting of the FDT to mmu.c, since the early
>> init code in head.S does not handle mapping of the FDT anymore.
>> At the same time, fix up some comments in head.S that have gone stale.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
> The patch looks good to me. I've just given this some testing loading
> DTBs at weird offsets and large disances from the kernel, and that seems
> to work, so:
>
> Reviewed-by: Mark Rutland <mark.rutland@arm.com>
> Tested-by: Mark Rutland <mark.rutland@arm.com>
>

Thank you.

I noticed that I forgot to make the Documentation change you requested
last time around, so I will roll that into the next version (with your
tags).

-- 
Ard.


>> ---
>>  Documentation/arm64/booting.txt | 13 ++++----
>>  arch/arm64/include/asm/boot.h   | 14 +++++++++
>>  arch/arm64/include/asm/fixmap.h | 15 ++++++++++
>>  arch/arm64/include/asm/mmu.h    |  1 +
>>  arch/arm64/kernel/head.S        | 39 +-----------------------
>>  arch/arm64/kernel/setup.c       | 30 +++++++------------
>>  arch/arm64/mm/Makefile          |  2 ++
>>  arch/arm64/mm/init.c            |  1 -
>>  arch/arm64/mm/mmu.c             | 66 +++++++++++++++++++++++++++++++++++++++++
>>  9 files changed, 117 insertions(+), 64 deletions(-)
>>  create mode 100644 arch/arm64/include/asm/boot.h
>>
>> diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
>> index f3c05b5f9f08..53f18e13d51c 100644
>> --- a/Documentation/arm64/booting.txt
>> +++ b/Documentation/arm64/booting.txt
>> @@ -45,11 +45,14 @@ sees fit.)
>>
>>  Requirement: MANDATORY
>>
>> -The device tree blob (dtb) must be placed on an 8-byte boundary within
>> -the first 512 megabytes from the start of the kernel image and must not
>> -cross a 2-megabyte boundary. This is to allow the kernel to map the
>> -blob using a single section mapping in the initial page tables.
>> -
>> +The device tree blob (dtb) must be placed on an 8-byte boundary and must
>> +not exceed 2 megabytes in size. Since the dtb will be mapped cacheable using
>> +blocks of up to 2 megabytes in size, it should not be placed within 2 megabytes
>> +of memreserves or other special carveouts that may be mapped with non-matching
>> +attributes.
>> +
>> +NOTE: versions prior to v4.2 also require that the DTB be placed within
>> +the 512 MB region starting at text_offset bytes below the kernel Image.
>>
>>  3. Decompress the kernel image
>>  ------------------------------
>> diff --git a/arch/arm64/include/asm/boot.h b/arch/arm64/include/asm/boot.h
>> new file mode 100644
>> index 000000000000..81151b67b26b
>> --- /dev/null
>> +++ b/arch/arm64/include/asm/boot.h
>> @@ -0,0 +1,14 @@
>> +
>> +#ifndef __ASM_BOOT_H
>> +#define __ASM_BOOT_H
>> +
>> +#include <asm/sizes.h>
>> +
>> +/*
>> + * arm64 requires the DTB to be 8 byte aligned and
>> + * not exceed 2MB in size.
>> + */
>> +#define MIN_FDT_ALIGN          8
>> +#define MAX_FDT_SIZE           SZ_2M
>> +
>> +#endif
>> diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
>> index 95e6b6dcbe37..c0739187a920 100644
>> --- a/arch/arm64/include/asm/fixmap.h
>> +++ b/arch/arm64/include/asm/fixmap.h
>> @@ -17,6 +17,7 @@
>>
>>  #ifndef __ASSEMBLY__
>>  #include <linux/kernel.h>
>> +#include <asm/boot.h>
>>  #include <asm/page.h>
>>
>>  /*
>> @@ -32,6 +33,20 @@
>>   */
>>  enum fixed_addresses {
>>         FIX_HOLE,
>> +
>> +       /*
>> +        * Reserve a virtual window for the FDT that is 2 MB larger than the
>> +        * maximum supported size, and put it at the top of the fixmap region.
>> +        * The additional space ensures that any FDT that does not exceed
>> +        * MAX_FDT_SIZE can be mapped regardless of whether it crosses any
>> +        * 2 MB alignment boundaries.
>> +        *
>> +        * Keep this at the top so it remains 2 MB aligned.
>> +        */
>> +#define FIX_FDT_SIZE           (MAX_FDT_SIZE + SZ_2M)
>> +       FIX_FDT_END,
>> +       FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,
>> +
>>         FIX_EARLYCON_MEM_BASE,
>>         FIX_TEXT_POKE0,
>>         __end_of_permanent_fixed_addresses,
>> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
>> index 3d311761e3c2..79fcfb048884 100644
>> --- a/arch/arm64/include/asm/mmu.h
>> +++ b/arch/arm64/include/asm/mmu.h
>> @@ -34,5 +34,6 @@ extern void init_mem_pgprot(void);
>>  extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
>>                                unsigned long virt, phys_addr_t size,
>>                                pgprot_t prot);
>> +extern void *fixmap_remap_fdt(phys_addr_t dt_phys);
>>
>>  #endif
>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>> index 19f915e8f6e0..30cffc5e7402 100644
>> --- a/arch/arm64/kernel/head.S
>> +++ b/arch/arm64/kernel/head.S
>> @@ -237,8 +237,6 @@ ENTRY(stext)
>>         bl      el2_setup                       // Drop to EL1, w20=cpu_boot_mode
>>         adrp    x24, __PHYS_OFFSET
>>         bl      set_cpu_boot_mode_flag
>> -
>> -       bl      __vet_fdt
>>         bl      __create_page_tables            // x25=TTBR0, x26=TTBR1
>>         /*
>>          * The following calls CPU setup code, see arch/arm64/mm/proc.S for
>> @@ -270,24 +268,6 @@ preserve_boot_args:
>>  ENDPROC(preserve_boot_args)
>>
>>  /*
>> - * Determine validity of the x21 FDT pointer.
>> - * The dtb must be 8-byte aligned and live in the first 512M of memory.
>> - */
>> -__vet_fdt:
>> -       tst     x21, #0x7
>> -       b.ne    1f
>> -       cmp     x21, x24
>> -       b.lt    1f
>> -       mov     x0, #(1 << 29)
>> -       add     x0, x0, x24
>> -       cmp     x21, x0
>> -       b.ge    1f
>> -       ret
>> -1:
>> -       mov     x21, #0
>> -       ret
>> -ENDPROC(__vet_fdt)
>> -/*
>>   * Macro to create a table entry to the next page.
>>   *
>>   *     tbl:    page table address
>> @@ -348,8 +328,7 @@ ENDPROC(__vet_fdt)
>>   * required to get the kernel running. The following sections are required:
>>   *   - identity mapping to enable the MMU (low address, TTBR0)
>>   *   - first few MB of the kernel linear mapping to jump to once the MMU has
>> - *     been enabled, including the FDT blob (TTBR1)
>> - *   - pgd entry for fixed mappings (TTBR1)
>> + *     been enabled
>>   */
>>  __create_page_tables:
>>         adrp    x25, idmap_pg_dir
>> @@ -439,22 +418,6 @@ __create_page_tables:
>>         create_block_map x0, x7, x3, x5, x6
>>
>>         /*
>> -        * Map the FDT blob (maximum 2MB; must be within 512MB of
>> -        * PHYS_OFFSET).
>> -        */
>> -       mov     x3, x21                         // FDT phys address
>> -       and     x3, x3, #~((1 << 21) - 1)       // 2MB aligned
>> -       mov     x6, #PAGE_OFFSET
>> -       sub     x5, x3, x24                     // subtract PHYS_OFFSET
>> -       tst     x5, #~((1 << 29) - 1)           // within 512MB?
>> -       csel    x21, xzr, x21, ne               // zero the FDT pointer
>> -       b.ne    1f
>> -       add     x5, x5, x6                      // __va(FDT blob)
>> -       add     x6, x5, #1 << 21                // 2MB for the FDT blob
>> -       sub     x6, x6, #1                      // inclusive range
>> -       create_block_map x0, x7, x3, x5, x6
>> -1:
>> -       /*
>>          * Since the page tables have been populated with non-cacheable
>>          * accesses (MMU disabled), invalidate the idmap and swapper page
>>          * tables again to remove any speculatively loaded cache lines.
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index 74753132c3ac..770ae9dc5a75 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -105,18 +105,6 @@ static struct resource mem_res[] = {
>>  #define kernel_code mem_res[0]
>>  #define kernel_data mem_res[1]
>>
>> -void __init early_print(const char *str, ...)
>> -{
>> -       char buf[256];
>> -       va_list ap;
>> -
>> -       va_start(ap, str);
>> -       vsnprintf(buf, sizeof(buf), str, ap);
>> -       va_end(ap);
>> -
>> -       printk("%s", buf);
>> -}
>> -
>>  /*
>>   * The recorded values of x0 .. x3 upon kernel entry.
>>   */
>> @@ -326,12 +314,14 @@ static void __init setup_processor(void)
>>
>>  static void __init setup_machine_fdt(phys_addr_t dt_phys)
>>  {
>> -       if (!dt_phys || !early_init_dt_scan(phys_to_virt(dt_phys))) {
>> -               early_print("\n"
>> -                       "Error: invalid device tree blob at physical address 0x%p (virtual address 0x%p)\n"
>> -                       "The dtb must be 8-byte aligned and passed in the first 512MB of memory\n"
>> -                       "\nPlease check your bootloader.\n",
>> -                       dt_phys, phys_to_virt(dt_phys));
>> +       void *dt_virt = fixmap_remap_fdt(dt_phys);
>> +
>> +       if (!dt_virt || !early_init_dt_scan(dt_virt)) {
>> +               pr_crit("\n"
>> +                       "Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
>> +                       "The dtb must be 8-byte aligned and must not exceed 2 MB in size\n"
>> +                       "\nPlease check your bootloader.",
>> +                       &dt_phys, dt_virt);
>>
>>                 while (true)
>>                         cpu_relax();
>> @@ -374,8 +364,6 @@ void __init setup_arch(char **cmdline_p)
>>  {
>>         setup_processor();
>>
>> -       setup_machine_fdt(__fdt_pointer);
>> -
>>         init_mm.start_code = (unsigned long) _text;
>>         init_mm.end_code   = (unsigned long) _etext;
>>         init_mm.end_data   = (unsigned long) _edata;
>> @@ -386,6 +374,8 @@ void __init setup_arch(char **cmdline_p)
>>         early_fixmap_init();
>>         early_ioremap_init();
>>
>> +       setup_machine_fdt(__fdt_pointer);
>> +
>>         parse_early_param();
>>
>>         /*
>> diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
>> index 773d37a14039..9d84feb41a16 100644
>> --- a/arch/arm64/mm/Makefile
>> +++ b/arch/arm64/mm/Makefile
>> @@ -4,3 +4,5 @@ obj-y                           := dma-mapping.o extable.o fault.o init.o \
>>                                    context.o proc.o pageattr.o
>>  obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
>>  obj-$(CONFIG_ARM64_PTDUMP)     += dump.o
>> +
>> +CFLAGS_mmu.o                   := -I$(srctree)/scripts/dtc/libfdt/
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index 89a05f467ffb..597831bdddf3 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -170,7 +170,6 @@ void __init arm64_memblock_init(void)
>>                 memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
>>  #endif
>>
>> -       early_init_fdt_reserve_self();
>>         early_init_fdt_scan_reserved_mem();
>>
>>         /* 4GB maximum for 32-bit only capable devices */
>> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
>> index 5b8b664422d3..82d3435bf14f 100644
>> --- a/arch/arm64/mm/mmu.c
>> +++ b/arch/arm64/mm/mmu.c
>> @@ -21,6 +21,7 @@
>>  #include <linux/kernel.h>
>>  #include <linux/errno.h>
>>  #include <linux/init.h>
>> +#include <linux/libfdt.h>
>>  #include <linux/mman.h>
>>  #include <linux/nodemask.h>
>>  #include <linux/memblock.h>
>> @@ -643,3 +644,68 @@ void __set_fixmap(enum fixed_addresses idx,
>>                 flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
>>         }
>>  }
>> +
>> +void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
>> +{
>> +       const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
>> +       pgprot_t prot = PAGE_KERNEL | PTE_RDONLY;
>> +       int granularity, size, offset;
>> +       void *dt_virt;
>> +
>> +       /*
>> +        * Check whether the physical FDT address is set and meets the minimum
>> +        * alignment requirement. Since we are relying on MIN_FDT_ALIGN to be
>> +        * at least 8 bytes so that we can always access the size field of the
>> +        * FDT header after mapping the first chunk, double check here if that
>> +        * is indeed the case.
>> +        */
>> +       BUILD_BUG_ON(MIN_FDT_ALIGN < 8);
>> +       if (!dt_phys || dt_phys % MIN_FDT_ALIGN)
>> +               return NULL;
>> +
>> +       /*
>> +        * Make sure that the FDT region can be mapped without the need to
>> +        * allocate additional translation table pages, so that it is safe
>> +        * to call create_mapping() this early.
>> +        *
>> +        * On 64k pages, the FDT will be mapped using PTEs, so we need to
>> +        * be in the same PMD as the rest of the fixmap.
>> +        * On 4k pages, we'll use section mappings for the FDT so we only
>> +        * have to be in the same PUD.
>> +        */
>> +       BUILD_BUG_ON(dt_virt_base % SZ_2M);
>> +
>> +       if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) {
>> +               BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PMD_SHIFT !=
>> +                            __fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT);
>> +
>> +               granularity = PAGE_SIZE;
>> +       } else {
>> +               BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PUD_SHIFT !=
>> +                            __fix_to_virt(FIX_BTMAP_BEGIN) >> PUD_SHIFT);
>> +
>> +               granularity = PMD_SIZE;
>> +       }
>> +
>> +       offset = dt_phys % granularity;
>> +       dt_virt = (void *)dt_virt_base + offset;
>> +
>> +       /* map the first chunk so we can read the size from the header */
>> +       create_mapping(round_down(dt_phys, granularity), dt_virt_base,
>> +                      granularity, prot);
>> +
>> +       if (fdt_check_header(dt_virt) != 0)
>> +               return NULL;
>> +
>> +       size = fdt_totalsize(dt_virt);
>> +       if (size > MAX_FDT_SIZE)
>> +               return NULL;
>> +
>> +       if (offset + size > granularity)
>> +               create_mapping(round_down(dt_phys, granularity), dt_virt_base,
>> +                              round_up(offset + size, granularity), prot);
>> +
>> +       memblock_reserve(dt_phys, size);
>> +
>> +       return dt_virt;
>> +}
>> --
>> 1.9.1
>>

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

* [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing
  2015-06-01  7:56     ` Ard Biesheuvel
@ 2015-06-01  9:56       ` Mark Rutland
  2015-06-01 10:46         ` Ard Biesheuvel
  0 siblings, 1 reply; 22+ messages in thread
From: Mark Rutland @ 2015-06-01  9:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 01, 2015 at 08:56:07AM +0100, Ard Biesheuvel wrote:
> (snip non-LAKML CCs)
> 
> On 22 May 2015 at 12:35, Catalin Marinas <catalin.marinas@arm.com> wrote:
> > On Mon, May 11, 2015 at 08:41:53AM +0200, Ard Biesheuvel wrote:
> >> This splits off the reservation of the memory occupied by the FDT
> >> binary itself from the processing of the memory reservations it
> >> contains. This is necessary because the physical address of the FDT,
> >> which is needed to perform the reservation, may not be known to the
> >> FDT driver core, i.e., it may be mapped outside the linear direct
> >> mapping, in which case __pa() returns a bogus value.
> >>
> >> Cc: Russell King <linux@arm.linux.org.uk>
> >> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >> Cc: Paul Mackerras <paulus@samba.org>
> >> Acked-by: Rob Herring <robh@kernel.org>
> >> Acked-by: Mark Rutland <mark.rutland@arm.com>
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >
> > For the arm64 part:
> >
> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> 
> Thanks Catalin,
> 
> Since there has been virtually no discussion about these patches, I
> guess they have missed the window for being considered for inclusion
> in v4.2
> 
> May I suggest that you at least consider these patches regarding the ID map
> 
> http://article.gmane.org/gmane.linux.ports.arm.kernel/411720
> http://article.gmane.org/gmane.linux.ports.arm.kernel/411721
> 
> since they are self-contained and the first one does fix a potential
> problem where the Image placement logic in the stub does not take the
> 512 MB alignment boundary into account. The second one is a trivial
> cleanup.

FWIW both of these look good to me.

> Perhaps Mark can comment on the desirability to include the FDT
> remapping patch (which depends on this 1/8).
> 
> http://article.gmane.org/gmane.linux.kernel.efi/5738

I would like to see that taken if possible.

Thanks,
Mark.

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

* [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing
  2015-06-01  9:56       ` Mark Rutland
@ 2015-06-01 10:46         ` Ard Biesheuvel
  2015-06-01 11:02           ` Mark Rutland
  0 siblings, 1 reply; 22+ messages in thread
From: Ard Biesheuvel @ 2015-06-01 10:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 1 June 2015 at 11:56, Mark Rutland <mark.rutland@arm.com> wrote:
> On Mon, Jun 01, 2015 at 08:56:07AM +0100, Ard Biesheuvel wrote:
>> (snip non-LAKML CCs)
>>
>> On 22 May 2015 at 12:35, Catalin Marinas <catalin.marinas@arm.com> wrote:
>> > On Mon, May 11, 2015 at 08:41:53AM +0200, Ard Biesheuvel wrote:
>> >> This splits off the reservation of the memory occupied by the FDT
>> >> binary itself from the processing of the memory reservations it
>> >> contains. This is necessary because the physical address of the FDT,
>> >> which is needed to perform the reservation, may not be known to the
>> >> FDT driver core, i.e., it may be mapped outside the linear direct
>> >> mapping, in which case __pa() returns a bogus value.
>> >>
>> >> Cc: Russell King <linux@arm.linux.org.uk>
>> >> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> >> Cc: Paul Mackerras <paulus@samba.org>
>> >> Acked-by: Rob Herring <robh@kernel.org>
>> >> Acked-by: Mark Rutland <mark.rutland@arm.com>
>> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> >
>> > For the arm64 part:
>> >
>> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
>>
>> Thanks Catalin,
>>
>> Since there has been virtually no discussion about these patches, I
>> guess they have missed the window for being considered for inclusion
>> in v4.2
>>
>> May I suggest that you at least consider these patches regarding the ID map
>>
>> http://article.gmane.org/gmane.linux.ports.arm.kernel/411720
>> http://article.gmane.org/gmane.linux.ports.arm.kernel/411721
>>
>> since they are self-contained and the first one does fix a potential
>> problem where the Image placement logic in the stub does not take the
>> 512 MB alignment boundary into account. The second one is a trivial
>> cleanup.
>
> FWIW both of these look good to me.
>
>> Perhaps Mark can comment on the desirability to include the FDT
>> remapping patch (which depends on this 1/8).
>>
>> http://article.gmane.org/gmane.linux.kernel.efi/5738
>
> I would like to see that taken if possible.
>

Thanks.

Actually, it does make kind of sense to take these four (i.e., this
1/8 plus the three referenced above) patches as a set, since together
they address all the known shortcomings in the EFI stub regarding the
placement of both the FDT and the kernel image. All the other stuff
can easily be deferred.

I will respin these 4 with the new tags added.

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

* [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing
  2015-06-01 10:46         ` Ard Biesheuvel
@ 2015-06-01 11:02           ` Mark Rutland
  2015-06-01 11:14             ` Ard Biesheuvel
  0 siblings, 1 reply; 22+ messages in thread
From: Mark Rutland @ 2015-06-01 11:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 01, 2015 at 11:46:27AM +0100, Ard Biesheuvel wrote:
> On 1 June 2015 at 11:56, Mark Rutland <mark.rutland@arm.com> wrote:
> > On Mon, Jun 01, 2015 at 08:56:07AM +0100, Ard Biesheuvel wrote:
> >> (snip non-LAKML CCs)
> >>
> >> On 22 May 2015 at 12:35, Catalin Marinas <catalin.marinas@arm.com> wrote:
> >> > On Mon, May 11, 2015 at 08:41:53AM +0200, Ard Biesheuvel wrote:
> >> >> This splits off the reservation of the memory occupied by the FDT
> >> >> binary itself from the processing of the memory reservations it
> >> >> contains. This is necessary because the physical address of the FDT,
> >> >> which is needed to perform the reservation, may not be known to the
> >> >> FDT driver core, i.e., it may be mapped outside the linear direct
> >> >> mapping, in which case __pa() returns a bogus value.
> >> >>
> >> >> Cc: Russell King <linux@arm.linux.org.uk>
> >> >> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >> >> Cc: Paul Mackerras <paulus@samba.org>
> >> >> Acked-by: Rob Herring <robh@kernel.org>
> >> >> Acked-by: Mark Rutland <mark.rutland@arm.com>
> >> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >> >
> >> > For the arm64 part:
> >> >
> >> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
> >>
> >> Thanks Catalin,
> >>
> >> Since there has been virtually no discussion about these patches, I
> >> guess they have missed the window for being considered for inclusion
> >> in v4.2
> >>
> >> May I suggest that you at least consider these patches regarding the ID map
> >>
> >> http://article.gmane.org/gmane.linux.ports.arm.kernel/411720
> >> http://article.gmane.org/gmane.linux.ports.arm.kernel/411721
> >>
> >> since they are self-contained and the first one does fix a potential
> >> problem where the Image placement logic in the stub does not take the
> >> 512 MB alignment boundary into account. The second one is a trivial
> >> cleanup.
> >
> > FWIW both of these look good to me.
> >
> >> Perhaps Mark can comment on the desirability to include the FDT
> >> remapping patch (which depends on this 1/8).
> >>
> >> http://article.gmane.org/gmane.linux.kernel.efi/5738
> >
> > I would like to see that taken if possible.
> >
> 
> Thanks.
> 
> Actually, it does make kind of sense to take these four (i.e., this
> 1/8 plus the three referenced above) patches as a set, since together
> they address all the known shortcomings in the EFI stub regarding the
> placement of both the FDT and the kernel image. All the other stuff
> can easily be deferred.

Putting those together as a cleanup+preparation series makes sense to
me, if that makes it easy for Catalin to pick them up now.

Do we have/need acks from Ben or Paul on this reservation patch?

Thanks,
Mark.

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

* [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing
  2015-06-01 11:02           ` Mark Rutland
@ 2015-06-01 11:14             ` Ard Biesheuvel
  2015-06-01 11:18               ` Mark Rutland
  0 siblings, 1 reply; 22+ messages in thread
From: Ard Biesheuvel @ 2015-06-01 11:14 UTC (permalink / raw)
  To: linux-arm-kernel

On 1 June 2015 at 13:02, Mark Rutland <mark.rutland@arm.com> wrote:
> On Mon, Jun 01, 2015 at 11:46:27AM +0100, Ard Biesheuvel wrote:
>> On 1 June 2015 at 11:56, Mark Rutland <mark.rutland@arm.com> wrote:
>> > On Mon, Jun 01, 2015 at 08:56:07AM +0100, Ard Biesheuvel wrote:
>> >> (snip non-LAKML CCs)
>> >>
>> >> On 22 May 2015 at 12:35, Catalin Marinas <catalin.marinas@arm.com> wrote:
>> >> > On Mon, May 11, 2015 at 08:41:53AM +0200, Ard Biesheuvel wrote:
>> >> >> This splits off the reservation of the memory occupied by the FDT
>> >> >> binary itself from the processing of the memory reservations it
>> >> >> contains. This is necessary because the physical address of the FDT,
>> >> >> which is needed to perform the reservation, may not be known to the
>> >> >> FDT driver core, i.e., it may be mapped outside the linear direct
>> >> >> mapping, in which case __pa() returns a bogus value.
>> >> >>
>> >> >> Cc: Russell King <linux@arm.linux.org.uk>
>> >> >> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> >> >> Cc: Paul Mackerras <paulus@samba.org>
>> >> >> Acked-by: Rob Herring <robh@kernel.org>
>> >> >> Acked-by: Mark Rutland <mark.rutland@arm.com>
>> >> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> >> >
>> >> > For the arm64 part:
>> >> >
>> >> > Acked-by: Catalin Marinas <catalin.marinas@arm.com>
>> >>
>> >> Thanks Catalin,
>> >>
>> >> Since there has been virtually no discussion about these patches, I
>> >> guess they have missed the window for being considered for inclusion
>> >> in v4.2
>> >>
>> >> May I suggest that you at least consider these patches regarding the ID map
>> >>
>> >> http://article.gmane.org/gmane.linux.ports.arm.kernel/411720
>> >> http://article.gmane.org/gmane.linux.ports.arm.kernel/411721
>> >>
>> >> since they are self-contained and the first one does fix a potential
>> >> problem where the Image placement logic in the stub does not take the
>> >> 512 MB alignment boundary into account. The second one is a trivial
>> >> cleanup.
>> >
>> > FWIW both of these look good to me.
>> >
>> >> Perhaps Mark can comment on the desirability to include the FDT
>> >> remapping patch (which depends on this 1/8).
>> >>
>> >> http://article.gmane.org/gmane.linux.kernel.efi/5738
>> >
>> > I would like to see that taken if possible.
>> >
>>
>> Thanks.
>>
>> Actually, it does make kind of sense to take these four (i.e., this
>> 1/8 plus the three referenced above) patches as a set, since together
>> they address all the known shortcomings in the EFI stub regarding the
>> placement of both the FDT and the kernel image. All the other stuff
>> can easily be deferred.
>
> Putting those together as a cleanup+preparation series makes sense to
> me, if that makes it easy for Catalin to pick them up now.
>
> Do we have/need acks from Ben or Paul on this reservation patch?
>

Considering that this patch is essentially a partial revert of
d1552ce449eb0 ("of/fdt: move memreserve and dtb memory reservations
into core") by Rob, who acked this patch and submitted his patch
without the acks of either Ben or Paul, and the fact that Ben and Paul
(and Russell) have all been cc'ed at least 3 times on this patch, my
take would be that it should be fine to go ahead without them. But it
is ultimately up to Catalin, of course.

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

* [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing
  2015-06-01 11:14             ` Ard Biesheuvel
@ 2015-06-01 11:18               ` Mark Rutland
  0 siblings, 0 replies; 22+ messages in thread
From: Mark Rutland @ 2015-06-01 11:18 UTC (permalink / raw)
  To: linux-arm-kernel

> > Do we have/need acks from Ben or Paul on this reservation patch?
> >
> 
> Considering that this patch is essentially a partial revert of
> d1552ce449eb0 ("of/fdt: move memreserve and dtb memory reservations
> into core") by Rob, who acked this patch and submitted his patch
> without the acks of either Ben or Paul, and the fact that Ben and Paul
> (and Russell) have all been cc'ed at least 3 times on this patch, my
> take would be that it should be fine to go ahead without them. But it
> is ultimately up to Catalin, of course.

That sounds fine to me also, just thought I should check.

Mark.

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

end of thread, other threads:[~2015-06-01 11:18 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-11  6:41 [PATCH 0/8] arm64 UEFI early FDT handling Ard Biesheuvel
2015-05-11  6:41 ` [PATCH 1/8] of/fdt: split off FDT self reservation from memreserve processing Ard Biesheuvel
2015-05-22 10:35   ` Catalin Marinas
2015-06-01  7:56     ` Ard Biesheuvel
2015-06-01  9:56       ` Mark Rutland
2015-06-01 10:46         ` Ard Biesheuvel
2015-06-01 11:02           ` Mark Rutland
2015-06-01 11:14             ` Ard Biesheuvel
2015-06-01 11:18               ` Mark Rutland
2015-05-11  6:41 ` [PATCH 2/8] arm64: use fixmap region for permanent FDT mapping Ard Biesheuvel
2015-06-01  9:53   ` Mark Rutland
2015-06-01  9:55     ` Ard Biesheuvel
2015-05-11  6:41 ` [PATCH 3/8] arm64: override early_init_dt_add_memory_arch() Ard Biesheuvel
2015-05-11  6:41 ` [PATCH 4/8] efi: move FDT handling to separate object file Ard Biesheuvel
2015-05-26 18:15   ` Matt Fleming
2015-05-11  6:41 ` [PATCH 5/8] arm64/efi: move EFI init before early FDT processing Ard Biesheuvel
2015-05-11  6:41 ` [PATCH 6/8] arm64/efi: ignore DT memory nodes instead of removing them Ard Biesheuvel
2015-05-11 16:28   ` Ganapatrao Kulkarni
2015-05-12 14:31   ` Leif Lindholm
2015-05-12 15:01     ` Ard Biesheuvel
2015-05-11  6:41 ` [PATCH 7/8] arm64/efi: ignore DT memreserve entries " Ard Biesheuvel
2015-05-11  6:42 ` [PATCH 8/8] arm64/efi: adapt to relaxed FDT placement requirements Ard Biesheuvel

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