kexec: create a new config option CONFIG_KEXEC_FILE for new syscall
Currently new system call kexec_file_load() and all the associated code compiles if CONFIG_KEXEC=y. But new syscall also compiles purgatory code which currently uses gcc option -mcmodel=large. This option seems to be available only gcc 4.4 onwards. Hiding new functionality behind a new config option will not break existing users of old gcc. Those who wish to enable new functionality will require new gcc. Having said that, I am trying to figure out how can I move away from using -mcmodel=large but that can take a while. I think there are other advantages of introducing this new config option. As this option will be enabled only on x86_64, other arches don't have to compile generic kexec code which will never be used. This new code selects CRYPTO=y and CRYPTO_SHA256=y. And all other arches had to do this for CONFIG_KEXEC. Now with introduction of new config option, we can remove crypto dependency from other arches. Now CONFIG_KEXEC_FILE is available only on x86_64. So whereever I had CONFIG_X86_64 defined, I got rid of that. For CONFIG_KEXEC_FILE, instead of doing select CRYPTO=y, I changed it to "depends on CRYPTO=y". This should be safer as "select" is not recursive. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Cc: Eric Biederman <ebiederm@xmission.com> Cc: H. Peter Anvin <hpa@zytor.com> Tested-by: Shaun Ruffell <sruffell@digium.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
b38af4721f
commit
74ca317c26
|
@ -17,6 +17,4 @@ obj-$(CONFIG_IA32_EMULATION) += ia32/
|
||||||
obj-y += platform/
|
obj-y += platform/
|
||||||
obj-y += net/
|
obj-y += net/
|
||||||
|
|
||||||
ifeq ($(CONFIG_X86_64),y)
|
obj-$(CONFIG_KEXEC_FILE) += purgatory/
|
||||||
obj-$(CONFIG_KEXEC) += purgatory/
|
|
||||||
endif
|
|
||||||
|
|
|
@ -1585,9 +1585,6 @@ source kernel/Kconfig.hz
|
||||||
|
|
||||||
config KEXEC
|
config KEXEC
|
||||||
bool "kexec system call"
|
bool "kexec system call"
|
||||||
select BUILD_BIN2C
|
|
||||||
select CRYPTO
|
|
||||||
select CRYPTO_SHA256
|
|
||||||
---help---
|
---help---
|
||||||
kexec is a system call that implements the ability to shutdown your
|
kexec is a system call that implements the ability to shutdown your
|
||||||
current kernel, and to start another kernel. It is like a reboot
|
current kernel, and to start another kernel. It is like a reboot
|
||||||
|
@ -1602,9 +1599,22 @@ config KEXEC
|
||||||
interface is strongly in flux, so no good recommendation can be
|
interface is strongly in flux, so no good recommendation can be
|
||||||
made.
|
made.
|
||||||
|
|
||||||
|
config KEXEC_FILE
|
||||||
|
bool "kexec file based system call"
|
||||||
|
select BUILD_BIN2C
|
||||||
|
depends on KEXEC
|
||||||
|
depends on X86_64
|
||||||
|
depends on CRYPTO=y
|
||||||
|
depends on CRYPTO_SHA256=y
|
||||||
|
---help---
|
||||||
|
This is new version of kexec system call. This system call is
|
||||||
|
file based and takes file descriptors as system call argument
|
||||||
|
for kernel and initramfs as opposed to list of segments as
|
||||||
|
accepted by previous system call.
|
||||||
|
|
||||||
config KEXEC_VERIFY_SIG
|
config KEXEC_VERIFY_SIG
|
||||||
bool "Verify kernel signature during kexec_file_load() syscall"
|
bool "Verify kernel signature during kexec_file_load() syscall"
|
||||||
depends on KEXEC
|
depends on KEXEC_FILE
|
||||||
---help---
|
---help---
|
||||||
This option makes kernel signature verification mandatory for
|
This option makes kernel signature verification mandatory for
|
||||||
kexec_file_load() syscall. If kernel is signature can not be
|
kexec_file_load() syscall. If kernel is signature can not be
|
||||||
|
|
|
@ -184,11 +184,8 @@ archheaders:
|
||||||
$(Q)$(MAKE) $(build)=arch/x86/syscalls all
|
$(Q)$(MAKE) $(build)=arch/x86/syscalls all
|
||||||
|
|
||||||
archprepare:
|
archprepare:
|
||||||
ifeq ($(CONFIG_KEXEC),y)
|
ifeq ($(CONFIG_KEXEC_FILE),y)
|
||||||
# Build only for 64bit. No loaders for 32bit yet.
|
|
||||||
ifeq ($(CONFIG_X86_64),y)
|
|
||||||
$(Q)$(MAKE) $(build)=arch/x86/purgatory arch/x86/purgatory/kexec-purgatory.c
|
$(Q)$(MAKE) $(build)=arch/x86/purgatory arch/x86/purgatory/kexec-purgatory.c
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
|
@ -71,6 +71,7 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
|
||||||
obj-$(CONFIG_X86_TSC) += trace_clock.o
|
obj-$(CONFIG_X86_TSC) += trace_clock.o
|
||||||
obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o
|
obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o
|
||||||
obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o
|
obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o
|
||||||
|
obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o
|
||||||
obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
|
obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
|
||||||
obj-y += kprobes/
|
obj-y += kprobes/
|
||||||
obj-$(CONFIG_MODULES) += module.o
|
obj-$(CONFIG_MODULES) += module.o
|
||||||
|
@ -118,5 +119,4 @@ ifeq ($(CONFIG_X86_64),y)
|
||||||
|
|
||||||
obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o
|
obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o
|
||||||
obj-y += vsmp_64.o
|
obj-y += vsmp_64.o
|
||||||
obj-$(CONFIG_KEXEC) += kexec-bzimage64.o
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -182,8 +182,7 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
|
||||||
crash_save_cpu(regs, safe_smp_processor_id());
|
crash_save_cpu(regs, safe_smp_processor_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_KEXEC_FILE
|
||||||
|
|
||||||
static int get_nr_ram_ranges_callback(unsigned long start_pfn,
|
static int get_nr_ram_ranges_callback(unsigned long start_pfn,
|
||||||
unsigned long nr_pfn, void *arg)
|
unsigned long nr_pfn, void *arg)
|
||||||
{
|
{
|
||||||
|
@ -696,5 +695,4 @@ int crash_load_segments(struct kimage *image)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_KEXEC_FILE */
|
||||||
#endif /* CONFIG_X86_64 */
|
|
||||||
|
|
|
@ -25,9 +25,11 @@
|
||||||
#include <asm/debugreg.h>
|
#include <asm/debugreg.h>
|
||||||
#include <asm/kexec-bzimage64.h>
|
#include <asm/kexec-bzimage64.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC_FILE
|
||||||
static struct kexec_file_ops *kexec_file_loaders[] = {
|
static struct kexec_file_ops *kexec_file_loaders[] = {
|
||||||
&kexec_bzImage64_ops,
|
&kexec_bzImage64_ops,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static void free_transition_pgtable(struct kimage *image)
|
static void free_transition_pgtable(struct kimage *image)
|
||||||
{
|
{
|
||||||
|
@ -178,6 +180,7 @@ static void load_segments(void)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC_FILE
|
||||||
/* Update purgatory as needed after various image segments have been prepared */
|
/* Update purgatory as needed after various image segments have been prepared */
|
||||||
static int arch_update_purgatory(struct kimage *image)
|
static int arch_update_purgatory(struct kimage *image)
|
||||||
{
|
{
|
||||||
|
@ -209,6 +212,12 @@ static int arch_update_purgatory(struct kimage *image)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#else /* !CONFIG_KEXEC_FILE */
|
||||||
|
static inline int arch_update_purgatory(struct kimage *image)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_KEXEC_FILE */
|
||||||
|
|
||||||
int machine_kexec_prepare(struct kimage *image)
|
int machine_kexec_prepare(struct kimage *image)
|
||||||
{
|
{
|
||||||
|
@ -329,6 +338,7 @@ void arch_crash_save_vmcoreinfo(void)
|
||||||
|
|
||||||
/* arch-dependent functionality related to kexec file-based syscall */
|
/* arch-dependent functionality related to kexec file-based syscall */
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC_FILE
|
||||||
int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
|
int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
|
||||||
unsigned long buf_len)
|
unsigned long buf_len)
|
||||||
{
|
{
|
||||||
|
@ -522,3 +532,4 @@ overflow:
|
||||||
(int)ELF64_R_TYPE(rel[i].r_info), value);
|
(int)ELF64_R_TYPE(rel[i].r_info), value);
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_KEXEC_FILE */
|
||||||
|
|
|
@ -24,7 +24,4 @@ $(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE
|
||||||
$(call if_changed,bin2c)
|
$(call if_changed,bin2c)
|
||||||
|
|
||||||
|
|
||||||
# No loaders for 32bits yet.
|
obj-$(CONFIG_KEXEC_FILE) += kexec-purgatory.o
|
||||||
ifeq ($(CONFIG_X86_64),y)
|
|
||||||
obj-$(CONFIG_KEXEC) += kexec-purgatory.o
|
|
||||||
endif
|
|
||||||
|
|
|
@ -64,7 +64,9 @@ bool kexec_in_progress = false;
|
||||||
char __weak kexec_purgatory[0];
|
char __weak kexec_purgatory[0];
|
||||||
size_t __weak kexec_purgatory_size = 0;
|
size_t __weak kexec_purgatory_size = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC_FILE
|
||||||
static int kexec_calculate_store_digests(struct kimage *image);
|
static int kexec_calculate_store_digests(struct kimage *image);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Location of the reserved area for the crash kernel */
|
/* Location of the reserved area for the crash kernel */
|
||||||
struct resource crashk_res = {
|
struct resource crashk_res = {
|
||||||
|
@ -341,6 +343,7 @@ out_free_image:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC_FILE
|
||||||
static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len)
|
static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len)
|
||||||
{
|
{
|
||||||
struct fd f = fdget(fd);
|
struct fd f = fdget(fd);
|
||||||
|
@ -612,6 +615,9 @@ out_free_image:
|
||||||
kfree(image);
|
kfree(image);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#else /* CONFIG_KEXEC_FILE */
|
||||||
|
static inline void kimage_file_post_load_cleanup(struct kimage *image) { }
|
||||||
|
#endif /* CONFIG_KEXEC_FILE */
|
||||||
|
|
||||||
static int kimage_is_destination_range(struct kimage *image,
|
static int kimage_is_destination_range(struct kimage *image,
|
||||||
unsigned long start,
|
unsigned long start,
|
||||||
|
@ -1375,6 +1381,7 @@ COMPAT_SYSCALL_DEFINE4(kexec_load, compat_ulong_t, entry,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC_FILE
|
||||||
SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
|
SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
|
||||||
unsigned long, cmdline_len, const char __user *, cmdline_ptr,
|
unsigned long, cmdline_len, const char __user *, cmdline_ptr,
|
||||||
unsigned long, flags)
|
unsigned long, flags)
|
||||||
|
@ -1451,6 +1458,8 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_KEXEC_FILE */
|
||||||
|
|
||||||
void crash_kexec(struct pt_regs *regs)
|
void crash_kexec(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
/* Take the kexec_mutex here to prevent sys_kexec_load
|
/* Take the kexec_mutex here to prevent sys_kexec_load
|
||||||
|
@ -2006,6 +2015,7 @@ static int __init crash_save_vmcoreinfo_init(void)
|
||||||
|
|
||||||
subsys_initcall(crash_save_vmcoreinfo_init);
|
subsys_initcall(crash_save_vmcoreinfo_init);
|
||||||
|
|
||||||
|
#ifdef CONFIG_KEXEC_FILE
|
||||||
static int __kexec_add_segment(struct kimage *image, char *buf,
|
static int __kexec_add_segment(struct kimage *image, char *buf,
|
||||||
unsigned long bufsz, unsigned long mem,
|
unsigned long bufsz, unsigned long mem,
|
||||||
unsigned long memsz)
|
unsigned long memsz)
|
||||||
|
@ -2682,6 +2692,7 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_KEXEC_FILE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move into place and start executing a preloaded standalone
|
* Move into place and start executing a preloaded standalone
|
||||||
|
|
Loading…
Reference in New Issue