Вложенная виртуализация

Под вложенной виртуализацией понимается гипервизор Hyper-V, эмулирующий расширения аппаратной виртуализации. Эти эмулированные расширения могут использоваться другим программным обеспечением виртуализации (например, вложенным гипервизором) для запуска на платформе Hyper-V.

Эта возможность доступна только для гостевых секций. Его необходимо включить для каждой виртуальной машины. Вложенная виртуализация не поддерживается в корневом разделе Windows.

Для определения различных уровней вложенной виртуализации используется следующая терминология:

Термин Определение
Гипервизор L0 Гипервизор Hyper-V, работающий на физическом оборудовании.
Корневая папка L1 Корневая операционная система Windows.
L1 Гость Виртуальная машина Hyper-V без вложенной низкоуровневой оболочки.
Гипервизор L1 Вложенный гипервизор, работающий на виртуальной машине Hyper-V.
Корневой каталог L2 Корневая операционная система Windows, работающая в контексте виртуальной машины Hyper-V.
L2 Гость Вложенная виртуальная машина, работающая в контексте виртуальной машины Hyper-V.

По сравнению с без операционной системой низкоуровневые оболочки могут существенно сократить производительность при работе на виртуальной машине. Гипервизоры L1 можно оптимизировать для работы на виртуальной машине Hyper-V с помощью интерфейсов с поддержкой, предоставляемых гипервизором L0.

Enlightened VMCS (Intel)

На платформах Intel программное обеспечение виртуализации использует структуры данных управления виртуальными машинами (VMCS) для настройки поведения процессора, связанного с виртуализацией. Виртуальные контроллеры должны быть активными с помощью инструкции VMPTRLD и изменены с помощью инструкций VMREAD и VMWRITE. Эти инструкции часто являются существенным узким местом для вложенной виртуализации, так как их необходимо эмулировать.

Гипервизор предоставляет функцию "просвещенного VMCS", которую можно использовать для управления поведением процессора, связанного с виртуализацией, с помощью структуры данных в гостевой физической памяти. Эту структуру данных можно изменить с помощью инструкций по обычному доступу к памяти, поэтому низкоуровневой оболочке L1 не нужно выполнять инструкции VMREAD, VMWRITE или VMPTRLD.

Гипервизор L1 может использовать просвещенные VMCS, записав 1 в соответствующее поле на странице Помощник по виртуальному процессору. Другое поле на странице помощника ВП управляет текущим активным vmCS с поддержкой. Каждый просвещенный VMCS имеет ровно одну страницу (4 КБ) и должен быть изначально обнулен. Инструкции VMPTRLD не должны выполняться, чтобы сделать освещенный VMCS активным или текущим.

После того как гипервизор L1 выполнит запись виртуальной машины с поддержкой VMCS, VMCS считается активным на процессоре. Освещенный VMCS может быть активен только на одном процессоре одновременно. Низкоуровневая оболочка L1 может выполнить инструкцию VMCLEAR для перехода с поддержкой VMCS из активного в неактивное состояние. Все инструкции VMREAD или VMWRITE, пока активна освещенная VMCS, не поддерживаются и могут привести к непредвиденному поведению.

Структура HV_VMX_ENLIGHTENED_VMCS определяет макет виртуальной машины с поддержкой. Все несинтетические поля сопоставляют с физической кодировкой INTEL VMCS.

Очистка полей

Гипервизор L0 может кэшировать части виртуальной машины с поддержкой. Просвещенные поля очистки VMCS определяют, какие части освещенного VMCS перезагружаются из гостевой памяти во вложенной записи виртуальной машины. Гипервизор L1 должен очищать соответствующие поля очистки VMCS каждый раз, когда изменяет освещенный VMCS. В противном случае гипервизор L0 может использовать устаревшую версию.

Просветление чистых полей контролируется через искусственное поле CleanFields просвещенного VMCS. По умолчанию все биты задаются таким образом, что гипервизор L0 должен перезагрузить соответствующие поля VMCS для каждой записи вложенной виртуальной машины.

Обнаружение компонентов

Поддержка интерфейса VMCS с поддержкой сообщается с конечным 0x40000004 CPUID.

Структура VMCS с поддержкой версий определяется с учетом будущих изменений. Каждая структура VMCS с поддержкой содержит поле версии, которое сообщается гипервизором L0.

