[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] xen:arm: Populate arm64 image header



While porting XEN on Amlogic SoC we found that in absence of
image_size field of XEN image header, bootloader(U-BOOT)
relocates[1] the XEN image to an address(not appropriate
for Amlogic) derived from text_offset.

This unwanted situation can be fixed by updating image_size field
along side kernel flags so that image wouldn't relocate from initial
load address.

[1]:https://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/lib/image.c;h=699bf44e702f7a7084997406203fd7d2aaaf87fa;hb=HEAD#l50

These changes are derived from kernel v4.18 files

Signed-off-by: Amit Singh Tomar <amittomer25@xxxxxxxxx>
---
 xen/arch/arm/arm64/head.S                     |  5 ++-
 xen/arch/arm/arm64/lib/assembler.h            | 11 +++++
 xen/arch/arm/xen.lds.S                        |  3 ++
 xen/include/asm-arm/arm64/linux_header_vars.h | 62 +++++++++++++++++++++++++++
 4 files changed, 79 insertions(+), 2 deletions(-)
 create mode 100644 xen/include/asm-arm/arm64/linux_header_vars.h

diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index d63734f..ce72c95 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -25,6 +25,7 @@
 #include <asm/early_printk.h>
 #include <efi/efierr.h>
 #include <asm/arm64/efibind.h>
+#include "lib/assembler.h"
 
 #define PT_PT     0xf7f /* nG=1 AF=1 SH=11 AP=01 NS=1 ATTR=111 T=1 P=1 */
 #define PT_MEM    0xf7d /* nG=1 AF=1 SH=11 AP=01 NS=1 ATTR=111 T=0 P=1 */
@@ -120,8 +121,8 @@ efi_head:
         add     x13, x18, #0x16
         b       real_start           /* branch to kernel start */
         .quad   0                    /* Image load offset from start of RAM */
-        .quad   0                    /* reserved */
-        .quad   0                    /* reserved */
+        le64sym _kernel_size_le      /* Effective size of kernel image, 
little-endian */
+        le64sym _kernel_flags_le     /* Informative flags, little-endian */
         .quad   0                    /* reserved */
         .quad   0                    /* reserved */
         .quad   0                    /* reserved */
diff --git a/xen/arch/arm/arm64/lib/assembler.h 
b/xen/arch/arm/arm64/lib/assembler.h
index 3f9c0dc..c0ef758 100644
--- a/xen/arch/arm/arm64/lib/assembler.h
+++ b/xen/arch/arm/arm64/lib/assembler.h
@@ -9,4 +9,15 @@
 #define CPU_BE(x...)
 #define CPU_LE(x...) x
 
+    /*
+     * Emit a 64-bit absolute little endian symbol reference in a way that
+     * ensures that it will be resolved at build time, even when building a
+     * PIE binary. This requires cooperation from the linker script, which
+     * must emit the lo32/hi32 halves individually.
+     */
+    .macro  le64sym, sym
+    .long   \sym\()_lo32
+    .long   \sym\()_hi32
+    .endm
+
 #endif /* __ASM_ASSEMBLER_H__ */
diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S
index 245a0e0..0b9af9e 100644
--- a/xen/arch/arm/xen.lds.S
+++ b/xen/arch/arm/xen.lds.S
@@ -5,6 +5,7 @@
 #include <xen/cache.h>
 #include <asm/page.h>
 #include <asm/percpu.h>
+#include <asm/arm64/linux_header_vars.h>
 #undef ENTRY
 #undef ALIGN
 
@@ -229,6 +230,8 @@ SECTIONS
   .stab.index 0 : { *(.stab.index) }
   .stab.indexstr 0 : { *(.stab.indexstr) }
   .comment 0 : { *(.comment) }
+
+  HEAD_SYMBOLS
 }
 
 /*
diff --git a/xen/include/asm-arm/arm64/linux_header_vars.h 
b/xen/include/asm-arm/arm64/linux_header_vars.h
new file mode 100644
index 0000000..3eeffec
--- /dev/null
+++ b/xen/include/asm-arm/arm64/linux_header_vars.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018, Amit Singh Tomar <amittomer25@xxxxxxxxx>.
+ *
+ * Derived from Linux kernel v4.18 file:
+ *
+ * arch/arm64/kernel/image.h
+ * Copyright (C) 2014 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms and conditions of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_IMAGE_H
+#define __ASM_IMAGE_H
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define DATA_LE32(data)                         \
+    ((((data) & 0x000000ff) << 24) |            \
+    (((data) & 0x0000ff00) << 8)   |            \
+    (((data) & 0x00ff0000) >> 8)   |            \
+    (((data) & 0xff000000) >> 24))
+#else
+#define DATA_LE32(data) ((data) & 0xffffffff)
+#endif
+
+#define DEFINE_IMAGE_LE64(sym, data)                    \
+    sym##_lo32 = DATA_LE32((data) & 0xffffffff);        \
+    sym##_hi32 = DATA_LE32((data) >> 32)
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define __HEAD_FLAG_BE         1
+#else
+#define __HEAD_FLAG_BE         0
+#endif
+
+#define __HEAD_FLAG_PAGE_SIZE  1 /* 4K hard-coded */
+
+#define __HEAD_FLAG_PHYS_BASE  1
+
+#define __HEAD_FLAGS    ((__HEAD_FLAG_BE << 0) |        \
+                        (__HEAD_FLAG_PAGE_SIZE << 1) |  \
+                        (__HEAD_FLAG_PHYS_BASE << 3))
+
+/*
+ * These will output as part of the Image header, which should be little-endian
+ * regardless of the endianness of the kernel. While constant values could be
+ * endian swapped in head.S, all are done here for consistency.
+ */
+#define HEAD_SYMBOLS                                    \
+    DEFINE_IMAGE_LE64(_kernel_size_le, _end - start);   \
+    DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS);
+
+#endif /* __ASM_IMAGE_H */
-- 
1.9.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.