Re: [RFC, PATCH 5/24] i386 Vmi code patching
From: Joshua LeVasseur
Date: Fri Mar 17 2006 - 19:46:35 EST
On Mar 17, 2006, at 22:11 , Chris Wright wrote:
* Joshua LeVasseur (jtl@xxxxxxxxxx) wrote:
extern "C" void
afterburn_cpu_write_gdt32_ext( burn_clobbers_frame_t *frame )
{
get_cpu()->gdtr = *(dtr_t *)frame->eax;
}
What is this get_cpu()? Accessing data structure that's avail. in ROM
and shared with hypervisor...could you elaborate a bit here?
thanks,
-chris
VMI is a very versatile interface due to the ROM; within the ROM you
can translate the instruction set architecture and device register
activity (as represented by the VMI interface) to a variety of
hypervisor interfaces. I use a virtual CPU to help perform the
translation. The performance of virtualization depends on the extent
to which you can minimize interaction with the hypervisor via
hypercalls. Many of the operations needn't be exposed to the
hypervisor, and only operate on the virtual CPU, and thus remain
completely within the ROM. The goal is to minimize interaction with
the hypervisor.
I don't share the virtual CPU with the hypervisor. There probably
are performance benefits for codesign between the hypervisor and ROM,
but I haven't had that luxury; I take the hypervisors as given and
none of them are fundamentally designed to use a ROM. On the other
hand, it makes sense to concentrate virtualization within the ROM,
rather than the hypervisor, for the same arguments you can make for
implementing functionality in an application rather than the kernel.
I've implemented ROMs for two (open source) hypervisors so far, and
try to share as much code between them as possible. The get_cpu() is
an abstraction to help hide the hypervisor specifics for locating the
virtual CPU (and it handles multiprocessor issues).
To help illustrate the role of the ROM, consider using Linux as a
hypervisor, i.e., Linux-on-Linux but with the guest kernel using the
VMI interface [1]. The ROM would translate the low-level operations
of the guest kernel into the system calls of the host Linux, and it
would be important to minimize the amount of interaction with the
host Linux. Consider interrupt delivery, which would probably be
mapped to POSIX signals. VMI offers VMI_EnableInterrupts(),
VMI_DisableInterrupts(), VMI_GetInterruptMask(), and
VMI_SetInterruptMask(). All of these operations are executed
frequently by Linux, and it would be critical to limit their side
effects to within the ROM; for performance reasons, they mustn't map
to POSIX signal mask/unmask operations. The solution is to update
only the EFLAGS in the virtual CPU when the guest kernel invokes
VMI_EnableInterrupts, DisableInterrupts, etc.. Then the ROM must
always accept asynchronous POSIX signal delivery, and must only
forward asynchronous events to the guest kernel if interrupts are
enabled in the virtual CPU. If the virtual CPU's interrupts are
disabled, then the event is only recorded in the virtual PIC, and
delivered at the next VMI_EnableInterrupts() or VMI_SetInterruptMask().
[1] Linux-on-Linux would probably limp with the current VMI. A
couple changes would be necessary, such as permitting the Linux
kernel to run at ring 3, and offering put_user() and get_user()
hooks, since the guest applications and guest kernel must use
different host address spaces. Unfortunately, put_user() and get_user
() hooks are higher-level interfaces that don't fit well within VMI.
For other CPU architectures with only two privilege levels, put_user
() and get_user() hooks may be necessary too.
Joshua
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/