mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	kexec: split kexec_load syscall from kexec core code
There are two kexec load syscalls, kexec_load another and kexec_file_load. kexec_file_load has been splited as kernel/kexec_file.c. In this patch I split kexec_load syscall code to kernel/kexec.c. And add a new kconfig option KEXEC_CORE, so we can disable kexec_load and use kexec_file_load only, or vice verse. The original requirement is from Ted Ts'o, he want kexec kernel signature being checked with CONFIG_KEXEC_VERIFY_SIG enabled. But kexec-tools use kexec_load syscall can bypass the checking. Vivek Goyal proposed to create a common kconfig option so user can compile in only one syscall for loading kexec kernel. KEXEC/KEXEC_FILE selects KEXEC_CORE so that old config files still work. Because there's general code need CONFIG_KEXEC_CORE, so I updated all the architecture Kconfig with a new option KEXEC_CORE, and let KEXEC selects KEXEC_CORE in arch Kconfig. Also updated general kernel code with to kexec_load syscall. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Dave Young <dyoung@redhat.com> Cc: Eric W. Biederman <ebiederm@xmission.com> Cc: Vivek Goyal <vgoyal@redhat.com> Cc: Petr Tesarik <ptesarik@suse.cz> Cc: Theodore Ts'o <tytso@mit.edu> Cc: Josh Boyer <jwboyer@fedoraproject.org> Cc: David Howells <dhowells@redhat.com> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									a43cac0d9d
								
							
						
					
					
						commit
						2965faa5e0
					
				
					 32 changed files with 1560 additions and 1527 deletions
				
			
		|  | @ -2,6 +2,9 @@ | |||
| # General architecture dependent options | ||||
| # | ||||
| 
 | ||||
| config KEXEC_CORE | ||||
| 	bool | ||||
| 
 | ||||
| config OPROFILE | ||||
| 	tristate "OProfile system profiling" | ||||
| 	depends on PROFILING | ||||
|  |  | |||
|  | @ -2020,6 +2020,7 @@ config KEXEC | |||
| 	bool "Kexec system call (EXPERIMENTAL)" | ||||
| 	depends on (!SMP || PM_SLEEP_SMP) | ||||
| 	depends on !CPU_V7M | ||||
| 	select KEXEC_CORE | ||||
| 	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 | ||||
|  |  | |||
|  | @ -518,6 +518,7 @@ source "drivers/sn/Kconfig" | |||
| config KEXEC | ||||
| 	bool "kexec system call" | ||||
| 	depends on !IA64_HP_SIM && (!SMP || HOTPLUG_CPU) | ||||
| 	select KEXEC_CORE | ||||
| 	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 | ||||
|  |  | |||
|  | @ -95,6 +95,7 @@ config MMU_SUN3 | |||
| config KEXEC | ||||
| 	bool "kexec system call" | ||||
| 	depends on M68KCLASSIC | ||||
| 	select KEXEC_CORE | ||||
| 	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 | ||||
|  |  | |||
|  | @ -2597,6 +2597,7 @@ source "kernel/Kconfig.preempt" | |||
| 
 | ||||
| config KEXEC | ||||
| 	bool "Kexec system call" | ||||
| 	select KEXEC_CORE | ||||
| 	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 | ||||
|  |  | |||
|  | @ -420,6 +420,7 @@ config PPC64_SUPPORTS_MEMORY_FAILURE | |||
| config KEXEC | ||||
| 	bool "kexec system call" | ||||
| 	depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) | ||||
| 	select KEXEC_CORE | ||||
| 	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 | ||||
|  |  | |||
|  | @ -48,6 +48,7 @@ config ARCH_SUPPORTS_DEBUG_PAGEALLOC | |||
| 
 | ||||
| config KEXEC | ||||
| 	def_bool y | ||||
| 	select KEXEC_CORE | ||||
| 
 | ||||
| config AUDIT_ARCH | ||||
| 	def_bool y | ||||
|  |  | |||
|  | @ -602,6 +602,7 @@ source kernel/Kconfig.hz | |||
| config KEXEC | ||||
| 	bool "kexec system call (EXPERIMENTAL)" | ||||
| 	depends on SUPERH32 && MMU | ||||
| 	select KEXEC_CORE | ||||
| 	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 | ||||
|  |  | |||
|  | @ -205,6 +205,7 @@ source "kernel/Kconfig.hz" | |||
| 
 | ||||
| config KEXEC | ||||
| 	bool "kexec system call" | ||||
| 	select KEXEC_CORE | ||||
| 	---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 | ||||
|  |  | |||
|  | @ -1754,6 +1754,7 @@ source kernel/Kconfig.hz | |||
| 
 | ||||
