318 |
and sharing memory. Conceptually, containers contain a set of |
and sharing memory. Conceptually, containers contain a set of |
319 |
integers identifying \keyword{virtual frame}s in the physical memory |
integers identifying \keyword{virtual frame}s in the physical memory |
320 |
server. A virtual frame references a physical frame but is not bound |
server. A virtual frame references a physical frame but is not bound |
321 |
to a particular physical frame (this allows the physical memory server |
to a particular physical frame (thereby allowing the physical memory |
322 |
to move the contents of frames around). Virtual frames are the |
server to move the contents between physical frames for page blocking, |
323 |
sharing mechanism for physical frames. Although virtual frames may |
assembly of DMA arena and memory defragmentation). Virtual frames are |
324 |
not be copied, they may be logically copied thereby creating a new |
thus the sharing mechanism for physical frames. Although virtual |
325 |
virtual frame with the same underlying physical frame in which case |
frames cannot be copied, their contents may be logically copied such |
326 |
the physical memory is shared. Sharing may be either real, |
that a new virtual frame is created with the same underlying physical |
327 |
e.g. System V shared memory, or logical, e.g. copy on write. |
frame. Sharing may be either real, e.g. System V shared memory, or |
328 |
|
logical, e.g. copy on write. |
329 |
|
|
330 |
When a virtual frame is allocated into a container, there may be no |
When a virtual frame is allocated into a container, there may be no |
331 |
physical frame associated with it. The physical memory server |
physical frame associated with it. The physical memory server |
342 |
backing store and the the frame identifier in the container is |
backing store and the the frame identifier in the container is |
343 |
maintained by the physical memory server. |
maintained by the physical memory server. |
344 |
|
|
345 |
When a task starts, it will allocate an initial contain and several |
When a task starts, it will allocate an initial container and several |
346 |
frames into it. Typically, the total amount of memory used by an |
frames into it. Typically, the total amount of memory used by an |
347 |
application will exceed the total number of guaranteed frames. When |
application will exceed the total number of guaranteed frames. When |
348 |
the task reaches its maximum permitted allocation, it must reuse an |
the task reaches its maximum permitted allocation, it must reuse an |
353 |
illustrates that imagining a virtual frame as bound to a page in a |
illustrates that imagining a virtual frame as bound to a page in a |
354 |
task's address space for its entire lifetime is incorrect. It should |
task's address space for its entire lifetime is incorrect. It should |
355 |
also now be clear that when the data is eventually brought back into |
also now be clear that when the data is eventually brought back into |
356 |
memory from backing store, it may reside in a different virtual frame. |
memory from backing store, it may reside in a different virtual frame |
357 |
|
(as well as a different physical frame). |
358 |
|
|
359 |
Containers are used for passing data between tasks. Typically there |
Containers are used for passing data between tasks. Typically there |
360 |
will be two tasks, a client and a server. L4 provides a mechanism to |
will be two tasks, a client and a server. L4 provides a mechanism to |
361 |
map pages from one address space to another. This mechanism could be |
map pages from one address space to another. This mechanism could be |
362 |
used when a file is mapped into a task's address space, however, this |
used to e.g. map a file into a client task's address space. An |
363 |
can present several problems. If the server dies before the client, |
analysis reveals several problems with this approach. If the server |
364 |
the mappings in the client's address space will suddenly disappear. |
dies before the client, the mappings in the client's address space |
365 |
Similarly, if the server is malicious, it may revoke the mappings at |
will suddenly disappear. Similarly, if the server is malicious, it |
366 |
some inconvenient (i.e. unrecoverable) time for the client causing it |
may revoke the mappings at some inconvenient (i.e. unrecoverable) time |
367 |
to crash. If a server allocates resources on behalf of the the client |
for the client causing it to crash. If a server allocates resources |
368 |
it becomes impossible to do system wide resource accounting as many |
on behalf of the the client it becomes impossible to do system wide |
369 |
servers are not trusted by the system. All of these problems are |
resource accounting as many servers are not trusted by the system. |
370 |
solved by containers. When a client needs to obtain a memory mapping |
All of these problems are solved by containers. When a client needs |
371 |
from a server, it creates a container and adds to it container the |
to read data from a server, it creates a container, adds the number of |
372 |
number of frames that the server will require for the operation. It |
frames that the server will require for the operation to it and |
373 |
then shares the container with the server and the server copies the |
finally shares the container with the server. After sending a request |
374 |
data into the frames. It is important to understand that the server |
to the server, the server copies the data into the provided container. |
375 |
does not ``fill'' the container: the number of frames remains constant |
It is important to understand that the server does not ``fill'' the |
376 |
but the state of the bits changes. When the server returns to the |
container: the number of frames remains constant; the state of the |
377 |
client, the client unshares the container and is now able to map the |
bits changes. When the server returns to the client, the client |
378 |
frames into its address space by contacting the physical memory |
unshares the container and is now able to map the frames into its |
379 |
server. Should the server die, the client remains uneffected as the |
address space by contacting the physical memory server. Should the |
380 |
data is cached in the physical memory server. The physical memory |
server die, the client remains uneffected as the data is cached in the |
381 |
server is also trusted thus if a task is malicious, it can only be |
physical memory server. The physical memory server is also trusted |
382 |
malicious during the initial copy of the data into the container, |
thus if a task is malicious, it can only be malicious during the |
383 |
i.e. before the client starts using the data. Finally, as the |
initial copy of the data into the container, i.e. before the client |
384 |
resources are allocated by the client via system servers, resource |
starts using the data. Finally, as the resources are allocated by the |
385 |
accounting is possible. |
client via system servers, resource accounting is possible. |
386 |
|
|
387 |
\subsection{Creating Containers} |
\subsection{The Container Interface} |
388 |
|
|
389 |
Applications are able allocate memory into containers. Containers may |
\paragraph{Creating Containers} |
390 |
be created using: |
|
391 |
|
A container may be created using: |
392 |
|
|
393 |
\begin{code} |
\begin{code} |
394 |
error\_t pm\_container\_create (out container\_t container) |
error\_t pm\_container\_create (out container\_t container) |
395 |
\end{code} |
\end{code} |
396 |
|
|
397 |
Memory allocation does not allocate physical frames: if so, it would |
A container\_t is, for all intents and purposes, a hurd\_cap\_t. If a |
398 |
be impossible to move memory around and memory would have to be |
container is shared with another task, the second task may allocate |
399 |
returned to the same spot after being swapped out and back in. |
frames which count against the container's owner's total allocated |
400 |
Containers are useful for grouping and then moving memory around. |
pages. This must be used with care. |
401 |
|
|
402 |
|
\paragraph{Sharing Containers} |
403 |
|
|
404 |
|
To allow another task to access the contents of a container, the |
405 |
|
container must be shared. Clearly, it is not desirable to grant full |
406 |
|
access to the container to the remote task: trust between a client and |
407 |
|
a server must exist, however, that trust is typically limited in both |
408 |
|
directions (neither the client trusts the server fully nor does the |
409 |
|
server fully trust the client). Since clients provide the resources |
410 |
|
to server to servers, servers need to a guarantee that the client will |
411 |
|
not touch the resources while it is in a critical section (for example |
412 |
|
while performing a DMA operation). Likewise, clients need to have the |
413 |
|
ability to cancel an exant request and reclaim shared resources if the |
414 |
|
server does not answer in a timely manner thereby also preventing the |
415 |
|
server from being able to steal resources. In both of these cases, |
416 |
|
the physical memory server acts as the trusted third party. The |
417 |
|
physical memory server allows a server to lock a container for a |
418 |
|
limited amount of time during which the client may not access or |
419 |
|
destroy the resource. At any other time, the client can cancel the |
420 |
|
server's access to the shared resource. |
421 |
|
|
422 |
|
To facility this, a second class capability is provided to access |
423 |
|
containers. Using this capability, clients may not allocate or |
424 |
|
deallocate frames. |
425 |
|
|
426 |
|
\begin{code} |
427 |
|
error\_t pm\_container\_share (in container\_t container, in task\_t |
428 |
|
remote, out container\_t weak_ref) |
429 |
|
\end{code} |
430 |
|
|
431 |
|
\noindent |
432 |
|
\variable{weak\_ref} can be passed to the sharee using the normal |
433 |
|
capability passing protocol. |
434 |
|
|
435 |
How to get frames. Type of frames (e.g. DMA) or fixed physical address. |
\paragraph{Allocating Memory} |
436 |
|
|
437 |
Memory is not allocate until map time (and not always then, |
Virtual frames may be allocated into a container using: |
438 |
e.g. logical copies). |
|
439 |
|
\begin{code} |
440 |
|
error\_t pm\_container\_allocate (in container\_t container, in |
441 |
|
frame\_t start, in out int count, in int flags) |
442 |
|
\end{code} |
443 |
|
|
444 |
|
\noindent |
445 |
|
\variable{start} is the first frame identifier to use for the new |
446 |
|
memory. If \variable{count} is greater than one then frames will be |
447 |
|
allocated in the subsequent $count - 1$ frame identifiers. The number |
448 |
|
of frames actually allocated is returned in \variable{count}. If an |
449 |
|
identifier already references a virtual frame, \errno{EEXIST} is |
450 |
|
returned. \variable{flags} is a bitwise or of: CONT_ALLOC_PARTIAL, |
451 |
|
CONT_ALLOC_SQUASH and CONT_ALLOC_EXTRA. If CONT_ALLOC_PARTIAL is set |
452 |
|
and the number of frames which can be allocated before a memory |
453 |
|
allocation error occurs is greater than one but less than |
454 |
|
\variable{count} then the maximum number of frames is allocated, count |
455 |
|
is set to that number and the error is returned. If |
456 |
|
CONT_ALLOC_PARTIAL is not set then partial allocations will fail, |
457 |
|
count will be set to 0 and an error will be returned. If |
458 |
|
CONT_ALLOC_SQUASH is set and a frame identifier already references a |
459 |
|
frame, the virtual frame will be dropped and its contents lost. Using |
460 |
|
this flag is dangerous and be a sign of internal inconsistencies in |
461 |
|
the task! All virtual frames should be accounted for by the task and |
462 |
|
deallocated explicitly. If CONT_ALLOC_EXTRA is set then extra frames |
463 |
|
may be allocated otherwise the physical memory server will only |
464 |
|
allocate up to the guaranteed virtual frame limit. This flag should |
465 |
|
only be used by tasks able to handle the added complexity of the extra |
466 |
|
frame protocol. The contents of allocated frames is undefined. |
467 |
|
|
468 |
|
% When obtaining data from a server (e.g. reading from a file), tasks |
469 |
|
% will: create a container, fill it with anonymous memory and share the |
470 |
|
% container with the server. Since this is a very common operation, a |
471 |
|
% short cut has been provided to which combines the three operations: |
472 |
|
|
473 |
\subsection{Mapping Memory} |
\paragraph{Mapping Memory} |
474 |
|
|
475 |
The physical memory server guarantees that a mapping operation will |
The physical memory server guarantees that a mapping operation will |
476 |
take a short amount of time: this is not guaranteed to happen |
take a short amount of time: there is no guarantee that this will |
477 |
immediately as the virtual frames may only be allocated at this point |
happen immediately as the underlying physical frames may have to be |
478 |
and they may have to be reaped from other tasks' extra frame |
allocated in which case the physical memory server may have to be reap |
479 |
allocations. |
physical pages from other tasks' extra frame allocations. |
480 |
|
|
481 |
The physical memory server may unmap pages at any time. This allows |
The physical memory server may unmap pages at any time. This allows |
482 |
the contents of vitual frames to be moved between physical frames by |
the physical memory server to fucntionally lock the contents of the |
483 |
the physical memory server which permits page blocking (i.e. the |
frame and move it to a new physical frame. Given this, tasks must be |
|
construction of superpages), the creation of DMAable memory areas or |
|
|
other specific physical address and the creation of contiguous blocks |
|
|
of memory (e.g. to defragment physical memory). Tasks must be |
|
484 |
prepared to reestablish a mapping with the physical memory server at |
prepared to reestablish a mapping with the physical memory server at |
485 |
any time. |
anytime. (Thus, the physical memory server does not serve as a |
486 |
|
registry of mappings.) |
487 |
|
|
488 |
Mappings may be granted readonly evil if the a read/write mapping was |
Read-only mappings may be returned when read/write mapping are |
489 |
requested: the physical memory server will not grant a read/write |
requested: the physical memory server will never grant a read/write |
490 |
mapping if the frame is marked copy on write. In order to get a |
mapping if the frame is marked copy on write. In order to obtain a |
491 |
read/write mapping (and thus force the copy on write early), the task |
read/write mapping (and thus force the copy on write), the task must |
492 |
must request add the enforced write flag when mapping. |
add the enforced write flag to the mapping request. |
493 |
|
|
494 |
\begin{code} |
\begin{code} |
495 |
error\_t pm\_container\_map (in container\_t container, in frame\_t |
error\_t pm\_container\_map (in container\_t container, in frame\_t |
497 |
\end{code} |
\end{code} |
498 |
|
|
499 |
\noindent |
\noindent |
500 |
Flags may is a bit wise or of: CONTAINER\_MAP\_READ, |
Flags may is a bit wise or of: CONT\_MAP\_READ, CONT\_MAP\_WRITE and |
501 |
CONTAINER\_MAP\_WRITE and CONTAINER\_MAP\_ENFORCE\_WRITE. |
CONT\_MAP\_FORCE\_WRITE. CONT\_MAP\_FORCE\_WRITE will only be |
502 |
|
respected if CONT\_MAP\_WRITE is also set. |
503 |
|
|
504 |
\subsection{Moving Data} |
\paragraph{Moving Data} |
505 |
|
|
506 |
In a monolithic kernel, little data is exchanged between tasks. In a |
In a monolithic kernel, little data is exchanged between tasks. In a |
507 |
multiserver system, file systems live in their own tasks and thus |
multiserver system, file systems live in their own tasks and thus |
508 |
reading and writing involve servers. Thus, powerful primatives for |
reading and writing involve servers. Thus, powerful primatives for |
509 |
moving memory around with the least number of physical copies, |
moving memory around with the least number of physical copies, |
510 |
i.e. using virtual copy mechanisms which preserve COW frames, etc. |
i.e. using virtual copy mechanisms which preserve COW pages, etc. |
511 |
|
|
512 |
It is important that an fs does not map from one task to another |
It is important that an fs does not map from one task to another |
513 |
directly: the client may not trust the source or the source may die, |
directly: the client may not trust the source or the source may die, |
514 |
etc. Doing the mapping via the phys memory server means all trust |
etc. Doing the mapping via the phys memory server means all trust |
515 |
issues are resolved at the time of mapping and can be reported to the |
issues are resolved at the time of mapping and can be reported to the |
516 |
user: the fs cannot pretend to be nice and then revoke mappings and |
user: the fs cannot pretend to be nice and then revoke mappings |
517 |
silently harm the client. |
silently harming the client. |
518 |
|
|
519 |
Data will be moved around using containers. Describe how to read and |
Data will be moved around using containers. Describe how to read and |
520 |
write. Task -> FS -> Device drivers. Locking memory. Caching. |
write. Task -> FS -> Device drivers. Locking memory. Caching. |