В настоящее время поддерживается только версия VMCS 1.

Рекомендации по реализации гипервизора

Для большинства полей VMCS соответствующее просвещенное поле VMCS поддерживается для виртуальной машины, если поле VMCS поддерживается для виртуальной машины, как определено с помощью архитектурных механизмов обнаружения признаков. Исключения отображаются в конечных 0x4000000A CPUID.

В случаях, когда архитектурные механизмы обнаружения признаков указывают на поддержку поля VMCS, для которого не определено просвещенное поле VMCS, гипервизор L1 не должен включать эту функцию, если он решит использовать освещенный VMCS.

Гипервизор Hyper-V L0 не будет указывать на поддержку поля VMCS, для которого не определено просвещенное поле VMCS или исключение. Если для другого гипервизора L0 требуется новое поле VMCS или исключение, обратитесь в корпорацию Майкрософт.

Поля VMCB с enlighened (AMD)

Amd имеет зарезервированное пространство в VMCB для использования гипервизора, а также связанный чистый бит. Зарезервированные байты находятся в разделе управления , смещение 0x3E0-3FF, VMCB. Чистый бит равен биту 31 (чистый бит должен быть недействителен всякий раз, когда гипервизор изменяет область "просветлений" VMCB).

Hyper-V использует зарезервированную область VMCB для настройки просветлений. Формат документирует структура HV_SVM_ENLIGHTENED_VMCB_FIELDS .

Растровое изображение с поддержкой MSR

Гипервизор L0 эмулирует элементы управления MSR-Bitmap на платформах Intel и AMD, которые позволяют программному обеспечению виртуализации управлять тем, какие операции доступа MSR создают перехваты.

Низкоуровневая оболочка L1 может работать совместно с низкоуровневой оболочкой L0, чтобы повысить эффективность доступа MSR. Он может включить точечные изображения с поддержкой MSR, задав для соответствующего поля в полях VMCS/VMCB значение 1. Если этот параметр включен, гипервизор L0 не отслеживает изменения в растровых изображениях MSR. Вместо этого гипервизор L1 должен сделать недействительным соответствующее чистое поле после внесения изменений в одно из растровых изображений MSR.

Поддержка растрового изображения с поддержкой MSR отображается в конечных 0x4000000A CPUID.

Совместимость с динамической миграцией

Hyper-V имеет возможность динамического переноса дочерней секции с одного узла на другой. Динамическая миграция обычно является прозрачной для дочерней секции. Однако в случае вложенной виртуализации гипервизору L1 может потребоваться знать о миграциях.

Уведомление о динамической миграции

Низкоуровневая оболочка L1 может запрашивать уведомление о переносе своей секции. Эта возможность перечисляется в cpuID как привилегия AccessReenlightenmentControls. Гипервизор L0 предоставляет искусственный MSR (HV_X64_MSR_REENLIGHTENMENT_CONTROL), который может использоваться гипервизором L1 для настройки вектора прерывания и целевого процессора. Гипервизор L0 внедряет прерывание с указанным вектором после каждой миграции.

#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;

Указанный вектор должен соответствовать фиксированному прерыванию APIC. TargetVp указывает индекс виртуального процессора.

Эмуляция TSC

Гостевая секция может быть перенесена между двумя компьютерами с разными частотами TSC. В таких случаях может потребоваться повторное вычисление значения TscScale на эталонной странице TSC .

Гипервизор L0 при необходимости эмулирует все доступы TSC после миграции, пока гипервизор L1 не сможет повторно вычислить значение TscScale. Гипервизор L1 может согласиться на эмуляцию TSC, записав в HV_X64_MSR_TSC_EMULATION_CONTROL MSR. Если вы согласились, гипервизор L0 эмулирует доступ к TSC после миграции.

Гипервизор L1 может запрашивать, эмулируются ли в настоящее время доступы TSC с помощью HV_X64_MSR_TSC_EMULATION_STATUS MSR. Например, низкоуровневая оболочка L1 может подписаться на уведомления динамической миграции и запрашивать состояние TSC после получения прерывания миграции. Он также может отключить эмуляцию TSC (после обновления значения TscScale) с помощью этого 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;

Виртуальная подсистема балансировки нагрузки

