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/