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.
De hypervisor biedt eenvoudige timingservices. Deze zijn gebaseerd op een referentietijdbron met constante snelheid (meestal de ACPI-timer op x64-systemen).
De volgende timerservices worden geleverd:
- Een referentietijdmeteritem per partitie.
- Vier synthetische timers per virtuele processor. Elke synthetische timer is een eenmalige of periodieke timer die een bericht aflevert of een interrupt bevestigt wanneer deze verloopt.
- Eén virtuele APIC-timer per virtuele processor.
- Een verlichting van partitiereferentietijd op basis van de ondersteuning van het hostplatform voor een Invariant Time Stamp Counter (iTSC).
Verwijzingsteller
De hypervisor onderhoudt een referentietijdmeteritem per partitie. Het heeft het kenmerk dat opeenvolgende toegang tot het strikt monotonisch verhogen (tijd) waarden retourneren, zoals wordt gezien door alle virtuele processors van een partitie. Bovendien is het referentiemeteritem frequentieconstante en niet beïnvloed door processor- of bussnelheidsovergangen of diepe processorbesparingsstatussen. De referentietijdmeteritem van een partitie wordt geïnitialiseerd tot nul wanneer de partitie wordt gemaakt. De referentiemeteritem voor alle partities telt op hetzelfde tarief, maar op elk gewenst moment verschillen hun absolute waarden meestal omdat partities verschillende aanmaaktijden hebben.
Het verwijzingsteller blijft tellen zolang ten minste één virtuele processor niet expliciet is onderbroken.
Register partitiereferentieteller
Op x64 Platforms
Op x64-platforms kan de referentiemeteritem van een partitie worden geopend via een MSR voor de hele partitie.
| MSR-adres | Registernaam | Description |
|---|---|---|
| 0x40000020 | HV_X64_MSR_TIME_REF_COUNT | Aantal tijdverwijzingen (partitiebreed) |
Op ARM64-platforms
Op ARM64-platforms wordt een referentieteller van een partitie geopend via het synthetische register HvRegisterTimeRefCount met behulp van de HvCallGetVpRegisters en HvCallSetVpRegisters hypercalls.
| Registernaam | Description |
|---|---|
| HvRegisterTimeRefCount | Aantal tijdverwijzingen (partitiebreed) |
Gedrag registreren
Wanneer een partitie wordt gemaakt, wordt de waarde van het referentietellerregister ingesteld op 0x0000000000000000. Deze waarde kan niet worden gewijzigd door een virtuele processor. Op x64-platforms leidt elke poging om naar de MSR te schrijven een #GP fout. Op ARM64-platforms worden pogingen om te schrijven via HvCallSetVpRegisters HV_STATUS_INVALID_PARAMETER geretourneerd.
Verlichting van partitiereferentietijd
De verlichting van de partitiereferentietijd geeft een referentietijdbron weer voor een partitie waarvoor geen snijpunt in de hypervisor is vereist. Deze verlichting is alleen beschikbaar wanneer het onderliggende platform ondersteuning biedt voor een invariant processor Time Stamp Counter (TSC) of iTSC. In dergelijke platforms blijft de frequentie van de processor-TSC constant, ongeacht de wijzigingen in de klokfrequentie van de processor als gevolg van het gebruik van energiebeheerstatussen zoals ACSI-processorprestatiesstatussen, niet-actieve slaapstatussen van de processor (ACPI C-states), enzovoort.
De verlichting van de partitieverwijzingstijd maakt gebruik van een virtuele TSC-waarde, een offset en een vermenigvuldiger om een gastpartitie in staat te stellen de genormaliseerde referentietijd te berekenen sinds het maken van de partitie, in 100nS-eenheden. Met het mechanisme kan een gastpartitie ook de referentietijd atomisch berekenen wanneer de gastpartitie wordt gemigreerd naar een platform met een andere TSC-snelheid en biedt een terugvalmechanisme ter ondersteuning van migratie naar platforms zonder de TSC-functie met constante snelheid.
Deze faciliteit is niet bedoeld om een bron van wandkloktijd te gebruiken, omdat de referentietijd die met deze faciliteit wordt berekend, lijkt te stoppen tijdens de tijd dat een gastpartitie wordt opgeslagen tot de volgende herstelbewerking.
Pagina tijdstempelteller voor partitiereferenties
De hypervisor biedt een partitiebrede virtuele referentie TSC-pagina die wordt overlay op de GPA-ruimte van de partitie. De pagina referentietijdstempelteller van een partitie wordt geopend via de referentie-TSC MSR.
De referentie-TSC-pagina wordt gedefinieerd met behulp van de volgende structuur:
typedef struct
{
volatile UINT32 TscSequence;
UINT32 Reserved1;
volatile UINT64 TscScale;
volatile INT64 TscOffset;
UINT64 Reserved2[509];
} HV_REFERENCE_TSC_PAGE;
TSC-pagina (Reference Time Stamp Counter)
Een gast die toegang wil tot de referentie-TSC-pagina moet een synthetische registratie gebruiken. Een partitie die de toegangsrechten AccessPartitionReferenceTsc heeft, heeft mogelijk toegang tot het register.
Op x64 Platforms
Op x64-platforms wordt de referentie-TSC-pagina geopend via een MSR.
| MSR-adres | Registernaam | Description |
|---|---|---|
| 0x40000021 | HV_X64_MSR_REFERENCE_TSC | Referentie-TSC-pagina |
Op ARM64-platforms
Op ARM64-platformen wordt de referentie-TSC-pagina geopend via het synthetische register hvRegisterReferenceTsc met behulp van de HvCallGetVpRegisters en HvCallSetVpRegisters hypercalls.
| Registernaam | Description |
|---|---|
| HvRegisterReferenceTsc | Referentie-TSC-pagina |
Indeling registreren
| Bits | Description | Attributes |
|---|---|---|
| 63:12 | GPA-paginanummer | Lezen/schrijven |
| 11:1 | RsvdP (waarde moet behouden blijven) | Lezen/schrijven |
| 0 | Enable | Lezen/schrijven |
Tijdens het maken van de gastpartitie wordt de waarde van de referentie-TSC MSR 0x0000000000000000. De referentie-TSC-pagina is dus standaard uitgeschakeld. De gast moet de referentie-TSC-pagina inschakelen door bit 0 in te stellen. Als het opgegeven basisadres buiten het einde van de GPA-ruimte van de partitie valt, is de referentie-TSC-pagina niet toegankelijk voor de gast. Bij het wijzigen van het register moeten gasten de waarde van de gereserveerde bits (1 tot en met 11) behouden voor toekomstige compatibiliteit.
TSC-mechanisme voor partitiereferenties
De tijd voor partitiereferenties wordt berekend met de volgende formule:
ReferenceTime = ((VirtualTsc * TscScale) >> 64) + TscOffset
De vermenigvuldiging is een 64-bits vermenigvuldiging, wat resulteert in een 128-bits getal dat vervolgens 64 keer naar het recht wordt verplaatst om de hoge 64 bits te verkrijgen.
De TscScale-waarde wordt gebruikt om de virtuele TSC-waarde voor migratie-gebeurtenissen aan te passen om de wijziging van de TSC-frequentie van het ene platform naar het andere te beperken.
De TscSequence-waarde wordt gebruikt om de toegang tot de verlichte referentietijd te synchroniseren als de schaal- en/of offsetvelden worden gewijzigd tijdens het opslaan/herstellen of livemigratie. Dit veld fungeert als een volgnummer dat wordt verhoogd wanneer de schaal en/of de offsetvelden worden gewijzigd. Een speciale waarde van 0x0 wordt gebruikt om aan te geven dat deze faciliteit geen betrouwbare referentietijd meer is en dat de VIRTUELE machine moet terugvallen op een andere bron.
De aanbevolen code voor het berekenen van de partitiereferentietijd met behulp van deze verlichting wordt hieronder weergegeven:
do
{
StartSequence = ReferenceTscPage->TscSequence;
if (StartSequence == 0)
{
// 0 means that the Reference TSC enlightenment is not available at
// the moment, and the Reference Time can only be obtained from
// reading the Reference Counter MSR.
ReferenceTime = rdmsr(HV_X64_MSR_TIME_REF_COUNT);
return ReferenceTime;
}
Tsc = rdtsc();
// Assigning Scale and Offset should neither happen before
// setting StartSequence, nor after setting EndSequence.
Scale = ReferenceTscPage->TscScale;
Offset = ReferenceTscPage->TscOffset;
EndSequence = ReferenceTscPage->TscSequence;
} while (EndSequence != StartSequence);
// The result of the multiplication is treated as a 128-bit value.
ReferenceTime = ((Tsc * Scale) >> 64) + Offset;
return ReferenceTime;
Synthetische timers
Synthetische timers bieden een mechanisme voor het genereren van een interrupt na enige opgegeven tijd in de toekomst. Zowel eenmalige als periodieke timers worden ondersteund. Een synthetische timer verzendt een bericht naar een opgegeven SynIC SINTx (synthetische interruptbron) na verloop of bevestigt een interrupt, afhankelijk van hoe deze is geconfigureerd.
De hypervisor garandeert dat een timerverloopsignaal nooit vóór de verlooptijd wordt afgeleverd. Het signaal kan op elk gewenst moment na de verlooptijd aankomen.
Periodieke timers
De hypervisor probeert regelmatig periodieke timers te signaleren. Als echter de virtuele processor die wordt gebruikt om aan te geven dat de vervaldatum niet beschikbaar is, kunnen sommige van de timerverlooptijd worden vertraagd. Een virtuele processor is mogelijk niet beschikbaar omdat deze is onderbroken (bijvoorbeeld tijdens het verwerken van snijpunt) of omdat de planner van de hypervisor heeft besloten dat de virtuele processor niet moet worden gepland op een logische processor (bijvoorbeeld omdat een andere virtuele processor gebruikmaakt van de logische processor of de virtuele processor het quotum heeft overschreden).
Als een virtuele processor gedurende een voldoende lange periode niet beschikbaar is, kan een volledige timerperiode worden gemist. In dit geval gebruikt de hypervisor een van de twee technieken.
De eerste techniek omvat timerperiodemodulatie, waardoor de periode wordt ingekort totdat de timer "inhaalt". Als een aanzienlijk aantal timersignalen is gemist, kan de hypervisor mogelijk niet compenseren met behulp van periodemodulatie. In dit geval kunnen sommige verloopsignalen van de timer volledig worden overgeslagen.
Voor timers die als luie zijn gemarkeerd, gebruikt de hypervisor een tweede techniek voor het omgaan met de situatie waarin een virtuele processor gedurende lange tijd niet beschikbaar is. In dit geval wordt het timersignaal uitgesteld totdat deze virtuele processor beschikbaar is. Als deze pas beschikbaar komt nadat de volgende timer is verlopen, wordt deze volledig overgeslagen.
Volgorde van timerverlooptijd
Synthetische en gevirtualiseerde timers genereren interrupts op of in de buurt van hun aangewezen verlooptijd. Vanwege hardware- en andere planningsinteracties kunnen onderbrekingen mogelijk worden vertraagd. Er mag geen volgorde worden aangenomen tussen een set timers.
Directe synthetische timers
"Directe" synthetische timers bevestigen een onderbreking bij het verlopen van de timer in plaats van een bericht te verzenden naar een synic synthetische interruptbron. Een synthetische timer is ingesteld op de modus Direct door het veld DirectMode van de synthetische timerconfiguratie-MSR's in te stellen. Het veld ApicVector bepaalt de interruptvector die wordt toegepast bij het verlopen van de timer.
Synthetische timerregisters
Synthetische timers worden geconfigureerd met behulp van synthetische registers die zijn gekoppeld aan elke virtuele processor. Elk van de vier synthetische timers heeft een gekoppeld paar registers (configuratie en aantal).
Op x64 Platforms
Op x64-platforms worden synthetische timers geopend via MSR's met behulp van de RDMSR- en WRMSR-instructies.
| MSR-adres | Registernaam | Description |
|---|---|---|
| 0x400000B0 | HV_X64_MSR_STIMER0_CONFIG | Configuratieregister voor synthetische timer 0. |
| 0x400000B1 | HV_X64_MSR_STIMER0_COUNT | Verlooptijd of periode voor synthetische timer 0. |
| 0x400000B2 | HV_X64_MSR_STIMER1_CONFIG | Configuratieregister voor synthetische timer 1. |
| 0x400000B3 | HV_X64_MSR_STIMER1_COUNT | Verlooptijd of periode voor synthetische timer 1. |
| 0x400000B4 | HV_X64_MSR_STIMER2_CONFIG | Configuratieregister voor synthetische timer 2. |
| 0x400000B5 | HV_X64_MSR_STIMER2_COUNT | Verlooptijd of periode voor synthetische timer 2. |
| 0x400000B6 | HV_X64_MSR_STIMER3_CONFIG | Configuratieregister voor synthetische timer 3. |
| 0x400000B7 | HV_X64_MSR_STIMER3_COUNT | Verlooptijd of periode voor synthetische timer 3. |
Op ARM64-platforms
Op ARM64-platformen worden synthetische timers geopend via synthetische registers met behulp van de HvCallGetVpRegisters en HvCallSetVpRegisters hypercalls.
| Registernaam | Description |
|---|---|
| HvRegisterStimer0Config | Configuratieregister voor synthetische timer 0. |
| HvRegisterStimer0Count | Verlooptijd of periode voor synthetische timer 0. |
| HvRegisterStimer1Config | Configuratieregister voor synthetische timer 1. |
| HvRegisterStimer1Count | Verlooptijd of periode voor synthetische timer 1. |
| HvRegisterStimer2Config | Configuratieregister voor synthetische timer 2. |
| HvRegisterStimer2Count | Verlooptijd of periode voor synthetische timer 2. |
| HvRegisterStimer3Config | Configuratieregister voor synthetische timer 3. |
| HvRegisterStimer3Count | Verlooptijd of periode voor synthetische timer 3. |
Opmerking: In ARM64 zijn synthetische timers optioneel omdat de ALGEMENE ARM-timer (GIT) rechtstreeks kan worden gebruikt zonder dat er overhead voor virtualisatie is. Gastbesturingssystemen moeten de voorkeur geven aan het gebruik van de algemene architectuurtimer voor betere prestaties.
Indeling registreren
Synthetische timerconfiguratie registreren
| Bits | Description | Attributes |
|---|---|---|
| 63:20 | RsvdZ (waarde moet worden ingesteld op nul) | Lezen/schrijven |
| 19:16 | SINTx - synthetische interruptbron | Lezen/schrijven |
| 15:13 | RsvdZ (waarde moet worden ingesteld op nul) | Lezen/schrijven |
| 12 | Directe modus : bevestigen en onderbreken bij het verlopen van de timer. | Lezen/schrijven |
| 11:4 | ApicVector - Bepaalt de bevestigde interruptvector in de directe modus | Lezen/schrijven |
| 3 | AutoEnable - Instellen als het schrijven van de bijbehorende teller impliciet ervoor zorgt dat de timer wordt ingeschakeld | Lezen/schrijven |
| 2 | Lui - instellen of timer lui is | Lezen/schrijven |
| 1 | Periodiek - Instellen als timer periodiek is | Lezen/schrijven |
| 0 | Ingeschakeld - instellen als timer is ingeschakeld | Lezen/schrijven |
Wanneer een virtuele processor wordt gemaakt en opnieuw wordt ingesteld, wordt de waarde van alle synthetische timerconfiguratieregisters (HV_X64_MSR_STIMER0_CONFIG tot HV_X64_MSR_STIMER3_CONFIG) ingesteld op 0x0000000000000000. Daarom worden alle synthetische timers standaard uitgeschakeld.
Als AutoEnable is ingesteld, zorgt het schrijven van een niet-nulwaarde voor het bijbehorende tellingsregister ervoor dat Inschakelen wordt ingesteld en geactiveerd. Anders moet Inschakelen worden ingesteld nadat u het bijbehorende aantalregister hebt geschreven om de teller te activeren. Zie de volgende sectie voor meer informatie over het aantalregisters.
Wanneer een eenmalige timer verloopt, wordt deze automatisch gemarkeerd als uitgeschakeld. Periodieke timers blijven ingeschakeld totdat ze expliciet zijn uitgeschakeld.
Als een eenmalige opname is ingeschakeld en het opgegeven aantal zich in het verleden bevindt, verloopt deze onmiddellijk.
Het is niet toegestaan om het SINTx-veld in te stellen op nul voor een ingeschakelde timer (die zich niet in de directe modus bevindt). Als u een poging doet, wordt de timer gemarkeerd als uitgeschakeld (dat wil gezegd, bit 0 gewist) onmiddellijk.
Het schrijven van het configuratieregister van een timer die al is ingeschakeld, kan leiden tot niet-gedefinieerd gedrag. Als u bijvoorbeeld alleen een timer wijzigt van één opname in periodiek, kan dit niet tot gevolg hebben dat wat bedoeld is. Timers moeten altijd worden uitgeschakeld voordat u andere eigenschappen wijzigt.
Synthetisch aantal timers registreren
| Bits | Description | Attributes |
|---|---|---|
| 63:0 | Aantal: verlooptijd voor eenmalige timers, duur voor periodieke timers | Lezen/schrijven |
De waarde die in het aantalregister is geprogrammeerd, is een tijdwaarde die wordt gemeten in 100 nanoseconden. Als u de waarde nul naar het register Aantal schrijft, wordt de teller gestopt, waardoor de timer wordt uitgeschakeld, onafhankelijk van de instelling van AutoEnable in het configuratieregister.
Houd er rekening mee dat het Aantal-register mag worden verpakt. Wrapping heeft geen effect op het gedrag van de timer, ongeacht een timereigenschap.
Voor eenmalige timers vertegenwoordigt deze de absolute verlooptijd van de timer. De timer verloopt wanneer de verwijzingsteller voor de partitie gelijk is aan of groter is dan de opgegeven tellingswaarde.
Voor periodieke timers vertegenwoordigt het aantal de periode van de timer. De eerste periode begint wanneer de synthetische timer is ingeschakeld.
Bericht over verlopen van synthetische timer
Timetimerverloopberichten worden verzonden wanneer een timer-gebeurtenis wordt geactiveerd. Raadpleeg de HV_TIMER_MESSAGE_PAYLOAD voor de definitie van de nettolading van het bericht.
Synthetische Time-Unhalted Timerregisters
Synthetische Time-Unhalted Timerregisters zijn beschikbaar op x64-platforms als een partitie de bevoegdheid AccessSyntheticTimerRegs heeft. Beschikbaarheid wordt aangegeven door EDX-bits 23 in het CPUID-blad van de Hypervisor-functieidentificatie 0x40000003. Deze functie is niet beschikbaar op ARM64-platforms.
Gastsoftware kan de synthetische time-unhalted timer programmeren om een periodieke interrupt te genereren na uitvoering gedurende een opgegeven tijdsduur in eenheden van 100ns. Wanneer de interrupt wordt geactiveerd, wordt het veld SyntheticTimeUnhaltedTimerExpired in de VP Assist-pagina ingesteld op TRUE. Gastsoftware kan dit veld opnieuw instellen op FALSE. In tegenstelling tot architecturale prestatiemeteritems wordt de synthetische timer nooit opnieuw ingesteld door de hypervisor en wordt deze continu uitgevoerd tussen interrupts. Als het vectorveld is ingesteld op 2 (de x64 NMI-vector), levert de timer een niet-maskerbare interrupt; anders levert het een vaste interrupt met behulp van de opgegeven vector.
In tegenstelling tot normale synthetische timers die tijd verzamelen wanneer de gast is gestopt (bijvoorbeeld: niet-actief), verzamelt de Synthetische Time-Unhalted Timer alleen tijd terwijl de gast niet wordt gestopt.
Op x64 Platforms
Op x64-platforms wordt de synthetische time-unhalted timer geopend via MSR's met behulp van de RDMSR- en WRMSR-instructies.
| MSR-adres | Registernaam | Description |
|---|---|---|
| 0x40000114 | HV_X64_MSR_STIME_UNHALTED_TIMER_CONFIG | Synthetische Time-Unhalted timerconfiguratie |
| 0x40000115 | HV_X64_MSR_STIME_UNHALTED_TIMER_COUNT | Synthetische Time-Unhalted Timer Count |
Indeling registreren
Synthetische Time-Unhalted timerconfiguratieregister
| Bits | Description | Attributes |
|---|---|---|
| 63:9 | RsvdZ (waarde moet worden ingesteld op nul) | Lezen/schrijven |
| 8 | Ingeschakeld | Lezen/schrijven |
| 7:0 | Vector | Lezen/schrijven |
Het vectorveld moet 2 zijn (om een NMI te leveren) of een waarde ≥ 16 (om een vaste interrupt te leveren). Andere waarden zijn ongeldig.
Synthetische Time-Unhalted Timer Count Register
| Bits | Description | Attributes |
|---|---|---|
| 63:0 | Periodieke snelheid van interrupts in 100 ns-eenheden | Lezen/schrijven |