On Tue, 2013-03-19 at 12:29 +0100, Norman Feske wrote:
Thanks Alex for your response,
mappings on its own. And second, grant does not allow steeling something, if Task A wants to revoke memory it mapped to Task B it can always use its local address to do that regardless of what Task B did by granting or mapping memory somewhere else. So in other words the 'l4_task_unmap' call is useful for tasks that are fully controlled by some other task (tasks that cannot map/grant by themselves) As for example L4Linux user-level tasks or virtual machines.
I am afraid that I did not express the fundamental idea of my proposal well enough. In the new version of roottask, roottask maps directly from the physical address space to the virtual address space of all other processes (in your example, this is task B) without keeping a local mapping. So roottask does not possess a mapping node to revoke such mappings. In order to be able to revoke mappings, it keeps records of the virtual addresses to where it installed the mappings in the other tasks. For revoking a mapping, roottask performs 'l4_task_unmap' with the remote task capability and the remote virtual address range as arguments.
I think I already got this. And my proposal is to not use l4_task_unmap to unmap memory from an arbitrary address space, doing this either need cooperation from the target or full control over the target address space (using VCPU or alien). However you can use unmap with a local address in the roottask (pager) and unmap from all children.
The "stealing" would happen if task B grants the mapping to somewhere else. My incentive behind the removal of the memory-granting mechanism is solely to avoid this loophole. I would appreciate to know more specifically, which "legitimate use cases" this would break. For example, does L4Re relies on granting memory? Please note that the mapping database is still in effect for mappings further propagated by task B. But task B would be the root of the mapping tree.
In fiasco the root of a mapping tree is always sigma0 as long as it does not grant, and our implementation doesn't. If an intermediate task uses grant it will not disconnect a subtree it will just move the mapping node to a different location (virtual address and/or task).
So we currently do not consider removing sigma0 as a user-level process. Nor do we consider changing the semantics that sigma0 has access to all physical memory resources. Hence there is currently no good reason to support unmapping memory from sigma0 because it could regain access to that memory by accessing it.
I did not suggest at all to change sigma0/roottasks's ultimate power over physical memory. Sigma0/roottask can still map any physical page to its local address space using l4_task_map with the physical address as source and its local virtual address as destination. The two fundamental differences are that those mappings are not installed auto-magically but explicitly, and that the mappings are not necessarily identity mappings. By explicitly installing the mappings, roottask gains robustness. By removing the identity-mapping policy of sigma0, roottask can use its virtual memory more flexible.
The semantic change is that currently there is no notion of physical addresses in the Fiasco API and your proposal introduces this notion for a single task, call it sigma0.
My line of thinking is that the fewer memory is shared between roottask and other user-space processes, the better. The current architecture shares all memory of all processes with roottask. In the variant I suggest, roottask shares no memory with other user processes.
I totally agree that for robustness reasons it would be good to not map all the memory to the roottask, and in fact you can already do this by changing the pager of the roottask thread itself to point to an invalid capability for example to prevent unwanted page faults to be resolved by sigma0. The tricky part is to map memory to clients that is not mapped in the server, one would have to request the memory on demand from sigma0 and then grant it to the client task. If you want to have revocation you would either need to enhance the sigma0 protocol to request sigma0 to do unmaps of memory on a sigma0-clients behalve, or need to use an extra task that has the whole memory mapped and use l4_task_map to map this memory to your roottask and then grant it to your client, for revocation you can use l4_task_unmap with that helper task.
Currently not, we consider sigma0 being part of our architecture and will probably stay with it. However, there could be possible enhancements to the sigma0 interface that support your use-cases. And there could also be some kernel-interface enhancements that allow more effective and robust user-level memory management.
Even though sigma0 and roottask happen to be executed in user space, both are logically part of the operating system's kernel because all other processes ultimately depend on them. According to the principles of microkernel construction, the kernel should be free from policy. Yet, you support keeping policy in the form of sigma0, which can easily be removed as my experiment suggests. According to the minimality principle, the kernel should contain functionalities only if they are strictly needed. I fail to grasp how sigma0 qualifies for that. When looking at the problem from this perspective, "enhancing" the sigma0 interface looks like going in the wrong direction. It would make the kernel of the system (which is not merely the code executed in privileged mode) not less complex but more complex.
This will be an endless discussion I think...
Our policy is that everybody can run its own implementation of sigma0 on Fiasco.OC and yes it is part core functionality for any OS running on Fiasco, this does not mean that we should put its functionality into the microkernel.
regards