summaryrefslogtreecommitdiff
path: root/kexec/arch/s390/kexec-image.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2005-04-26 15:20:54 +0200
committerEric W. Biederman <ebiederm@xmission.com>2006-07-27 03:04:56 -0600
commit47406fd61a7eb4694a6033edd5e1ce4eeb3a6a72 (patch)
tree33a1f3dc66d3e0770ed02a69fab5df8b4572f1b1 /kexec/arch/s390/kexec-image.c
parent5cce75bdd6a154a7bee733bcce8f7fe1baf40adf (diff)
add s390 support to kexec-tools-1.101
--===============39718348520004598== Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Milton, first of all thanks for looking at the patches. > 1) When patching the command line, you read the string from the > optarg. While you clear the area in the kernel looking at > COMMAND_LINE_SIZE, you do not limit the length that you copy into > the kernel by this amount. This would seem like a buffer-overflow > situation that could easily be trapped. Yes, you're right. The kernel image could be damaged. Fixed. > 2) I noticed your ramdisk code is quite similar in function to > slurp_file in kexec/kexec.c. I realize this is probably a new > function. Fixed as well :) > 3) Your elf-rel loading seem to not be implemented, but your probe > returns 0 just like the image loader. I think you're talking about the function machine_verify_elf_rel(). Unlike the probe functions this one should return 0 on error, shouldn't it? > 4) You seem to have several addresses hard-coded into the kexec-s390.h > file. This would seem to limit the image you are loading, including > any panic crash kernel options using the current scheme. I don't > know your abi to know what other issues you might have with a more > generic kexec to image interface. (It appears you setup your image > to load as if it were from 0 but skipping IMAGE_READ_OFFSET bytes. The hard coded addresses are part of the kernel abi. Nothing needs to be changed here. Skipping the first 64k of the kernel image is ok too, since you usually would only find a loader routine there which would load the rest of the kernel image into ram and then start it. If you are really interested you might have a look at arch/s390/kernel/head.S in the kernel sources :) Also we do not plan to use the kdump feature. It doesn't make too much sense for the s390 architecture since we have already other mechanisms which allow to reliably dump complete memory and register contents at any given state of the system. The patch below should be better (still against 1.101). Guess I will come up with an improved kernel patch too. Thanks, Heiko diffstat: configure | 5 - kexec/arch/s390/Makefile | 6 + kexec/arch/s390/include/arch/options.h | 11 ++ kexec/arch/s390/kexec-elf-rel-s390.c | 23 +++++ kexec/arch/s390/kexec-image.c | 137 +++++++++++++++++++++++++++++++++ kexec/arch/s390/kexec-s390.c | 104 +++++++++++++++++++++++++ kexec/arch/s390/kexec-s390.h | 25 ++++++ kexec/kexec-syscall.h | 7 + purgatory/arch/s390/Makefile | 7 + purgatory/arch/s390/include/limits.h | 54 +++++++++++++ purgatory/arch/s390/include/stdint.h | 24 +++++ 11 files changed, 402 insertions(+), 1 deletion(-)
Diffstat (limited to 'kexec/arch/s390/kexec-image.c')
-rw-r--r--kexec/arch/s390/kexec-image.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/kexec/arch/s390/kexec-image.c b/kexec/arch/s390/kexec-image.c
new file mode 100644
index 0000000..e1849f0
--- /dev/null
+++ b/kexec/arch/s390/kexec-image.c
@@ -0,0 +1,137 @@
+/*
+ * kexec/arch/s390/kexec-image.c
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ * Heiko Carstens <heiko.carstens@de.ibm.com>
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <getopt.h>
+#include "../../kexec.h"
+#include "kexec-s390.h"
+
+#define OPT_APPEND OPT_MAX+0
+#define OPT_RAMDISK OPT_MAX+1
+
+int
+image_s390_load(int argc, char **argv, const char *kernel_buf,
+ off_t kernel_size, struct kexec_info *info)
+{
+ void *krnl_buffer;
+ char *rd_buffer;
+ const char *command_line;
+ const char *ramdisk;
+ int command_line_len;
+ off_t ramdisk_len;
+ unsigned int ramdisk_origin;
+ int opt;
+
+ static const struct option options[] =
+ {
+ KEXEC_OPTIONS
+ {"command-line", 1, 0, OPT_APPEND},
+ {"initrd", 1, 0, OPT_RAMDISK},
+ {0, 0, 0, 0},
+ };
+ static const char short_options[] = KEXEC_OPT_STR "";
+
+ ramdisk = NULL;
+ command_line = NULL;
+ ramdisk_len = 0;
+ ramdisk_origin = 0;
+
+ while ((opt = getopt_long(argc,argv,short_options,options,0)) != -1) {
+ switch(opt) {
+ case '?':
+ usage();
+ return -1;
+ break;
+ case OPT_APPEND:
+ command_line = optarg;
+ break;
+ case OPT_RAMDISK:
+ ramdisk = optarg;
+ break;
+ }
+ }
+
+ /* Process a given command_line: */
+ if (command_line) {
+ command_line_len = strlen(command_line) + 1; /* Remember the '\0' */
+ if (command_line_len > COMMAND_LINESIZE) {
+ fprintf(stderr, "Command line too long.\n");
+ return -1;
+ }
+ }
+
+ /* Add kernel segment */
+ add_segment(info, kernel_buf + IMAGE_READ_OFFSET,
+ kernel_size - IMAGE_READ_OFFSET, IMAGE_READ_OFFSET,
+ kernel_size - IMAGE_READ_OFFSET);
+
+ /* We do want to change the kernel image */
+ krnl_buffer = (void *) kernel_buf + IMAGE_READ_OFFSET;
+
+ /* Load ramdisk if present */
+ if (ramdisk) {
+ rd_buffer = slurp_file(ramdisk, &ramdisk_len);
+ if (rd_buffer == NULL) {
+ fprintf(stderr, "Could not read ramdisk.\n");
+ return -1;
+ }
+ ramdisk_origin = RAMDISK_ORIGIN_ADDR;
+ add_segment(info, rd_buffer, ramdisk_len, RAMDISK_ORIGIN_ADDR, ramdisk_len);
+ }
+
+ /* Register the ramdisk in the kernel. */
+ {
+ unsigned long long *tmp;
+
+ tmp = krnl_buffer + INITRD_START_OFFS;
+ *tmp = (unsigned long long) ramdisk_origin;
+
+ tmp = krnl_buffer + INITRD_SIZE_OFFS;
+ *tmp = (unsigned long long) ramdisk_len;
+ }
+
+ /*
+ * We will write a probably given command line.
+ * First, erase the old area, then setup the new parameters:
+ */
+ if (command_line) {
+ memset(krnl_buffer + COMMAND_LINE_OFFS, 0, COMMAND_LINESIZE);
+ memcpy(krnl_buffer + COMMAND_LINE_OFFS, command_line, strlen(command_line));
+ }
+
+ info->entry = (void *) IMAGE_READ_OFFSET;
+
+ return 0;
+}
+
+int
+image_s390_probe(const char *kernel_buf, off_t kernel_size)
+{
+ /*
+ * Can't reliably tell if an image is valid,
+ * therefore everything is valid.
+ */
+ return 0;
+}
+
+void
+image_s390_usage(void)
+{
+ printf("--command-line=STRING Pass a custom command line STRING to the kernel.\n"
+ "--initrd=FILENAME Use the file FILENAME as a ramdisk.\n"
+ );
+}