Delen via


Geneste virtualisatie

Geneste virtualisatie verwijst naar de Hyper-V hypervisor die hardwarevirtualisatie-extensies emuleren. Deze geëmuleerde extensies kunnen worden gebruikt door andere virtualisatiesoftware (bijvoorbeeld een geneste hypervisor) die op het Hyper-V-platform kan worden uitgevoerd.

Deze mogelijkheid is alleen beschikbaar voor gastpartities. Deze moet per virtuele machine worden ingeschakeld. Geneste virtualisatie wordt niet ondersteund in een Windows-hoofdpartitie.

De volgende terminologie wordt gebruikt om verschillende niveaus van geneste virtualisatie te definiëren:

Termijn Definition
L0 Hypervisor De Hyper-V hypervisor die wordt uitgevoerd op fysieke hardware.
L1 Root Het Windows-hoofdbesturingssysteem.
L1 Gast Een Hyper-V virtuele machine zonder geneste hypervisor.
L1 Hypervisor Een geneste hypervisor die wordt uitgevoerd binnen een Hyper-V virtuele machine.
L2 Root Een windows-hoofdbesturingssysteem dat wordt uitgevoerd binnen de context van een Hyper-V virtuele machine.
L2 Gast Een geneste virtuele machine die wordt uitgevoerd binnen de context van een Hyper-V virtuele machine.

In vergelijking met bare-metal kunnen hypervisors een aanzienlijke prestatieregressie uitvoeren bij het uitvoeren in een virtuele machine. L1-hypervisors kunnen worden geoptimaliseerd voor uitvoering in een Hyper-V VM met behulp van verlichte interfaces van de L0-hypervisor.

Deze mogelijkheid wordt momenteel alleen ondersteund op x64.

Verlichte VMCS (Intel)

Op Intel-platforms maakt virtualisatiesoftware gebruik van VMCSs (Virtual Machine Control Data Structures) om processorgedrag te configureren met betrekking tot virtualisatie. VMCSs moeten actief worden gemaakt met behulp van een VMPTRLD-instructie en gewijzigd met behulp van VMREAD- en VMWRITE-instructies. Deze instructies zijn vaak een belangrijk knelpunt voor geneste virtualisatie, omdat ze moeten worden geëmuleerd.

De hypervisor maakt een functie voor 'verlichte VMCS' beschikbaar die kan worden gebruikt om het gedrag van virtualisatiegerelateerde processoren te beheren met behulp van een gegevensstructuur in het fysieke gastgeheugen. Deze gegevensstructuur kan worden gewijzigd met behulp van normale instructies voor geheugentoegang, waardoor de L1-hypervisor niet nodig is om VMREAD- of VMWRITE- of VMPTRLD-instructies uit te voeren.

De L1-hypervisor kan ervoor kiezen om verlichte VMCSs te gebruiken door 1 naar het bijbehorende veld op de pagina Virtual Processor Assist te schrijven. Een ander veld op de pagina VP Assist bepaalt de momenteel actieve VMCS met functionaliteit. Elke verlichte VMCS is precies één pagina (4 kB) groot en moet in eerste instantie worden nul gemaakt. Er moet geen VMPTRLD-instructie worden uitgevoerd om een verlichte VMCS actief of actueel te maken.

Nadat de L1-hypervisor een VM-vermelding met een verlichte VMCS heeft uitgevoerd, wordt de VMCS beschouwd als actief op de processor. Een verlichte VMCS kan slechts op één processor tegelijk actief zijn. De L1-hypervisor kan een VMSELECT-instructie uitvoeren om een verlichte VMCS over te schakelen van de actieve naar de niet-actieve status. Instructies voor VMREAD of VMWRITE terwijl een verlichte VMCS actief is, wordt niet ondersteund en kan leiden tot onverwacht gedrag.

De HV_VMX_ENLIGHTENED_VMCS-structuur definieert de indeling van de verlichte VMCS. Alle niet-synthetische velden worden toegewezen aan een fysieke Intel VMCS-codering.

