Skip to contentSkip to conversation

arm64: avoid early __va translations

PATCH New Ard Biesheuvel 4 participants 17 messages Feb 12, 2016 – Feb 22, 2016

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v3 cover arm64: avoid early __va translations

This is a somewhat cleaner approach for dealing with the issue that the early FDT performs __va() translations before the linear mapping has been set up. Being able to defer the assignment of memstart_addr until after we have discovered all of memory is an important piece of functionality, not only for KASLR but also for mapping the linear region as efficiently as possible.

Changes since v2:
- replace __weak function in patches #1 and #2 with a preprocessor macro
- add patch to address the circular header dependency when including asm/bug.h in asm/memory.h
- turned the hack that adds the BUG_ON() into a proper patch

Patch #1 refactors the early FDT code so that the actual assignment of initrd_start and initrd_end (which is where the __va() translations are performed) can be overridden in architecture specific code.

Patch #2 performs the override, and only records the physical addresses as they are found in the /chosen node, or on the command line, and defers the __va() translation until after memstart_addr has been assigned.

Patch #3 reshuffles some #includes and #defines so that asm/bug.h can be included (and used) in asm/memory.h

Patch #4 implements a BUG_ON() check to ensure that no references to memstart_addr are made before it has been assigned.

Ard Biesheuvel (4):
of/fdt: factor out assignment of initrd_start/initrd_end
arm64: defer __va translation of initrd_start and initrd_end
arm64: prevent potential circular header dependencies in asm/bug.h
arm64: prevent __va() translations before memstart_addr is assigned

 arch/arm64/include/asm/bug.h            |  2 +-
 arch/arm64/include/asm/debug-monitors.h |  2 +-
 arch/arm64/include/asm/memory.h         | 12 ++++++++++-
 arch/arm64/kvm/hyp/debug-sr.c           |  1 +
 arch/arm64/mm/init.c                    | 21 +++++++++++++++-----
 drivers/of/fdt.c                        | 14 ++++++++++---
 6 files changed, 41 insertions(+), 11 deletions(-)
Signature · 1 line
2.5.0
#1 lore raw

PATCH v3 1/4 of/fdt: factor out assignment of initrd_start/initrd_end

Since architectures may not yet have their linear mapping up and running when the initrd address is discovered from the DT, factor out the assignment of initrd_start and initrd_end, so that an architecture can override it and use the translation it needs.

---
 drivers/of/fdt.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