Виртуальная подсистема балансировки нагрузки, доступная гипервизором, может быть расширена для кэширования преобразований из L2 GGP в GA. Как и в случае с TLB на логическом процессоре, виртуальная подсистема балансировки нагрузки является несогласованным кэшем, и эта несогласованность видна гостям. Гипервизор предоставляет операции для управления подсистемой балансировки нагрузки.

Прямая виртуальная очистка

Гипервизор предоставляет гипермасштабирования (HvCallFlushVirtualAddressSpace, HvCallFlushVirtualAddressSpaceEx, HvCallFlushVirtualAddressList и HvCallFlushVirtualAddressListEx), которые позволяют операционным системам более эффективно управлять виртуальной подсистемой балансировки нагрузки. Гипервизор L1 может разрешить гостевой системе использовать эти гипермасштабирования и делегировать ответственность за их обработку низкоуровневой оболочке L0. Для этого требуется использовать страницу поддержки секционирования (и виртуальный VMCS на платформах Intel).

При использовании виртуальная подсистема балансировки нагрузки помечает все кэшированные сопоставления идентификатором вложенного контекста (VMCS или VMCB), который их создал. В ответ на прямой виртуальный гипервызов из гостевого узла L2 гипервизор L0 делает недействительными все кэшированные сопоставления, созданные вложенными контекстами, где

  • VmId совпадает с VmId вызывающего объекта.
  • VpId содержится в указанной processorMask или HV_FLUSH_ALL_PROCESSORS указано

Поддержка прямой виртуальной очистки сообщается в конечной 0x4000000A CPUID.

Конфигурация

Прямая обработка гипермасштабирований виртуальной очистки включается:

  1. Задав для поля NestedEnlightenmentsControl.Features.DirectHypercall страницы помощника виртуального процессора значение 1.
  2. Задав для поля EnlightenmentsControl.NestedFlushVirtualHypercall просвещенного VMCS или VMCB значение 1.

Прежде чем включить его, гипервизор L1 должен настроить следующие дополнительные поля для просвещенных VMCS/VMCB:

  • VpId: идентификатор виртуального процессора, которым управляет просвещенный VMCS/VMCB.
  • VmId: идентификатор виртуальной машины, к которой относится просвещенный VMCS/VMCB.
  • PartitionAssistPage: физический адрес гостевого пользователя страницы поддержки секционирования.

Низкоуровневая оболочка L1 также должна предоставлять следующие возможности для своих гостей через CPUID.

  • UseHypercallForLocalFlush
  • UseHypercallForRemoteFlush

Страница "Помощь по секционированиям"

Страница поддержки секционирования — это выровненная по размеру страница область памяти, которую гипервизор L1 должен выделить, и ноль, прежде чем можно будет использовать гипермасштабирования прямой очистки. Его GPA необходимо записать в соответствующее поле в просвещенном VMCS/VMCB.

struct
{
    UINT32 TlbLockCount;
} VM_PARTITION_ASSIST_PAGE;

Синтетические VM-Exit

Если значение TlbLockCount страницы поддержки секционирования вызывающего объекта не равно нулю, гипервизор L0 доставляет VM-Exit с искусственной причиной выхода в гипервизор L1 после обработки прямого виртуального гиперзагрузчика.

На платформах Intel предоставляется VM-Exit с причиной HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH выхода. На платформах AMD доставляется VM-Exit с кодом HV_SVM_EXITCODE_ENL выхода, а параметр ExitInfo1 имеет значение 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)

Преобразование адресов второго уровня

Если для гостевого раздела включена вложенная виртуализация, модуль управления памятью (MMU), предоставляемый секцией, включает поддержку преобразования адресов второго уровня. Преобразование адресов второго уровня — это возможность, которую гипервизор L1 может использовать для виртуализации физической памяти. При использовании некоторые адреса, которые будут рассматриваться как физические адреса гостей , обрабатываются как физические адреса L2 (L2 GGP) и преобразуются в GA путем обхода набора структур разбиения по страницам.

Низкоуровневая оболочка L1 может решить, как и где использовать адресные пространства второго уровня. Адресное пространство каждого второго уровня определяется 64-разрядным значением идентификатора гостя. На платформах Intel это значение совпадает с указателем EPT. На платформах AMD значение равно полю NCR3 VMCB.

Совместимость

