Implemented a protocol between a client and its pager to
request and get a capability to ipc to another client of the pager.
Pager first ensures the request is valid from its client.
It then tries to use a greater capability that it possesses, to
produce a new capability that the client requested. Once the kernel
validates the correct one and replicates/reduces it to client's
need, it grants it to the client.
Pager handles client capability requests by using one of its own
capabilities to create a new one that suits the client's needs.
The current issue is that the kernel can have multiple caps and it
may not know which one is suitable for using to create one for the client.
The kernel knows this very well, so the solution would be to attempt to
use capabilities that roughly match (i.e. by type) and leave it to
the kernel to decide whether it is any powerful to suit client's needs.
In posix, test0 makes inter-space ipc for testing extended ipc. This
correctly fails when only the cap to ipc to pager is given to all tasks
in the container.
In order to overcome this problem, the tasks who fork for doing ipc to
each other make a request to the pager to get capabilities to do so.
Pager finds its own widened ipc capability over the container, replicates
it, validates and reduces it to desired boundaries (i.e. just ipc betw.
two spaces) and grants it as IMMUTABLE to requesting tasks.
This protocol may be useful in implementing a client/server capability
request relationship. Code builds but untested.
Modifying task_virt_to_page() so that it takes into account page
protections. If mm0 writes to a task page that is meant to be
read-only, (e.g. the zero page) the design is broken.
Every access to a task's page will take the page fault route,
and the page fault handler will return the page instead of 0.
Utcb support has beed added. It has the same drawback as in the stack support:
the area in questen has to be already mapped-in. There is some basic
infrastructure for utcb to support mapping but it is far from being complete.
MAPPING_ENABLE symbolic constant controls this behaviour.
There are also some minor fixes for the stack support and the utcb common helper
routines.
The difference between this thread library and the existing ones like pthreads
is the necessity of informing the library about the address range of the stack
and the l4 specific utcb. Utcb has not been supported yet. As for stack, there
is also a drawback: library does not support mapping. In other words, the stack
area in question has to be already mapped-in. Thus, for now we only support
threads sharing their address spaces: TC_SHARE_SPACE. In this respect, it is
very similar to pthreads.
bss segment may have some of it at the end of data, but the bits
that lie on a new page need to be mmaped as anonymous. When this
occured we were not passing the new page boundary but the last
data page where bss started
This is one of the steps we need in the process of providing a similar interface
for thread creation which can be found in the mainstream operating systems like
Linux.
Examples container type is designed to keep applications using codezero
userspace libraries, which is aiming to help newcomers who would like to
develop programs on top of the l4 microkernel.
Now bare bone application is one of the examples. In the near future, lots of
new programs will be introduced to show the various aspects of codezero
eco-system.
Currently, the tid returned from kernel contains container id as
well, which makes it sufficient to do inter-container syscalls without
any preparation.
The helpers added are for presentation purposes only. Container id
is deleted so that the raw thread id is available for printing or
similar.
Thread ids now contain their container ids in the top 2 nibbles.
Threads on other containers can be addressed by changing those
two nibbles. The addressing of inter-container threads are
subject to capabilities.
Task ids are now unsigned as the container ids will need to be encoded
in the id fields as well.
For requests who require even more comprehensive id input, (such as
thread creation) also added is the container id so that threads
_could_ potentially be created in other containers as well.
VIRTMEM and PHYSMEM are theoretically separate resources to be
protected than a MAP resource, which is meant to protect the syscall
privileges.
In practice MAP is always used together with a VIRTMEM and a PHYSMEM
resource, therefore reach VIRTMEM/PHYSMEM resource is now merged with
the MAP capability, combining the micro-permission bits.
Previously all pending events were handled on return of exceptions
in process context. This was causing threads that run in userspace
and take no exceptions not handle their pending events indefinitely.
Now scheduler handles them in irq context as well.
Multi-threaded apps can now wait on children to destroy.
WAIT_ON is useful when a child exists with an exit code and the pager
of the child does not want to take the hassle of destorying it via an
ipc. It provides an alternative method of synchronous thread destruction,
where the child destroys itself directly rather than the parent issuing
a destroy on it explicitly.
Reiterating again to simplify:
Working:
- Pager issues destroy, client also issues exit
they work in sync.
Missing
- Pager killing itself
- Pager killing all children while killing itself
- Pager waiting on children
This malloc is a very simple first-fit sort of allocator. Now, it builds
without any problem but because we havent fixed include paths and added
it to the referenced libraries in the posix container yet, POSIX doesnt
build. So take it with caution.
(cherry picked from commit 65523743e86268eddd3bd2aab58476003f71c2c2)
We moved initial list of a pager's caps from ktcb to task's space
since the task is expected to trust its space.
Most references to task->cap_list had to change. Although a single
cap list only tells part of the story about the task's caps, the
TASK_CAP_LIST macro works for us to get the first private set of
caps that a task has.