So far we've focused on explaining the basics of how to virtualize
efficiently the CPU, but
let's now look at the other types of resources looking at memory first.
We will explain how memory virtualization can be achieved for
the two basic virtualization approaches,
whether it's based on full virtualization, or
requires guest modification and we will talk about full virtualization first.
For full virtualization a key requirement is that the guest operating
system continues to observe a contiguous linear physical address space
that starts from physical address zero, this is what an operating system with
c if it actually own the physical memory and run natively on physical hardware.
To achieve this we distinguish among three types of addresses,
virtual addresses, so
these are the ones that are used by the applications in the guest.
Physical addresses, these are the ones that the guest thinks are the addresses
of the physical resource and the machine addresses, these are the actual machine
addresses with the actual physical addresses on the underlying platform.
The similar distinction of virtual verses physical verses machine will also
apply to the page numbers and the page frame numbers.
So given this, the guest operating system can continue make mappings of
virtual addresses to of the physical addresses that it thinks it owns,
and then underneath that the hypervisor will then pick
these physical addresses that the guests believes are the real ones and
map them to the real machine addresses.
So in a sense they're two page tables, one that's maintained by the guest
operating system, and another one that's maintained by the hypervisor.
Now remember that at the hardware level, we have a number of mechanisms,
the memory management unit, the TLB caching of the address translations,
that these mechanisms help with the address translation process,
make it much more efficient, and don't require us, in software,
to repeatedly perform address translations and validations.
Now this option that we discussed so
far will require that every single memory access goes through
two separate translation, the first one which will be done in software,
and then the second one potentially can take advantage of hardware
resources like TLB because the hardware will understand only this page table.
Clearly this will be too expensive since this will add over hands on
every single memory reference,
it will slow down the ability to run at near native hardware speeds.
The second option is for the hypervisor to maintain a shadow page table,
in which it actually looks at what are the virtual addresses that
the guests has mapped to these physical addresses.
And then in the shadow page table it directly establishes
a mapping between the virtual addresses that are used by the guest, and
the machine addresses that are used by the hypervisor by the physical hardware.
Then if the hardware MMU uses this page table, the guest operating system
is allowed to execute natively using the applications will use virtual addresses,
and these will be directly translated to the machine addresses that are,
used by the physical hardware.
The hypervisor will clearly have to be responsible to maintain consistence
between these two page tables and it will have to employ mechanism that for
instance invalidate, what is the currently valid page tables,
shadow page table whenever there is a, context wedge or
to write protect the guest page table, in order to keep track of new mappings
that the guest operating system install since similar mechanism.
This write protection is necessary so that whenever the guest OS tries to
install new virtual to physical address mapping in the page
tables that are used by the guest, this will cause a trap to the hypervisor,
and then the hypervisor will be able to pick up that virtual address and
then associate the corresponding machine address and
insert this mapping into the page table that is used by the hardware MMU.
This can be done completely transparently to the guest
operating system.