Velden opschonen

De L0-hypervisor kan ervoor kiezen om onderdelen van de verlichte VMCS op te cachen. De verlichte VMCS-velden bepalen welke onderdelen van de verlichte VMCS opnieuw worden geladen vanuit het gastgeheugen op een geneste VM-vermelding. De L1-hypervisor moet de bijbehorende VMCS-schone velden wissen telkens wanneer deze de verlichte VMCS wijzigt, anders kan de L0-hypervisor een verouderde versie gebruiken.

De verlichting van schone velden wordt beheerd via het synthetische veld CleanFields van de verlichte VMCS. Standaard worden alle bits zo ingesteld dat de L0-hypervisor de bijbehorende VMCS-velden voor elke geneste VM-vermelding opnieuw moet laden.

Functieontdekking

Ondersteuning voor een verlichte VMCS-interface wordt gerapporteerd met CPUID leaf 0x40000004.

De verlichte VMCS-structuur is geversied om rekening te houden met toekomstige wijzigingen. Elke verlichte VMCS-structuur bevat een versieveld dat wordt gerapporteerd door de L0-hypervisor.

De enige VMCS-versie die momenteel wordt ondersteund, is 1.

Overwegingen bij de implementatie van hypervisor

Voor de meeste VMCS-velden wordt het overeenkomstige veld VMCS ondersteund voor een VIRTUELE machine als het veld VMCS wordt ondersteund voor de VIRTUELE machine, zoals wordt bepaald via mechanismen voor het detecteren van architectuurfuncties. Uitzonderingen worden gerapporteerd in de CPUID-leaf-0x4000000A.

In gevallen waarin detectiemechanismen voor architectuurfuncties wijzen op ondersteuning voor een VMCS-veld waarvoor geen verlicht VMCS-veld is gedefinieerd, moet de L1-hypervisor de functie niet inschakelen als deze ervoor kiest om verlichte VMCS te gebruiken.

De Hyper-V L0-hypervisor geeft geen ondersteuning aan voor een VMCS-veld waarvoor geen verlicht VMCS-veld of -uitzondering is gedefinieerd. Neem contact op met Microsoft als een andere L0-hypervisor een nieuw, verlicht VMCS-veld of een nieuwe uitzondering nodig heeft om te worden gedefinieerd.

Enlighened VMCB-velden (AMD)

AMD heeft gereserveerde ruimte in de VMCB voor hypervisorgebruik, evenals een bijbehorende schone bit. De gereserveerde bytes bevinden zich in de besturingssectie, offset 0x3E0-3FF, van de VMCB. De schone bit is bit 31 (de schone bit moet ongeldig worden wanneer de hypervisor het gedeelte 'verlichting' van de VMCB wijzigt).

Hyper-V maakt gebruik van het gereserveerde VMCB-gebied om verlichting te configureren. De HV_SVM_ENLIGHTENED_VMCB_FIELDS structuur bevat de indeling.

Verlichte MSR-bitmap

De L0-hypervisor emuleren de besturingselementen 'MSR-Bitmap' op zowel Intel- als AMD-platforms waarmee virtualisatiesoftware kan bepalen welke MSR-toegangspunten genereren.

De L1-hypervisor kan samenwerken met de L0-hypervisor om MSR-toegang efficiënter te maken. Hiermee kunnen verlichte MSR-bitmaps worden ingeschakeld door het bijbehorende veld in de verlichte VMCS-/VMCB-velden in te stellen op 1. Wanneer deze functie is ingeschakeld, controleert de L0-hypervisor de MSR-bitmaps niet op wijzigingen. In plaats daarvan moet de L1-hypervisor het overeenkomstige schone veld ongeldig maken nadat er wijzigingen zijn aangebracht in een van de MSR-bitmaps.

Ondersteuning voor de verlichte MSR-bitmap wordt gerapporteerd in de CPUID leaf-0x4000000A.

Compatibiliteit met livemigratie

