In the case of a propagated message, current->get_partner()'s result may not
refer to the same thread as from_tcb->get_{local,global}_id(). This changeset
narrows the case where local TIDs are returned to avoid this confusion.
This changeset also makes explicit (through the use of an ASSERT()) the
assumption that only global IDs are passed through propagation.
This could happen if CPU was not set to I686, P4, or K8
(Thanks to Simon Kellner for a hint that helped finding this bug)
- Removed redundant "defined(CONFIG_CPU_X86_K8)"
- Fixed typo in comment
1) A race condition that causes an assertion to fail: kdb_current_cpu stores
the current CPU executing within the KDB; all other CPUs are sleeping
uninterruptibly waiting for a broadcast NMI to either go on or try to enter
KDB themselves (see kdb_t::pre()). There might actually occur a race
condition, because the CPU leaving KDB first resets kdb_current_cpu, then
uses an NMI broadcast to inform other CPUs that they may go on or enter KDB,
and finally verifies the value of kdb_current_cpu. But meanwhile the value
may have changed because of another CPU instantly entering KDB again.
Solution: remove the bogus assertion
2) Occasionally, depending on the hardware circumstances, an NMI may arrive
at the processor while a pending NMI hasn't been serviced yet. In this case
a CPU may receive an "exit KDB" NMI without having had time to process the
"enter KDB" NMI. In that case, it will jump into KDB with reason
X86_EXC_NMI. Handle this case by just leaving KDB instantly.
3) Only send broadcast NMIs to stop other CPUs if the CPU has actually
initiated the entering of KDB (i.e., if it isn't one of those having
received a broadcast NMI itself).
stored in the init section, i.e., at a low address, so that it can be called
before virtual memory has been initialized. Later on, however, init memory
may not be mapped into each address space anymore. The fix introduces a
private init_gate() and a public add_gate() function to idt_t, of which the
former is used during initialization, and the later afterwards.
- In rare cases, we might get a NMI (or breakpoint exception) just after
sys_ipc has been invoked, but _before_ esp has been set to tss.esp0 in that
case, we need to switch stacks manually and preserve the processor-saved
frame. We make sure that, before tss there is enough scratch space to cover
EFLAGS, CS, and EIP saved by the processor; this way, we can get around
without having to spend KDB its own interrupt task gate