drivers/of/fdt.c +11 -3
index 1f98156f8996..3e90bce70545 100644
@@ -760,6 +760,16 @@ const void * __init of_flat_dt_match_machine(const void *default_match,
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
+#ifndef __early_init_dt_declare_initrd
+static void __early_init_dt_declare_initrd(unsigned long start,
+					   unsigned long end)
+{
+	initrd_start = (unsigned long)__va(start);
+	initrd_end = (unsigned long)__va(end);
+	initrd_below_start_ok = 1;
+}
+#endif
+
 /**
  * early_init_dt_check_for_initrd - Decode initrd location from flat tree
  * @node: reference to node containing initrd location ('chosen')
@@ -782,9 +792,7 @@ static void __init early_init_dt_check_for_initrd(unsigned long node)
 		return;
 	end = of_read_number(prop, len/4);
 
-	initrd_start = (unsigned long)__va(start);
-	initrd_end = (unsigned long)__va(end);
-	initrd_below_start_ok = 1;
+	__early_init_dt_declare_initrd(start, end);
 
 	pr_debug("initrd_start=0x%llx  initrd_end=0x%llx\n",
 		 (unsigned long long)start, (unsigned long long)end);
Signature · 1 line
2.5.0
#2 lore raw

PATCH v3 1/4 of/fdt: factor out assignment of initrd_start/initrd_end

Quoted 10 lines · Ard Biesheuvel

Since architectures may not yet have their linear mapping up and running when the initrd address is discovered from the DT, factor out the assignment of initrd_start and initrd_end, so that an architecture can override it and use the translation it needs.

---
 drivers/of/fdt.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

Mark, Rob, any comments on this?

Will

Quoted 35 lines
drivers/of/fdt.c +11 -3
index 1f98156f8996..3e90bce70545 100644
@@ -760,6 +760,16 @@ const void * __init of_flat_dt_match_machine(const void *default_match,
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
+#ifndef __early_init_dt_declare_initrd
+static void __early_init_dt_declare_initrd(unsigned long start,
+					   unsigned long end)
+{
+	initrd_start = (unsigned long)__va(start);
+	initrd_end = (unsigned long)__va(end);
+	initrd_below_start_ok = 1;
+}
+#endif
+
 /**
  * early_init_dt_check_for_initrd - Decode initrd location from flat tree
  * @node: reference to node containing initrd location ('chosen')
@@ -782,9 +792,7 @@ static void __init early_init_dt_check_for_initrd(unsigned long node)
 		return;
 	end = of_read_number(prop, len/4);
 
-	initrd_start = (unsigned long)__va(start);
-	initrd_end = (unsigned long)__va(end);
-	initrd_below_start_ok = 1;
+	__early_init_dt_declare_initrd(start, end);
 
 	pr_debug("initrd_start=0x%llx  initrd_end=0x%llx\n",
 		 (unsigned long long)start, (unsigned long long)end);
Signature · 1 line
2.5.0
#3 lore raw

PATCH v3 1/4 of/fdt: factor out assignment of initrd_start/initrd_end

Quoted 6 lines · Will Deacon
Quoted 5 lines · Ard Biesheuvel

Since architectures may not yet have their linear mapping up and running when the initrd address is discovered from the DT, factor out the assignment of initrd_start and initrd_end, so that an architecture can override it and use the translation it needs.

Quoted 8 lines
Quoted 5 lines
---
 drivers/of/fdt.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

Mark, Rob, any comments on this?

Already acked by Rob, and pulled into -next by Catalin ...

#4 lore raw

PATCH v3 1/4 of/fdt: factor out assignment of initrd_start/initrd_end

Quoted 13 lines · Ard Biesheuvel
Quoted 12 lines · Will Deacon
Quoted 10 lines · Ard Biesheuvel

Since architectures may not yet have their linear mapping up and running when the initrd address is discovered from the DT, factor out the assignment of initrd_start and initrd_end, so that an architecture can override it and use the translation it needs.

---
 drivers/of/fdt.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
Quoted 4 lines
Quoted 2 lines

Mark, Rob, any comments on this?

Already acked by Rob, and pulled into -next by Catalin ...

Weird, I don't see that in my inbox or on the list archives. Where should I be looking?

I'd certainly like to see some performance measurement of the BUG_ON in PHYS_ADDR that is introduced later in the series too.

Will

#5 lore raw

PATCH v3 1/4 of/fdt: factor out assignment of initrd_start/initrd_end

Quoted 17 lines · Will Deacon
Quoted 16 lines · Ard Biesheuvel
Quoted 14 lines · Will Deacon
Quoted 10 lines · Ard Biesheuvel

Since architectures may not yet have their linear mapping up and running when the initrd address is discovered from the DT, factor out the assignment of initrd_start and initrd_end, so that an architecture can override it and use the translation it needs.

---
 drivers/of/fdt.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

Mark, Rob, any comments on this?

Quoted 8 lines
Quoted 1 line

Already acked by Rob, and pulled into -next by Catalin ...

Weird, I don't see that in my inbox or on the list archives. Where should I be looking?

I'd certainly like to see some performance measurement of the BUG_ON in PHYS_ADDR that is introduced later in the series too.

Apologies, I removed you from cc unintentionally.

http://thread.gmane.org/gmane.linux.ports.arm.kernel/478714

#6 lore raw

PATCH v3 2/4 arm64: defer __va translation of initrd_start and initrd_end

In reply to Ard Biesheuvel

Commit 66f51676a095 ("arm64: allow kernel Image to be loaded anywhere in physical memory") defers the assignment of memstart_addr to the point where all memory has been discovered and possibly clipped based on the size of the linear region and the presence of a mem= command line parameter.

However, this results in __va() translations that have been performed up to this point to have been carried out with a preliminary, incorrect value of memstart_addr, and these values need to be fixed up. So wire up the generic support to declare the initrd addresses, and implement it without __va() translations, and perform the translation after memstart_addr has been assigned.

---
 arch/arm64/include/asm/memory.h |  8 ++++++++
 arch/arm64/mm/init.c            | 13 +++++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)
arch/arm64/include/asm/memory.h +8 -0
index 083361531a61..c900883a3119 100644
@@ -121,6 +121,14 @@
 #define IOREMAP_MAX_ORDER	(PMD_SHIFT)
 #endif
 
+#ifdef CONFIG_BLK_DEV_INITRD
+#define __early_init_dt_declare_initrd(__start, __end)			\
+	do {								\
+		initrd_start = (__start);				\
+		initrd_end = (__end);					\
+	} while (0)
+#endif
+
 #ifndef __ASSEMBLY__
 
 extern phys_addr_t		memstart_addr;
arch/arm64/mm/init.c +9 -4
index 3a9fc46cbf80..ed85778b32e5 100644
@@ -61,8 +61,8 @@ static int __init early_initrd(char *p)
 	if (*endp == ',') {
 		size = memparse(endp + 1, NULL);
 
-		initrd_start = (unsigned long)__va(start);
-		initrd_end = (unsigned long)__va(start + size);
+		initrd_start = start;
+		initrd_end = start + size;
 	}
 	return 0;
 }
@@ -213,8 +213,13 @@ void __init arm64_memblock_init(void)
 	 */
 	memblock_reserve(__pa(_text), _end - _text);
 #ifdef CONFIG_BLK_DEV_INITRD
-	if (initrd_start)
-		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
+	if (initrd_start) {
+		memblock_reserve(initrd_start, initrd_end - initrd_start);
+
+		/* the generic initrd code expects virtual addresses */
+		initrd_start = __phys_to_virt(initrd_start);
+		initrd_end = __phys_to_virt(initrd_end);
+	}
 #endif
 
 	early_init_fdt_scan_reserved_mem();
Signature · 1 line
2.5.0
#7 lore raw

PATCH v3 3/4 arm64: prevent potential circular header dependencies in asm/bug.h

In reply to Ard Biesheuvel

Currently, using BUG_ON() in header files is cumbersome, due to the fact that asm/bug.h transitively includes a lot of other header files, resulting in the actual BUG_ON() invocation appearing before its definition in the preprocessor input. So let's reverse the #include dependency between asm/bug.h and asm/debug-monitors.h, by moving the definition of BUG_BRK_IMM from the latter to the former. Also fix up one user of asm/debug-monitors.h which relied on a transitive include.

---
 arch/arm64/include/asm/bug.h            | 2 +-
 arch/arm64/include/asm/debug-monitors.h | 2 +-
 arch/arm64/kvm/hyp/debug-sr.c           | 1 +
 3 files changed, 3 insertions(+), 2 deletions(-)
arch/arm64/include/asm/bug.h +1 -1
index 4a748ce9ba1a..679d49221998 100644
@@ -18,7 +18,7 @@
 #ifndef _ARCH_ARM64_ASM_BUG_H
 #define _ARCH_ARM64_ASM_BUG_H
 
-#include <asm/debug-monitors.h>
+#define BUG_BRK_IMM			0x800
 
 #ifdef CONFIG_GENERIC_BUG
 #define HAVE_ARCH_BUG
arch/arm64/include/asm/debug-monitors.h +1 -1
index 279c85b5ec09..e893a1fca9c2 100644
@@ -20,6 +20,7 @@
 
 #include <linux/errno.h>
 #include <linux/types.h>
+#include <asm/bug.h>
 #include <asm/esr.h>
 #include <asm/insn.h>
 #include <asm/ptrace.h>
@@ -57,7 +58,6 @@
 #define FAULT_BRK_IMM			0x100
 #define KGDB_DYN_DBG_BRK_IMM		0x400
 #define KGDB_COMPILED_DBG_BRK_IMM	0x401
-#define BUG_BRK_IMM			0x800
 
 /*
  * BRK instruction encoding
arch/arm64/kvm/hyp/debug-sr.c +1 -0
index c9c1e97501a9..2f8bca8af295 100644
@@ -18,6 +18,7 @@
 #include <linux/compiler.h>
 #include <linux/kvm_host.h>
 
+#include <asm/debug-monitors.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_mmu.h>
 
Signature · 1 line
2.5.0
#8 lore raw

PATCH v3 3/4 arm64: prevent potential circular header dependencies in asm/bug.h

Quoted 21 lines · Ard Biesheuvel

Currently, using BUG_ON() in header files is cumbersome, due to the fact that asm/bug.h transitively includes a lot of other header files, resulting in the actual BUG_ON() invocation appearing before its definition in the preprocessor input. So let's reverse the #include dependency between asm/bug.h and asm/debug-monitors.h, by moving the definition of BUG_BRK_IMM from the latter to the former. Also fix up one user of asm/debug-monitors.h which relied on a transitive include.

---
 arch/arm64/include/asm/bug.h            | 2 +-
 arch/arm64/include/asm/debug-monitors.h | 2 +-
 arch/arm64/kvm/hyp/debug-sr.c           | 1 +
 3 files changed, 3 insertions(+), 2 deletions(-)
arch/arm64/include/asm/bug.h +0 -0
index 4a748ce9ba1a..679d49221998 100644

arch/arm64/include/asm/bug.h line 21

Quoted 5 lines
arch/arm64/include/asm/bug.h +1 -1
@@ -18,7 +18,7 @@
 #ifndef _ARCH_ARM64_ASM_BUG_H
 #define _ARCH_ARM64_ASM_BUG_H
 
-#include <asm/debug-monitors.h>
+#define BUG_BRK_IMM			0x800

I'd really like to keep all the BRK immediates together, otherwise it's error-prone if/when we allocate new encodings. Maybe we could add a new header file for them, if we really need to?

Alternatively, given that this is all behind DEBUG_VM, you could rewrite the check as if (unlikely(...)) panic(...);

Will

#9 lore raw

PATCH v3 4/4 arm64: prevent __va() translations before memstart_addr is assigned

In reply to Ard Biesheuvel

Since memstart_addr is assigned relatively late in the boot code, after generic code like DT parsing and memblock manipulation has already occurred, we need to ensure that no __va() translation occur until memstart_addr has been set to a meaningful value.

So initialize memstart_addr to a value that cannot represent a valid physical address, and BUG() if memstart_addr is referenced while it still holds this value. Note that the > comparison against LLONG_MAX (not ULLONG_MAX) resolves to a single tbnz instruction that performs a conditional jump to a brk instruction that is emitted out of line.

---
 arch/arm64/include/asm/memory.h | 4 +++-
 arch/arm64/mm/init.c            | 8 +++++++-
 2 files changed, 10 insertions(+), 2 deletions(-)
arch/arm64/include/asm/memory.h +3 -1
index c900883a3119..ae398919fb5f 100644
@@ -24,6 +24,7 @@
 #include <linux/compiler.h>
 #include <linux/const.h>
 #include <linux/types.h>
+#include <asm/bug.h>
 #include <asm/sizes.h>
 
 /*
@@ -133,7 +134,8 @@
 
 extern phys_addr_t		memstart_addr;
 /* PHYS_OFFSET - the physical address of the start of memory. */
-#define PHYS_OFFSET		({ memstart_addr; })
+#define PHYS_OFFSET		\
+	({ BUG_ON(memstart_addr > LLONG_MAX); memstart_addr; })
 
 /* the virtual base of the kernel image (minus TEXT_OFFSET) */
 extern u64			kimage_vaddr;
arch/arm64/mm/init.c +7 -1
index ed85778b32e5..023c41f22b5b 100644
@@ -48,7 +48,13 @@
 
 #include "mm.h"
 
-phys_addr_t memstart_addr __read_mostly = 0;
+/*
+ * We need to be able to catch inadvertent references to memstart_addr
+ * that occur (potentially in generic code) before arm64_memblock_init()
+ * executes, which assigns it its actual value. So use a default value
+ * that cannot be mistaken for a real physical address.
+ */
+phys_addr_t memstart_addr __read_mostly = ULLONG_MAX;
 phys_addr_t arm64_dma_phys_limit __read_mostly;
 
 #ifdef CONFIG_BLK_DEV_INITRD
Signature · 1 line
2.5.0
#10 lore raw

PATCH v3 4/4 arm64: prevent __va() translations before memstart_addr is assigned

Quoted 10 lines · Ard Biesheuvel

Since memstart_addr is assigned relatively late in the boot code, after generic code like DT parsing and memblock manipulation has already occurred, we need to ensure that no __va() translation occur until memstart_addr has been set to a meaningful value.

So initialize memstart_addr to a value that cannot represent a valid physical address, and BUG() if memstart_addr is referenced while it still holds this value. Note that the > comparison against LLONG_MAX (not ULLONG_MAX) resolves to a single tbnz instruction that performs a conditional jump to a brk instruction that is emitted out of line.

Even so, I'd imagine that having a measurable impact on system performance. Did you have a go at benchmarking this?

Will

#11 lore raw

PATCH v3 4/4 arm64: prevent __va() translations before memstart_addr is assigned

Quoted 6 lines · Will Deacon
Quoted 5 lines · Ard Biesheuvel

Since memstart_addr is assigned relatively late in the boot code, after generic code like DT parsing and memblock manipulation has already occurred, we need to ensure that no __va() translation occur until memstart_addr has been set to a meaningful value.

Quoted 9 lines
Quoted 5 lines

So initialize memstart_addr to a value that cannot represent a valid physical address, and BUG() if memstart_addr is referenced while it still holds this value. Note that the > comparison against LLONG_MAX (not ULLONG_MAX) resolves to a single tbnz instruction that performs a conditional jump to a brk instruction that is emitted out of line.

Even so, I'd imagine that having a measurable impact on system performance. Did you have a go at benchmarking this?

So in what kind of workload would the __pa() translation be on a hot path? If you're dealing with DMA or other things that involve physical addresses, surely, the single predicted non-taken branch instruction shouldn't hurt?

maintainer
#12 lore raw

PATCH v3 4/4 arm64: prevent __va() translations before memstart_addr is assigned

Quoted 13 lines · Ard Biesheuvel
Quoted 12 lines · Will Deacon
Quoted 10 lines · Ard Biesheuvel

Since memstart_addr is assigned relatively late in the boot code, after generic code like DT parsing and memblock manipulation has already occurred, we need to ensure that no __va() translation occur until memstart_addr has been set to a meaningful value.

So initialize memstart_addr to a value that cannot represent a valid physical address, and BUG() if memstart_addr is referenced while it still holds this value. Note that the > comparison against LLONG_MAX (not ULLONG_MAX) resolves to a single tbnz instruction that performs a conditional jump to a brk instruction that is emitted out of line.

Quoted 7 lines
Quoted 2 lines

Even so, I'd imagine that having a measurable impact on system performance. Did you have a go at benchmarking this?

So in what kind of workload would the __pa() translation be on a hot path? If you're dealing with DMA or other things that involve physical addresses, surely, the single predicted non-taken branch instruction shouldn't hurt?

I recall we looked at this in the early arm64 days and found a lot of memory accesses to memstart_addr but we decided to keep it as the alternatives would have been: (a) no more single Image or (b) always 4-levels page tables.

You could try perf to get some statistics but, for example, most of the code that works on pages (e.g. block I/O) and needs to access a page ends up doing a kmap(page) which in turns does a __va(). You also have lots of virt_to_page() calls in sl*b, so we need to see what impact this change has.

Signature · 1 line
Catalin
#13 lore raw

PATCH v3 4/4 arm64: prevent __va() translations before memstart_addr is assigned

Quoted 27 lines · Catalin Marinas
Quoted 13 lines · Ard Biesheuvel
Quoted 12 lines · Will Deacon
Quoted 10 lines · Ard Biesheuvel

Since memstart_addr is assigned relatively late in the boot code, after generic code like DT parsing and memblock manipulation has already occurred, we need to ensure that no __va() translation occur until memstart_addr has been set to a meaningful value.

So initialize memstart_addr to a value that cannot represent a valid physical address, and BUG() if memstart_addr is referenced while it still holds this value. Note that the > comparison against LLONG_MAX (not ULLONG_MAX) resolves to a single tbnz instruction that performs a conditional jump to a brk instruction that is emitted out of line.

Quoted 7 lines
Quoted 2 lines

Even so, I'd imagine that having a measurable impact on system performance. Did you have a go at benchmarking this?

So in what kind of workload would the __pa() translation be on a hot path? If you're dealing with DMA or other things that involve physical addresses, surely, the single predicted non-taken branch instruction shouldn't hurt?

I recall we looked at this in the early arm64 days and found a lot of memory accesses to memstart_addr but we decided to keep it as the alternatives would have been: (a) no more single Image or (b) always 4-levels page tables.

Quoted 6 lines

You could try perf to get some statistics but, for example, most of the code that works on pages (e.g. block I/O) and needs to access a page ends up doing a kmap(page) which in turns does a __va(). You also have lots of virt_to_page() calls in sl*b, so we need to see what impact this change has.

I guess virt_to_page() is only valid on linear addresses, so we could reimplement it not to use the comparison with PAGE_OFFSET that I added to __pa() for the kernmap stuff

maintainer
#14 lore raw

PATCH v3 4/4 arm64: prevent __va() translations before memstart_addr is assigned

In reply to Will Deacon
Quoted 6 lines · Will Deacon
Quoted 5 lines · Ard Biesheuvel

Since memstart_addr is assigned relatively late in the boot code, after generic code like DT parsing and memblock manipulation has already occurred, we need to ensure that no __va() translation occur until memstart_addr has been set to a meaningful value.

Quoted 8 lines
Quoted 5 lines

So initialize memstart_addr to a value that cannot represent a valid physical address, and BUG() if memstart_addr is referenced while it still holds this value. Note that the > comparison against LLONG_MAX (not ULLONG_MAX) resolves to a single tbnz instruction that performs a conditional jump to a brk instruction that is emitted out of line.

Even so, I'd imagine that having a measurable impact on system performance. Did you have a go at benchmarking this?

Good point, I forgot about this discussion. We should revert this part indeed or at least make it dependent on some config option like DEBUG_VM.

Signature · 1 line
Catalin
#15 lore raw

PATCH v3 4/4 arm64: prevent __va() translations before memstart_addr is assigned

Quoted 13 lines · Catalin Marinas
Quoted 12 lines · Will Deacon
Quoted 10 lines · Ard Biesheuvel

Since memstart_addr is assigned relatively late in the boot code, after generic code like DT parsing and memblock manipulation has already occurred, we need to ensure that no __va() translation occur until memstart_addr has been set to a meaningful value.

So initialize memstart_addr to a value that cannot represent a valid physical address, and BUG() if memstart_addr is referenced while it still holds this value. Note that the > comparison against LLONG_MAX (not ULLONG_MAX) resolves to a single tbnz instruction that performs a conditional jump to a brk instruction that is emitted out of line.

Quoted 7 lines
Quoted 2 lines

Even so, I'd imagine that having a measurable impact on system performance. Did you have a go at benchmarking this?

Good point, I forgot about this discussion. We should revert this part indeed or at least make it dependent on some config option like DEBUG_VM.

OK, let me code that up

#16 lore raw

v3 cover arm64: avoid early __va translations

In reply to Ard Biesheuvel

Hi Ard,

Quoted 33 lines · Ard Biesheuvel

This is a somewhat cleaner approach for dealing with the issue that the early FDT performs __va() translations before the linear mapping has been set up. Being able to defer the assignment of memstart_addr until after we have discovered all of memory is an important piece of functionality, not only for KASLR but also for mapping the linear region as efficiently as possible.

Changes since v2:
- replace __weak function in patches #1 and #2 with a preprocessor macro
- add patch to address the circular header dependency when including asm/bug.h in asm/memory.h
- turned the hack that adds the BUG_ON() into a proper patch

Patch #1 refactors the early FDT code so that the actual assignment of initrd_start and initrd_end (which is where the __va() translations are performed) can be overridden in architecture specific code.

Patch #2 performs the override, and only records the physical addresses as they are found in the /chosen node, or on the command line, and defers the __va() translation until after memstart_addr has been assigned.

Patch #3 reshuffles some #includes and #defines so that asm/bug.h can be included (and used) in asm/memory.h

Patch #4 implements a BUG_ON() check to ensure that no references to memstart_addr are made before it has been assigned.

Ard Biesheuvel (4):
of/fdt: factor out assignment of initrd_start/initrd_end
arm64: defer __va translation of initrd_start and initrd_end
arm64: prevent potential circular header dependencies in asm/bug.h
arm64: prevent __va() translations before memstart_addr is assigned

Quoted 7 lines
 arch/arm64/include/asm/bug.h            |  2 +-
 arch/arm64/include/asm/debug-monitors.h |  2 +-
 arch/arm64/include/asm/memory.h         | 12 ++++++++++-
 arch/arm64/kvm/hyp/debug-sr.c           |  1 +
 arch/arm64/mm/init.c                    | 21 +++++++++++++++-----
 drivers/of/fdt.c                        | 14 ++++++++++---
 6 files changed, 41 insertions(+), 11 deletions(-)

Tried these on one of our LS2 boards so here's a:

---
Best Regards, Laurentiu