From 7c3109cb6c5e1834bb3b6f788c9dcaa0ddbdf090 Mon Sep 17 00:00:00 2001 From: Jamey Sharp Date: Thu, 15 May 2008 22:42:10 -0700 Subject: [PATCH] Factor uname-based native architecture detection into a common function. This code was copy-pasted into every architecture and was basically identical. Besides producing a nice net reduction in code, this factors a portability challenge into a single function that can be easily replaced at build-time. Signed-off-by: Jamey Sharp Signed-off-by: Simon Horman --- kexec/Makefile | 1 + kexec/arch/arm/kexec-arm.c | 23 +++++------------------ kexec/arch/i386/kexec-x86.c | 39 +++++++++++++-------------------------- kexec/arch/ia64/kexec-ia64.c | 23 +++++------------------ kexec/arch/mips/kexec-mips.c | 29 ++++++++--------------------- kexec/arch/ppc/kexec-ppc.c | 29 ++++++++--------------------- kexec/arch/ppc64/kexec-ppc64.c | 29 ++++++++--------------------- kexec/arch/s390/kexec-s390.c | 8 ++++++-- kexec/arch/sh/kexec-sh.c | 34 ++++++++++------------------------ kexec/arch/x86_64/kexec-x86_64.c | 29 ++++++++--------------------- kexec/kexec.c | 6 ++++++ kexec/kexec.h | 9 +++++++++ kexec/phys_arch.c | 23 +++++++++++++++++++++++ 13 files changed, 110 insertions(+), 172 deletions(-) --- a/kexec/Makefile +++ b/kexec/Makefile @@ -20,6 +20,7 @@ KEXEC_SRCS += kexec/kexec-elf-boot.c KEXEC_SRCS += kexec/kexec-iomem.c KEXEC_SRCS += kexec/crashdump.c KEXEC_SRCS += kexec/crashdump-xen.c +KEXEC_SRCS += kexec/phys_arch.c KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C) --- a/kexec/arch/arm/kexec-arm.c +++ b/kexec/arch/arm/kexec-arm.c @@ -12,7 +12,6 @@ #include #include #include -#include #include "../../kexec.h" #include "../../kexec-syscall.h" #include "kexec-arm.h" @@ -109,25 +108,13 @@ int arch_process_options(int argc, char return 0; } +const struct arch_map_entry arches[] = { + { "arm", KEXEC_ARCH_ARM }, + { 0 }, +}; + int arch_compat_trampoline(struct kexec_info *info) { - int result; - struct utsname utsname; - result = uname(&utsname); - if (result < 0) { - fprintf(stderr, "uname failed: %s\n", - strerror(errno)); - return -1; - } - if (strncmp(utsname.machine, "arm",3) == 0) - { - info->kexec_flags |= KEXEC_ARCH_ARM; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", - utsname.machine); - return -1; - } return 0; } --- a/kexec/arch/i386/kexec-x86.c +++ b/kexec/arch/i386/kexec-x86.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "../../kexec.h" #include "../../kexec-elf.h" #include "../../kexec-syscall.h" @@ -223,29 +222,22 @@ int arch_process_options(int argc, char return 0; } +const struct arch_map_entry arches[] = { + /* For compatibility with older patches + * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_386 here. + */ + { "i386", KEXEC_ARCH_DEFAULT }, + { "i486", KEXEC_ARCH_DEFAULT }, + { "i586", KEXEC_ARCH_DEFAULT }, + { "i686", KEXEC_ARCH_DEFAULT }, + { "x86_64", KEXEC_ARCH_X86_64 }, + { 0 }, +}; + int arch_compat_trampoline(struct kexec_info *info) { - int result; - struct utsname utsname; - result = uname(&utsname); - if (result < 0) { - fprintf(stderr, "uname failed: %s\n", - strerror(errno)); - return -1; - } - if ( (strcmp(utsname.machine, "i386") == 0) || - (strcmp(utsname.machine, "i486") == 0) || - (strcmp(utsname.machine, "i586") == 0) || - (strcmp(utsname.machine, "i686") == 0)) + if ((info->kexec_flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_X86_64) { - /* For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_386 here. - */ - info->kexec_flags |= KEXEC_ARCH_DEFAULT; - } - else if (strcmp(utsname.machine, "x86_64") == 0) - { - info->kexec_flags |= KEXEC_ARCH_X86_64; if (!info->rhdr.e_shdr) { fprintf(stderr, "A trampoline is required for cross architecture support\n"); @@ -256,11 +248,6 @@ int arch_compat_trampoline(struct kexec_ info->entry = (void *)elf_rel_get_addr(&info->rhdr, "compat_x86_64"); } - else { - fprintf(stderr, "Unsupported machine type: %s\n", - utsname.machine); - return -1; - } return 0; } --- a/kexec/arch/ia64/kexec-ia64.c +++ b/kexec/arch/ia64/kexec-ia64.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "../../kexec.h" #include "../../kexec-syscall.h" @@ -204,25 +203,13 @@ int arch_process_options(int argc, char return 0; } +const struct arch_map_entry arches[] = { + { "ia64", KEXEC_ARCH_IA_64 }, + { 0 }, +}; + int arch_compat_trampoline(struct kexec_info *info) { - int result; - struct utsname utsname; - result = uname(&utsname); - if (result < 0) { - fprintf(stderr, "uname failed: %s\n", - strerror(errno)); - return -1; - } - if (strcmp(utsname.machine, "ia64") == 0) - { - info->kexec_flags |= KEXEC_ARCH_IA_64; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", - utsname.machine); - return -1; - } return 0; } --- a/kexec/arch/mips/kexec-mips.c +++ b/kexec/arch/mips/kexec-mips.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "../../kexec.h" #include "../../kexec-syscall.h" #include "kexec-mips.h" @@ -122,28 +121,16 @@ int arch_process_options(int argc, char return 0; } +const struct arch_map_entry arches[] = { + /* For compatibility with older patches + * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_MIPS here. + */ + { "mips", KEXEC_ARCH_DEFAULT }, + { 0 }, +}; + int arch_compat_trampoline(struct kexec_info *info) { - int result; - struct utsname utsname; - result = uname(&utsname); - if (result < 0) { - fprintf(stderr, "uname failed: %s\n", - strerror(errno)); - return -1; - } - if (strcmp(utsname.machine, "mips") == 0) - { - /* For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_MIPS here. - */ - info->kexec_flags |= KEXEC_ARCH_DEFAULT; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", - utsname.machine); - return -1; - } return 0; } --- a/kexec/arch/ppc/kexec-ppc.c +++ b/kexec/arch/ppc/kexec-ppc.c @@ -12,7 +12,6 @@ #include #include #include -#include #include "../../kexec.h" #include "../../kexec-syscall.h" #include "kexec-ppc.h" @@ -117,28 +116,16 @@ int arch_process_options(int argc, char return 0; } +const struct arch_map_entry arches[] = { + /* For compatibility with older patches + * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_PPC here. + */ + { "ppc", KEXEC_ARCH_DEFAULT }, + { 0 }, +}; + int arch_compat_trampoline(struct kexec_info *info) { - int result; - struct utsname utsname; - result = uname(&utsname); - if (result < 0) { - fprintf(stderr, "uname failed: %s\n", - strerror(errno)); - return -1; - } - if (strcmp(utsname.machine, "ppc") == 0) - { - /* For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_PPC here. - */ - info->kexec_flags |= KEXEC_ARCH_DEFAULT; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", - utsname.machine); - return -1; - } return 0; } --- a/kexec/arch/ppc64/kexec-ppc64.c +++ b/kexec/arch/ppc64/kexec-ppc64.c @@ -28,7 +28,6 @@ #include #include #include -#include #include "../../kexec.h" #include "../../kexec-syscall.h" #include "kexec-ppc64.h" @@ -681,28 +680,16 @@ int arch_process_options(int argc, char return 0; } +const struct arch_map_entry arches[] = { + /* We are running a 32-bit kexec-tools on 64-bit ppc64. + * So pass KEXEC_ARCH_PPC64 here + */ + { "ppc64", KEXEC_ARCH_PPC64 }, + { 0 }, +}; + int arch_compat_trampoline(struct kexec_info *info) { - int result; - struct utsname utsname; - result = uname(&utsname); - if (result < 0) { - fprintf(stderr, "uname failed: %s\n", - strerror(errno)); - return -1; - } - if (strcmp(utsname.machine, "ppc64") == 0) - { - /* We are running a 32-bit kexec-tools on 64-bit ppc64. - * So pass KEXEC_ARCH_PPC64 here - */ - info->kexec_flags |= KEXEC_ARCH_PPC64; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", - utsname.machine); - return -1; - } return 0; } --- a/kexec/arch/s390/kexec-s390.c +++ b/kexec/arch/s390/kexec-s390.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "../../kexec.h" #include "../../kexec-syscall.h" #include "kexec-s390.h" @@ -95,9 +94,14 @@ int arch_process_options(int argc, char return 0; } +const struct arch_map_entry arches[] = { + { "s390", KEXEC_ARCH_S390 }, + { "s390x", KEXEC_ARCH_S390 }, + { 0 }, +}; + int arch_compat_trampoline(struct kexec_info *info) { - info->kexec_flags |= KEXEC_ARCH_S390; return 0; } --- a/kexec/arch/sh/kexec-sh.c +++ b/kexec/arch/sh/kexec-sh.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "../../kexec.h" #include "../../kexec-syscall.h" #include "kexec-sh.h" @@ -99,31 +98,18 @@ int arch_process_options(int argc, char return 0; } +const struct arch_map_entry arches[] = { + /* For compatibility with older patches + * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_SH here. + */ + { "sh3", KEXEC_ARCH_DEFAULT }, + { "sh4", KEXEC_ARCH_DEFAULT }, + { "sh4a", KEXEC_ARCH_DEFAULT }, + { 0 }, +}; + int arch_compat_trampoline(struct kexec_info *info) { - int result; - struct utsname utsname; - result = uname(&utsname); - if (result < 0) { - fprintf(stderr, "uname failed: %s\n", - strerror(errno)); - return -1; - } - if ( (strcmp(utsname.machine, "sh3") == 0) || - (strcmp(utsname.machine, "sh4") == 0) || - (strcmp(utsname.machine, "sh4a") == 0)) - { - /* - * For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_SH here. - */ - info->kexec_flags |= KEXEC_ARCH_DEFAULT; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", - utsname.machine); - return -1; - } return 0; } --- a/kexec/arch/x86_64/kexec-x86_64.c +++ b/kexec/arch/x86_64/kexec-x86_64.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "../../kexec.h" #include "../../kexec-elf.h" #include "../../kexec-syscall.h" @@ -224,28 +223,16 @@ int arch_process_options(int argc, char return 0; } +const struct arch_map_entry arches[] = { + /* For compatibility with older patches + * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_X86_64 here. + */ + { "x86_64", KEXEC_ARCH_DEFAULT }, + { 0 }, +}; + int arch_compat_trampoline(struct kexec_info *info) { - int result; - struct utsname utsname; - result = uname(&utsname); - if (result < 0) { - fprintf(stderr, "uname failed: %s\n", - strerror(errno)); - return -1; - } - if (strcmp(utsname.machine, "x86_64") == 0) - { - /* For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_X86_64 here. - */ - info->kexec_flags |= KEXEC_ARCH_DEFAULT; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", - utsname.machine); - return -1; - } return 0; } --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -607,6 +607,7 @@ static int my_load(const char *type, int int i = 0; int result; struct kexec_info info; + long native_arch; int guess_only = 0; memset(&info, 0, sizeof(info)); @@ -674,6 +675,11 @@ static int my_load(const char *type, int return -1; } /* If we are not in native mode setup an appropriate trampoline */ + native_arch = physical_arch(); + if (native_arch < 0) { + return -1; + } + info.kexec_flags |= native_arch; if (arch_compat_trampoline(&info) < 0) { return -1; } --- a/kexec/kexec.h +++ b/kexec/kexec.h @@ -4,6 +4,7 @@ #include "config.h" #include +#include #include #define USE_BSD #include @@ -125,6 +126,14 @@ struct kexec_info { unsigned long kern_size; }; +struct arch_map_entry { + const char *machine; + unsigned long arch; +}; + +extern const struct arch_map_entry arches[]; +long physical_arch(void); + void usage(void); int get_memory_ranges(struct memory_range **range, int *ranges, unsigned long kexec_flags); --- /dev/null +++ b/kexec/phys_arch.c @@ -0,0 +1,23 @@ +#include "kexec.h" +#include +#include +#include + +long physical_arch(void) +{ + struct utsname utsname; + int i, result = uname(&utsname); + if (result < 0) { + fprintf(stderr, "uname failed: %s\n", + strerror(errno)); + return -1; + } + + for (i = 0; arches[i].machine; ++i) + if (strcmp(utsname.machine, arches[i].machine) == 0) + return arches[i].arch; + + fprintf(stderr, "Unsupported machine type: %s\n", + utsname.machine); + return -1; +}