Hyper-V heeft de mogelijkheid om een onderliggende partitie live te migreren van de ene host naar een andere host. Livemigraties zijn doorgaans transparant voor de onderliggende partitie. In het geval van geneste virtualisatie moet de L1-hypervisor zich echter mogelijk bewust zijn van migraties.

Livemigratiemelding

Een L1-hypervisor kan aanvragen om een melding te ontvangen wanneer de partitie wordt gemigreerd. Deze mogelijkheid wordt in CPUID opgesomd als de bevoegdheid AccessReenlightenmentControls. De L0-hypervisor maakt een synthetische MSR (HV_X64_MSR_REENLIGHTENMENT_CONTROL) beschikbaar die door de L1-hypervisor kan worden gebruikt om een interruptvector en doelprocessor te configureren. De L0-hypervisor injecteert na elke migratie een interrupt met de opgegeven vector.

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

De opgegeven vector moet overeenkomen met een vaste APIC-interrupt. TargetVp geeft de index van de virtuele processor op.

TSC-emulatie

Een gastpartitie kan live worden gemigreerd tussen twee machines met verschillende TSC-frequenties. In dergelijke gevallen moet de TscScale-waarde van de referentie-TSC-pagina mogelijk opnieuw worden gecomputeerd.

De L0-hypervisor emuleert eventueel alle TSC-toegangen na een migratie totdat de L1-hypervisor de kans heeft gehad om de TscScale-waarde opnieuw te compileren. De L1-hypervisor kan kiezen voor TSC-emulatie door naar de HV_X64_MSR_TSC_EMULATION_CONTROL MSR te schrijven. Als de L0-hypervisor is aangemeld, worden TSC-toegangen na een migratie geëmuleren.

De L1-hypervisor kan een query uitvoeren als TSC-toegang momenteel wordt geëmuleerd met behulp van de HV_X64_MSR_TSC_EMULATION_STATUS MSR. De L1-hypervisor kan zich bijvoorbeeld abonneren op livemigratiemeldingen en de TSC-status opvragen nadat deze de migratieonderbreking heeft ontvangen. Het kan ook TSC-emulatie uitschakelen (nadat deze de TscScale-waarde heeft bijgewerkt) met behulp van deze 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;

Virtuele TLB

De virtuele TLB die door de hypervisor wordt weergegeven, kan worden uitgebreid tot het opslaan van vertalingen van L2 GPO's naar GPO's. Net als bij de TLB op een logische processor is de virtuele TLB een niet-coherente cache en is deze niet-coherentie zichtbaar voor gasten. De hypervisor maakt bewerkingen beschikbaar om de TLB te beheren.

Direct virtueel leegmaken

De hypervisor maakt hypercalls beschikbaar (HvCallFlushVirtualAddressSpace, HvCallFlushVirtualAddressSpaceEx, HvCallFlushVirtualAddressList en HvCallFlushVirtualAddressListEx) waarmee besturingssystemen de virtuele TLB efficiënter kunnen beheren. De L1-hypervisor kan ervoor kiezen om toe te staan dat de gast deze hypercalls gebruikt en de verantwoordelijkheid voor de verwerking ervan delegeert aan de L0-hypervisor. Hiervoor is het gebruik van een partitiehulppagina (en een virtuele VMCS op Intel-platforms) vereist.

Wanneer de virtuele TLB wordt gebruikt, worden alle toewijzingen in de cache gelabeld met een id van de geneste context (VMCS of VMCB) die ze hebben gemaakt. Als reactie op een directe virtuele flush hypercall van een L2-gast, worden alle toewijzingen in de cache die zijn gemaakt door geneste contexten, ongeldig gemaakt door de L0-hypervisor

  • De VmId is hetzelfde als de VmId van de aanroeper
  • De VpId is opgenomen in de opgegeven ProcessorMask of HV_FLUSH_ALL_PROCESSORS is opgegeven

Ondersteuning voor directe virtuele flushes wordt gerapporteerd in CPUID leaf 0x4000000A.

