Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La virtualización anidada hace referencia a la Hyper-V hipervisor emulando extensiones de virtualización de hardware. Este software de virtualización (por ejemplo, un hipervisor anidado) puede usar estas extensiones emuladas para ejecutarse en la plataforma Hyper-V.
Esta funcionalidad solo está disponible para las particiones invitadas. Debe estar habilitado por máquina virtual. La virtualización anidada no se admite en una partición raíz de Windows.
La terminología siguiente se usa para definir varios niveles de virtualización anidada:
| Término | Definición |
|---|---|
| Hipervisor L0 | El hipervisor de Hyper-V que se ejecuta en hardware físico. |
| Raíz L1 | Sistema operativo raíz de Windows. |
| Invitado L1 | Una máquina virtual Hyper-V sin un hipervisor anidado. |
| Hipervisor L1 | Hipervisor anidado que se ejecuta dentro de una máquina virtual Hyper-V. |
| Raíz L2 | Un sistema operativo Windows raíz que se ejecuta en el contexto de una máquina virtual Hyper-V. |
| Invitado L2 | Una máquina virtual anidada, que se ejecuta dentro del contexto de una máquina virtual Hyper-V. |
En comparación con los hipervisores sin sistema operativo, los hipervisores pueden incurrir en una regresión de rendimiento significativa al ejecutarse en una máquina virtual. Los hipervisores L1 se pueden optimizar para ejecutarse en una máquina virtual de Hyper-V mediante interfaces habilitadas proporcionadas por el hipervisor L0.
Esta funcionalidad solo se admite actualmente en x64.
VMCS habilitada (Intel)
En las plataformas Intel, el software de virtualización usa estructuras de datos de control de máquinas virtuales (VMCS) para configurar el comportamiento del procesador relacionado con la virtualización. Los VMCS deben activarse mediante una instrucción VMPTRLD y modificarse mediante las instrucciones VMREAD y VMWRITE. Estas instrucciones suelen ser un cuello de botella significativo para la virtualización anidada, ya que deben emularse.
El hipervisor expone una característica "VMCS habilitada", que se puede usar para controlar el comportamiento del procesador relacionado con la virtualización mediante una estructura de datos en la memoria física invitada. Esta estructura de datos se puede modificar mediante instrucciones de acceso a memoria normales, por lo que no es necesario que el hipervisor L1 ejecute las instrucciones VMREAD o VMWRITE o VMPTRLD.
El hipervisor L1 puede optar por usar VMCS habilitadas escribiendo 1 en el campo correspondiente en la página Asistencia del procesador virtual. Otro campo de la página vp assist controla el VMCS actualmente activo activado. Cada VMCS habilitada es exactamente una página (4 KB) de tamaño y debe estar inicialmente cero. No se debe ejecutar ninguna instrucción VMPTRLD para que una VMCS habilitada esté activa o actual.
Una vez que el hipervisor L1 realiza una entrada de máquina virtual con un VMCS habilitada, el VMCS se considera activo en el procesador. Un VMCS optimizado solo puede estar activo en un único procesador al mismo tiempo. El hipervisor L1 puede ejecutar una instrucción VMCLEAR para realizar la transición de un VMCS optimizado desde el estado activo al estado no activo. Las instrucciones VMREAD o VMWRITE mientras una VMCS habilitada está activa no se admite y pueden dar lugar a un comportamiento inesperado.
La estructura HV_VMX_ENLIGHTENED_VMCS define el diseño de VMCS habilitada. Todos los campos no sintéticos se asignan a una codificación de VMCS física intel.
Limpiar campos
El hipervisor L0 puede optar por almacenar en caché partes de VMCS habilitadas. Los campos limpios VMCS optimizados controlan qué partes de VMCS habilitadas se vuelven a cargar de la memoria invitada en una entrada de máquina virtual anidada. El hipervisor L1 debe borrar los campos limpios de VMCS correspondientes cada vez que modifica el VMCS optimizado; de lo contrario, el hipervisor L0 podría usar una versión obsoleta.
La iluminación de los campos limpios se controla a través del campo sintético "CleanFields" de vmCS habilitada. De forma predeterminada, todos los bits se establecen de forma que el hipervisor L0 debe volver a cargar los campos VMCS correspondientes para cada entrada de máquina virtual anidada.
Detección de características
La compatibilidad con una interfaz VMCS habilitada se notifica con 0x40000004 hoja CPUID.
La estructura de VMCS habilitada tiene versiones para tener en cuenta los cambios futuros. Cada estructura VMCS habilitada contiene un campo de versión, que el hipervisor L0 notifica.
La única versión de VMCS admitida actualmente es 1.
Consideraciones sobre la implementación del hipervisor
Para la mayoría de los campos VMCS, se admite el campo VMCS habilitada correspondiente para una máquina virtual si se admite el campo VMCS para la máquina virtual, según se determine a través de mecanismos de detección de características de arquitectura. Las excepciones se notifican en 0x4000000A hoja CPUID.
En los casos en los que los mecanismos de detección de características arquitectónicas indican compatibilidad con un campo VMCS para el que no se define ningún campo VMCS habilitado, el hipervisor L1 no debe habilitar la característica si decide usar VMCS habilitada.
El hipervisor L0 de Hyper-V no indicará la compatibilidad con un campo VMCS para el que no se haya definido ningún campo o excepción vmCS habilitada. Si otro hipervisor L0 necesita que se defina un nuevo campo o excepción de VMCS habilitada, póngase en contacto con Microsoft.
Campos VMCB inscritos (AMD)
AMD tiene espacio reservado en VMCB para el uso del hipervisor, así como un bit limpio asociado. Los bytes reservados se encuentran en la sección de control, desplazamiento 0x3E0-3FF, del VMCB. El bit limpio es el bit 31 (el bit limpio se debe invalidar cada vez que el hipervisor modifica el área "iluminaciones" de VMCB).
Hyper-V utiliza el área reservada VMCB para configurar iluminaciones. La estructura HV_SVM_ENLIGHTENED_VMCB_FIELDS documenta el formato.
Mapa de bits de MSR optimizado
El hipervisor L0 emula los controles "MSR-Bitmap" en plataformas Intel y AMD que permiten que el software de virtualización controle qué accesos MSR generan interceptaciones.
El hipervisor L1 puede colaborar con el hipervisor L0 para que los accesos de MSR sean más eficaces. Puede habilitar mapas de bits de MSR habilitados estableciendo el campo correspondiente en los campos VMCS o VMCB habilitados en 1. Cuando está habilitado, el hipervisor L0 no supervisa los mapas de bits de MSR para ver los cambios. En su lugar, el hipervisor L1 debe invalidar el campo limpio correspondiente después de realizar cambios en uno de los mapas de bits de MSR.
La compatibilidad con el mapa de bits de MSR optimizado se notifica en el 0x4000000A hoja CPUID.
Compatibilidad con la migración en vivo
Hyper-V tiene la capacidad de migrar en vivo una partición secundaria de un host a otro host. Normalmente, las migraciones en vivo son transparentes para la partición secundaria. Sin embargo, en el caso de la virtualización anidada, es posible que el hipervisor L1 tenga que tener en cuenta las migraciones.
Notificación de migración en vivo
Un hipervisor L1 puede solicitar que se notifique cuando se migre su partición. Esta funcionalidad se enumera en CPUID como privilegio "AccessReenlightenmentControls". El hipervisor L0 expone un MSR sintético (HV_X64_MSR_REENLIGHTENMENT_CONTROL) que el hipervisor L1 puede usar para configurar un vector de interrupción y un procesador de destino. El hipervisor L0 insertará una interrupción con el vector especificado después de cada migración.
#define HV_X64_MSR_REENLIGHTENMENT_CONTROL (0x40000106)
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 Vector :8;
UINT64 RsvdZ1 :8;
UINT64 Enabled :1;
UINT64 RsvdZ2 :15;
UINT64 TargetVp :32;
};
} HV_REENLIGHTENMENT_CONTROL;
El vector especificado debe corresponder a una interrupción APIC fija. TargetVp especifica el índice del procesador virtual.
Emulación de TSC
Una partición de invitado puede migrarse en vivo entre dos máquinas con diferentes frecuencias de TSC. En esos casos, es posible que sea necesario volver a calcular el valor de TscScale de la página de referencia de TSC .
El hipervisor L0 emula opcionalmente todos los accesos de TSC después de una migración hasta que el hipervisor L1 ha tenido la oportunidad de volver a calcular el valor de TscScale. El hipervisor L1 puede participar en la emulación de TSC escribiendo en la HV_X64_MSR_TSC_EMULATION_CONTROL MSR. Si participa, el hipervisor L0 emula los accesos de TSC después de que se realice una migración.
El hipervisor L1 puede consultar si actualmente se emulan los accesos de TSC mediante el msr de HV_X64_MSR_TSC_EMULATION_STATUS. Por ejemplo, el hipervisor L1 podría suscribirse a las notificaciones de migración en vivo y consultar el estado de TSC después de recibir la interrupción de la migración. También puede desactivar la emulación de TSC (después de actualizar el valor de TscScale) mediante este MSR.
#define HV_X64_MSR_TSC_EMULATION_CONTROL (0x40000107)
#define HV_X64_MSR_TSC_EMULATION_STATUS (0x40000108)
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 Enabled :1;
UINT64 RsvdZ :63;
};
} HV_TSC_EMULATION_CONTROL;
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 InProgress : 1;
UINT64 RsvdP1 : 63;
};
} HV_TSC_EMULATION_STATUS;
Virtual TLB
El TLB virtual expuesto por el hipervisor se puede extender para almacenar en caché las traducciones de GPO L2 a GPO. Al igual que con el TLB en un procesador lógico, el TLB virtual es una caché no coherente y esta no coherencia es visible para los invitados. El hipervisor expone las operaciones para administrar el TLB.
Vaciado virtual directo
El hipervisor expone hiperllamadas (HvCallFlushVirtualAddressSpace, HvCallFlushVirtualAddressSpaceEx, HvCallFlushVirtualAddressList y HvCallFlushVirtualAddressListEx) que permiten a los sistemas operativos administrar de forma más eficaz el TLB virtual. El hipervisor L1 puede optar por permitir que su invitado use esas hiperllamadas y delegar la responsabilidad de controlarlos en el hipervisor L0. Esto requiere el uso de una página de asistencia de partición (y un VMCS virtual en plataformas Intel).
Cuando se usa, el TLB virtual etiqueta todas las asignaciones almacenadas en caché con un identificador del contexto anidado (VMCS o VMCB) que los creó. En respuesta a una hiperllamada directa de vaciado virtual desde un invitado L2, el hipervisor L0 invalida todas las asignaciones almacenadas en caché creadas por contextos anidados donde
- VmId es el mismo que vmid del autor de la llamada.
- El vpId está contenido en el procesador especificado o HV_FLUSH_ALL_PROCESSORS se especifica
La compatibilidad con vaciados virtuales directos se notifica en el 0x4000000A hoja CPUID.
Configuración
El control directo de hiperllamadas de vaciado virtual está habilitado por:
- Establecer el campo NestedEnlightenmentsControl.Features.DirectHypercall de la página Asistencia del procesador virtual en 1.
- Establecer el campo EnlightensControl.NestedFlushVirtualHypercall de un VMCS o VMCB optimizado en 1.
Antes de habilitarlo, el hipervisor L1 debe configurar los siguientes campos adicionales de VMCS/VMCB habilitados:
- VpId: identificador del procesador virtual que controla VMCS o VMCB habilitada.
- VmId: identificador de la máquina virtual a la que pertenece VMCS o VMCB habilitada.
- PartitionAssistPage: dirección física de invitado de la página de asistencia de partición.
El hipervisor L1 también debe exponer las siguientes funcionalidades a sus invitados a través de CPUID.
- UseHypercallForLocalFlush
- UseHypercallForRemoteFlush
Página De asistencia para particiones
La página de asistencia para particiones es una región de tamaño de página alineada de tamaño de página de memoria que el hipervisor L1 debe asignar y cero antes de que se puedan usar hiperllamadas de vaciado directo. Su GPA debe escribirse en el campo correspondiente en vmCS/VMCB habilitada.
struct
{
UINT32 TlbLockCount;
} VM_PARTITION_ASSIST_PAGE;
VM-Exit sintético
Si el TlbLockCount de la página de asistencia de partición del autor de la llamada no es cero, el hipervisor L0 entrega un VM-Exit con una razón de salida sintética al hipervisor L1 después de controlar una hiperllamada de vaciado virtual directo.
En las plataformas Intel, se entrega un VM-Exit con motivo HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH de salida. En las plataformas AMD, se entrega un VM-Exit con código HV_SVM_EXITCODE_ENL de salida y ExitInfo1 se establece en HV_SVM_ENL_EXITCODE_TRAP_AFTER_FLUSH.
#define HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH 0x10000031
#define HV_SVM_EXITCODE_ENL 0xF0000000
#define HV_SVM_ENL_EXITCODE_TRAP_AFTER_FLUSH (1)
Traducción de direcciones de segundo nivel
Cuando la virtualización anidada está habilitada para una partición de invitado, la unidad de administración de memoria (MMU) expuesta por la partición incluye compatibilidad con la traducción de direcciones de segundo nivel. La traducción de direcciones de segundo nivel es una funcionalidad que el hipervisor L1 puede usar para virtualizar la memoria física. Cuando se usa, ciertas direcciones que se tratarían como direcciones físicas invitadas (GPO) se tratan como direcciones físicas de invitado L2 (GPO L2) y se traducen en GPO mediante el recorrido de un conjunto de estructuras de paginación.
El hipervisor L1 puede decidir cómo y dónde usar espacios de direcciones de segundo nivel. Cada segundo espacio de direcciones de nivel se identifica mediante un valor de identificador de 64 bits definido por el invitado. En las plataformas Intel, este valor es el mismo que el puntero EPT. En las plataformas AMD, el valor es igual al campo vmCB nCR3.
Compatibility
La segunda funcionalidad de traducción de direcciones de nivel expuesta por el hipervisor suele ser compatible con la compatibilidad con VMX o SVM para la traducción de direcciones. Sin embargo, existen las siguientes diferencias observables por invitado:
- Internamente, el hipervisor puede usar tablas de páginas instantáneas que traducen GPO L2 a SPAs. En estas implementaciones, estas tablas de páginas sombras aparecen en software como TLB grandes. Sin embargo, pueden ser observables varias diferencias. En primer lugar, las tablas de instantáneas se pueden compartir entre dos procesadores virtuales, mientras que las TLB tradicionales son estructuras por procesador y son independientes. Este uso compartido puede ser visible porque un procesador virtual puede rellenar una entrada de tabla de páginas sombras que otro procesador virtual usa posteriormente.
- Algunas implementaciones de hipervisor pueden usar la protección interna de escritura de tablas de páginas invitadas para vaciar de forma diferida las asignaciones de MMU de estructuras de datos internas (por ejemplo, tablas de páginas sombras). Esto es invisible arquitectónicamente para el invitado porque el hipervisor controlará las escrituras en estas tablas de forma transparente. Sin embargo, es posible que las escrituras realizadas en las páginas de GPA subyacentes por otras particiones o por dispositivos no desencadenen el vaciado de TLB adecuado.
- En algunas implementaciones del hipervisor, es posible que un error de página de segundo nivel no invalide las asignaciones almacenadas en caché.
Vaciados de TLB de segundo nivel iluminados
El hipervisor también admite un conjunto de mejoras que permiten a un invitado administrar el TLB de segundo nivel de forma más eficaz. Estas operaciones mejoradas se pueden usar indistintamente con las operaciones de administración de TLB heredadas.
El hipervisor admite las siguientes hiperllamadas para invalidar los TTLB:
| Hypercall | Description |
|---|---|
| HvCallFlushGuestPhysicalAddressSpace | invalida las asignaciones de GPA L2 almacenadas en caché en GPA dentro de un segundo espacio de direcciones de segundo nivel. |
| HvCallFlushGuestPhysicalAddressList | invalida las asignaciones de GVA o L2 GPA almacenadas en caché dentro de una parte de un espacio de direcciones de segundo nivel. |
En las plataformas AMD, todas las entradas de TLB se etiquetan de forma arquitectónica con un ASID (identificador de espacio de direcciones). La invalidación del ASID hace que se invaliden todos los elementos completos de TLB asociados al ASID. El hipervisor anidado puede optar opcionalmente por un "TLB optimizado" estableciendo EnlightenedNptTlb en "1" en HV_SVM_ENLIGHTENED_VMCB_FIELDS. Si el hipervisor anidado opta por la iluminación, las invalidaciones de ASID simplemente vacían todo el TLB derivados de la traducción de direcciones de primer nivel (es decir, el espacio de direcciones virtuales). Para vaciar las entradas de TLB derivadas de la tabla de páginas anidadas (NEST) y forzar el hipervisor L0 para recompilar las tablas de páginas de sombras, se deben usar las hiperllamadas HvCallFlushGuestPhyssicalAddressList HvCallFlushGuestPhyssicalAddressList.
Excepciones de virtualización anidadas
En plataformas Intel. El hipervisor L1 puede optar por combinar excepciones de virtualización en la clase de excepción de error de página. El hipervisor L0 anuncia la compatibilidad con esta iluminación en la hoja CPUID de las características de virtualización anidada del hipervisor.
Esta iluminación se puede habilitar estableciendo VirtualizationException en "1" en HV_NESTED_ENLIGHTENMENTS_CONTROL estructura de datos en la página Virtual Processor Assist.
MSR de virtualización anidada
Registro de índices VP anidados
El hipervisor L1 expone un MSR que informa del índice VP subyacente del procesador actual.
| Dirección MSR | Nombre del registro | Description |
|---|---|---|
| 0x40001002 | HV_X64_MSR_NESTED_VP_INDEX | En una partición raíz anidada, informa del índice VP subyacente del procesador actual. |
MSR sinic anidados
En una partición raíz anidada, las siguientes MSR permiten el acceso a los registros SynIC correspondientes del hipervisor base.
Para buscar el índice del procesador subyacente, los autores de llamadas deben usar primero HV_X64_MSR_NESTED_VP_INDEX.
| Dirección MSR | Nombre del registro | MSR subyacente |
|---|---|---|
| 0x40001080 | HV_X64_MSR_NESTED_SCONTROL | HV_X64_MSR_SCONTROL |
| 0x40001081 | HV_X64_MSR_NESTED_SVERSION | HV_X64_MSR_SVERSION |
| 0x40001082 | HV_X64_MSR_NESTED_SIEFP | HV_X64_MSR_SIEFP |
| 0x40001083 | HV_X64_MSR_NESTED_SIMP | HV_X64_MSR_SIMP |
| 0x40001084 | HV_X64_MSR_NESTED_EOM | HV_X64_MSR_EOM |
| 0x40001090 | HV_X64_MSR_NESTED_SINT0 | HV_X64_MSR_SINT0 |
| 0x40001091 | HV_X64_MSR_NESTED_SINT1 | HV_X64_MSR_SINT1 |
| 0x40001092 | HV_X64_MSR_NESTED_SINT2 | HV_X64_MSR_SINT2 |
| 0x40001093 | HV_X64_MSR_NESTED_SINT3 | HV_X64_MSR_SINT3 |
| 0x40001094 | HV_X64_MSR_NESTED_SINT4 | HV_X64_MSR_SINT4 |
| 0x40001095 | HV_X64_MSR_NESTED_SINT5 | HV_X64_MSR_SINT5 |
| 0x40001096 | HV_X64_MSR_NESTED_SINT6 | HV_X64_MSR_SINT6 |
| 0x40001097 | HV_X64_MSR_NESTED_SINT7 | HV_X64_MSR_SINT7 |
| 0x40001098 | HV_X64_MSR_NESTED_SINT8 | HV_X64_MSR_SINT8 |
| 0x40001099 | HV_X64_MSR_NESTED_SINT9 | HV_X64_MSR_SINT9 |
| 0x4000109A | HV_X64_MSR_NESTED_SINT10 | HV_X64_MSR_SINT10 |
| 0x4000109B | HV_X64_MSR_NESTED_SINT11 | HV_X64_MSR_SINT11 |
| 0x4000109C | HV_X64_MSR_NESTED_SINT12 | HV_X64_MSR_SINT12 |
| 0x4000109D | HV_X64_MSR_NESTED_SINT13 | HV_X64_MSR_SINT13 |
| 0x4000109E | HV_X64_MSR_NESTED_SINT14 | HV_X64_MSR_SINT14 |
| 0x4000109F | HV_X64_MSR_NESTED_SINT15 | HV_X64_MSR_SINT15 |