At start of day, a guest operating system needs to setup the virtual
CPU it is executing on. This includes installing vectors for the
virtual IDT so that the guest OS can handle interrupts, page faults,
etc. However the very first thing a guest OS must setup is a pair
of hypervisor callbacks: these are the entry points which Xen will
use when it wishes to notify the guest OS of an occurrence.
set_callbacks(unsigned long event_selector, unsigned long
event_address, unsigned long failsafe_selector, unsigned long
failsafe_address)
Register the normal (``event'') and failsafe callbacks for
event processing. In each case the code segment selector and
address within that segment are provided. The selectors must
have RPL 1; in XenLinux we simply use the kernel's CS for both
event_selector and failsafe_selector.
The value event_address specifies the address of the guest OSes
event handling and dispatch routine; the failsafe_address
specifies a separate entry point which is used only if a fault occurs
when Xen attempts to use the normal callback.
On x86/64 systems the hypercall takes slightly different
arguments. This is because callback CS does not need to be specified
(since teh callbacks are entered via SYSRET), and also because an
entry address needs to be specified for SYSCALLs from guest user
space:
set_callbacks(unsigned long event_address, unsigned long
failsafe_address, unsigned long syscall_address)
After installing the hypervisor callbacks, the guest OS can
install a `virtual IDT' by using the following hypercall:
set_trap_table(trap_info_t *table)
Install one or more entries into the per-domain
trap handler table (essentially a software version of the IDT).
Each entry in the array pointed to by table includes the
exception vector number with the corresponding segment selector
and entry point. Most guest OSes can use the same handlers on
Xen as when running on the real hardware.
A further hypercall is provided for the management of virtual CPUs:
vcpu_op(int cmd, int vcpuid, void *extra_args)
This hypercall can be used to bootstrap VCPUs, to bring them up and
down and to test their current status.