Configuratie

Directe verwerking van virtuele flush hypercalls is ingeschakeld door:

  1. Het veld NestedEnlightenmentsControl.Features.DirectHypercall van de pagina Virtual Processor Assist instellen op 1.
  2. Het veld EnlightenmentsControl.NestedFlushVirtualHypercall van een verlichte VMCS of VMCB instellen op 1.

Voordat u deze inschakelt, moet de L1-hypervisor de volgende aanvullende velden van de verlichte VMCS/VMCB configureren:

  • VpId: id van de virtuele processor die door de verlichte VMCS/VMCB wordt beheerd.
  • VmId: id van de virtuele machine waartoe de verlichte VMCS/VMCB behoort.
  • PartitionAssistPage: fysiek gastadres van de pagina partitiehulp.

De L1-hypervisor moet ook de volgende mogelijkheden beschikbaar maken voor zijn gasten via CPUID.

  • UseHypercallForLocalFlush
  • UseHypercallForRemoteFlush

Pagina Partition Assist

De pagina partition assist is een uitgelijnd paginaformaatgebied van het geheugen dat de L1-hypervisor moet toewijzen en nul voordat directe flush hypercalls kunnen worden gebruikt. De GPA moet worden geschreven naar het bijbehorende veld in de verlichte VMCS / VMCB.

struct
{
    UINT32 TlbLockCount;
} VM_PARTITION_ASSIST_PAGE;

Synthetische VM-Exit

Als de TlbLockCount van de partitiehulppagina van de beller niet-nul is, levert de L0-hypervisor een VM-Exit met een synthetische afsluitreden aan de L1-hypervisor na het verwerken van een directe virtuele flush hypercall.

Op Intel-platforms wordt een VM-Exit met afsluitreden HV_VMX_SYNTHETIC_EXIT_REASON_TRAP_AFTER_FLUSH geleverd. Op AMD-platforms wordt een VM-Exit met afsluitcode HV_SVM_EXITCODE_ENL geleverd en is ExitInfo1 ingesteld op 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)

Adresomzetting op het tweede niveau

Wanneer geneste virtualisatie is ingeschakeld voor een gastpartitie, bevat de MMU (Memory Management Unit) die door de partitie wordt weergegeven, ondersteuning voor adresomzetting op het tweede niveau. Adresomzetting op het tweede niveau is een mogelijkheid die kan worden gebruikt door de L1-hypervisor om fysiek geheugen te virtualiseren. In gebruik worden bepaalde adressen die worden behandeld als fysieke gastadressen (GPO's) behandeld als fysieke L2-gastadressen (L2 GPO's) en vertaald naar GPO's door een set wisselstructuren te doorlopen.

De L1-hypervisor kan bepalen hoe en waar adresruimten op het tweede niveau moeten worden gebruikt. Elke adresruimte op het tweede niveau wordt geïdentificeerd door een door een gast gedefinieerde 64-bits id-waarde. Op Intel-platforms is deze waarde gelijk aan de EPT-aanwijzer. Op AMD-platforms is de waarde gelijk aan het veld nCR3 VMCB.

Compatibility

De mogelijkheid voor adresomzetting op het tweede niveau die wordt weergegeven door de hypervisor, is over het algemeen compatibel met VMX- of SVM-ondersteuning voor adresomzetting. De volgende waarneembare verschillen voor gasten bestaan echter:

  • Intern kan de hypervisor schaduwpaginatabellen gebruiken die L2 GPO's vertalen naar SPA's. In dergelijke implementaties lijken deze schaduwpaginatabellen software als grote TLB's te bevatten. Er kunnen echter verschillende verschillen waarneembaar zijn. Ten eerste kunnen schaduwpaginatabellen worden gedeeld tussen twee virtuele processors, terwijl traditionele TLBs per processor structuren zijn en onafhankelijk zijn. Dit delen is mogelijk zichtbaar omdat een paginatoegang door één virtuele processor een schaduwpaginatabelvermelding kan vullen die vervolgens door een andere virtuele processor wordt gebruikt.
  • Sommige hypervisorimplementaties kunnen gebruikmaken van interne schrijfbeveiliging van gastpaginatabellen om MMU-toewijzingen van interne gegevensstructuren te luieren (bijvoorbeeld schaduwpaginatabellen). Dit is architectonisch onzichtbaar voor de gast, omdat schrijfbewerkingen naar deze tabellen transparant worden verwerkt door de hypervisor. Schrijfbewerkingen die worden uitgevoerd naar de onderliggende GPA-pagina's door andere partities of door apparaten, activeren mogelijk niet de juiste TLB-flush.
  • Bij sommige hypervisor-implementaties kan een paginafout op het tweede niveau mogelijk geen ongeldige toewijzingen in de cache veroorzaken.

