OBS User unknown 2008-02-22 00:34:24 +00:00 committed by Git OBS Bridge
parent f195429c4b
commit 60fc4dc586
5 changed files with 26 additions and 321 deletions

View File

@ -1,308 +0,0 @@
This patch increases the kernel command line size for x86_64 and i386
to 2048 characters. This is necessary because with kernel 2.6.20-rc6-mm
and newer, the kernel command line size has increased and kexec needs
lot of command line space, so this solves some "command line overflow"
problems.
To be able to warn users running older kernels that the command line
is too long (and don't wait that the kernel truncates it), the
patch tries to get the kernel command line length from the kernel
image that is loaded if possible by checking the length of the
static array that holds the kernel command line when booting.
If this is not possible or the command line is not in the range
[256; 2048], the default value is used (2048).
Signed-off-by: Bernhard Walle <bwalle@suse.de>
---
include/x86/x86-linux.h | 8 ++-----
kexec/arch/i386/crashdump-x86.c | 36 ++++++++++++++++++++++++++++++++---
kexec/arch/i386/crashdump-x86.h | 5 ++++
kexec/arch/i386/kexec-bzImage.c | 8 +++----
kexec/arch/i386/kexec-elf-x86.c | 8 +++----
kexec/arch/i386/x86-linux-setup.c | 6 +++--
kexec/arch/x86_64/crashdump-x86_64.c | 35 +++++++++++++++++++++++++++++++---
kexec/arch/x86_64/crashdump-x86_64.h | 3 ++
kexec/arch/x86_64/kexec-elf-x86_64.c | 11 ++++++----
9 files changed, 95 insertions(+), 25 deletions(-)
--- a/include/x86/x86-linux.h
+++ b/include/x86/x86-linux.h
@@ -148,14 +148,12 @@ struct x86_linux_param_header {
#endif
struct e820entry e820_map[E820MAX]; /* 0x2d0 */
/* 0x550 */
-#define COMMAND_LINE_SIZE 256
+#define COMMAND_LINE_SIZE 2048
};
struct x86_linux_faked_param_header {
- struct x86_linux_param_header hdr; /* 0x00 */
- uint8_t reserved16[688]; /* 0x550 */
- uint8_t command_line[COMMAND_LINE_SIZE]; /* 0x800 */
- uint8_t reserved17[1792]; /* 0x900 - 0x1000 */
+ struct x86_linux_param_header hdr;
+ uint8_t command_line[COMMAND_LINE_SIZE];
};
struct x86_linux_header {
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -46,6 +46,36 @@ static struct memory_range crash_memory_
/* Memory region reserved for storing panic kernel and other data. */
static struct memory_range crash_reserved_mem;
+/* real length of the command line from the kernel image, needed because
+ * command line size on x86-64 was increased recently in -mm tree */
+int real_command_line_size = COMMAND_LINE_SIZE;
+
+
+/* Tries to read the kernel command line size from the symbol table
+ * of the ELF kernel binary. */
+void set_command_line_size(struct mem_ehdr *ehdr)
+{
+ int ret;
+ struct mem_sym mem_sym;
+
+ /* > 2.6.20-rc6-mm */
+ ret = elf_rel_find_symbol(ehdr, "saved_command_line", &mem_sym);
+ if (ret != 0) {
+ /* older kernel */
+ ret = elf_rel_find_symbol(ehdr, "boot_command_line", &mem_sym);
+ if (ret != 0) {
+ return;
+ }
+ }
+
+ /* current -mm kernel */
+ if (mem_sym.st_size >= 256 && mem_sym.st_size < COMMAND_LINE_SIZE) {
+ real_command_line_size = mem_sym.st_size;
+ return;
+ }
+}
+
+
/* Reads the appropriate file and retrieves the SYSTEM RAM regions for whom to
* create Elf headers. Keeping it separate from get_memory_ranges() as
* requirements are different in the case of normal kexec and crashdumps.
@@ -363,7 +393,7 @@ static int cmdline_add_memmap(char *cmdl
strcpy(str_mmap, " memmap=exactmap");
len = strlen(str_mmap);
cmdlen = strlen(cmdline) + len;
- if (cmdlen > (COMMAND_LINE_SIZE - 1))
+ if (cmdlen > (real_command_line_size - 1))
die("Command line overflow\n");
strcat(cmdline, str_mmap);
@@ -388,7 +418,7 @@ static int cmdline_add_memmap(char *cmdl
strcat (str_mmap, "K");
len = strlen(str_mmap);
cmdlen = strlen(cmdline) + len;
- if (cmdlen > (COMMAND_LINE_SIZE - 1))
+ if (cmdlen > (real_command_line_size - 1))
die("Command line overflow\n");
strcat(cmdline, str_mmap);
}
@@ -418,7 +448,7 @@ static int cmdline_add_elfcorehdr(char *
strcat(str, "K");
len = strlen(str);
cmdlen = strlen(cmdline) + len;
- if (cmdlen > (COMMAND_LINE_SIZE - 1))
+ if (cmdlen > (real_command_line_size - 1))
die("Command line overflow\n");
strcat(cmdline, str);
#if 0
--- a/kexec/arch/i386/crashdump-x86.h
+++ b/kexec/arch/i386/crashdump-x86.h
@@ -2,8 +2,11 @@
#define CRASHDUMP_X86_H
struct kexec_info;
+struct mem_ehdr;
int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline,
unsigned long max_addr, unsigned long min_base);
+void set_command_line_size(struct mem_ehdr *ehdr);
+
#define PAGE_OFFSET 0xc0000000
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
@@ -19,4 +22,6 @@ int load_crashdump_segments(struct kexec
#define BACKUP_SRC_END 0x0009ffff
#define BACKUP_SRC_SIZE (BACKUP_SRC_END - BACKUP_SRC_START + 1)
+extern int real_command_line_size;
+
#endif /* CRASHDUMP_X86_H */
--- a/kexec/arch/i386/kexec-bzImage.c
+++ b/kexec/arch/i386/kexec-bzImage.c
@@ -156,12 +156,12 @@ int do_bzImage_load(struct kexec_info *i
* taking crash dumps.
*/
if (info->kexec_flags & KEXEC_ON_CRASH) {
- modified_cmdline = xmalloc(COMMAND_LINE_SIZE);
- memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE);
+ modified_cmdline = xmalloc(real_command_line_size);
+ memset((void *)modified_cmdline, 0, real_command_line_size);
if (command_line) {
strncpy(modified_cmdline, command_line,
- COMMAND_LINE_SIZE);
- modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0';
+ real_command_line_size);
+ modified_cmdline[real_command_line_size - 1] = '\0';
}
/* If panic kernel is being loaded, additional segments need
--- a/kexec/arch/i386/kexec-elf-x86.c
+++ b/kexec/arch/i386/kexec-elf-x86.c
@@ -166,12 +166,12 @@ int elf_x86_load(int argc, char **argv,
* taking crash dumps.
*/
if (info->kexec_flags & KEXEC_ON_CRASH) {
- modified_cmdline = xmalloc(COMMAND_LINE_SIZE);
- memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE);
+ modified_cmdline = xmalloc(real_command_line_size);
+ memset((void *)modified_cmdline, 0, real_command_line_size);
if (command_line) {
strncpy(modified_cmdline, command_line,
- COMMAND_LINE_SIZE);
- modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0';
+ real_command_line_size);
+ modified_cmdline[real_command_line_size - 1] = '\0';
}
modified_cmdline_len = strlen(modified_cmdline);
}
--- a/kexec/arch/i386/x86-linux-setup.c
+++ b/kexec/arch/i386/x86-linux-setup.c
@@ -32,6 +32,8 @@
#include "kexec-x86.h"
#include "x86-linux-setup.h"
+extern int real_command_line_size;
+
void init_linux_parameters(struct x86_linux_param_header *real_mode)
{
/* Fill in the values that are usually provided by the kernel. */
@@ -91,8 +93,8 @@ void setup_linux_bootloader_parameters(
}
/* Fill in the command line */
- if (cmdline_len > COMMAND_LINE_SIZE) {
- cmdline_len = COMMAND_LINE_SIZE;
+ if (cmdline_len > real_command_line_size) {
+ cmdline_len = real_command_line_size;
}
cmdline_ptr = ((char *)real_mode) + cmdline_offset;
memcpy(cmdline_ptr, cmdline, cmdline_len);
--- a/kexec/arch/x86_64/crashdump-x86_64.c
+++ b/kexec/arch/x86_64/crashdump-x86_64.c
@@ -50,6 +50,35 @@ static struct crash_elf_info elf_info =
/* Forward Declaration. */
static int exclude_crash_reserve_region(int *nr_ranges);
+/* real length of the command line from the kernel image, needed because
+ * command line size on x86-64 was increased recently in -mm tree */
+int real_command_line_size = COMMAND_LINE_SIZE;
+
+
+/* Tries to read the kernel command line size from the symbol table
+ * of the ELF kernel binary. */
+void set_command_line_size(struct mem_ehdr *ehdr)
+{
+ int ret;
+ struct mem_sym mem_sym;
+
+ /* > 2.6.20-rc6-mm */
+ ret = elf_rel_find_symbol(ehdr, "saved_command_line", &mem_sym);
+ if (ret != 0) {
+ /* older kernel */
+ ret = elf_rel_find_symbol(ehdr, "boot_command_line", &mem_sym);
+ if (ret != 0) {
+ return;
+ }
+ }
+
+ /* current -mm kernel */
+ if (mem_sym.st_size >= 256 && mem_sym.st_size < COMMAND_LINE_SIZE) {
+ real_command_line_size = mem_sym.st_size;
+ return;
+ }
+}
+
#define KERN_VADDR_ALIGN 0x100000 /* 1MB */
/* Read kernel physical load addr from the file returned by proc_iomem()
@@ -494,7 +523,7 @@ static int cmdline_add_memmap(char *cmdl
strcat (str_mmap, "K");
len = strlen(str_mmap);
cmdlen = strlen(cmdline) + len;
- if (cmdlen > (COMMAND_LINE_SIZE - 1))
+ if (cmdlen > (real_command_line_size - 1))
die("Command line overflow\n");
strcat(cmdline, str_mmap);
}
@@ -523,7 +552,7 @@ static int cmdline_add_elfcorehdr(char *
strcat(str, "K");
len = strlen(str);
cmdlen = strlen(cmdline) + len;
- if (cmdlen > (COMMAND_LINE_SIZE - 1))
+ if (cmdlen > (real_command_line_size - 1))
die("Command line overflow\n");
strcat(cmdline, str);
#ifdef DEBUG
@@ -555,7 +584,7 @@ static int cmdline_add_memmap_acpi(char
strcat (str_mmap, "K");
len = strlen(str_mmap);
cmdlen = strlen(cmdline) + len;
- if (cmdlen > (COMMAND_LINE_SIZE - 1))
+ if (cmdlen > (real_command_line_size - 1))
die("Command line overflow\n");
strcat(cmdline, str_mmap);
--- a/kexec/arch/x86_64/crashdump-x86_64.h
+++ b/kexec/arch/x86_64/crashdump-x86_64.h
@@ -3,6 +3,7 @@
int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline,
unsigned long max_addr, unsigned long min_base);
+void set_command_line_size(struct mem_ehdr *ehdr);
#define __START_KERNEL_map 0xffffffff80000000UL
#define PAGE_OFFSET 0xffff810000000000UL
@@ -21,4 +22,6 @@ int load_crashdump_segments(struct kexec
#define BACKUP_SRC_END 0x0009ffff
#define BACKUP_SRC_SIZE (BACKUP_SRC_END - BACKUP_SRC_START + 1)
+extern int real_command_line_size;
+
#endif /* CRASHDUMP_X86_64_H */
--- a/kexec/arch/x86_64/kexec-elf-x86_64.c
+++ b/kexec/arch/x86_64/kexec-elf-x86_64.c
@@ -166,12 +166,12 @@ int elf_x86_64_load(int argc, char **arg
* taking crash dumps.
*/
if (info->kexec_flags & KEXEC_ON_CRASH) {
- modified_cmdline = xmalloc(COMMAND_LINE_SIZE);
- memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE);
+ modified_cmdline = xmalloc(real_command_line_size);
+ memset((void *)modified_cmdline, 0, real_command_line_size);
if (command_line) {
strncpy(modified_cmdline, command_line,
- COMMAND_LINE_SIZE);
- modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0';
+ real_command_line_size);
+ modified_cmdline[real_command_line_size - 1] = '\0';
}
modified_cmdline_len = strlen(modified_cmdline);
}
@@ -182,6 +182,9 @@ int elf_x86_64_load(int argc, char **arg
entry = ehdr.e_entry;
max_addr = elf_max_addr(&ehdr);
+ /* try to set the command line size correctly */
+ set_command_line_size(&ehdr);
+
/* Do we want arguments? */
if (arg_style != ARG_STYLE_NONE) {
/* Load the setup code */

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b3ded4283e7b26e502c26dc6bf47ab6a562d004519c7244ff17c98d44dc33c93
size 300304

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:844b853c8a4ddfca15f5ca43a804454e2fd3881fb4b780c8df54e4a84024f5fa
size 207895

View File

@ -1,3 +1,12 @@
-------------------------------------------------------------------
Thu Feb 21 10:55:57 CET 2008 - bwalle@suse.de
- update to kexec-tools-testing v20080221-rc
o Only include needed files in distribution tarball
o Clean up whitespace in include/x86/x86-linux.h
o Kexec command line length
- removed kexec-longer-cmdline.diff: fixed mainline differently
-------------------------------------------------------------------
Wed Feb 20 08:30:37 CET 2008 - bwalle@suse.de

View File

@ -16,23 +16,22 @@ Name: kexec-tools
%ifarch ppc
BuildRequires: gcc-64bit glibc-devel-64bit
%endif
%define package_version testing-20080219-rc
%define package_version testing-20080221-rc
License: GPL v2 or later
Group: System/Kernel
Requires: %insserv_prereq %fillup_prereq
AutoReqProv: on
Summary: Tools for fast kernel loading
Version: 1.101
Release: 169
Release: 171
Source: %{name}-%{package_version}.tar.bz2
Source1: README.SUSE
Url: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: zlib-devel
Patch1: kexec-longer-cmdline.diff
Patch2: kexec-tools.ppc32-64bit-purgatory.patch
Patch3: kexec-tools.gcc-bug.patch
Patch4: kexec-tools-portability-issue
BuildRequires: autoconf zlib-devel
Patch1: kexec-tools.ppc32-64bit-purgatory.patch
Patch2: kexec-tools.gcc-bug.patch
Patch3: kexec-tools-portability-issue
%description
Kexec is a user space utility for loading another kernel and asking the
@ -56,7 +55,6 @@ Authors:
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%build
%{?suse_update_config -f}
@ -64,6 +62,7 @@ cp %{SOURCE1} .
%ifarch ia64
RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS | sed -e 's/-fstack-protector//')
%endif
autoconf
CFLAGS=$RPM_OPT_FLAGS ./configure \
--prefix=/ \
%ifarch ppc
@ -71,8 +70,7 @@ CFLAGS=$RPM_OPT_FLAGS ./configure \
--build=powerpc64-suse-linux \
%endif
--sbindir=/sbin \
--libdir=/%_lib
make clean
--libdir=/%_lib || true
make #CPPFLAGS="$RPM_OPT_FLAGS"
%install
@ -93,6 +91,12 @@ install -c -m 0644 kexec/kexec.8 $RPM_BUILD_ROOT%{_mandir}/man8
%endif
%changelog
* Thu Feb 21 2008 bwalle@suse.de
- update to kexec-tools-testing v20080221-rc
o Only include needed files in distribution tarball
o Clean up whitespace in include/x86/x86-linux.h
o Kexec command line length
- removed kexec-longer-cmdline.diff: fixed mainline differently
* Wed Feb 20 2008 bwalle@suse.de
- update to kexec-tools-testing v20080219-rc
o Fix the feature determining ELF32/ELF64 automatically