On 08/17/2014 12:55 AM, Adam Lackorzynski wrote:
So now I'm not sure how you want to proceed. Are your programs special ones, i.e. that they are quite different from L4 programs or are they L4 programs? I wondering where to do the paging, however, in any case it sounds to me like doing it in a different task would be good.
To address your question: You map the pager to the task with the dst_task->map() call as shown above. The pager is probably a thread you implement, for doing your work. The order does not really matter because the thread only starts running until the run_thread call, i.e. it does not matter whether the pager cap (any cap) is mapped before or after it has been registered with the thread.
How would I configure the new task to use the same pager that the current task is? Looking at libloader, I'd think it would be something like:
task-map(L4Re::This_task, env->rm().fpage(), env->rm().snd_base());
but I'm not sure if I need to create a new region map or something like that. I think I've got memory mapping working, but the process dies with an unhandled read page fault.
- Noah Zentzis
On Tue Aug 19, 2014 at 20:59:16 -0700, Noah Zentzis wrote:
On 08/17/2014 12:55 AM, Adam Lackorzynski wrote:
So now I'm not sure how you want to proceed. Are your programs special ones, i.e. that they are quite different from L4 programs or are they L4 programs? I wondering where to do the paging, however, in any case it sounds to me like doing it in a different task would be good.
To address your question: You map the pager to the task with the dst_task->map() call as shown above. The pager is probably a thread you implement, for doing your work. The order does not really matter because the thread only starts running until the run_thread call, i.e. it does not matter whether the pager cap (any cap) is mapped before or after it has been registered with the thread.
How would I configure the new task to use the same pager that the current task is? Looking at libloader, I'd think it would be something like:
task-map(L4Re::This_task, env->rm().fpage(), env->rm().snd_base());
but I'm not sure if I need to create a new region map or something like that. I think I've got memory mapping working, but the process dies with an unhandled read page fault.
Yes, you'd need to create a new region mapper for the new task, one that knows about the virtual address space layout of that one. Should be possible by using a new instance of Region_map as done in the l4re_kernel. You'll also need to create an IPC-gate to be used as the pager for the new task and which is routed to the Region_map instance for that task. You also need to handle other events that come through the pager channel, see Dispatcher::dispatch in l4re_kernel/server/src/dispatcher.cc for the switch block.
Adam
On 08/21/2014 02:14 PM, Adam Lackorzynski wrote:
Yes, you'd need to create a new region mapper for the new task, one that knows about the virtual address space layout of that one. Should be possible by using a new instance of Region_map as done in the l4re_kernel.You'll also need to create an IPC-gate to be used as the pager for the new task and which is routed to the Region_map instance for that task. You also need to handle other events that come through the pager channel, see Dispatcher::dispatch in l4re_kernel/server/src/dispatcher.cc for the switch block.
I'm not sure how to create a new Rm instance - I'm trying this:
L4::CapL4Re::Rm region = newcapL4Re::Rm(); // allocate capability factory->create(region, L4Re::Protocol::Rm); check_cap(region, "Failed to allocate region map");
But the factory fails to create a new region map. This is, as far as I can tell, exactly what libloader is doing, so I'm not sure what's wrong. Also, can I use the current task's pager for testing instead of implementing the interface, or will it fail if I don't handle paging myself?
- Noah Zentzis
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 28.08.2014 06:33, Noah Zentzis wrote:
On 08/21/2014 02:14 PM, Adam Lackorzynski wrote:
Yes, you'd need to create a new region mapper for the new task, one that knows about the virtual address space layout of that one. Should be possible by using a new instance of Region_map as done in the l4re_kernel.You'll also need to create an IPC-gate to be used as the pager for the new task and which is routed to the Region_map instance for that task. You also need to handle other events that come through the pager channel, see Dispatcher::dispatch in l4re_kernel/server/src/dispatcher.cc for the switch block.
I'm not sure how to create a new Rm instance - I'm trying this:
L4::CapL4Re::Rm region = newcapL4Re::Rm(); // allocate capability factory->create(region, L4Re::Protocol::Rm); check_cap(region, "Failed to allocate region map");
Adam already pointed you to l4re_kernel, which is the binary that is initially loaded into each application's address space:
* l4re_kernel first sets up a new region map (this is the data structure representing the address space) in l4re_kernel/server/src/main.cc * It then calls the loader's load() method, which is implemented in l4re_kernel/server/src/loader.cc. * Loader::start() sets up a new thread within this address space and sets itself as the pager of this thread. In the function there are two ways of doing so: 1. Either you have a capability to the thread that shall be the pager. Then you can enter this cap as the newly created thread's pager. 2. Alternatively you can create a new IPC gate using factory_create_gate(). Then you bind the pager thread to this gate and give the newly created thread the gate capability as its pager. * With this set up, the new thread will start executing application code. If it raises a page fault, the kernel redirects this fault to the pager thread, which we set in the previous setp. These messages will arive in l4re_kernel/server/src/dispatcher.cc. The dispatcher identifies them by looking at the IPC message's label field, which will be L4_PROTO_PAGE_FAULT for page faults and L4Re::Protocol::Rm for region management requests.
But the factory fails to create a new region map. This is, as far as I can tell, exactly what libloader is doing, so I'm not sure what's wrong. Also, can I use the current task's pager for testing instead of implementing the interface, or will it fail if I don't handle paging myself?
The default memory management model in L4Re is that each application's address space is managed by one pager thread, the region manager. This model requires the RM to be part of the same address space and hence your local pager will not be able to handle page faults for a remote task.
Hth, Bjoern
l4-hackers@os.inf.tu-dresden.de