| config KEXEC | ||||
| 	bool "kexec system call" | ||||
| 	select KEXEC_CORE | ||||
| 	---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 | ||||
|  | @ -1770,8 +1771,8 @@ config KEXEC | |||
| 
 | ||||
| config KEXEC_FILE | ||||
| 	bool "kexec file based system call" | ||||
| 	select KEXEC_CORE | ||||
| 	select BUILD_BIN2C | ||||
| 	depends on KEXEC | ||||
| 	depends on X86_64 | ||||
| 	depends on CRYPTO=y | ||||
| 	depends on CRYPTO_SHA256=y | ||||
|  |  | |||
|  | @ -414,7 +414,7 @@ xloadflags: | |||
| # define XLF23 0 | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CONFIG_X86_64) && defined(CONFIG_EFI) && defined(CONFIG_KEXEC) | ||||
| #if defined(CONFIG_X86_64) && defined(CONFIG_EFI) && defined(CONFIG_KEXEC_CORE) | ||||
| # define XLF4 XLF_EFI_KEXEC | ||||
| #else | ||||
| # define XLF4 0 | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ extern void show_trace(struct task_struct *t, struct pt_regs *regs, | |||
| extern void __show_regs(struct pt_regs *regs, int all); | ||||
| extern unsigned long oops_begin(void); | ||||
| extern void oops_end(unsigned long, struct pt_regs *, int signr); | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| extern int in_crash_kexec; | ||||
| #else | ||||
| /* no crash dump is ever in progress if no crash kernel can be kexec'd */ | ||||
|  |  | |||
|  | @ -71,8 +71,8 @@ obj-$(CONFIG_LIVEPATCH)		+= livepatch.o | |||
| obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | ||||
| 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_CORE)	+= machine_kexec_$(BITS).o | ||||
| obj-$(CONFIG_KEXEC_CORE)	+= relocate_kernel_$(BITS).o crash.o | ||||
| obj-$(CONFIG_KEXEC_FILE)	+= kexec-bzimage64.o | ||||
| obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o | ||||
| obj-y				+= kprobes/ | ||||
|  |  | |||
|  | @ -200,7 +200,7 @@ static void kvm_setup_secondary_clock(void) | |||
|  * kind of shutdown from our side, we unregister the clock by writting anything | ||||
|  * that does not have the 'enable' bit set in the msr | ||||
|  */ | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| static void kvm_crash_shutdown(struct pt_regs *regs) | ||||
| { | ||||
| 	native_write_msr(msr_kvm_system_time, 0, 0); | ||||
|  | @ -259,7 +259,7 @@ void __init kvmclock_init(void) | |||
| 	x86_platform.save_sched_clock_state = kvm_save_sched_clock_state; | ||||
| 	x86_platform.restore_sched_clock_state = kvm_restore_sched_clock_state; | ||||
| 	machine_ops.shutdown  = kvm_shutdown; | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	machine_ops.crash_shutdown  = kvm_crash_shutdown; | ||||
| #endif | ||||
| 	kvm_get_preset_lpj(); | ||||
|  |  | |||
|  | @ -673,7 +673,7 @@ struct machine_ops machine_ops = { | |||
| 	.emergency_restart = native_machine_emergency_restart, | ||||
| 	.restart = native_machine_restart, | ||||
| 	.halt = native_machine_halt, | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	.crash_shutdown = native_machine_crash_shutdown, | ||||
| #endif | ||||
| }; | ||||
|  | @ -703,7 +703,7 @@ void machine_halt(void) | |||
| 	machine_ops.halt(); | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| void machine_crash_shutdown(struct pt_regs *regs) | ||||
| { | ||||
| 	machine_ops.crash_shutdown(regs); | ||||
|  |  | |||
|  | @ -478,7 +478,7 @@ static void __init memblock_x86_reserve_range_setup_data(void) | |||
|  * --------- Crashkernel reservation ------------------------------ | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 
 | ||||
| /*
 | ||||
|  * Keep the crash kernel below this limit.  On 32 bits earlier kernels | ||||
|  |  | |||
|  | @ -364,7 +364,7 @@ INIT_PER_CPU(irq_stack_union); | |||
| 
 | ||||
| #endif /* CONFIG_X86_32 */ | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| #include <asm/kexec.h> | ||||
| 
 | ||||
| . = ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE, | ||||
|  |  | |||
|  | @ -1264,7 +1264,7 @@ static void vmcs_load(struct vmcs *vmcs) | |||
| 		       vmcs, phys_addr); | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| /*
 | ||||
|  * This bitmap is used to indicate whether the vmclear | ||||
|  * operation is enabled on all cpus. All disabled by | ||||
|  | @ -1302,7 +1302,7 @@ static void crash_vmclear_local_loaded_vmcss(void) | |||
| #else | ||||
| static inline void crash_enable_local_vmclear(int cpu) { } | ||||
| static inline void crash_disable_local_vmclear(int cpu) { } | ||||
| #endif /* CONFIG_KEXEC */ | ||||
| #endif /* CONFIG_KEXEC_CORE */ | ||||
| 
 | ||||
| static void __loaded_vmcs_clear(void *arg) | ||||
| { | ||||
|  | @ -10411,7 +10411,7 @@ static int __init vmx_init(void) | |||
| 	if (r) | ||||
| 		return r; | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	rcu_assign_pointer(crash_vmclear_loaded_vmcss, | ||||
| 			   crash_vmclear_local_loaded_vmcss); | ||||
| #endif | ||||
|  | @ -10421,7 +10421,7 @@ static int __init vmx_init(void) | |||
| 
 | ||||
| static void __exit vmx_exit(void) | ||||
| { | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); | ||||
| 	synchronize_rcu(); | ||||
| #endif | ||||
|  |  | |||
|  | @ -650,7 +650,7 @@ static void __init get_systab_virt_addr(efi_memory_desc_t *md) | |||
| 
 | ||||
| static void __init save_runtime_map(void) | ||||
| { | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	efi_memory_desc_t *md; | ||||
| 	void *tmp, *p, *q = NULL; | ||||
| 	int count = 0; | ||||
|  | @ -748,7 +748,7 @@ static void * __init efi_map_regions(int *count, int *pg_shift) | |||
| 
 | ||||
| static void __init kexec_enter_virtual_mode(void) | ||||
| { | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	efi_memory_desc_t *md; | ||||
| 	void *p; | ||||
| 
 | ||||
|  |  | |||
|  | @ -492,7 +492,7 @@ static void uv_nmi_touch_watchdogs(void) | |||
| 	touch_nmi_watchdog(); | ||||
| } | ||||
| 
 | ||||
| #if defined(CONFIG_KEXEC) | ||||
| #if defined(CONFIG_KEXEC_CORE) | ||||
| static atomic_t uv_nmi_kexec_failed; | ||||
| static void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs) | ||||
| { | ||||
|  | @ -519,13 +519,13 @@ static void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs) | |||
| 	uv_nmi_sync_exit(0); | ||||
| } | ||||
| 
 | ||||
| #else /* !CONFIG_KEXEC */ | ||||
| #else /* !CONFIG_KEXEC_CORE */ | ||||
| static inline void uv_nmi_kdump(int cpu, int master, struct pt_regs *regs) | ||||
| { | ||||
| 	if (master) | ||||
| 		pr_err("UV: NMI kdump: KEXEC not supported in this kernel\n"); | ||||
| } | ||||
| #endif /* !CONFIG_KEXEC */ | ||||
| #endif /* !CONFIG_KEXEC_CORE */ | ||||
| 
 | ||||
| #ifdef CONFIG_KGDB | ||||
| #ifdef CONFIG_KGDB_KDB | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ config EFI_VARS_PSTORE_DEFAULT_DISABLE | |||
| 
 | ||||
| config EFI_RUNTIME_MAP | ||||
| 	bool "Export efi runtime maps to sysfs" | ||||
| 	depends on X86 && EFI && KEXEC | ||||
| 	depends on X86 && EFI && KEXEC_CORE | ||||
| 	default y | ||||
| 	help | ||||
| 	  Export efi runtime memory maps to /sys/firmware/efi/runtime-map. | ||||
|  |  | |||
|  | @ -467,7 +467,7 @@ static void pci_device_shutdown(struct device *dev) | |||
| 	pci_msi_shutdown(pci_dev); | ||||
| 	pci_msix_shutdown(pci_dev); | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	/*
 | ||||
| 	 * If this is a kexec reboot, turn off Bus Master bit on the | ||||
| 	 * device to tell it to not continue to do DMA. Don't touch | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ | |||
| 
 | ||||
| #include <uapi/linux/kexec.h> | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| #include <linux/list.h> | ||||
| #include <linux/linkage.h> | ||||
| #include <linux/compat.h> | ||||
|  | @ -329,13 +329,13 @@ int __weak arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr, | |||
| int __weak arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, | ||||
| 					unsigned int relsec); | ||||
| 
 | ||||
| #else /* !CONFIG_KEXEC */ | ||||
| #else /* !CONFIG_KEXEC_CORE */ | ||||
| struct pt_regs; | ||||
| struct task_struct; | ||||
| static inline void crash_kexec(struct pt_regs *regs) { } | ||||
| static inline int kexec_should_crash(struct task_struct *p) { return 0; } | ||||
| #define kexec_in_progress false | ||||
| #endif /* CONFIG_KEXEC */ | ||||
| #endif /* CONFIG_KEXEC_CORE */ | ||||
| 
 | ||||
| #endif /* !defined(__ASSEBMLY__) */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -526,14 +526,14 @@ extern unsigned long __initramfs_size; | |||
| 
 | ||||
| static void __init free_initrd(void) | ||||
| { | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	unsigned long crashk_start = (unsigned long)__va(crashk_res.start); | ||||
| 	unsigned long crashk_end   = (unsigned long)__va(crashk_res.end); | ||||
| #endif | ||||
| 	if (do_retain_initrd) | ||||
| 		goto skip; | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	/*
 | ||||
| 	 * If the initrd region is overlapped with crashkernel reserved region, | ||||
| 	 * free only memory that is not part of crashkernel region. | ||||
|  |  | |||
|  | @ -49,6 +49,7 @@ obj-$(CONFIG_MODULES) += module.o | |||
| obj-$(CONFIG_MODULE_SIG) += module_signing.o | ||||
| obj-$(CONFIG_KALLSYMS) += kallsyms.o | ||||
| obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o | ||||
| obj-$(CONFIG_KEXEC_CORE) += kexec_core.o | ||||
| obj-$(CONFIG_KEXEC) += kexec.o | ||||
| obj-$(CONFIG_KEXEC_FILE) += kexec_file.o | ||||
| obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o | ||||
|  |  | |||
|  | @ -9094,7 +9094,7 @@ static void perf_event_init_cpu(int cpu) | |||
| 	mutex_unlock(&swhash->hlist_mutex); | ||||
| } | ||||
| 
 | ||||
| #if defined CONFIG_HOTPLUG_CPU || defined CONFIG_KEXEC | ||||
| #if defined CONFIG_HOTPLUG_CPU || defined CONFIG_KEXEC_CORE | ||||
| static void __perf_event_exit_context(void *__info) | ||||
| { | ||||
| 	struct remove_event re = { .detach_group = true }; | ||||
|  |  | |||
							
								
								
									
										1495
									
								
								kernel/kexec.c
									
									
									
									
									
								
							
							
						
						
									
										1495
									
								
								kernel/kexec.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1511
									
								
								kernel/kexec_core.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1511
									
								
								kernel/kexec_core.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -90,7 +90,7 @@ static ssize_t profiling_store(struct kobject *kobj, | |||
| KERNEL_ATTR_RW(profiling); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| static ssize_t kexec_loaded_show(struct kobject *kobj, | ||||
| 				 struct kobj_attribute *attr, char *buf) | ||||
| { | ||||
|  | @ -134,7 +134,7 @@ static ssize_t vmcoreinfo_show(struct kobject *kobj, | |||
| } | ||||
| KERNEL_ATTR_RO(vmcoreinfo); | ||||
| 
 | ||||
| #endif /* CONFIG_KEXEC */ | ||||
| #endif /* CONFIG_KEXEC_CORE */ | ||||
| 
 | ||||
| /* whether file capabilities are enabled */ | ||||
| static ssize_t fscaps_show(struct kobject *kobj, | ||||
|  | @ -196,7 +196,7 @@ static struct attribute * kernel_attrs[] = { | |||
| #ifdef CONFIG_PROFILING | ||||
| 	&profiling_attr.attr, | ||||
| #endif | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	&kexec_loaded_attr.attr, | ||||
| 	&kexec_crash_loaded_attr.attr, | ||||
| 	&kexec_crash_size_attr.attr, | ||||
|  |  | |||
|  | @ -835,7 +835,7 @@ const struct file_operations kmsg_fops = { | |||
| 	.release = devkmsg_release, | ||||
| }; | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| /*
 | ||||
|  * This appends the listed symbols to /proc/vmcore | ||||
|  * | ||||
|  |  | |||
|  | @ -346,7 +346,7 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, | |||
| 		kernel_restart(buffer); | ||||
| 		break; | ||||
| 
 | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	case LINUX_REBOOT_CMD_KEXEC: | ||||
| 		ret = kernel_kexec(); | ||||
| 		break; | ||||
|  |  | |||
|  | @ -621,7 +621,7 @@ static struct ctl_table kern_table[] = { | |||
| 		.proc_handler	= proc_dointvec, | ||||
| 	}, | ||||
| #endif | ||||
| #ifdef CONFIG_KEXEC | ||||
| #ifdef CONFIG_KEXEC_CORE | ||||
| 	{ | ||||
| 		.procname	= "kexec_load_disabled", | ||||
| 		.data		= &kexec_load_disabled, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Dave Young
						Dave Young