kexec for 2.5.42
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
O.k. My first pass at getting up to date with the current kernel is available at:
http://www.xmission.com/~ebiederm/files/kexec/linux-2.5.42.kexec.x86.diff
http://www.xmission.com/~ebiederm/files/kexec/kexec-tools-1.0.tar.gz
The big changes are:
1) I have rebundled my tools so it is a little easier to get at:
2) I have included a test case kexec_test that tests the stranger cases, so when the kernel doesn't boot, we can rule out the kexec code.
3) I have added a call to device_shutdown so device drivers get a chance to shut up.
4) I have moved kexec into its one system call instead of treating sys_reboot like an ioctl. The big reason is that while there is a lot of generic code some very architecture specific code must be written for each architecture, and having to register a system call means the code won't become active by accident.
I will probably split this up before sending to Linus but anyway, here is the patch so you can pick it apart and tell me what you don't like.
Eric
MAINTAINERS | 7 arch/i386/Config.help | 14 arch/i386/config.in | 3 arch/i386/kernel/Makefile | 1 arch/i386/kernel/apic.c | 71 ++++ arch/i386/kernel/dmi_scan.c | 27 - arch/i386/kernel/entry.S | 3 arch/i386/kernel/io_apic.c | 2 arch/i386/kernel/machine_kexec.c | 141 ++++++++ arch/i386/kernel/reboot.c | 32 - arch/i386/kernel/relocate_kernel.S | 84 ++++ arch/i386/kernel/smp.c | 24 + include/asm-i386/apicdef.h | 1 include/asm-i386/kexec.h | 25 + include/linux/kexec.h | 49 ++ kernel/Makefile | 3 kernel/kexec.c | 630 +++++++++++++++++++++++++++++++++++++ kernel/sys.c | 59 +++ 18 files changed, 1116 insertions, 60 deletions
MAINTAINERS +7 -0
@@ -934,6 +934,13 @@ W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/ S: Maintained +KEXEC +P: Eric Biederman +M: [email protected] +M: [email protected] +L: [email protected] +S: Maintained + LANMEDIA WAN CARD DRIVER P: Andrew Stanley-Jones M: [email protected]
arch/i386/Config.help +14 -0
@@ -411,6 +411,20 @@ you have use for it; the module is called binfmt_misc.o. If you don't know what to answer at this point, say Y. +CONFIG_KEXEC + kexec is a system call that implements kernel level exec support. + Or the ability to boot linux from linux. The kexec system call + allows you to replace your current kernel with another kernel, + not necessarily linux. + + A known caveat is that for this to be fully useful all of the + devices must be shutdown. One way to impelment this is to build + all devices as modules and remove them before rebooting. + + You will probably want to dig up the elfboottools package as this + has the first implementation of a user client that uses this kernel + interface. + CONFIG_M386 This is the processor type of your CPU. This information is used for optimizing purposes. In order to compile a kernel that can run on
arch/i386/config.in +3 -0
@@ -242,6 +242,9 @@ fi fi +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'Kernel execing kernel support' CONFIG_KEXEC +fi endmenu mainmenu_option next_comment
arch/i386/kernel/Makefile +1 -0
@@ -25,6 +25,7 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse.o obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o +obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o obj-$(CONFIG_X86_NUMAQ) += numaq.o
arch/i386/kernel/apic.c +71 -0
107 lines not on this page · raw message
arch/i386/kernel/dmi_scan.c +1 -26
@@ -204,31 +204,6 @@return 0 ; } -/* -* Some machines require the "reboot=s" commandline option, this quirk makes that automatic. -*/ -static __init int set_smp_reboot (struct dmi_blacklist *d) -{ -#ifdef CONFIG_SMP -extern int reboot_smp; -if (reboot_smp ==0 ) - { - reboot_smp =1 ; -printk (KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n" , d->ident); - } -#endif -return 0 ; -} - -/* -* Some machines require the "reboot=b,s" commandline option, this quirk makes that automatic. -*/ -static __init int set_smp_bios_reboot (struct dmi_blacklist *d) -{ -set_smp_reboot (d); -set_bios_reboot (d); -return 0 ; -}/* * Some bioses have a broken protected mode poweroff and need to use realmode
@@ -519,7 +494,7 @@MATCH (DMI_BIOS_VERSION ,"4.60 PGMA" ), MATCH(DMI_BIOS_DATE, "134526184"), NO_MATCH } }, - { set_smp_bios_reboot, "Dell PowerEdge 1300", { /* Handle problems with rebooting on Dell 1300's */ + { set_bios_reboot, "Dell PowerEdge 1300", { /* Handle problems with rebooting on Dell 1300's */MATCH (DMI_SYS_VENDOR ,"Dell Computer Corporation" ),MATCH (DMI_PRODUCT_NAME ,"PowerEdge 1300/" ),NO_MATCH ,NO_MATCH
arch/i386/kernel/entry.S +2 -1
@@ -736,7 +736,8 @@ .long sys_alloc_hugepages /* 250 */ .long sys_free_hugepages .long sys_exit_group - + .long sys_kexec + .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall .endr
arch/i386/kernel/io_apic.c +0 -2
@@ -1112,8 +1112,6 @@* Clear the IO-APIC before rebooting: */ clear_IO_APIC (); - -disconnect_bsp_APIC (); }/*
arch/i386/kernel/machine_kexec.c +141 -0
141 lines not on this page · raw message
arch/i386/kernel/reboot.c +1 -31
@@ -19,8 +19,7 @@int reboot_thru_bios;#ifdef CONFIG_SMP -int reboot_smp =0 ; -static int reboot_cpu =-1 ; +int reboot_cpu =-1 ;/* specifies the internal linux cpu id, not the apicid */ /* shamelessly grabbed from lib/vsprintf.c for readability */ #define is_digit (c) ((c) >= '0' && (c) <= '9')#endif
@@ -42,7 +41,6 @@break ;#ifdef CONFIG_SMP case 's' :/* "smp" reboot by executing reset on BSP or other CPU*/ - reboot_smp =1 ;if (is_digit (*(str+1 ))) { reboot_cpu = (int ) (*(str+1 ) -'0' );if (is_digit (*(str+2 )))
@@ -224,34 +222,6 @@void machine_restart (char * __unused) {#if CONFIG_SMP -int cpuid; - - cpuid =GET_APIC_ID (apic_read (APIC_ID )); - -if (reboot_smp) { - -/* check to see if reboot_cpu is valid -if its not, default to the BSP */ -if ((reboot_cpu ==-1 ) || - (reboot_cpu > (NR_CPUS -1 )) || - !(phys_cpu_present_map & (1 <<cpuid))) - reboot_cpu = boot_cpu_physical_apicid; - - reboot_smp =0 ;/* use this as a flag to only go through this once*/ -/* re-run this function on the other CPUs -it will fall though this section since we have -cleared reboot_smp, and do the reboot if it is the -correct CPU, otherwise it halts. */ -if (reboot_cpu != cpuid) -smp_call_function ((void *)machine_restart ,NULL ,1 ,0 ); - } - -/* if reboot_cpu is still -1, then we want a tradional reboot, -and if we are not running on the reboot_cpu,, halt */ -if ((reboot_cpu !=-1 ) && (cpuid != reboot_cpu)) { -for (;;) - __asm__ __volatile__ ("hlt" ); - }/* * Stop all CPUs and turn off local APICs and the IO-APIC, so * other OSs see a clean IRQ state.
arch/i386/kernel/relocate_kernel.S +84 -0
84 lines not on this page · raw message
arch/i386/kernel/smp.c +24 -0
@@ -611,6 +611,30 @@void smp_send_stop (void ) { +extern int reboot_cpu; +int reboot_cpu_id; + +/* The boot cpu is always logical cpu 0 */ + reboot_cpu_id =0 ; + +/* See if there has been give a command line override . +*/ +if ((reboot_cpu !=-1 ) && !(reboot_cpu >=NR_CPUS ) && +test_bit (reboot_cpu, &cpu_online_map)) { + reboot_cpu_id = reboot_cpu; + } + +/* Make certain the the cpu I'm rebooting on is online */ +if (!test_bit (reboot_cpu_id, &cpu_online_map)) { + reboot_cpu_id =smp_processor_id (); + } + +/* Make certain I only run on the appropriate processor */ +set_cpus_allowed (current,1 << reboot_cpu_id); + +/* O.k. Now that I'm on the appropriate processor stop +* all of the others. +*/ smp_call_function (stop_this_cpu,NULL ,1 ,0 );local_irq_disable ();
include/asm-i386/apicdef.h +1 -0
@@ -86,6 +86,7 @@#define APIC_LVT_REMOTE_IRR (1<<14)#define APIC_INPUT_POLARITY (1<<13)#define APIC_SEND_PENDING (1<<12) +#define APIC_MODE_MASK 0x700#define GET_APIC_DELIVERY_MODE (x) (((x)>>8)&0x7)#define SET_APIC_DELIVERY_MODE (x,y) (((x)&~0x700)|((y)<<8))#define APIC_MODE_FIXED 0x0
include/asm-i386/kexec.h +25 -0
@@ -0,0 +1,25 @@ +#ifndef _I386_KEXEC_H +#define _I386_KEXEC_H + +#include <asm/fixmap.h> + +/* +* KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. +* I.e. Maximum page that is mapped directly into kernel memory, +* and kmap is not required. +* +* Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct +* calculation for the amount of memory directly mappable into the +* kernel memory space. +*/ + +/* Maximum physical address we can use pages from */ +#define KEXEC_SOURCE_MEMORY_LIMIT (FIXADDR_START - PAGE_OFFSET) +/* Maximum address we can reach in physical address mode */ +#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) + +#define KEXEC_REBOOT_CODE_SIZE 4096 +#define KEXEC_REBOOT_CODE_ALIGN 0 + + +#endif /* _I386_KEXEC_H */
include/linux/kexec.h +49 -0
49 lines not on this page · raw message
kernel/Makefile +3 -0
@@ -19,6 +19,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o +obj-$(CONFIG_KEXEC) += kexec.o ifneq ($(CONFIG_IA64),y) # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
@@ -28,5 +29,7 @@ # to get a correct value for the wait-channel (WCHAN in ps). --davidm CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer endif + +obj-$(CONFIG_KEXEC) += kexec.o include $(TOPDIR)/Rules.make
kernel/kexec.c +630 -0
630 lines not on this page · raw message
kernel/sys.c +59 -0
71 lines not on this page · raw message
Quoted 2 lines · Eric W. Biederman
O.k. My first pass at getting up to date with the current kernel is available at:
Yipee! I was already having nightmares that we'd have to live without it for another major kernel release cycle.
I had a quick glance at it, and it looks quite lovely. You want to get rid of the load_elf_kernel prototype in include/linux/kexec.h, though :-)
Thanks,
- Werner
Signature · 3 lines
_________________________________________________________________________ / Werner Almesberger, Buenos Aires, Argentina [email protected] / /_http://www.almesberger.net/____________________________________________/