void __attribute__((weak)) bust_spinlocks(int yes) { if (yes) { ++oops_in_progress; } else { #ifdef CONFIG_VT unblank_screen(); #endif console_unblank(); ipipe_trace_panic_dump(); if (--oops_in_progress == 0) wake_up_klogd(); } }
void ipipe_root_only(void) { struct ipipe_domain *this_domain; unsigned long flags; flags = hard_smp_local_irq_save(); this_domain = __ipipe_current_domain; if (likely(this_domain == ipipe_root_domain && !test_bit(IPIPE_STALL_FLAG, &__ipipe_head_status))) { hard_smp_local_irq_restore(flags); return; } if (!__this_cpu_read(ipipe_percpu.context_check)) { hard_smp_local_irq_restore(flags); return; } hard_smp_local_irq_restore(flags); ipipe_prepare_panic(); ipipe_trace_panic_freeze(); if (this_domain != ipipe_root_domain) printk(KERN_ERR "I-pipe: Detected illicit call from head domain '%s'\n" KERN_ERR " into a regular Linux service\n", this_domain->name); else printk(KERN_ERR "I-pipe: Detected stalled head domain, " "probably caused by a bug.\n" " A critical section may have been " "left unterminated.\n"); dump_stack(); ipipe_trace_panic_dump(); }
int __ipipe_handle_exception(struct pt_regs *regs, long error_code, int vector) { bool root_entry = false; unsigned long flags = 0; unsigned long cr2 = 0; if (ipipe_root_domain_p) { root_entry = true; local_save_flags(flags); /* * Replicate hw interrupt state into the virtual mask * before calling the I-pipe event handler over the * root domain. Also required later when calling the * Linux exception handler. */ if (irqs_disabled_hw()) local_irq_disable(); } #ifdef CONFIG_KGDB /* catch exception KGDB is interested in over non-root domains */ else if (__ipipe_xlate_signo[vector] >= 0 && !kgdb_handle_exception(vector, __ipipe_xlate_signo[vector], error_code, regs)) return 1; #endif /* CONFIG_KGDB */ if (vector == ex_do_page_fault) cr2 = native_read_cr2(); if (unlikely(ipipe_trap_notify(vector, regs))) { if (root_entry) local_irq_restore_nosync(flags); return 1; } if (likely(ipipe_root_domain_p)) { /* * If root is not the topmost domain or in case we faulted in * the iret path of x86-32, regs.flags does not match the root * domain state. The fault handler or the low-level return * code may evaluate it. So fix this up, either by the root * state sampled on entry or, if we migrated to root, with the * current state. */ __fixup_if(root_entry ? raw_irqs_disabled_flags(flags) : raw_irqs_disabled(), regs); } else { /* Detect unhandled faults over non-root domains. */ struct ipipe_domain *ipd = ipipe_current_domain; /* Switch to root so that Linux can handle the fault cleanly. */ __ipipe_current_domain = ipipe_root_domain; ipipe_trace_panic_freeze(); /* Always warn about user land and unfixable faults. */ if (user_mode_vm(regs) || !search_exception_tables(instruction_pointer(regs))) { printk(KERN_ERR "BUG: Unhandled exception over domain" " %s at 0x%lx - switching to ROOT\n", ipd->name, instruction_pointer(regs)); dump_stack(); ipipe_trace_panic_dump(); #ifdef CONFIG_IPIPE_DEBUG /* Also report fixable ones when debugging is enabled. */ } else { printk(KERN_WARNING "WARNING: Fixable exception over " "domain %s at 0x%lx - switching to ROOT\n", ipd->name, instruction_pointer(regs)); dump_stack(); ipipe_trace_panic_dump(); #endif /* CONFIG_IPIPE_DEBUG */ } } if (vector == ex_do_page_fault) write_cr2(cr2); __ipipe_std_extable[vector](regs, error_code); /* * Relevant for 64-bit: Restore root domain state as the low-level * return code will not align it to regs.flags. */ if (root_entry) local_irq_restore_nosync(flags); return 0; }