Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Virtual Secure Mode (VSM) is een set hypervisormogelijkheden en -verlichting die wordt aangeboden aan host- en gastpartities waarmee nieuwe beveiligingsgrenzen binnen besturingssysteemsoftware kunnen worden gemaakt en beheerd. VSM is de hypervisorfaciliteit waarop Windows-beveiligingsfuncties, waaronder Device Guard, Credential Guard, virtuele TPM's en afgeschermde VM's, zijn gebaseerd. Deze beveiligingsfuncties zijn geïntroduceerd in Windows 10 en Windows Server 2016.
VSM maakt besturingssysteemsoftware in de hoofd- en gastpartities mogelijk om geïsoleerde geheugenregio's te maken voor opslag en verwerking van systeembeveiligingsassets. Toegang tot deze geïsoleerde regio's wordt beheerd en alleen verleend via de hypervisor, een zeer bevoegd, zeer vertrouwd onderdeel van de Trusted Compute Base (TCB) van het systeem. Omdat de hypervisor wordt uitgevoerd op een hoger niveau van bevoegdheden dan besturingssysteemsoftware en exclusieve controle heeft over belangrijke systeemhardwarebronnen, zoals besturingselementen voor geheugentoegangsmachtigingen in de CPU MMU en IOMMU vroeg in de systeem initialisatie, kan de hypervisor deze geïsoleerde regio's beschermen tegen onbevoegde toegang, zelfs van besturingssysteemsoftware (bijvoorbeeld besturingssysteemkernel en apparaatstuurprogramma's) met toegang tot de supervisormodus (d.w.z. CPL0, of "Ring 0").
Met deze architectuur, zelfs als normale software op systeemniveau wordt uitgevoerd in de supervisormodus (bijvoorbeeld kernel, stuurprogramma's, enzovoort) wordt aangetast door schadelijke software, kunnen de assets in geïsoleerde regio's die worden beveiligd door de hypervisor, beveiligd blijven.
VTL (Virtual Trust Level)
VSM bereikt en onderhoudt isolatie via VTLs (Virtual Trust Levels). VTLs worden ingeschakeld en beheerd op basis van zowel per partitie als per virtuele processor.
Virtuele vertrouwensniveaus zijn hiërarchisch, met hogere niveaus die meer bevoegdheden hebben dan lagere niveaus. VTL0 is het minst bevoegde niveau, waarbij VTL1 meer bevoegdheden heeft dan VTL0, VTL2 meer bevoegdheden heeft dan VTL1, enzovoort.
Architectuur worden maximaal 16 niveaus van VTLs ondersteund; een hypervisor kan er echter voor kiezen om minder dan 16 VTL's te implementeren. Momenteel worden slechts twee VTLs geïmplementeerd.
typedef UINT8 HV_VTL, *PHV_VTL;
#define HV_NUM_VTLS 2
#define HV_INVALID_VTL ((HV_VTL) -1)
#define HV_VTL_ALL 0xF
Elke VTL heeft een eigen set geheugentoegangsbeveiligingen. Deze toegangsbeveiligingen worden beheerd door de hypervisor in de fysieke adresruimte van een partitie en kunnen dus niet worden gewijzigd door software op systeemniveau die in de partitie wordt uitgevoerd.
Omdat meer bevoegde VTLs hun eigen geheugenbeveiligingen kunnen afdwingen, kunnen hogere VTLs effectief gebieden van geheugen beschermen tegen lagere VTLs. In de praktijk kan een lagere VTL geïsoleerde geheugenregio's beveiligen door ze te beveiligen met een hogere VTL. VTL0 kan bijvoorbeeld een geheim opslaan in VTL1, waarna alleen VTL1 er toegang toe heeft. Zelfs als VTL0 is aangetast, is het geheim veilig.
VTL-beveiligingen
Er zijn meerdere facetten voor het bereiken van isolatie tussen VTLs:
- Geheugentoegangsbeveiligingen: elke VTL onderhoudt een set toegangsbeveiligingen voor fysiek gastgeheugen. Software die wordt uitgevoerd op een bepaalde VTL, heeft alleen toegang tot het geheugen overeenkomstig deze beveiliging.
- Status van virtuele processor: virtuele processors behouden afzonderlijke statussen per VTL. Elke VTL definieert bijvoorbeeld een set privé-VP-registers. Software die wordt uitgevoerd op een lagere VTL, heeft geen toegang tot de registerstatus van de hogere virtuele VTL-processor.
- Interrupts: Samen met een afzonderlijke processorstatus heeft elke VTL ook een eigen interruptsubsysteem (lokale APIC op x64, GIC CPU-interface op ARM64). Hierdoor kunnen hogere VTLs interrupts verwerken zonder dat er sprake is van interferentie van een lagere VTL.
- Overlaypagina's: bepaalde overlaypagina's worden per VTL onderhouden, zodat hogere VTLs betrouwbare toegang hebben. Er is bijvoorbeeld een afzonderlijke hypercall-overlaypagina per VTL.
VSM-detectie en -status
De VSM-mogelijkheid wordt geadverteerd naar partities via de vlag voor partitiebevoegdheden van AccessVsm. Alleen partities met alle volgende bevoegdheden kunnen gebruikmaken van VSM: AccessVsm, AccessVpRegisters en AccessSynicRegs.
VSM-mogelijkheidsdetectie
Gasten hebben toegang tot een rapport over VSM-mogelijkheden via een synthetische registratie.
Op x64 Platforms
Op x64-platforms wordt dit register geopend via een MSR:
| MSR-adres | Registernaam | Description |
|---|---|---|
| 0x000D0006 | HV_X64_REGISTER_VSM_CAPABILITIES | Rapport over VSM-mogelijkheden. |
Op ARM64-platforms
Op ARM64-platformen wordt dit register geopend via HvRegisterVsmCapabilities met behulp van de Hypercalls HvCallGetVpRegisters.
Notatie registreren
Op x64 Platforms
| Bits | Description | Attributes |
|---|---|---|
| 63 | Dr6Shared | Lezen |
| 62:47 | MbecVtlMask | Lezen |
| 46 | DenyLowerVtlStartup | Lezen |
| 45:0 | RsvdZ | Lezen |
Op ARM64-platforms
| Bits | Description | Attributes |
|---|---|---|
| 63 | RsvdZ | Lezen |
| 62:47 | MbecVtlMask | Lezen |
| 46 | DenyLowerVtlStartup | Lezen |
| 45:0 | RsvdZ | Lezen |
Veldbeschrijvingen
Dr6Shared (alleen x64): Geeft aan de gast aan of Dr6 een gedeeld register is tussen de VTLs.
MbecVtlMask: Geeft aan de gast de VTLs aan waarvoor MBEC kan worden ingeschakeld.
DenyLowerVtlStartup: geeft aan de gast aan of een VTL het opnieuw instellen van een VP kan weigeren door een lagere VTL.
VSM-statusregister
Naast een vlag voor partitiebevoegdheden kunnen twee virtuele registers worden gebruikt voor meer informatie over de VSM-status: HvRegisterVsmPartitionStatus en HvRegisterVsmVpStatus.
HvRegisterVsmPartitionStatus
HvRegisterVsmPartitionStatus is een alleen-lezenregister per partitie dat wordt gedeeld in alle VTLs. Dit register bevat informatie over welke VTLs zijn ingeschakeld voor de partitie, welke VTLs op modus gebaseerde uitvoeringsbesturingselementen hebben ingeschakeld, evenals de maximaal toegestane VTL.
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 EnabledVtlSet : 16;
UINT64 MaximumVtl : 4;
UINT64 MbecEnabledVtlSet: 16;
UINT64 ReservedZ : 28;
};
} HV_REGISTER_VSM_PARTITION_STATUS;
HvRegisterVsmVpStatus
HvRegisterVsmVpStatus is een alleen-lezen register en wordt gedeeld in alle VTLs. Het is een register per VP, wat betekent dat elke virtuele processor een eigen exemplaar onderhoudt. Dit register bevat informatie over welke VTLs zijn ingeschakeld, wat actief is, evenals de MBEC-modus die actief is op een VP.
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 ActiveVtl : 4;
UINT64 ActiveMbecEnabled : 1;
UINT64 ReservedZ0 : 11;
UINT64 EnabledVtlSet : 16;
UINT64 ReservedZ1 : 32;
};
} HV_REGISTER_VSM_VP_STATUS;
ActiveVtl is de id van de VTL-context die momenteel actief is op de virtuele processor.
ActiveMbecEnabled geeft aan dat MBEC momenteel actief is op de virtuele processor.
EnabledVtlSet is een bitmap van de VTL's die zijn ingeschakeld op de virtuele processor.
VTL-beginstatus partitioneren
Wanneer een partitie wordt gestart of opnieuw wordt ingesteld, wordt deze uitgevoerd in VTL0. Alle andere VTLs worden uitgeschakeld bij het maken van partities.
VTL-inschakeling
Als u een VTL wilt gaan gebruiken, moet een lagere VTL het volgende initiëren:
- Schakel de doel-VTL in voor de partitie. Hierdoor is de VTL algemeen beschikbaar voor de partitie.
- Schakel de doel-VTL in op een of meer virtuele processors. Hierdoor is de VTL beschikbaar voor een VP en wordt de oorspronkelijke context ingesteld. Het wordt aanbevolen dat alle VM's dezelfde ingeschakelde VTLs hebben. Als een VTL is ingeschakeld op sommige VPs (maar niet alle) kan dit leiden tot onverwacht gedrag.
- Zodra de VTL is ingeschakeld voor een partitie en VP, kan deze beginnen met het instellen van toegangsbeveiligingen zodra de vlag EnableVtlProtection is ingesteld.
Houd er rekening mee dat VTLs niet opeenvolgend hoeven te zijn.
Een doel-VTL inschakelen voor een partitie
De HvCallEnablePartitionVtl hypercall wordt gebruikt om een VTL in te schakelen voor een bepaalde partitie. Houd er rekening mee dat voordat software daadwerkelijk kan worden uitgevoerd in een bepaalde VTL, die VTL moet worden ingeschakeld op virtuele processors in de partitie.
Een doel-VTL inschakelen voor virtuele processors
Zodra een VTL is ingeschakeld voor een partitie, kan deze worden ingeschakeld op de virtuele processors van de partitie. De HvCallEnableVpVtl hypercall kan worden gebruikt om VTLs in te schakelen voor een virtuele processor, waarmee de eerste context wordt ingesteld.
Virtuele processors hebben één 'context' per VTL. Als een VTL wordt overgeschakeld, wordt ook de privéstatus van de VTL gewijzigd.
VTL-configuratie
Zodra een VTL is ingeschakeld, kan de configuratie worden gewijzigd door een VP die wordt uitgevoerd op een gelijke of hogere VTL.
Partitieconfiguratie
Partitiebrede kenmerken kunnen worden geconfigureerd met behulp van het HvRegisterVsmPartitionConfig-register. Er is één exemplaar van dit register voor elke VTL (groter dan 0) op elke partitie.
Elke VTL kan een eigen exemplaar van HV_REGISTER_VSM_PARTITION_CONFIG en exemplaren voor lagere VTL's wijzigen. VTLs wijzigen dit register mogelijk niet voor hogere VTLs.
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 EnableVtlProtection : 1;
UINT64 DefaultVtlProtectionMask : 4;
UINT64 ZeroMemoryOnReset : 1;
UINT64 DenyLowerVtlStartup : 1;
UINT64 ReservedZ : 2;
UINT64 InterceptVpStartup : 1;
UINT64 ReservedZ : 54; };
} HV_REGISTER_VSM_PARTITION_CONFIG;
De velden van dit register worden hieronder beschreven.
VTL-beveiliging inschakelen
Zodra een VTL is ingeschakeld, moet de vlag EnableVtlProtection worden ingesteld voordat de geheugenbeveiliging kan worden toegepast. Deze vlag is write-once, wat betekent dat deze niet kan worden gewijzigd zodra deze is ingesteld.
Standaardbeveiligingsmasker
Standaard past het systeem RWX-beveiliging toe op alle momenteel toegewezen pagina's en toekomstige 'hot-added' pagina's. Dynamische pagina's verwijzen naar geheugen dat tijdens een bewerking voor het wijzigen van de grootte wordt toegevoegd aan een partitie.
Een hogere VTL kan een ander standaardbeleid voor geheugenbeveiliging instellen door DefaultVtlProtectionMask op te geven in HV_REGISTER_VSM_PARTITION_CONFIG. Dit masker moet worden ingesteld op het moment dat de VTL is ingeschakeld. Het kan niet worden gewijzigd nadat deze is ingesteld en wordt alleen gewist door het opnieuw instellen van een partitie.
| Bit | Description |
|---|---|
| 0 | Lezen |
| 1 | Write |
| 2 | Kernelmodus uitvoeren (KMX) |
| 3 | Gebruikersmodus uitvoeren (UMX) |
Nul geheugen bij opnieuw instellen
ZeroMemOnReset is een bit die bepaalt of het geheugen nul is voordat een partitie opnieuw wordt ingesteld. Deze configuratie is standaard ingeschakeld. Als de bit is ingesteld, wordt het geheugen van de partitie nul uitgevoerd bij het opnieuw instellen, zodat het geheugen van een hogere VTL niet kan worden aangetast door een lagere VTL. Als deze bit is gewist, wordt het geheugen van de partitie niet nul ingesteld bij het opnieuw instellen.
DenyLowerVtlStartup
De vlag DenyLowerVtlStartup bepaalt of een virtuele processor kan worden gestart of opnieuw kan worden ingesteld door lagere VTLs. Dit omvat architecturale manieren om een virtuele processor (bijvoorbeeld SIPI op X64) en de HvCallStartVirtualProcessor hypercall opnieuw in te schakelen.
InterceptVpStartup
Als de vlag InterceptVpStartup is ingesteld, genereert het starten of opnieuw instellen van een virtuele processor een snijpunt naar de hogere VTL.
Lagere VTLs configureren
Het volgende register kan worden gebruikt door hogere VTLs om het gedrag van lagere VTLs te configureren:
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 MbecEnabled : 1;
UINT64 TlbLocked : 1;
UINT64 ReservedZ : 62;
};
} HV_REGISTER_VSM_VP_SECURE_VTL_CONFIG;
Elke VTL (hoger dan 0) heeft een exemplaar van dit register voor elke VTL die lager is dan zichzelf. VTL2 heeft bijvoorbeeld twee exemplaren van dit register: één voor VTL1 en een tweede voor VTL0.
De velden van dit register worden hieronder beschreven.
MbecEnabled
Dit veld configureert of MBEC is ingeschakeld voor de lagere VTL.
TlbLocked
Met dit veld wordt de TLB van de lagere VTL vergrendeld. Deze mogelijkheid kan worden gebruikt om te voorkomen dat lagere VTLs TLB-ongeldige fouten veroorzaken die een hogere VTL kunnen verstoren. Wanneer deze bit is ingesteld, worden alle aanvragen voor het leegmaken van de adresruimte van de lagere VTL geblokkeerd totdat de vergrendeling wordt opgeheven.
Als u de TLB wilt ontgrendelen, kan de hogere VTL deze bit wissen. Zodra een VP terugkeert naar een lagere VTL, worden alle TLB-vergrendelingen vrijgegeven die op het moment worden opgeslagen.
VTL-vermelding
Een VTL wordt 'ingevoerd' wanneer een VP overschakelt van een lagere VTL naar een hogere. Dit kan om de volgende redenen gebeuren:
- VTL-aanroep: dit is wanneer software expliciet code in een hogere VTL wil aanroepen.
- Beveiligde interrupt: als een interrupt wordt ontvangen voor een hogere VTL, voert de VP de hogere VTL in.
- Beveiligd snijpunt: bepaalde acties activeren een beveiligde interrupt (bijvoorbeeld toegang tot bepaalde MSR's).
Zodra een VTL is ingevoerd, moet deze vrijwillig afsluiten. Een hogere VTL kan niet worden gebruikt door een lagere VTL.
Reden van VTL-vermelding identificeren
Als u op de juiste wijze wilt reageren op een vermelding, moet een hogere VTL mogelijk weten wat de reden is waarom deze is ingevoerd. Om onderscheid te maken tussen invoerredenen, wordt de VTL-vermelding opgenomen in de HV_VP_VTL_CONTROL structuur.
VTL-aanroep
Een 'VTL-aanroep' is wanneer een lagere VTL een vermelding in een hogere VTL initieert (bijvoorbeeld om een geheugengebied met de hogere VTL te beveiligen) via de HvCallVtlCall hypercall.
VTL-aanroepen behouden de status van gedeelde registers tussen VTL-switches. Privéregisters blijven behouden op VTL-niveau. De uitzondering op deze beperkingen zijn de registers/instructies die vereist zijn voor de VTL-aanroepreeks.
Op x64 Platforms
De volgende registers zijn vereist voor een VTL-aanroep op x64:
| x64 | x86 | Description |
|---|---|---|
| RCX | EDX:EAX | Hiermee geeft u een VTL-aanroepbesturingsinvoer voor de hypervisor op |
| RAX | ECX | Gereserveerd |
Alle bits in de invoer van het VTL-aanroepbeheer zijn momenteel gereserveerd.
Op ARM64-platforms
Op ARM64-platforms wordt een VTL-aanroep gestart met behulp van de HVC-instructie met onmiddellijke waarde 2. De hypervisor ontsleutelt deze specifieke onmiddellijke waarde en verwerkt deze als een HvCallVtlCall-hypercall. Er is geen specifieke registerstatus vereist voor de besturingsinvoer op ARM64.
Beperkingen voor VTL-aanroepen
VTL-aanroepen kunnen alleen worden gestart vanuit de meest bevoegde processormodus. Op x64-systemen kan een VTL-aanroep bijvoorbeeld alleen afkomstig zijn van CPL0 en op ARM64-systemen van EL1. Een VTL-aanroep gestart vanuit een processormodus die alles behalve de meeste bevoegdheden op het systeem tot gevolg heeft dat de hypervisor een uitzondering in de virtuele processor injecteert (#UD op x64, niet-gedefinieerde instructieuitzondering op ARM64).
Een VTL-aanroep kan alleen overschakelen naar de eerstvolgende hoogste VTL. Met andere woorden, als er meerdere VTLs zijn ingeschakeld, kan een aanroep een VTL niet overslaan. De volgende acties resulteren in een uitzondering (#UD op x64, niet-gedefinieerde instructies voor ARM64):
- Een VTL-aanroep gestart vanuit een processormodus die alles behalve de meeste bevoegdheden op het systeem (architectuurspecifiek) is.
- Een VTL-aanroep vanuit de echte modus (alleen x86/x64)
- Een VTL-aanroep op een virtuele processor waarbij de doel-VTL is uitgeschakeld (of nog niet is ingeschakeld).
- Een VTL-aanroep met een ongeldige invoerwaarde voor besturingselementen
VTL afsluiten
Een switch naar een lagere VTL wordt een 'return' genoemd. Zodra een VTL is verwerkt, kan deze een VTL-retour initiëren om over te schakelen naar een lagere VTL. De enige manier waarop een VTL kan worden geretourneerd, is als een hogere VTL vrijwillig een VTL initieert. Een lagere VTL kan nooit een hogere VTL voorbereiden.
VTL-retour
Een 'VTL return' is wanneer een hogere VTL een switch initieert naar een lagere VTL via de HvCallVtlReturn hypercall. Net als bij een VTL-aanroep wordt de status van de privéprocessor uitgeschakeld en blijft de gedeelde status aanwezig. Als de lagere VTL expliciet is aangeroepen in de hogere VTL, wordt de hypervisor de instructieaanwijzer van de hogere VTL verhoogd voordat de retour is voltooid, zodat deze kan doorgaan na een VTL-aanroep.
Op x64 Platforms
Voor een VTL-retourcodereeks op x64 is het gebruik van de volgende registers vereist:
| x64 | x86 | Description |
|---|---|---|
| RCX | EDX:EAX | Hiermee geeft u een VTL-retourbesturingsinvoer voor de hypervisor op |
| RAX | ECX | Gereserveerd |
Op ARM64-platforms
Op ARM64-platforms wordt een VTL-retour geïnitieerd met behulp van de HVC-instructie met onmiddellijke waarde 3. De hypervisor decodeert deze specifieke onmiddellijke waarde en verwerkt deze als een HvCallVtlReturn hypercall.
Invoer van VTL-retourbeheer
De invoer van het VTL-retourbeheer heeft de volgende indeling:
| Bits | Veld | Description |
|---|---|---|
| 63:1 | RsvdZ | |
| 0 | Snel rendement | Registers worden niet hersteld |
Met de volgende acties wordt een #UD uitzondering gegenereerd:
- Een VTL-retour wordt uitgevoerd wanneer de laagste VTL momenteel actief is
- Een VTL-retour uitvoeren met een ongeldige invoerwaarde voor besturingselementen
- Een poging om een VTL te retourneren vanuit een processormodus die alles behalve de meeste bevoegdheden heeft op het systeem (architectuurspecifiek)
Snel terugsturen
Als onderdeel van het verwerken van een retour kan de hypervisor de registerstatus van de lagere VTL herstellen vanuit de HV_VP_VTL_CONTROL structuur. Na het verwerken van een beveiligde interrupt kan een hogere VTL bijvoorbeeld een hogere VTL willen retourneren zonder de status van de lagere VTL te verstoren. Daarom biedt de hypervisor een mechanisme om de registers van de lagere VTL te herstellen naar hun pre-aanroepwaarde die is opgeslagen in de VTL-besturingsstructuur.
Als dit gedrag niet nodig is, kan een hogere VTL een 'snel rendement' gebruiken. Een snelle terugkeer is wanneer de hypervisor de registerstatus niet herstelt vanuit de besturingsstructuur. Dit moet waar mogelijk worden gebruikt om onnodige verwerking te voorkomen.
Dit veld kan worden ingesteld met bit 0 van de VTL-retourinvoer. Als deze is ingesteld op 0, worden de registers hersteld vanuit de HV_VP_VTL_CONTROL structuur. Als deze bit is ingesteld op 1, worden de registers niet hersteld (een snelle terugkeer).
Hypercall Page Assist (alleen x64)
Op x64-platforms biedt de hypervisor mechanismen om te helpen bij VTL-aanroepen en wordt geretourneerd via de hypercall-pagina. Op deze pagina wordt de specifieke codereeks geabstraheerd die nodig is om van VTLs te wisselen.
De codereeksen voor het uitvoeren van VTL-aanroepen en retournaties kunnen worden geopend door specifieke instructies uit te voeren op de hypercall-pagina. De oproep-/retoursegmenten bevinden zich op een offset op de hypercall-pagina die wordt bepaald door het virtuele register HvRegisterVsmCodePageOffsets. Dit is een alleen-lezen en partitiebreed register, met een afzonderlijk exemplaar per VTL.
Een VTL kan een VTL-aanroep/return uitvoeren met behulp van de INSTRUCTIE OPROEP. Een OPROEP naar de juiste locatie op de hypercall-pagina initieert een VTL-aanroep/retour.
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 VtlCallOffset : 12;
UINT64 VtlReturnOffset : 12;
UINT64 ReservedZ : 40;
};
} HV_REGISTER_VSM_CODE_PAGE_OFFSETS;
Samenvattend zijn de stappen voor het aanroepen van een codereeks met behulp van de hypercall-pagina op x64 als volgt:
- De hypercall-pagina toewijzen aan de GPA-ruimte van een VTL
- Bepaal de juiste offset voor de codereeks (VTL-aanroep of return).
- Voer de codereeks uit met BEHULP van CALL.
Opmerking: Op ARM64-platforms worden VTL-aanroepen en retourneert rechtstreeks uitgevoerd met behulp van de HVC-instructie met specifieke directe waarden (2 voor VTL-aanroep, 3 voor VTL-retour) zoals beschreven in de secties VTL-aanroep en VTL-retour. Het register HvRegisterVsmCodePageOffsets is niet beschikbaar op ARM64.
Geheugentoegangsbeveiligingen
Een noodzakelijke beveiliging van VSM is de mogelijkheid om geheugentoegang te isoleren.
Hogere VTLs hebben een hoge mate van controle over het type geheugentoegang dat is toegestaan door lagere VTLs. Er zijn drie basistypen beveiligingen die kunnen worden opgegeven door een hogere VTL voor een bepaalde GPA-pagina: Lezen, Schrijven en eXecute. Deze worden gedefinieerd in de volgende tabel:
| Naam | Description |
|---|---|
| Lezen | Hiermee bepaalt u of leestoegang is toegestaan tot een geheugenpagina |
| Write | Hiermee bepaalt u of schrijftoegang is toegestaan voor een geheugenpagina |
| Execute | Hiermee bepaalt u of het ophalen van instructies is toegestaan voor een geheugenpagina. |
Deze drie combinaties voor de volgende typen geheugenbeveiliging:
- Geen toegang
- Alleen-lezen, geen uitvoering
- Alleen-lezen, uitvoeren
- Lezen/schrijven, geen uitvoering
- Lezen/schrijven, uitvoeren
Als op modus gebaseerd uitvoeringsbeheer (MBEC) is ingeschakeld, kunnen beveiligingen voor gebruikers- en kernelmodus afzonderlijk worden ingesteld.
Hogere VTLs kunnen de geheugenbeveiliging voor een GPA instellen via de HvCallModifyVtlProtectionMask hypercall.
Hiërarchie geheugenbeveiliging
Machtigingen voor geheugentoegang kunnen worden ingesteld door een aantal bronnen voor een bepaalde VTL. De machtigingen van elke VTL kunnen mogelijk worden beperkt door een aantal andere VTLs, evenals door de hostpartitie. De volgorde waarin beveiligingen worden toegepast, is het volgende:
- Geheugenbeveiligingen die zijn ingesteld door de host
- Geheugenbeveiligingen die zijn ingesteld door hogere VTLs
Met andere woorden, VTL-beveiliging vervangt hostbeveiligingen. VTLs op een hoger niveau vervangen VTLs op lager niveau. Houd er rekening mee dat een VTL mogelijk geen machtigingen voor geheugentoegang voor zichzelf instelt.
Een conforme interface zal naar verwachting geen niet-RAM-type over RAM-geheugen leggen.
Schendingen van geheugentoegang
Als een VP met een lagere VTL probeert een geheugenbeveiliging te schenden die is ingesteld door een hogere VTL, wordt er een snijpunt gegenereerd. Dit snijpunt wordt ontvangen door de hogere VTL die de beveiliging instelt. Hierdoor kunnen hogere VTLs de schending per geval verwerken. De hogere VTL kan er bijvoorbeeld voor kiezen om een fout te retourneren of de toegang te emuleren.
Op modus gebaseerd uitvoeren van besturingselement (MBEC)
Wanneer een VTL een geheugenbeperking op een lagere VTL plaatst, kan het een onderscheid maken tussen de gebruikers- en kernelmodus wanneer een 'execute'-bevoegdheid wordt verleend. Als er bijvoorbeeld code-integriteitscontroles zouden plaatsvinden in een hogere VTL, betekent de mogelijkheid om onderscheid te maken tussen gebruikersmodus en kernelmodus dat een VTL code-integriteit kan afdwingen voor alleen kernelmodustoepassingen.
Naast de traditionele drie geheugenbeveiligingen (lezen, schrijven, uitvoeren), introduceert MBEC een onderscheid tussen de gebruikersmodus en kernelmodus voor het uitvoeren van beveiligingen. Als MBEC is ingeschakeld, biedt een VTL de mogelijkheid om vier typen geheugenbeveiliging in te stellen:
| Naam | Description |
|---|---|
| Lezen | Hiermee bepaalt u of leestoegang is toegestaan tot een geheugenpagina |
| Write | Hiermee bepaalt u of schrijftoegang is toegestaan voor een geheugenpagina |
| Gebruikersmodus uitvoeren (UMX) | Hiermee bepaalt u of instructies die zijn gegenereerd in de gebruikersmodus, zijn toegestaan voor een geheugenpagina. OPMERKING: Als MBEC is uitgeschakeld, wordt deze instelling genegeerd. |
| Kernelmodus uitvoeren (KMX) | Hiermee bepaalt u of instructies die zijn gegenereerd in de kernelmodus, zijn toegestaan voor een geheugenpagina. OPMERKING: Als MBEC is uitgeschakeld, wordt met deze instelling zowel de gebruikersmodus als de kernelmodus uitgevoerd. |
Het geheugen dat is gemarkeerd met de beveiliging 'User-Mode Uitvoeren' is alleen uitvoerbaar wanneer de virtuele processor wordt uitgevoerd in de gebruikersmodus. Op dezelfde manier zou het geheugen 'Kernel-Mode Uitvoeren' alleen uitvoerbaar zijn wanneer de virtuele processor wordt uitgevoerd in de kernelmodus.
KMX en UMX kunnen onafhankelijk worden ingesteld, zodat uitvoermachtigingen anders worden afgedwongen tussen de gebruikers- en kernelmodus. Alle combinaties van UMX en KMX worden ondersteund, met uitzondering van KMX=1, UMX=0. Het gedrag van deze combinatie is niet gedefinieerd.
MBEC is standaard uitgeschakeld voor alle VTLs en virtuele processors. Wanneer MBEC is uitgeschakeld, bepaalt de kernelmodus bit voor geheugentoegang. Als MBEC is uitgeschakeld, is KMX=1-code dus uitvoerbaar in zowel kernel- als gebruikersmodus.
Descriptortabellen (alleen x64)
Op x64-platforms moet elke code in de gebruikersmodus die toegang heeft tot descriptortabellen, zich in GPA-pagina's bevinden die zijn gemarkeerd als KMX=UMX=1. Software in de gebruikersmodus die toegang heeft tot descriptortabellen van een GPA-pagina die is gemarkeerd als KMX=0, wordt niet ondersteund en resulteert in een algemene beveiligingsfout.
ARM64 maakt geen gebruik van x86-stijl descriptortabellen; machtigingen voor geheugentoegang worden beheerd via vermeldingen in de vertaaltabel en het op EL gebaseerde bevoegdheidsmodel.
MBEC-configuratie
Als u op modus gebaseerd uitvoeringsbeheer wilt gebruiken, moet dit op twee niveaus worden ingeschakeld:
- Wanneer de VTL is ingeschakeld voor een partitie, moet MBEC zijn ingeschakeld met HvCallEnablePartitionVtl
- MBEC moet worden geconfigureerd per VP en per VTL, met behulp van HvRegisterVsmVpSecureConfigVtlX.
MBEC-interactie met preventie van uitvoering van supervisormodus (SMEP) (alleen x64)
Supervisor-Mode Execution Prevention (SMEP) is een processorfunctie die wordt ondersteund op x64-platforms. SMEP kan van invloed zijn op de werking van MBEC vanwege de beperking van supervisortoegang tot geheugenpagina's. De hypervisor voldoet aan het volgende beleid met betrekking tot SMEP:
- Als SMEP niet beschikbaar is voor het gastbesturingssystemen (of dit nu het gevolg is van hardwaremogelijkheden of processorcompatibiliteitsmodus), werkt MBEC niet.
- Als SMEP beschikbaar is en is ingeschakeld, werkt MBEC niet.
- Als SMEP beschikbaar is en is uitgeschakeld, vallen alle uitvoerbeperkingen onder het KMX-besturingselement. Daarom mag alleen code die als KMX=1 is gemarkeerd, worden uitgevoerd.
Statusisolatie van virtuele processor
Virtuele processors onderhouden afzonderlijke statussen voor elke actieve VTL. Sommige van deze status is echter privé voor een bepaalde VTL en de resterende status wordt gedeeld tussen alle VTLs.
De hypervisor onderhoudt een context per VTL voor elke virtuele processor, waarbij alle gastbare processorstatus wordt opgeslagen die moet worden geïsoleerd tussen VTLs. Elke VTL heeft een eigen exemplaar van een privéstatus, waaronder controleregisters, uitzonderingsvectoren, systeemconfiguratieregisters en synthetische hypervisorregisters. Deze per VTL-opslag zorgt voor een volledige isolatie van de uitvoeringscontext bij het schakelen tussen vertrouwensniveaus.
Status die behouden blijft per VTL (a.k.a. privéstatus) wordt opgeslagen door de hypervisor over VTL-overgangen. Als een VTL-switch wordt gestart, slaat de hypervisor de huidige privéstatus op voor de actieve VTL en schakelt deze vervolgens over naar de privéstatus van de doel-VTL. Gedeelde status blijft actief, ongeacht de VTL-switches.
Privéstatus
Elke VTL onderhoudt een eigen volledige uitvoeringscontext die bestaat uit:
- Uitvoeringsstatus: Instructiepointer (PC/RIP), stackpointer (SP/RSP), processorvlagmen (PSTATE/RFLAGS)
- Controleregisters: Configuratie van geheugenbeheer (paginatabellen, vertaalbesturingselementen, geheugenkenmerken)
- Afhandeling van uitzonderingen: Uitzonderingsvectors, registers van uitzonderings syndroom, foutadresregisters
- Systeemconfiguratie: Besturingselementen voor processorfuncties, besturingselementen voor foutopsporing, timerconfiguratie
- Synthetische registers: Hypervisor-interface registreert specifiek voor elke VTL (hypercall-pagina, gast os-id, referentie-TSC, synthetische interruptcontroller)
Deze isolatie zorgt ervoor dat elke VTL onafhankelijke controle heeft over de uitvoeringsomgeving en de privéstatus van andere VTL's niet kan observeren of verstoren.
Op x64 Platforms
Op x64-platforms onderhoudt elke VTL een eigen uitvoeringscontext via architectuurspecifieke MSR's en registers. De hypervisor behoudt deze over VTL-switches en zorgt voor een volledige isolatie van de uitvoeringsomgeving.
Privé-MSR's regelen systeemoproepmechanismen, geheugenkenmerken, processorfuncties en de hypervisorinterface.
Architectuur-MSR's:
- SYSENTER_CS, SYSENTER_ESP, SYSENTER_EIP, STAR, LSTAR, CSTAR, SFMASK, EFER, PAT, KERNEL_GSBASE, FS. BASIS, GS. BASIS, TSC_AUX
- Lokale APIC-registers (inclusief CR8/TPR)
Synthetische MSR's:
- HV_X64_MSR_HYPERCALL
- HV_X64_MSR_GUEST_OS_ID
- HV_X64_MSR_REFERENCE_TSC
- HV_X64_MSR_APIC_FREQUENCY
- HV_X64_MSR_EOI
- HV_X64_MSR_ICR
- HV_X64_MSR_TPR
- HV_X64_MSR_VP_ASSIST_PAGE
- HV_X64_MSR_NPIEP_CONFIG
- HV_X64_MSR_SIRBP
- HV_X64_MSR_SCONTROL
- HV_X64_MSR_SVERSION
- HV_X64_MSR_SIEFP
- HV_X64_MSR_SIMP
- HV_X64_MSR_EOM
- HV_X64_MSR_SINT0 – HV_X64_MSR_SINT15
- HV_X64_MSR_STIMER0_CONFIG – HV_X64_MSR_STIMER3_CONFIG
- HV_X64_MSR_STIMER0_COUNT – HV_X64_MSR_STIMER3_COUNT
Privéregisters beheren de uitvoeringsomgeving, het geheugenbeheer en de afhandeling van uitzonderingen:
- Uitvoeringsstatus: RIP (instructiepointer), RSP (stackpointer), RFLAGS (processorvlags)
- Geheugenbeheer: CR0 (processorbesturing), CR3 (basis van paginatabel), CR4 (processorfuncties)
- Descriptortabellen: IDTR (interrupt descriptortabel), GDTR (algemene descriptortabel)
- Segmentregisters: CS, DS, ES, FS, GS, SS, TR, LDTR
- Besturingselement voor foutopsporing: DR7 (register voor foutopsporingsbeheer)
- Tijdstempel: TSC (tijdstempelteller, onafhankelijke tijdverwijzing per VTL)
- Foutopsporingsstatus: DR6 (foutopsporingsstatusregister - afhankelijk van processortype; hvRegisterVsmCapabilities lezen om te bepalen of gedeeld of privé)
Op ARM64-platforms
Op ARM64-platforms onderhoudt elke VTL een eigen volledige systeemregistercontext. De hypervisor behoudt deze registers over VTL-switches en zorgt voor een volledige isolatie van de uitvoerings- en uitzonderingsomgeving.
Uitvoeringsstatus registreert de controleprogrammastroom en processormodus:
- PC (programmateller), SP_EL0, SP_EL1 (stackpointers)
- PSTATE (processorstatusvlagmen), FPCR/FPSR (drijvendekommagesturingselement/status)
- ELR_EL1, SPSR_EL1 (uitzonderingskoppeling registreren, opgeslagen programmastatus)
Geheugenbeheer en vertaalbeheer registreert het configureren van virtueel geheugen:
- TTBR0_EL1, TTBR1_EL1 (basisregisters voor vertaaltabellen)
- TCR_EL1 (register voor vertaalbeheer)
- MAIR_EL1 (indirectieregister voor geheugenkenmerken)
- SCTLR_EL1 (systeembeheerregister)
- CONTEXTIDR_EL1 (context-id)
Uitzonderings- en interruptafhandeling registreert het gedrag van uitzonderingsbeheer:
- VBAR_EL1 (register van vectorbasisadres - locatie van uitzonderingsvectortabel)
- ESR_EL1 (uitzonderings syndroom register)
- FAR_EL1 (foutadresregister)
- AFSR0_EL1, AFSR1_EL1 (hulpfoutstatusregisters)
Systeemconfiguratie registreert besturingselementprocessorfuncties:
- CPACR_EL1 (coprocessortoegangsbeheer)
- ACTLR_EL1 (hulpcontroleregister)
- AMAIR_EL1 (indirectieregister voor hulpgeheugenkenmerken)
- ZCR_EL1, SMCR_EL1 (SVE/SME-configuratie indien ondersteund)
Registers voor foutopsporing en prestatiebewaking zijn VTL-privé. Dit omvat alle systeemregisters voor foutopsporing (MDSCR_EL1, DBGBCR_EL1[], DBGBVR_EL1[], DBGWCR_EL1[], DBGWVR_EL1[], enzovoort) en alle prestatiemeterregisters (PMCR_EL0 en gerelateerde PMU-registers)
Timerconfiguratie registreert:
- CNTKCTL_EL1 (kerneltimerbesturing)
- CNTV_CTL_EL0, CNTV_CVAL_EL0 (virtueel timerbeheer en waarde vergelijken)
ThreadIdentificatieregisters :
- TPIDR_EL0, TPIDR_EL1, TPIDRRO_EL0 (thread-id-registers)
Synthetische hypervisorregisters (toegankelijk via hypercalls, niet rechtstreeks als systeemregisters):
- HvRegisterGuestOsId (identificatie van gastbesturingssystemen)
- HvRegisterHypercallMsrValue (hypercall interface enablement)
- HvRegisterReferenceTsc (pagina referentietijdstempelteller)
- HvRegisterVpAssistPage (VP Assist-pagina voor deze VTL)
- Synthetische interrupt controller registers (SynIC)
- Synthetische timerregisters (Stimer0-3)
- Lokale interruptcontrollerinterface (GIC CPU-interface)
Deze uitgebreide isolatie per VTL-register zorgt ervoor dat elke VTL volledige controle heeft over de uitvoeringsomgeving, geheugenbeheer, uitzonderingsafhandeling en hypervisorinterface zonder interferentie van andere VTLs.
Gedeelde status
VTLs delen bepaalde processorstatus om de overhead van VTL-overgangen te verminderen en efficiënte communicatie tussen vertrouwensniveaus mogelijk te maken. Gedeelde status omvat algemene registers die worden gebruikt voor het doorgeven van berekeningen en gegevens, de status van drijvende komma en bepaalde systeemstatusregisters die geen invloed hebben op de beveiligingsgrenzen.
Door algemene registers over VTLs te delen, kan een VTL-aanroep parameters rechtstreeks doorgeven in registers en kan een VTL-retour resultaten doorgeven zonder dat er geheugencommunicatie nodig is. Dit ontwerp verbetert de prestaties van cross-VTL-aanroepen aanzienlijk, terwijl de beveiligingsisolatie van de privéstatus behouden blijft.
Op x64 Platforms
Op x64-platforms bevat gedeelde status registers voor algemeen gebruik voor berekeningen, systeeminformatieregisters en bepaalde statusregisters die geen invloed hebben op beveiligingsisolatie.
Gedeelde MSR's bieden systeemgegevens en -configuraties die gemeenschappelijk zijn voor VTLs:
- HV_X64_MSR_TSC_FREQUENCY
- HV_X64_MSR_VP_INDEX
- HV_X64_MSR_VP_RUNTIME
- HV_X64_MSR_RESET
- HV_X64_MSR_TIME_REF_COUNT
- HV_X64_MSR_GUEST_IDLE
- HV_X64_MSR_DEBUG_DEVICE_OPTIONS
- MTRR's
- MCG_CAP
- MCG_STATUS
Gedeelde registers maken efficiënte gegevensdoorgifte en berekeningen mogelijk voor VTLs:
- General-Purpose Registers: Rax, Rbx, Rcx, Rdx, Rsi, Rbap, R8-R15 (gebruikt voor berekening en parameterdoorgifte tijdens VTL-aanroepen)
- Uitzonderingsinformatie: CR2 (lineair adres van paginafout - gedeeld voor context van uitzonderingsafhandeling)
- Foutopsporingsgegevens: DR0-DR3 (foutopsporingsadresregisters - gebruikt voor onderbrekingspuntadressen)
-
Floating-Point en vectorstatus:
- X87 drijvendekommastatus (verouderde berekening van drijvende komma)
- XMM-status (128-bits SSE-vectoren)
- AVX-status (256-bits vectoren)
- XCR0/XFEM (uitgebreide functie inschakelen masker)
- Foutopsporingsstatus: DR6 (foutopsporingsstatusregister - afhankelijk van processortype; hvRegisterVsmCapabilities lezen om te bepalen of gedeeld of privé)
Op ARM64-platforms
Op ARM64-platforms omvat gedeelde status registers die worden gebruikt voor berekeningen, gegevensdoorgifte en drijvendekommabewerkingen. Dankzij dit delen kunnen efficiënte VTL-aanroepen worden uitgevoerd door parameters en resultaten rechtstreeks in registers door te geven.
Gedeelde registers maken berekening en communicatie tussen VTU's mogelijk:
-
General-Purpose Registreert: X0-X17, X19-X28 (gebruikt voor berekening en parameterdoorgifte)
- X0-X7 doorgaans gebruikt voor functieparameters en retourwaarden tijdens VTL-aanroepen
- X8-X17, X19-X28 beschikbaar voor algemene berekening
- Opmerking: X18 (platformregister) en pc zijn om veiligheidsredenen privé per VTL
- Opmerking: X29 (FP/frame pointer), X30 (LR/link register) en SP zijn privé per VTL
-
Floating-Point en vectorstatus:
- Q0-Q31 (128-bits NEON/drijvende kommaregisters voor vectorberekeningen)
- Geavanceerde SIMD-status (NEON) voor vectorbewerkingen
- Opmerking: SVE-status (Z0-Z31, P0-P15, FFR) en SME-status zijn VTL-privé. Het onderste 128-bits gedeelte (Q-registers) wordt gedeeld, maar de bovenste bits van Z-registers zijn mogelijk beschadigd bij VTL-overgangen. Software mag niet afhankelijk zijn van Z-registerinhoud die behouden blijft tussen VTL-switches.
- Opmerking: spe (statistische profileringsextensie) wordt gedeeld tussen VTLs, met uitzondering van PMBSR_EL1 die VTL-privé is
-
Systeeminformatieregisters (alleen-lezen of niet-beveiligingskritiek):
- Systeemidentificatie en functieregisters
- Cache- en TLB-typegegevens
ARM64 volgt hetzelfde principe als x64: de algemene berekeningsstatus wordt gedeeld voor efficiëntie, terwijl de controle- en configuratiestatus die van invloed is op de beveiligingsgrenzen privé blijft voor elke VTL.
Echte modus (alleen x64)
De echte modus wordt niet ondersteund voor een VTL die groter is dan 0 op x64-platforms. VTLs die groter zijn dan 0 kunnen worden uitgevoerd in de 32-bits of 64-bits modus op x64.
VTL-interruptbeheer
Om een hoog isolatieniveau tussen virtuele vertrouwensniveaus te bereiken, biedt de virtuele beveiligde modus een afzonderlijk interruptsubsysteem voor elke VTL die is ingeschakeld op een virtuele processor. Dit zorgt ervoor dat een VTL interrupts kan verzenden en ontvangen zonder tussenkomst van een minder veilige VTL.
Elke VTL heeft een eigen interruptcontroller, die alleen actief is als de virtuele processor wordt uitgevoerd in die specifieke VTL. Als een virtuele processor VTL-status wijzigt, wordt de interruptcontroller die actief is op de processor ook overgeschakeld.
Op x64-platforms heeft elke VTL een afzonderlijk lokaal APIC-exemplaar. Op ARM64-platforms heeft elke VTL een afzonderlijke GIC.
Een interrupt die is gericht op een VTL die hoger is dan de actieve VTL, veroorzaakt een onmiddellijke VTL-switch. De hogere VTL kan vervolgens de interrupt ontvangen. Als de hogere VTL de interrupt niet kan ontvangen vanwege het prioriteitsmasker (TPR/CR8 op x64, GIC-prioriteitsmasker op ARM64), wordt de interrupt vastgehouden als 'in behandeling' en schakelt de VTL niet over. Als er meerdere VTU's zijn met onderbrekingen die in behandeling zijn, heeft de hoogste VTL voorrang (zonder kennisgeving aan de lagere VTL).
Wanneer een interrupt is gericht op een lagere VTL, wordt de interrupt pas geleverd wanneer de volgende keer dat de virtuele processor overgaat naar de beoogde VTL.
Op x64-platforms worden INIT- en opstart-IP-adressen die zijn gericht op een lagere VTL verwijderd op een virtuele processor waarvoor een hogere VTL is ingeschakeld. Omdat opstartmechanismen voor architectuurprocessors mogelijk worden geblokkeerd, moet de HvCallStartVirtualProcessor hypercall worden gebruikt om processors te starten.
Op ARM64-platforms worden PSCI-interfacemethoden (zoals CPU_ON) voor het online brengen van processors op dezelfde manier geblokkeerd wanneer een hogere VTL is ingeschakeld. De HvCallStartVirtualProcessor hypercall biedt een consistent platformoverschrijdend mechanisme om processors te starten.
Maskering onderbreken en VTL-switches
Op x64 Platforms
Voor het overschakelen van VTLs, RFLAGS. ALS dit niet van invloed is op het feit of een beveiligde interrupt een VTL-switch activeert. Als RFLAGS. ALS wordt gewist om interrupts te maskeren, worden interrupts in hogere VTLs nog steeds veroorzaakt door een VTL-switch naar een hogere VTL. Alleen de hogere TPR/CR8-waarde van de VTL wordt in aanmerking genomen bij het bepalen of de VTL onmiddellijk moet worden onderbroken.
Dit gedrag is ook van invloed op onderbrekingen die in behandeling zijn bij een VTL-retour. Als de RFLAGS. Als bit wordt gewist om interrupts in een bepaalde VTL te maskeren en de VTL retourneert (naar een lagere VTL), evalueert de hypervisor eventuele in behandeling zijnde interrupts opnieuw. Hierdoor wordt een onmiddellijke aanroep teruggezet naar de hogere VTL.
Op ARM64-platforms
Op dezelfde manier heeft de DAIF (PSTATE-interruptmaskerbits) geen invloed op het feit of een beveiligde interrupt een VTL-switch activeert. Als interrupts worden gemaskeerd via PSTATE, veroorzaken onderbrekingen die zijn gericht op hogere VTLs nog steeds een VTL-switch. Alleen het hogere GIC-prioriteitsmasker van de VTL wordt in aanmerking genomen bij het bepalen of de interrupt onmiddellijk moet worden geleverd.
Virtual Interrupt Notification Assist
Hogere VTU's kunnen zich registreren om een melding te ontvangen als ze de onmiddellijke levering van een interrupt naar een lagere VTL van dezelfde virtuele processor blokkeren. Hogere VTLs kunnen Virtual Interrupt Notification Assist (VINA) inschakelen via een virtueel register HvRegisterVsmVina:
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 Vector : 8;
UINT64 Enabled : 1;
UINT64 AutoReset : 1;
UINT64 AutoEoi : 1;
UINT64 ReservedP : 53;
};
} HV_REGISTER_VSM_VINA;
Elke VTL op elke VP heeft een eigen VINA-exemplaar, evenals een eigen versie van HvRegisterVsmVina. De VINA-faciliteit genereert een edge geactiveerde interrupt naar de momenteel actieve hogere VTL wanneer een interrupt voor de lagere VTL gereed is voor onmiddellijke levering.
Om te voorkomen dat er een overstroming van interrupts optreedt wanneer deze faciliteit is ingeschakeld, bevat de VINA-faciliteit een beperkte status. Wanneer een VINA-interrupt wordt gegenereerd, wordt de status van de VINA-faciliteit gewijzigd in 'Asserted'. Het verzenden van een end-of-interrupt naar de SINT die is gekoppeld aan de VINA-faciliteit zal de status "Asserted" niet wissen. De assertiestatus kan slechts op twee manieren worden gewist:
- De status kan handmatig worden gewist door naar het veld VinaAsserted van de HV_VP_VTL_CONTROL structuur te schrijven.
- De status wordt automatisch gewist bij de volgende vermelding bij de VTL als de optie 'automatisch opnieuw instellen bij VTL-vermelding' is ingeschakeld in het HvRegisterVsmVina-register.
Hierdoor kan code die wordt uitgevoerd op een beveiligde VTL, alleen worden gewaarschuwd voor de eerste interrupt die wordt ontvangen voor een lagere VTL. Als een beveiligde VTL op de hoogte wil worden gesteld van extra interrupts, kan het veld VinaAsserted van de vp-assist-pagina worden gewist en wordt deze op de hoogte gesteld van de volgende nieuwe interrupt.
Beveiligde snijpunten
Met de hypervisor kan een hogere VTL snijpunten installeren voor gebeurtenissen die plaatsvinden in de context van een lagere VTL. Dit geeft hogere VTLs een verhoogde controle over lagere VTL-resources. Veilige onderscheppingen kunnen worden gebruikt om systeemkritieke resources te beveiligen en aanvallen van lagere VTLs te voorkomen.
Een beveiligd snijpunt wordt in de wachtrij geplaatst bij de hogere VTL en die VTL kan worden uitgevoerd op de VP.
Typen beveiligde snijpunt
| Snijpunttype | Snijpunt is van toepassing op |
|---|---|
| Geheugentoegang | Er wordt geprobeerd toegang te krijgen tot GPA-beveiliging die is ingesteld door een hogere VTL. |
| Toegang tot register beheren | Er wordt geprobeerd toegang te krijgen tot een set controleregisters die zijn opgegeven door een hogere VTL. |
Geneste snijpunten
Meerdere VTLs kunnen beveiligde snijpunten installeren voor dezelfde gebeurtenis in een lagere VTL. Er wordt dus een hiërarchie ingesteld om te bepalen waar geneste snijpunten worden gewaarschuwd. De volgende lijst is de volgorde waarin het snijpunt wordt gewaarschuwd:
- Lagere VTL
- Hogere VTL
Veilige snijpunten verwerken
Zodra een VTL op de hoogte is gesteld van een beveiligd snijpunt, moet deze actie ondernemen zodat de lagere VTL kan worden voortgezet. De hogere VTL kan het snijpunt op verschillende manieren verwerken, waaronder: het injecteren van een uitzondering, het emuleren van de toegang of het verstrekken van een proxy aan de toegang. Als de privéstatus van de lagere VTL VP moet worden gewijzigd, moet HvCallSetVpRegisters worden gebruikt.
Secure Register Intercepts (alleen x64)
Op x64-platforms kan een hogere VTL onderscheppen op toegang tot bepaalde besturingsregisters en MSR's. Dit wordt bereikt door HvX64RegisterCrInterceptControl in te stellen met behulp van de Hypercall HvCallSetVpRegisters . Als u de besturingsbit instelt in HvX64RegisterCrInterceptControl, wordt voor elke toegang tot het bijbehorende controleregister een snijpunt geactiveerd.
Deze functie is specifiek voor x64 omdat het x64-besturingsregisters (CR0, CR4, XCR0) en x64 MSRs (EFER, LSTAR, STAR, enzovoort) onderschept. ARM64-platformen bieden mogelijk ondersteuning voor vergelijkbare onderscheppingsmogelijkheden via verschillende mechanismen.
typedef union
{
UINT64 AsUINT64;
struct
{
UINT64 Cr0Write : 1;
UINT64 Cr4Write : 1;
UINT64 XCr0Write : 1;
UINT64 IA32MiscEnableRead : 1;
UINT64 IA32MiscEnableWrite : 1;
UINT64 MsrLstarRead : 1;
UINT64 MsrLstarWrite : 1;
UINT64 MsrStarRead : 1;
UINT64 MsrStarWrite : 1;
UINT64 MsrCstarRead : 1;
UINT64 MsrCstarWrite : 1;
UINT64 ApicBaseMsrRead : 1;
UINT64 ApicBaseMsrWrite : 1;
UINT64 MsrEferRead : 1;
UINT64 MsrEferWrite : 1;
UINT64 GdtrWrite : 1;
UINT64 IdtrWrite : 1;
UINT64 LdtrWrite : 1;
UINT64 TrWrite : 1;
UINT64 MsrSysenterCsWrite : 1;
UINT64 MsrSysenterEipWrite : 1;
UINT64 MsrSysenterEspWrite : 1;
UINT64 MsrSfmaskWrite : 1;
UINT64 MsrTscAuxWrite : 1;
UINT64 MsrSgxLaunchControlWrite : 1;
UINT64 RsvdZ : 39;
};
} HV_REGISTER_CR_INTERCEPT_CONTROL;
Maskerregisters
Om een nauwkeuriger beheer mogelijk te maken, heeft een subset van controleregisters ook bijbehorende maskerregisters. Maskerregisters kunnen worden gebruikt om snijpunten te installeren op een subset van de bijbehorende besturingsregisters. Wanneer een maskerregister niet is gedefinieerd, activeert elke toegang (zoals gedefinieerd door HvX64RegisterCrInterceptControl) een snijpunt.
De hypervisor ondersteunt de volgende maskerregisters: HvX64RegisterCrInterceptCr0Mask, HvX64RegisterCrInterceptCr4Mask en HvX64RegisterCrInterceptIa32MiscEnableMask.
DMA en apparaten
Apparaten hebben in feite hetzelfde bevoegdheidsniveau als VTL0. Wanneer VSM is ingeschakeld, wordt alle door het apparaat toegewezen geheugen gemarkeerd als VTL0. Alle DMA-toegangen hebben dezelfde bevoegdheden als VTL0.