asmlinkage void __ipipe_unstall_iret_root(struct pt_regs regs) { ipipe_declare_cpuid; /* Emulate IRET's handling of the interrupt flag. */ local_irq_disable_hw(); ipipe_load_cpuid(); /* Restore the software state as it used to be on kernel entry. CAUTION: NMIs must *not* return through this emulation. */ if (!(regs.eflags & X86_EFLAGS_IF)) { __set_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status); regs.eflags |= X86_EFLAGS_IF; } else { __clear_bit(IPIPE_STALL_FLAG, &ipipe_root_domain->cpudata[cpuid].status); /* Only sync virtual IRQs here, so that we don't recurse indefinitely in case of an external interrupt flood. */ if ((ipipe_root_domain->cpudata[cpuid]. irq_pending_hi & IPIPE_IRQMASK_VIRT) != 0) __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT); } }
/* * This is our default idle handler. We need to disable * interrupts here to ensure we don't miss a wakeup call. */ static void default_idle(void) { #ifdef CONFIG_IPIPE ipipe_suspend_domain(); #endif local_irq_disable_hw(); if (!need_resched()) idle_with_irq_disabled(); local_irq_enable_hw(); }
void __ipipe_halt_root(void) { struct ipipe_percpu_domain_data *p; /* Emulate sti+hlt sequence over the root domain. */ local_irq_disable_hw(); p = ipipe_root_cpudom_ptr(); trace_hardirqs_on(); __clear_bit(IPIPE_STALL_FLAG, &p->status); if (unlikely(__ipipe_ipending_p(p))) { __ipipe_sync_pipeline(); local_irq_enable_hw(); } else { #ifdef CONFIG_IPIPE_TRACE_IRQSOFF ipipe_trace_end(0x8000000E); #endif /* CONFIG_IPIPE_TRACE_IRQSOFF */ asm volatile("sti; hlt": : :"memory"); } }