aee378209e
Fix Bug 925630 - kexec-tools: support for arm64 https://bugzilla.redhat.com/show_bug.cgi?id=925630 involves three things: 1. back porting upstream code to enable the function of kexec-tools on arm64 patchset backported from upstream: commit abdfe97736f89d9bc73662b9134604b0229a599e commit 522df5f7217fda01ece3f6ac3e9987b0320c2bb0 commit 217bcc00c9309416a6c6cd0584196559d28a9259 2. fix the arm related building issue by using autoreconf in spec file 3. patches to fix the issue of higher version gcc used by koji (not upstrem yet, and the corresponding fix in kernel side is in other package) kexec-tools-2.0.13-arm64-Add-support-for-additional-relocations-in-the-kexec-purgatory-code.patch kexec-tools-2.0.13-arm64-Add-support-of-R_AARCH64_PREL32-relocation-in-.patch [panand: apply patches in 3 of above paragraph] Signed-off-by: Pingfan Liu <piliu@redhat.com> Acked-by: Dave Young <dyoung@redhat.com> Acked-by: Pratyush Anand <panand@redhat.com>
209 lines
5.1 KiB
Diff
209 lines
5.1 KiB
Diff
From 217bcc00c9309416a6c6cd0584196559d28a9259 Mon Sep 17 00:00:00 2001
|
|
From: Geoff Levand <geoff@infradead.org>
|
|
Date: Wed, 21 Sep 2016 18:14:25 +0000
|
|
Subject: [PATCH 1/3] kexec: Add common device tree routines
|
|
|
|
Common device tree routines that can be shared between all arches
|
|
that have device tree support.
|
|
|
|
Signed-off-by: Geoff Levand <geoff@infradead.org>
|
|
Tested-By: Pratyush Anand <panand@redhat.com>
|
|
Tested-By: Matthias Brugger <mbrugger@suse.com>
|
|
Signed-off-by: Simon Horman <horms@verge.net.au>
|
|
---
|
|
kexec/Makefile | 4 ++
|
|
kexec/dt-ops.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
kexec/dt-ops.h | 13 ++++++
|
|
3 files changed, 162 insertions(+)
|
|
create mode 100644 kexec/dt-ops.c
|
|
create mode 100644 kexec/dt-ops.h
|
|
|
|
diff --git a/kexec/Makefile b/kexec/Makefile
|
|
index e2aee84..cc3f08b 100644
|
|
--- a/kexec/Makefile
|
|
+++ b/kexec/Makefile
|
|
@@ -73,6 +73,10 @@ dist += kexec/mem_regions.c kexec/mem_regions.h
|
|
$(ARCH)_MEM_REGIONS =
|
|
KEXEC_SRCS += $($(ARCH)_MEM_REGIONS)
|
|
|
|
+dist += kexec/dt-ops.c kexec/dt-ops.h
|
|
+$(ARCH)_DT_OPS =
|
|
+KEXEC_SRCS += $($(ARCH)_DT_OPS)
|
|
+
|
|
include $(srcdir)/kexec/arch/alpha/Makefile
|
|
include $(srcdir)/kexec/arch/arm/Makefile
|
|
include $(srcdir)/kexec/arch/i386/Makefile
|
|
diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c
|
|
new file mode 100644
|
|
index 0000000..915dbf5
|
|
--- /dev/null
|
|
+++ b/kexec/dt-ops.c
|
|
@@ -0,0 +1,145 @@
|
|
+#include <assert.h>
|
|
+#include <errno.h>
|
|
+#include <inttypes.h>
|
|
+#include <libfdt.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+
|
|
+#include "kexec.h"
|
|
+#include "dt-ops.h"
|
|
+
|
|
+static const char n_chosen[] = "/chosen";
|
|
+
|
|
+static const char p_bootargs[] = "bootargs";
|
|
+static const char p_initrd_start[] = "linux,initrd-start";
|
|
+static const char p_initrd_end[] = "linux,initrd-end";
|
|
+
|
|
+int dtb_set_initrd(char **dtb, off_t *dtb_size, off_t start, off_t end)
|
|
+{
|
|
+ int result;
|
|
+ uint64_t value;
|
|
+
|
|
+ dbgprintf("%s: start %jd, end %jd, size %jd (%jd KiB)\n",
|
|
+ __func__, (intmax_t)start, (intmax_t)end,
|
|
+ (intmax_t)(end - start),
|
|
+ (intmax_t)(end - start) / 1024);
|
|
+
|
|
+ value = cpu_to_fdt64(start);
|
|
+
|
|
+ result = dtb_set_property(dtb, dtb_size, n_chosen, p_initrd_start,
|
|
+ &value, sizeof(value));
|
|
+
|
|
+ if (result)
|
|
+ return result;
|
|
+
|
|
+ value = cpu_to_fdt64(end);
|
|
+
|
|
+ result = dtb_set_property(dtb, dtb_size, n_chosen, p_initrd_end,
|
|
+ &value, sizeof(value));
|
|
+
|
|
+ if (result) {
|
|
+ dtb_delete_property(*dtb, n_chosen, p_initrd_start);
|
|
+ return result;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int dtb_set_bootargs(char **dtb, off_t *dtb_size, const char *command_line)
|
|
+{
|
|
+ return dtb_set_property(dtb, dtb_size, n_chosen, p_bootargs,
|
|
+ command_line, strlen(command_line) + 1);
|
|
+}
|
|
+
|
|
+int dtb_set_property(char **dtb, off_t *dtb_size, const char *node,
|
|
+ const char *prop, const void *value, int value_len)
|
|
+{
|
|
+ int result;
|
|
+ int nodeoffset;
|
|
+ void *new_dtb;
|
|
+ int new_size;
|
|
+
|
|
+ value_len = FDT_TAGALIGN(value_len);
|
|
+
|
|
+ new_size = FDT_TAGALIGN(*dtb_size + fdt_node_len(node)
|
|
+ + fdt_prop_len(prop, value_len));
|
|
+
|
|
+ new_dtb = malloc(new_size);
|
|
+
|
|
+ if (!new_dtb) {
|
|
+ dbgprintf("%s: malloc failed\n", __func__);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ result = fdt_open_into(*dtb, new_dtb, new_size);
|
|
+
|
|
+ if (result) {
|
|
+ dbgprintf("%s: fdt_open_into failed: %s\n", __func__,
|
|
+ fdt_strerror(result));
|
|
+ goto on_error;
|
|
+ }
|
|
+
|
|
+ nodeoffset = fdt_path_offset(new_dtb, node);
|
|
+
|
|
+ if (nodeoffset == -FDT_ERR_NOTFOUND) {
|
|
+ result = fdt_add_subnode(new_dtb, nodeoffset, node);
|
|
+
|
|
+ if (result) {
|
|
+ dbgprintf("%s: fdt_add_subnode failed: %s\n", __func__,
|
|
+ fdt_strerror(result));
|
|
+ goto on_error;
|
|
+ }
|
|
+ } else if (nodeoffset < 0) {
|
|
+ dbgprintf("%s: fdt_path_offset failed: %s\n", __func__,
|
|
+ fdt_strerror(nodeoffset));
|
|
+ goto on_error;
|
|
+ }
|
|
+
|
|
+ result = fdt_setprop(new_dtb, nodeoffset, prop, value, value_len);
|
|
+
|
|
+ if (result) {
|
|
+ dbgprintf("%s: fdt_setprop failed: %s\n", __func__,
|
|
+ fdt_strerror(result));
|
|
+ goto on_error;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Can't call free on dtb since dtb may have been mmaped by
|
|
+ * slurp_file().
|
|
+ */
|
|
+
|
|
+ result = fdt_pack(new_dtb);
|
|
+
|
|
+ if (result)
|
|
+ dbgprintf("%s: Unable to pack device tree: %s\n", __func__,
|
|
+ fdt_strerror(result));
|
|
+
|
|
+ *dtb = new_dtb;
|
|
+ *dtb_size = fdt_totalsize(*dtb);
|
|
+
|
|
+ return 0;
|
|
+
|
|
+on_error:
|
|
+ free(new_dtb);
|
|
+ return result;
|
|
+}
|
|
+
|
|
+int dtb_delete_property(char *dtb, const char *node, const char *prop)
|
|
+{
|
|
+ int result;
|
|
+ int nodeoffset = fdt_path_offset(dtb, node);
|
|
+
|
|
+ if (nodeoffset < 0) {
|
|
+ dbgprintf("%s: fdt_path_offset failed: %s\n", __func__,
|
|
+ fdt_strerror(nodeoffset));
|
|
+ return nodeoffset;
|
|
+ }
|
|
+
|
|
+ result = fdt_delprop(dtb, nodeoffset, prop);
|
|
+
|
|
+ if (result)
|
|
+ dbgprintf("%s: fdt_delprop failed: %s\n", __func__,
|
|
+ fdt_strerror(nodeoffset));
|
|
+
|
|
+ return result;
|
|
+}
|
|
diff --git a/kexec/dt-ops.h b/kexec/dt-ops.h
|
|
new file mode 100644
|
|
index 0000000..e70d15d
|
|
--- /dev/null
|
|
+++ b/kexec/dt-ops.h
|
|
@@ -0,0 +1,13 @@
|
|
+#if !defined(KEXEC_DT_OPS_H)
|
|
+#define KEXEC_DT_OPS_H
|
|
+
|
|
+#include <sys/types.h>
|
|
+
|
|
+int dtb_set_initrd(char **dtb, off_t *dtb_size, off_t start, off_t end);
|
|
+int dtb_set_bootargs(char **dtb, off_t *dtb_size, const char *command_line);
|
|
+int dtb_set_property(char **dtb, off_t *dtb_size, const char *node,
|
|
+ const char *prop, const void *value, int value_len);
|
|
+
|
|
+int dtb_delete_property(char *dtb, const char *node, const char *prop);
|
|
+
|
|
+#endif
|
|
--
|
|
2.9.3
|
|
|