Hi, just to add that in the normal case obviously the correct process *is* running when the semaphore is accessed (sem_wait(), sem_post()), but there is one exception: sem_waitirq() which is called either by the watchdog ISR or by the signal dispatch logic. In this case most likely the correct process is *not* running, meaning access to the sem fields needed by the kernel either go to the wrong address environment, or cause a page fault. So the control fields in sem_t are tied to the process that instantiates the semaphore, and if it messes the fields up only the process itself is affected (the process can be killed for being naughty but the kernel survives). But in those two exception cases, the kernel needs access to the semaphore.
This is the best argument that I have heard for splitting the semaphore data.
Another option would be keep the kernel addressing within the sem_t.