Skip to content

Commit

Permalink
kexec: create a new config option CONFIG_KEXEC_FILE for new syscall
Browse files Browse the repository at this point in the history
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 <[email protected]>
Cc: Eric Biederman <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Tested-by: Shaun Ruffell <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
rhvgoyal authored and torvalds committed Aug 29, 2014
1 parent b38af47 commit 74ca317
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 20 deletions.
4 changes: 1 addition & 3 deletions arch/x86/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,4 @@ obj-$(CONFIG_IA32_EMULATION) += ia32/
obj-y += platform/
obj-y += net/

ifeq ($(CONFIG_X86_64),y)
obj-$(CONFIG_KEXEC) += purgatory/
endif
obj-$(CONFIG_KEXEC_FILE) += purgatory/
18 changes: 14 additions & 4 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1585,9 +1585,6 @@ source kernel/Kconfig.hz

config KEXEC
bool "kexec system call"
select BUILD_BIN2C
select CRYPTO
select CRYPTO_SHA256
---help---
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
Expand All @@ -1602,9 +1599,22 @@ config KEXEC
interface is strongly in flux, so no good recommendation can be
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
bool "Verify kernel signature during kexec_file_load() syscall"
depends on KEXEC
depends on KEXEC_FILE
---help---
This option makes kernel signature verification mandatory for
kexec_file_load() syscall. If kernel is signature can not be
Expand Down
5 changes: 1 addition & 4 deletions arch/x86/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,8 @@ archheaders:
$(Q)$(MAKE) $(build)=arch/x86/syscalls all

archprepare:
ifeq ($(CONFIG_KEXEC),y)
# Build only for 64bit. No loaders for 32bit yet.
ifeq ($(CONFIG_X86_64),y)
ifeq ($(CONFIG_KEXEC_FILE),y)
$(Q)$(MAKE) $(build)=arch/x86/purgatory arch/x86/purgatory/kexec-purgatory.c
endif
endif

###
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
obj-$(CONFIG_X86_TSC) += trace_clock.o
obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).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-y += kprobes/
obj-$(CONFIG_MODULES) += module.o
Expand Down Expand Up @@ -118,5 +119,4 @@ ifeq ($(CONFIG_X86_64),y)

obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o
obj-y += vsmp_64.o
obj-$(CONFIG_KEXEC) += kexec-bzimage64.o
endif
6 changes: 2 additions & 4 deletions arch/x86/kernel/crash.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,7 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
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,
unsigned long nr_pfn, void *arg)
{
Expand Down Expand Up @@ -696,5 +695,4 @@ int crash_load_segments(struct kimage *image)

return ret;
}

#endif /* CONFIG_X86_64 */
#endif /* CONFIG_KEXEC_FILE */
11 changes: 11 additions & 0 deletions arch/x86/kernel/machine_kexec_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
#include <asm/debugreg.h>
#include <asm/kexec-bzimage64.h>

#ifdef CONFIG_KEXEC_FILE
static struct kexec_file_ops *kexec_file_loaders[] = {
&kexec_bzImage64_ops,
};
#endif

static void free_transition_pgtable(struct kimage *image)
{
Expand Down Expand Up @@ -178,6 +180,7 @@ static void load_segments(void)
);
}

#ifdef CONFIG_KEXEC_FILE
/* Update purgatory as needed after various image segments have been prepared */
static int arch_update_purgatory(struct kimage *image)
{
Expand Down Expand Up @@ -209,6 +212,12 @@ static int arch_update_purgatory(struct kimage *image)

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)
{
Expand Down Expand Up @@ -329,6 +338,7 @@ void arch_crash_save_vmcoreinfo(void)

/* arch-dependent functionality related to kexec file-based syscall */

#ifdef CONFIG_KEXEC_FILE
int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
unsigned long buf_len)
{
Expand Down Expand Up @@ -522,3 +532,4 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
(int)ELF64_R_TYPE(rel[i].r_info), value);
return -ENOEXEC;
}
#endif /* CONFIG_KEXEC_FILE */
5 changes: 1 addition & 4 deletions arch/x86/purgatory/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,4 @@ $(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE
$(call if_changed,bin2c)


# No loaders for 32bits yet.
ifeq ($(CONFIG_X86_64),y)
obj-$(CONFIG_KEXEC) += kexec-purgatory.o
endif
obj-$(CONFIG_KEXEC_FILE) += kexec-purgatory.o
11 changes: 11 additions & 0 deletions kernel/kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ bool kexec_in_progress = false;
char __weak kexec_purgatory[0];
size_t __weak kexec_purgatory_size = 0;

#ifdef CONFIG_KEXEC_FILE
static int kexec_calculate_store_digests(struct kimage *image);
#endif

/* Location of the reserved area for the crash kernel */
struct resource crashk_res = {
Expand Down Expand Up @@ -341,6 +343,7 @@ static int kimage_alloc_init(struct kimage **rimage, unsigned long entry,
return ret;
}

#ifdef CONFIG_KEXEC_FILE
static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len)
{
struct fd f = fdget(fd);
Expand Down Expand Up @@ -612,6 +615,9 @@ kimage_file_alloc_init(struct kimage **rimage, int kernel_fd,
kfree(image);
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,
unsigned long start,
Expand Down Expand Up @@ -1375,6 +1381,7 @@ COMPAT_SYSCALL_DEFINE4(kexec_load, compat_ulong_t, entry,
}
#endif

#ifdef CONFIG_KEXEC_FILE
SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
unsigned long, cmdline_len, const char __user *, cmdline_ptr,
unsigned long, flags)
Expand Down Expand Up @@ -1451,6 +1458,8 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
return ret;
}

#endif /* CONFIG_KEXEC_FILE */

void crash_kexec(struct pt_regs *regs)
{
/* Take the kexec_mutex here to prevent sys_kexec_load
Expand Down Expand Up @@ -2006,6 +2015,7 @@ static int __init crash_save_vmcoreinfo_init(void)

subsys_initcall(crash_save_vmcoreinfo_init);

#ifdef CONFIG_KEXEC_FILE
static int __kexec_add_segment(struct kimage *image, char *buf,
unsigned long bufsz, unsigned long mem,
unsigned long memsz)
Expand Down Expand Up @@ -2682,6 +2692,7 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,

return 0;
}
#endif /* CONFIG_KEXEC_FILE */

/*
* Move into place and start executing a preloaded standalone
Expand Down

0 comments on commit 74ca317

Please sign in to comment.