Verlichte TLB-flushes op het tweede niveau

De hypervisor ondersteunt ook een set verbeteringen waarmee een gast de TLB op het tweede niveau efficiënter kan beheren. Deze verbeterde bewerkingen kunnen door elkaar worden gebruikt met verouderde TLB-beheerbewerkingen.

De hypervisor ondersteunt de volgende hypercalls om TLBs ongeldig te maken:

Hypercall Description
HvCallFlushGuestPhysicalAddressSpace invalidates cached L2 GPA to GPA mappings within a second level address space.
HvCallFlushGuestPhysicalAddressList invalidates cached GVA /L2 GPA to GPA mappings binnen een gedeelte van een tweede niveau adresruimte.

Op AMD-platforms worden alle TLB-vermeldingen architectonisch getagd met een ASID (adresruimte-id). Ongeldigheid van de ASID zorgt ervoor dat alle TLB-gehelen die aan de ASID zijn gekoppeld, ongeldig worden gemaakt. De geneste hypervisor kan eventueel kiezen voor een 'verlichte TLB' door EnlightenedNptTlb in te stellen op '1' in HV_SVM_ENLIGHTENED_VMCB_FIELDS. Als de geneste hypervisor ervoor kiest om de verlichting te gebruiken, worden met ASID-invalidaties alleen TLB-gehelen gewist die zijn afgeleid van de adresomzetting op het eerste niveau (d.w.w.v. de virtuele adresruimte). Als u TLB-vermeldingen wilt leegmaken die zijn afgeleid van de geneste paginatabel (NPT) en de L0-hypervisor wilt dwingen schaduwpaginatabellen opnieuw te bouwen, moet de HvCallFlushGuestPhysicalAddressSpace of HvCallFlushGuestPhysicalAddressList hypercalls worden gebruikt.

Geneste virtualisatie-uitzonderingen

Op Intel-platforms. de L1-hypervisor kan ervoor kiezen om virtualisatieuitzonderingsuitzonderingsklasse te combineren in de uitzonderingsklasse voor paginafouten. De L0-hypervisor kondigt ondersteuning aan voor deze verlichting in het CPUID-blad hypervisor geneste virtualisatiefuncties.

Deze verlichting kan worden ingeschakeld door VirtualizationException in te stellen op '1' in HV_NESTED_ENLIGHTENMENTS_CONTROL gegevensstructuur op de pagina Virtual Processor Assist.

Geneste virtualisatie-MSR's

Register van geneste VP-index

De L1-hypervisor maakt een MSR beschikbaar die de onderliggende VP-index van de huidige processor rapporteert.

MSR-adres Registernaam Description
0x40001002 HV_X64_MSR_NESTED_VP_INDEX In een geneste hoofdpartitie rapporteert de onderliggende VP-index van de huidige processor.

Geneste SynIC MSR's

In een geneste hoofdpartitie staan de volgende MSR's toegang toe tot de bijbehorende SynIC-registers van de basishypervisor.

Als u de index van de onderliggende processor wilt vinden, moeten bellers eerst HV_X64_MSR_NESTED_VP_INDEX gebruiken.

MSR-adres Registernaam Onderliggende 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