Jens Nerche <[EMAIL PROTECTED]> wrote:
> In the first paging step the guest os selects a page. But may be that page
> is in use (in another os), so the monitor in the second paging step has to
> search another page for substitution. If this is a clear page it should
> be so matter, if not this is a page for shared memory, so the monitor
> has to find the right page.
I don't think there should be any default relationship between guest
physical page numbers and host physical page numbers. The monitor
uses an array of pages allocated from the host, which the host won't
use for anything (of course). Those pages will serve as guest physical
pages (in whatever sequence we choose). [ This is the simple version
where we use only non-paged memory, see below for the general case. ]
> We use page protection mechanisms for detecting guest os page table writes.
Definitely.
> There are several questions:
> 1. Do we need a segmentation level for monitor? (Between Level 1 and 2)
> 2. Can we combine Level 3 and 4 so we need only one Paging Level?
> 3. Are we able to hide this architecture so that guests don't
> see them?
We can't use any different 'levels'; replacing the hardware segmentation
and paging features by *any* software solution would be *much* too
expensive.
We'll have to use the hardware features, but with a twist: whenever
the guest loads a PDBR, we load the real PDBR with a pointer to a
*monitor* structure. This monitor page directory is constructed by
reading the guest page directory and replacing all guest physical page
numbers with the corresponding host physical page numbers. Subsequently,
the guest page direcory (and page tables) are marked read-only, and any
attempt to modify those will trap to the monitor, where we can update
the 'real' monitor page tables in step.
Similarly we will use monitor GDT and LDTs. Those will be not much
different from the original guest GDT/LDT, except that we will need
to modify e.g. call gates (don't want the guest to write itself a
call gate to real ring-0, do we? :-/), and we probably need to have
some additional entries for use by the monitor.
> To the 3.: Is there an other chance than use swapping aggressively? If we
> have only the context of exact one os in ram there should be no problem -
> but the performance...
Trying to use paged memory as guest physical memory should IMO be an
optimization to be performed later; we should really have the other
stuff in place first. Obivously, the details of how to implement this
will depend on the implementation of still missing features, but one
option of solving this could go about like this:
The monitor page fault handler compares the 'real' monitor page table
with the guest page table. If the guest thinks the (virtual) page
should have an underlying physical page, but the monitor doesn't think
so, the monitor switches back to the host and causes a host page fault;
the handler will allocate a physical page any page in the contents of
the host swap file. If, however, the guest thinks that the page
*shouldn't* be present, we just forward the page fault to the *guest*
page fault handler, which will page in the page from the guest swap file.
[ Some time past, I've sent pseudo-code for the page fault handler
to the list ... ]
The difficult problem is when to decide to free a page. Obviously,
when the guest frees a page from the guest page tables, we're free to
free it from the monitor page tables as well and return it to the host.
On the other hand, we'll want to *take away* pages, if the host memory
pressure becomes to high. We can't just let the host swap pages out
arbitrarily, because they are still entered into the monitor page
tables, which are in actual use by the processor when running the
monitor! (Think SMP kernels: one processor running our monitor, the
other processor trying to swap out ...)
So, we'll need to keep pages locked on the host side whenever they
are mapped to the monitor page tables. But then we might just as
well use non-paged memory throughout, because the guest will soon
have touched every guest physical page once, and then they are all
mapped :-/ So, we'll have to implement some kind of swap algorithm
ourselves; we'd have to notice (somehow) that the host needs to
swap out pages, and then choose which guest physical pages have
been accessed least frequently (recently?) and throw them out of
the monitor page tables before unlocking them on the host side ...
[ A general note on terminology: For many of the processor data
structures, e.g. page tables, GDT, ... we'll constantly need
to consider three variants. I've tried to consistenly use the
same adjectives when referring to them: host, monitor, and guest.
host: The variant that is actually loaded into the processor
registers whenever the host OS is running.
monitor: The variant that is actually loaded into the processor
registers whenever the FreeMWare monitor *or* the guest
OS running under it is active.
guest: The variant that *would* be loaded into the processor
registers, if the guest OS were running natively. (This
must never be actually loaded into the processor when
running under FreeMWare!)
]
Bye,
Ulrich