l4_thread_ex_regs and suspending thread

Adam Lackorzynski adam at os.inf.tu-dresden.de
Tue Jul 19 00:10:11 CEST 2016


Hi,

On Mon Jul 18, 2016 at 07:01:53 +0300, Valery V. Sedletski wrote:
> Adam Lackorzynski wrote:
> > So I'm looking at the late v2 version of Fiasco and I'm reading the code
> > such that ~0 means "don't change this value". The current/old value is
> > delivered back in any case. Regarding the L4_INVALID_ID, I'm reading the
> > code such that the pager will not be set when the target ID does not
> > exist, which includes L4_INVALID_ID, i.e. the thread's pager should not
> > be changed.
> 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?

> > > 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.



Adam
-- 
Adam                 adam at os.inf.tu-dresden.de
  Lackorzynski         http://os.inf.tu-dresden.de/~adam/



More information about the l4-hackers mailing list