Возможности преобразования адресов второго уровня, предоставляемые гипервизором, обычно совместимы с поддержкой преобразования адресов VMX или SVM. Однако существуют следующие различия, наблюдаемые гостями:

  • На внутреннем уровне низкоуровневая оболочка может использовать таблицы теневых страниц, которые преобразуют PGP L2 в spaas. В таких реализациях эти таблицы теневых страниц отображаются в виде больших TLB. Однако можно наблюдать несколько различий. Во-первых, таблицы теневых страниц можно совместно использовать между двумя виртуальными процессорами, тогда как традиционные TLB являются структурами отдельных процессоров и независимы. Этот общий доступ может быть видимым, так как доступ к странице одним виртуальным процессором может заполнить запись таблицы теневых страниц, которая впоследствии используется другим виртуальным процессором.
  • Некоторые реализации гипервизора могут использовать внутреннюю защиту записи таблиц гостевых страниц для отложенной очистки сопоставлений MMU из внутренних структур данных (например, таблиц теневых страниц). Это архитектурно невидимо для гостя, так как низкоуровневая оболочка будет прозрачно обрабатывать операции записи в эти таблицы. Однако записи, выполняемые на базовые страницы GPA другими секциями или устройствами, могут не активировать соответствующую очистку TLB.
  • В некоторых реализациях низкоуровневой оболочки ошибка страницы второго уровня может не сделать кэшированные сопоставления недействительными.

Просвещенные дисковые сбросы TLB второго уровня

Гипервизор также поддерживает ряд усовершенствований, позволяющих гостевой машине более эффективно управлять подсистемой балансировки нагрузки второго уровня. Эти расширенные операции можно использовать взаимозаменяемо с устаревшими операциями управления TLB.

Гипервизор поддерживает следующие гипермасштабирования, чтобы сделать недействительными TLB:

Гипервызов Описание
HvCallFlushGuestPhysicalAddressSpace делает недействительными кэшированные сопоставления GPA L2 и GPA в адресном пространстве второго уровня.
HvCallFlushGuestPhysicalAddressList делает недействительными кэшированные сопоставления GVA/L2 GPA с GPA в части адресного пространства второго уровня.

На платформах AMD все записи TLB архитектурны помечены ASID (идентификатором адресного пространства). Недействительность ASID приводит к тому, что все компоненты TLB, связанные с ASID, будут признаны недействительными. Вложенный гипервизор может при необходимости выбрать "просвещенный TLB", задав для EnlightenedNptTlb значение "1" в HV_SVM_ENLIGHTENED_VMCB_FIELDS. Если вложенный гипервизор выбирается в режиме осветления, ASID просто очищает целые TLB, производные от преобразования адресов первого уровня (т. е. виртуального адресного пространства). Для очистки записей TLB, производных от вложенной таблицы страниц (ДНЯО), и принудительного перестроения таблиц теневых страниц низкоуровневой оболочки L0 необходимо использовать гипермасштабирование HvCallFlushGuushGuestPhysushGuestPhysicalAddressListPhysicalAddressSpace или HvCallFlushGuestPhysicalAddressList.

Исключения вложенной виртуализации

На платформах Intel. Гипервизор L1 может согласиться на объединение исключений виртуализации в классе исключений сбоя страницы. Низкоуровневая оболочка L0 объявляет поддержку этого окружения в конечной части функции вложенной виртуализации гипервизора CPUID.

Это просветление можно включить, задав VirtualizationException значение "1" в HV_NESTED_ENLIGHTENMENTS_CONTROL структуре данных на странице Помощник по виртуальному процессору.

Вложенные msr виртуализации

Вложенный регистр индекса VP

Гипервизор L1 предоставляет MSR, который сообщает базовый индекс VP текущего процессора.

Адрес MSR Имя регистрации Описание
0x40001002 HV_X64_MSR_NESTED_VP_INDEX Во вложенном корневом разделе сообщает базовый индекс VP текущего процессора.

Вложенные MSR SynIC

Во вложенном корневом разделе следующие msR разрешают доступ к соответствующим MSR SynIC базового гипервизора.

Чтобы найти индекс базового процессора, вызывающим абонентам следует сначала использовать HV_X64_MSR_NESTED_VP_INDEX.

Адрес MSR Имя регистрации Базовый MSR
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