l4_thread_ex_regs and suspending thread
Valery V. Sedletski
_valerius at mail.ru
Wed Jul 20 01:32:29 CEST 2016
Adam Lackorzynski wrote:
> Hi,
>
...
> but strange that it got a pagefault in case ~0 or L4_INVALID_ID is
> specified, but does not change the registers or/and pager/preempter if I
> specify 0 for eip/esp or l4_threadid_t initialized with zeros instead of
> L4_INVALID_ID
> I'm looking at
> https://svn.tudos.org/repos/tudos/trunk/kernel/fiasco/src/kern/thread.cpp,
> Thread::initialize, starting at line 850. There, sp and ip are only
> changed when they're not ~0. Pager and preempter are only set if they're
> valid (the lookup function is used to derive the pointer, which is 0 for
> the invalid_id). Are we looking at the same code?
>
Yes, I see that in my Fiasco sources. And also I see that it changes
pager/preempter only if they are not zero. (probably, it is converted
from l4_threadid_t earlier). ip/sp are checked against ~0. And it seems
that you're right. -- I changed something in the code, and now it
doesn't cause the unhandled pagefault, so, probably, it was my proble,.
It seems to suspend/resume without problems now, though I didn't
saved/restored thread state yet (as you said later on this text)
>>>> So, is it possible anyhow to suspend/resume the running thread from another
>>>> thread? I know, that the thread can be suspended if entering unconditional
>>>> l4_ipc_wait(), but this is from the inside that thread. How could it be done
>>>> from an outside thread?
>>> One way is to set the thread on such a loop via ex_regs (and paying
>>> attention to the register contents which basically means there's some
>>> assembly code involved). Another way is to do
>>> ex_regs(id, ~0, ~0, L4_THREAD_EX_REGS_RAISE_EXCEPTION) which will
>>> trigger an artificial exception in the thread and have it send an
>>> exception IPC to its pager. The pager should then just not reply to have
>>> the thread suspended, and then reply when you want to have the thread go
>>> on later. What makes this a bit tricky is when L4 IPC is involves which
>>> you will cancel with ex_regs, or not, if you use the
>>> L4_THREAD_EX_REGS_NO_CANCEL flag.
>>>
>> I tried the 1st way -- set eip to the address of IPC wait loop, so it does
>> suspend here, but resume doesn't work. -- You said that I'll need to set
>> some registers via assember, but I wonder which ones -- the changed one is
>> eip only. esp and eflags are only read, but didn't changed, others seems to
>> be not altered with ex_regs...
> What I meant is that the code must not change the thread's registers, or
> it needs to ensure that the original values are restored when resuming
> the thread. So when forcefully engaging the thread into an IPC,
> registers might be changed when returning from that IPC, for example,
> because it was cancelled. Thus the code which does the suspend should
> save all CPU registers and just restore all of them when doing the
> resume. That operation will take some assembly efforts.
> With L4_THREAD_EX_REGS_RAISE_EXCEPTION this effort is taken by the
> kernel and the pager just needs to memcpy the state away but requires
> interaction with said pager so it depends on the setup what it easier to
> do.
>
>
Ah, so something can be changed when cancelling the IPC -- then I'll
need to save/restore the thread state manually (or use the 2nd method
with L4_THREAD_EX_REGS_RAISE_EXCEPTION).
Thank you very much for clarification!
> Adam
More information about the l4-hackers
mailing list