/* * Reset the system, copy boot CPU registers to absolute zero, * and jump to the kdump image */ static void __do_machine_kdump(void *image) { int (*start_kdump)(int); unsigned long prefix; /* store_status() saved the prefix register to lowcore */ prefix = (unsigned long) S390_lowcore.prefixreg_save_area; /* Now do the reset */ s390_reset_system(); /* * Copy dump CPU store status info to absolute zero. * This need to be done *after* s390_reset_system set the * prefix register of this CPU to zero */ memcpy((void *) __LC_FPREGS_SAVE_AREA, (void *)(prefix + __LC_FPREGS_SAVE_AREA), 512); __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); start_kdump = (void *)((struct kimage *) image)->start; start_kdump(1); /* Die if start_kdump returns */ disabled_wait((unsigned long) __builtin_return_address(0)); }
NORET_TYPE void panic(const char * fmt, ...) { static char buf[1024]; va_list args; #if defined(CONFIG_ARCH_S390) unsigned long caller = (unsigned long) __builtin_return_address(0); #endif bust_spinlocks(1); va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); printk(KERN_EMERG "Kernel panic: %s\n",buf); if (in_interrupt()) printk(KERN_EMERG "In interrupt handler - not syncing\n"); else if (!current->pid) printk(KERN_EMERG "In idle task - not syncing\n"); else sys_sync(); bust_spinlocks(0); #ifdef CONFIG_SMP smp_send_stop(); #endif notifier_call_chain(&panic_notifier_list, 0, NULL); if (panic_timeout > 0) { /* * Delay timeout seconds before rebooting the machine. * We can't use the "normal" timers since we just panicked.. */ printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); mdelay(panic_timeout*1000); /* * Should we run the reboot notifier. For the moment Im * choosing not too. It might crash, be corrupt or do * more harm than good for other reasons. */ machine_restart(NULL); } #ifdef __sparc__ { extern int stop_a_enabled; /* Make sure the user can actually press L1-A */ stop_a_enabled = 1; printk("Press L1-A to return to the boot prom\n"); } #endif #if defined(CONFIG_ARCH_S390) disabled_wait(caller); #endif sti(); for(;;) { CHECK_EMERGENCY_SYNC } }
static void s390_handle_damage(char *msg) { printk(KERN_EMERG "%s\n", msg); #ifdef CONFIG_SMP smp_send_stop(); #endif disabled_wait((unsigned long) __builtin_return_address(0)); }
/* * Reset system and call either kdump or normal kexec */ static void __machine_kexec(void *data) { struct kimage *image = data; pfault_fini(); if (image->type == KEXEC_TYPE_CRASH) s390_reset_system(__do_machine_kdump, data); else s390_reset_system(__do_machine_kexec, data); disabled_wait((unsigned long) __builtin_return_address(0)); }
/* * Reset system and call either kdump or normal kexec */ void machine_kexec(struct kimage *image) { if (image->type == KEXEC_TYPE_CRASH && !kdump_csum_valid(image)) return; smp_send_stop(); pfault_fini(); if (image->type == KEXEC_TYPE_CRASH) s390_reset_system(__do_machine_kdump, image); else s390_reset_system(__do_machine_kexec, image); disabled_wait((unsigned long) __builtin_return_address(0)); }
/* * Get the TOD clock running. */ static void __init reset_tod_clock(void) { u64 time; if (store_clock(&time) == 0) return; /* TOD clock not running. Set the clock to Unix Epoch. */ if (set_clock(TOD_UNIX_EPOCH) != 0 || store_clock(&time) != 0) disabled_wait(0); sched_clock_base_cc = TOD_UNIX_EPOCH; S390_lowcore.last_update_clock = sched_clock_base_cc; }
/* * Do normal kexec */ static void __do_machine_kexec(void *data) { relocate_kernel_t data_mover; struct kimage *image = data; s390_reset_system(); data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page); /* Call the moving routine */ (*data_mover)(&image->head, image->start); /* Die if kexec returns */ disabled_wait((unsigned long) __builtin_return_address(0)); }
static void __init reset_tod_clock(void) { u64 time; if (store_tod_clock(&time) == 0) return; /* TOD clock not running. Set the clock to Unix Epoch. */ if (set_tod_clock(TOD_UNIX_EPOCH) != 0 || store_tod_clock(&time) != 0) disabled_wait(); memset(tod_clock_base, 0, 16); *(__u64 *) &tod_clock_base[1] = TOD_UNIX_EPOCH; S390_lowcore.last_update_clock = TOD_UNIX_EPOCH; }
static void __machine_kexec(void *data) { struct kimage *image = data; pfault_fini(); tracing_off(); debug_locks_off(); if (image->type == KEXEC_TYPE_CRASH) { lgr_info_log(); s390_reset_system(__do_machine_kdump, data); } else { s390_reset_system(__do_machine_kexec, data); } disabled_wait((unsigned long) __builtin_return_address(0)); }
/* * Reset system and call either kdump or normal kexec */ static void __machine_kexec(void *data) { __arch_local_irq_stosm(0x04); /* enable DAT */ pfault_fini(); tracing_off(); debug_locks_off(); #ifdef CONFIG_CRASH_DUMP if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH) { lgr_info_log(); s390_reset_system(setup_regs, __do_machine_kdump, data); } else #endif s390_reset_system(NULL, __do_machine_kexec, data); disabled_wait((unsigned long) __builtin_return_address(0)); }
static unsigned s390_count_running_cpus(void) { CPUState *cpu; int nr_running = 0; CPU_FOREACH(cpu) { uint8_t state = S390_CPU(cpu)->env.cpu_state; if (state == CPU_STATE_OPERATING || state == CPU_STATE_LOAD) { if (!disabled_wait(cpu)) { nr_running++; } } } return nr_running; }
/* * Reset system and call either kdump or normal kexec */ void machine_kexec(struct kimage *image) { if (image->type == KEXEC_TYPE_CRASH && !kdump_csum_valid(image)) return; smp_send_stop(); pfault_fini(); tracing_off(); debug_locks_off(); if (image->type == KEXEC_TYPE_CRASH) { lgr_info_log(); s390_reset_system(__do_machine_kdump, image); } else { s390_reset_system(__do_machine_kexec, image); } disabled_wait((unsigned long) __builtin_return_address(0)); }
NORET_TYPE void panic(const char * fmt, ...) { long i; static char buf[1024]; va_list args; #if defined(CONFIG_ARCH_S390) unsigned long caller = (unsigned long) __builtin_return_address(0); #endif bust_spinlocks(1); va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); bust_spinlocks(0); #ifdef CONFIG_SMP smp_send_stop(); #endif notifier_call_chain(&panic_notifier_list, 0, buf); if (!panic_blink) panic_blink = no_blink; if (panic_timeout > 0) { /* * Delay timeout seconds before rebooting the machine. * We can't use the "normal" timers since we just panicked.. */ printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); for (i = 0; i < panic_timeout*1000; ) { touch_nmi_watchdog(); i += panic_blink(i); mdelay(1); i++; } /* * Should we run the reboot notifier. For the moment Im * choosing not too. It might crash, be corrupt or do * more harm than good for other reasons. */ machine_restart(NULL); } #ifdef __sparc__ { extern int stop_a_enabled; /* Make sure the user can actually press Stop-A (L1-A) */ stop_a_enabled = 1; printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom\n"); } #endif #if defined(CONFIG_ARCH_S390) disabled_wait(caller); #endif local_irq_enable(); for (i = 0;;) { i += panic_blink(i); mdelay(1); i++; } }
/** * panic - halt the system * @fmt: The text string to print * * Display a message, then perform cleanups. * * This function never returns. */ void panic(const char *fmt, ...) { static char buf[1024]; va_list args; long i, i_next = 0, len; int state = 0; int old_cpu, this_cpu; bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers; /* * Disable local interrupts. This will prevent panic_smp_self_stop * from deadlocking the first cpu that invokes the panic, since * there is nothing to prevent an interrupt handler (that runs * after setting panic_cpu) from invoking panic() again. */ local_irq_disable(); /* * It's possible to come here directly from a panic-assertion and * not have preempt disabled. Some functions called from here want * preempt to be disabled. No point enabling it later though... * * Only one CPU is allowed to execute the panic code from here. For * multiple parallel invocations of panic, all other CPUs either * stop themself or will wait until they are stopped by the 1st CPU * with smp_send_stop(). * * `old_cpu == PANIC_CPU_INVALID' means this is the 1st CPU which * comes here, so go ahead. * `old_cpu == this_cpu' means we came from nmi_panic() which sets * panic_cpu to this CPU. In this case, this is also the 1st CPU. */ this_cpu = raw_smp_processor_id(); old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, this_cpu); if (old_cpu != PANIC_CPU_INVALID && old_cpu != this_cpu) panic_smp_self_stop(); console_verbose(); bust_spinlocks(1); va_start(args, fmt); len = vscnprintf(buf, sizeof(buf), fmt, args); va_end(args); if (len && buf[len - 1] == '\n') buf[len - 1] = '\0'; pr_emerg("Kernel panic - not syncing: %s\n", buf); #ifdef CONFIG_DEBUG_BUGVERBOSE /* * Avoid nested stack-dumping if a panic occurs during oops processing */ if (!test_taint(TAINT_DIE) && oops_in_progress <= 1) dump_stack(); #endif /* * If we have crashed and we have a crash kernel loaded let it handle * everything else. * If we want to run this after calling panic_notifiers, pass * the "crash_kexec_post_notifiers" option to the kernel. * * Bypass the panic_cpu check and call __crash_kexec directly. */ if (!_crash_kexec_post_notifiers) { printk_safe_flush_on_panic(); __crash_kexec(NULL); /* * Note smp_send_stop is the usual smp shutdown function, which * unfortunately means it may not be hardened to work in a * panic situation. */ smp_send_stop(); } else { /* * If we want to do crash dump after notifier calls and * kmsg_dump, we will need architecture dependent extra * works in addition to stopping other CPUs. */ crash_smp_send_stop(); } /* * Run any panic handlers, including those that might need to * add information to the kmsg dump output. */ atomic_notifier_call_chain(&panic_notifier_list, 0, buf); /* Call flush even twice. It tries harder with a single online CPU */ printk_safe_flush_on_panic(); kmsg_dump(KMSG_DUMP_PANIC); /* * If you doubt kdump always works fine in any situation, * "crash_kexec_post_notifiers" offers you a chance to run * panic_notifiers and dumping kmsg before kdump. * Note: since some panic_notifiers can make crashed kernel * more unstable, it can increase risks of the kdump failure too. * * Bypass the panic_cpu check and call __crash_kexec directly. */ if (_crash_kexec_post_notifiers) __crash_kexec(NULL); #ifdef CONFIG_VT unblank_screen(); #endif console_unblank(); /* * We may have ended up stopping the CPU holding the lock (in * smp_send_stop()) while still having some valuable data in the console * buffer. Try to acquire the lock then release it regardless of the * result. The release will also print the buffers out. Locks debug * should be disabled to avoid reporting bad unlock balance when * panic() is not being callled from OOPS. */ debug_locks_off(); console_flush_on_panic(); panic_print_sys_info(); if (!panic_blink) panic_blink = no_blink; if (panic_timeout > 0) { /* * Delay timeout seconds before rebooting the machine. * We can't use the "normal" timers since we just panicked. */ pr_emerg("Rebooting in %d seconds..\n", panic_timeout); for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP) { touch_nmi_watchdog(); if (i >= i_next) { i += panic_blink(state ^= 1); i_next = i + 3600 / PANIC_BLINK_SPD; } mdelay(PANIC_TIMER_STEP); } } if (panic_timeout != 0) { /* * This will not be a clean reboot, with everything * shutting down. But if there is a chance of * rebooting the system it will be rebooted. */ emergency_restart(); } #ifdef __sparc__ { extern int stop_a_enabled; /* Make sure the user can actually press Stop-A (L1-A) */ stop_a_enabled = 1; pr_emerg("Press Stop-A (L1-A) from sun keyboard or send break\n" "twice on console to return to the boot prom\n"); } #endif #if defined(CONFIG_S390) { unsigned long caller; caller = (unsigned long)__builtin_return_address(0); disabled_wait(caller); } #endif pr_emerg("---[ end Kernel panic - not syncing: %s ]---\n", buf); local_irq_enable(); for (i = 0; ; i += PANIC_TIMER_STEP) { touch_softlockup_watchdog(); if (i >= i_next) { i += panic_blink(state ^= 1); i_next = i + 3600 / PANIC_BLINK_SPD; } mdelay(PANIC_TIMER_STEP); } }
NORET_TYPE void panic(const char * fmt, ...) { long i; static char buf[1024]; va_list args; #if defined(CONFIG_S390) unsigned long caller = (unsigned long) __builtin_return_address(0); #endif /* * It's possible to come here directly from a panic-assertion and not * have preempt disabled. Some functions called from here want * preempt to be disabled. No point enabling it later though... */ preempt_disable(); bust_spinlocks(1); va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); bust_spinlocks(0); /* * If we have crashed and we have a crash kernel loaded let it handle * everything else. * Do we want to call this before we try to display a message? */ crash_kexec(NULL); #ifdef CONFIG_SMP /* * Note smp_send_stop is the usual smp shutdown function, which * unfortunately means it may not be hardened to work in a panic * situation. */ smp_send_stop(); #endif atomic_notifier_call_chain(&panic_notifier_list, 0, buf); if (!panic_blink) panic_blink = no_blink; if (panic_timeout > 0) { /* * Delay timeout seconds before rebooting the machine. * We can't use the "normal" timers since we just panicked.. */ printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); for (i = 0; i < panic_timeout*1000; ) { touch_nmi_watchdog(); i += panic_blink(i); mdelay(1); i++; } /* This will not be a clean reboot, with everything * shutting down. But if there is a chance of * rebooting the system it will be rebooted. */ emergency_restart(); } #ifdef __sparc__ { extern int stop_a_enabled; /* Make sure the user can actually press Stop-A (L1-A) */ stop_a_enabled = 1; printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom\n"); } #endif #if defined(CONFIG_S390) disabled_wait(caller); #endif local_irq_enable(); for (i = 0;;) { touch_softlockup_watchdog(); i += panic_blink(i); mdelay(1); i++; } }
NORET_TYPE void panic(const char * fmt, ...) { long i; static char buf[1024]; va_list args; #if defined(CONFIG_S390) unsigned long caller = (unsigned long) __builtin_return_address(0); #endif int count,chr_count; /* * It's possible to come here directly from a panic-assertion and not * have preempt disabled. Some functions called from here want * preempt to be disabled. No point enabling it later though... */ preempt_disable(); bust_spinlocks(1); va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf); bust_spinlocks(0); #ifdef CONFIG_KERNEL_PANIC_DUMP PANIC_Current += sprintf(PANIC_Current,"Kernel panic - not syncing: %s\n",buf); if (!multiple_panic) { multiple_panic++; printk(KERN_EMERG "PANIC_DUMP Test : \n"); count = PANIC_Current - PANIC_Base; printk("count : %d\n",count); chr_count = 0; while(count) { memset(buf,0x0,1024); if(count > 1024) { memcpy(buf,PANIC_Base+chr_count,1024); printk("%s",buf); chr_count += 1024; count -= 1024; } else { memcpy(buf,PANIC_Base+chr_count,count); printk("%s",buf); chr_count += count; count -= count; } } { mm_segment_t old_fs; struct file *filp; int writelen; loff_t pos =0; fl_owner_t id = current->files; preempt_enable(); old_fs = get_fs(); set_fs(KERNEL_DS); struct timeval val; struct tm *ptm,ptmTemp; char dt[35]; do_gettimeofday(&val); ptm = localtime_r(&val.tv_sec,&ptmTemp); memset(dt , 0x00 , sizeof(dt)); // format : YYMMDDhhmm sprintf(dt, "/data/KERNEL_PANIC%04d%02d%02d%02d%02d.txt" , ptm->tm_year+1900 , ptm->tm_mon+1 , ptm->tm_mday , ptm->tm_hour, ptm->tm_min); printk("Panic log file is %s \n",dt); count = PANIC_Current - PANIC_Base; chr_count = 0; filp = filp_open(dt,O_CREAT|O_WRONLY,0666); if(filp<0) printk("Sorry. Can't creat panic file\n"); else { // vfs_write(filp, PANIC_Base, strlen(PANIC_Base), while(count) { memset(buf,0x0,1024); if(count > 1024) { memcpy(buf,PANIC_Base+chr_count,1024); writelen = filp->f_op->write(filp,buf,1024,&filp->f_pos); if(writelen == 0) printk("Write Error!!\n"); else filp->f_op->flush(filp,id); chr_count += 1024; count -= 1024; } else { memcpy(buf,PANIC_Base+chr_count,count); writelen = filp->f_op->write(filp,buf,count,&filp->f_pos); if(writelen == 0) printk("Write Error\n"); else filp->f_op->flush(filp,id); chr_count += count; count -= count; } } } set_fs(old_fs); preempt_disable(); } count = PANIC_Current - PANIC_Base; printk("\nPanic Dump END, panic message size is : %d\n",count); } else { #if 0 /* Reset Target */ #else while (1); #endif } #endif /* * If we have crashed and we have a crash kernel loaded let it handle * everything else. * Do we want to call this before we try to display a message? */ crash_kexec(NULL); #ifdef CONFIG_SMP /* * Note smp_send_stop is the usual smp shutdown function, which * unfortunately means it may not be hardened to work in a panic * situation. */ smp_send_stop(); #endif atomic_notifier_call_chain(&panic_notifier_list, 0, buf); if (!panic_blink) panic_blink = no_blink; if (panic_timeout > 0) { /* * Delay timeout seconds before rebooting the machine. * We can't use the "normal" timers since we just panicked.. */ printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout); for (i = 0; i < panic_timeout*1000; ) { touch_nmi_watchdog(); i += panic_blink(i); mdelay(1); i++; } /* This will not be a clean reboot, with everything * shutting down. But if there is a chance of * rebooting the system it will be rebooted. */ emergency_restart(); } #ifdef __sparc__ { extern int stop_a_enabled; /* Make sure the user can actually press Stop-A (L1-A) */ stop_a_enabled = 1; printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom\n"); } #endif #if defined(CONFIG_S390) disabled_wait(caller); #endif local_irq_enable(); for (i = 0;;) { touch_softlockup_watchdog(); i += panic_blink(i); mdelay(1); i++; } }
void virtio_panic(const char *string) { sclp_print(string); disabled_wait(); while (1) { } }