Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O hipervisor fornece serviços de tempo simples. Elas se baseiam em uma fonte de tempo de referência de taxa constante (normalmente o temporizador ACPI em sistemas x64).
Os seguintes serviços de temporizador são fornecidos:
- Um contador de tempo de referência por partição.
- Quatro temporizadores sintéticos por processador virtual. Cada temporizador sintético é um temporizador periódico ou de tiro único que entrega uma mensagem ou declara uma interrupção quando ela expira.
- Um temporizador APIC virtual por processador virtual.
- Uma iluminação de tempo de referência de partição, com base no suporte da plataforma de host para um iTSC (Contador de Carimbo de Data/Hora Invariável).
Contador de Referência
O hipervisor mantém um contador de tempo de referência por partição. Ele tem a característica de que os acessos sucessivos a ele retornam valores estritamente monotonicamente crescentes (tempo), como visto por todos os processadores virtuais de uma partição. Além disso, o contador de referência é constante de taxa e não afetado por transições de velocidade de processador ou barramento ou estados profundos de economia de energia do processador. O contador de tempo de referência de uma partição é inicializado como zero quando a partição é criada. O contador de referência para todas as partições conta com a mesma taxa, mas a qualquer momento, seus valores absolutos normalmente serão diferentes porque as partições terão tempos de criação diferentes.
O contador de referência continua a contar até que pelo menos um processador virtual não seja suspenso explicitamente.
Registro do Contador de Referência de Partição
Em plataformas x64
Em plataformas x64, o contador de referência de uma partição pode ser acessado por meio de uma MSR em toda a partição.
| Endereço MSR | Nome do Registro | Description |
|---|---|---|
| 0x40000020 | HV_X64_MSR_TIME_REF_COUNT | Contagem de referência de tempo (em toda a partição) |
Em plataformas ARM64
Nas plataformas ARM64, o contador de referência de uma partição é acessado por meio do registro sintético HvRegisterTimeRefCount usando as hiperchamadas HvCallGetVpRegisters e HvCallSetVpRegisters.
| Nome do Registro | Description |
|---|---|
| HvRegisterTimeRefCount | Contagem de referência de tempo (em toda a partição) |
Comportamento de registro
Quando uma partição é criada, o valor do registro do contador de referência é definido como 0x0000000000000000. Esse valor não pode ser modificado por um processador virtual. Em plataformas x64, qualquer tentativa de gravação no MSR resulta em uma falha de #GP. Em plataformas ARM64, as tentativas de gravação por meio de HvCallSetVpRegisters retornam HV_STATUS_INVALID_PARAMETER.
Iluminação do tempo de referência de partição
O esclarecimento de tempo de referência de partição apresenta uma fonte de tempo de referência para uma partição que não requer uma interceptação no hipervisor. Essa iluminação só está disponível quando a plataforma subjacente oferece suporte a um TSC (Contador de Carimbo de Data/Hora) do processador invariável ou iTSC. Nessas plataformas, a frequência TSC do processador permanece constante, independentemente das alterações na frequência do relógio do processador devido ao uso de estados de gerenciamento de energia, como estados de desempenho do processador ACPI, estados de suspensão ociosos do processador (estados CPI de ACPI), etc.
A iluminação de tempo de referência de partição usa um valor TSC virtual, um deslocamento e um multiplicador para habilitar uma partição de convidado para calcular o tempo de referência normalizado desde a criação da partição, em unidades de 100nS. O mecanismo também permite que uma partição de convidado compute atomicamente o tempo de referência quando a partição de convidado é migrada para uma plataforma com uma taxa TSC diferente e fornece um mecanismo de fallback para dar suporte à migração para plataformas sem o recurso TSC de taxa constante.
Essa instalação não se destina a ser usada como uma fonte de tempo de relógio de parede, pois o tempo de referência computado usando essa instalação parecerá parar durante o tempo em que uma partição de convidado é salva até a restauração subsequente.
Página do contador de carimbo de data/hora de referência de partição
O hipervisor fornece uma página TSC de referência virtual em toda a partição que é sobreposta no espaço GPA da partição. A página do contador de carimbo de data/hora de referência de uma partição é acessada por meio do MSR TSC de referência.
A página TSC de referência é definida usando a seguinte estrutura:
typedef struct
{
volatile UINT32 TscSequence;
UINT32 Reserved1;
volatile UINT64 TscScale;
volatile INT64 TscOffset;
UINT64 Reserved2[509];
} HV_REFERENCE_TSC_PAGE;
Registro de página do TSC (Contador de Carimbo de Data/Hora de Referência)
Um convidado que deseja acessar sua página TSC de referência deve usar um registro sintético. Uma partição que possui o privilégio AccessPartitionReferenceTsc pode acessar o registro.
Em plataformas x64
Em plataformas x64, a página TSC de referência é acessada por meio de um MSR.
| Endereço MSR | Nome do Registro | Description |
|---|---|---|
| 0x40000021 | HV_X64_MSR_REFERENCE_TSC | Página TSC de referência |
Em plataformas ARM64
Nas plataformas ARM64, a página TSC de referência é acessada por meio do registro sintético HvRegisterReferenceTsc usando as hiperchamadas HvCallGetVpRegisters e HvCallSetVpRegisters.
| Nome do Registro | Description |
|---|---|
| HvRegisterReferenceTsc | Página TSC de referência |
Registrar Layout
| Bits | Description | Attributes |
|---|---|---|
| 63:12 | Número da página GPA | Leitura/gravação |
| 11:1 | RsvdP (o valor deve ser preservado) | Leitura/gravação |
| 0 | Enable | Leitura/gravação |
No momento da criação da partição de convidado, o valor do MSR TSC de referência é 0x0000000000000000. Assim, a página TSC de referência é desabilitada por padrão. O convidado deve habilitar a página TSC de referência definindo o bit 0. Se o endereço base especificado estiver além do final do espaço GPA da partição, a página TSC de referência não estará acessível ao convidado. Ao modificar o registro, os convidados devem preservar o valor dos bits reservados (1 a 11) para compatibilidade futura.
Mecanismo TSC de referência de partição
O tempo de referência da partição é computado pela seguinte fórmula:
ReferenceTime = ((VirtualTsc * TscScale) >> 64) + TscOffset
A multiplicação é uma multiplicação de 64 bits, o que resulta em um número de 128 bits que, em seguida, é deslocado 64 vezes para a direita para obter os 64 bits altos.
O valor de TscScale é usado para ajustar o valor do TSC Virtual em eventos de migração para reduzir as alterações de frequência TSC de uma plataforma para outra.
O valor de TscSequence é usado para sincronizar o acesso ao tempo de referência habilitado se a escala e/ou os campos de deslocamento forem alterados durante a migração ao vivo ou de salvamento. Esse campo serve como um número de sequência incrementado sempre que a escala e/ou os campos de deslocamento são modificados. Um valor especial de 0x0 é usado para indicar que essa instalação não é mais uma fonte confiável de tempo de referência e a VM deve voltar para uma fonte diferente.
O código recomendado para calcular o tempo de referência de partição usando esse esclarecimento é mostrado abaixo:
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;
Temporizadores Sintéticos
Os temporizadores sintéticos fornecem um mecanismo para gerar uma interrupção após algum tempo especificado no futuro. Há suporte para temporizadores de um tiro e periódicos. Um temporizador sintético envia uma mensagem para um SINTx SynIC especificado (fonte de interrupção sintética) após a expiração ou declara uma interrupção, dependendo de como ela é configurada.
O hipervisor garante que um sinal de expiração do temporizador nunca será entregue antes do tempo de expiração. O sinal pode chegar a qualquer momento após o tempo de expiração.
Temporizadores Periódicos
O hipervisor tenta sinalizar temporizadores periódicos regularmente. No entanto, se o processador virtual usado para sinalizar a expiração não estiver disponível, algumas das expirações do temporizador poderão ser atrasadas. Um processador virtual pode estar indisponível porque está suspenso (por exemplo, durante a manipulação de interceptação) ou porque o agendador do hipervisor decidiu que o processador virtual não deve ser agendado em um processador lógico (por exemplo, porque outro processador virtual está usando o processador lógico ou o processador virtual excedeu sua cota).
Se um processador virtual estiver indisponível por um período de tempo suficientemente longo, um período de tempo integral poderá ser perdido. Nesse caso, o hipervisor usa uma das duas técnicas.
A primeira técnica envolve a modulação do período do temporizador, reduzindo de fato o período até que o temporizador "pegue". Se um número significativo de sinais de temporizador tiver sido perdido, o hipervisor poderá ser incapaz de compensar usando a modulação de período. Nesse caso, alguns sinais de expiração de temporizador podem ser ignorados completamente.
Para temporizadores marcados como lentos, o hipervisor usa uma segunda técnica para lidar com a situação em que um processador virtual fica indisponível por um longo período de tempo. Nesse caso, o sinal do temporizador é adiado até que esse processador virtual esteja disponível. Se ele não ficar disponível até pouco antes do próximo temporizador expirar, ele será totalmente ignorado.
Ordenação de expirações do temporizador
Temporizadores sintéticos e virtualizados geram interrupções em ou perto do tempo de expiração designado. Devido ao hardware e outras interações de agendamento, as interrupções podem ser potencialmente atrasadas. Nenhuma ordenação pode ser assumida entre qualquer conjunto de temporizadores.
Temporizadores Sintéticos Diretos
Os temporizadores sintéticos "diretos" afirmam uma interrupção após a expiração do temporizador em vez de enviar uma mensagem para uma fonte de interrupção sintética SynIc. Um temporizador sintético é definido como modo "direto" definindo o campo "DirectMode" das MSRs de configuração do temporizador sintético. O campo "ApicVector" controla o vetor de interrupção que é declarado após a expiração do temporizador.
Registros de temporizador sintético
Os temporizadores sintéticos são configurados usando registros sintéticos associados a cada processador virtual. Cada um dos quatro temporizadores sintéticos tem um par associado de registros (configuração e contagem).
Em plataformas x64
Em plataformas x64, os temporizadores sintéticos são acessados por meio de MSRs usando as instruções RDMSR e WRMSR.
| Endereço MSR | Nome do Registro | Description |
|---|---|---|
| 0x400000B0 | HV_X64_MSR_STIMER0_CONFIG | Registro de configuração para o temporizador sintético 0. |
| 0x400000B1 | HV_X64_MSR_STIMER0_COUNT | Tempo de expiração ou período para o temporizador sintético 0. |
| 0x400000B2 | HV_X64_MSR_STIMER1_CONFIG | Registro de configuração para o temporizador sintético 1. |
| 0x400000B3 | HV_X64_MSR_STIMER1_COUNT | Tempo de expiração ou período para o temporizador sintético 1. |
| 0x400000B4 | HV_X64_MSR_STIMER2_CONFIG | Registro de configuração para o temporizador sintético 2. |
| 0x400000B5 | HV_X64_MSR_STIMER2_COUNT | Tempo de expiração ou período para o temporizador sintético 2. |
| 0x400000B6 | HV_X64_MSR_STIMER3_CONFIG | Registro de configuração para o temporizador sintético 3. |
| 0x400000B7 | HV_X64_MSR_STIMER3_COUNT | Tempo de expiração ou período para o temporizador sintético 3. |
Em plataformas ARM64
Nas plataformas ARM64, os temporizadores sintéticos são acessados por meio de registros sintéticos usando as hiperchamadas HvCallGetVpRegisters e HvCallSetVpRegisters.
| Nome do Registro | Description |
|---|---|
| HvRegisterStimer0Config | Registro de configuração para o temporizador sintético 0. |
| HvRegisterStimer0Count | Tempo de expiração ou período para o temporizador sintético 0. |
| HvRegisterStimer1Config | Registro de configuração para o temporizador sintético 1. |
| HvRegisterStimer1Count | Tempo de expiração ou período para o temporizador sintético 1. |
| HvRegisterStimer2Config | Registro de configuração para o temporizador sintético 2. |
| HvRegisterStimer2Count | Tempo de expiração ou período para o temporizador sintético 2. |
| HvRegisterStimer3Config | Registro de configuração para o temporizador sintético 3. |
| HvRegisterStimer3Count | Tempo de expiração ou período para o temporizador sintético 3. |
Nota: No ARM64, os temporizadores sintéticos são opcionais porque o ARM Generic Timer (GIT) pode ser usado diretamente sem incorrer em sobrecarga de virtualização. Os sistemas operacionais convidados devem preferir usar o temporizador genérico de arquitetura para melhorar o desempenho.
Registrar Layout
Registro de configuração do temporizador sintético
| Bits | Description | Attributes |
|---|---|---|
| 63:20 | RsvdZ (o valor deve ser definido como zero) | Leitura/gravação |
| 19:16 | SINTx – fonte de interrupção sintética | Leitura/gravação |
| 15:13 | RsvdZ (o valor deve ser definido como zero) | Leitura/gravação |
| 12 | Modo Direto – Declarar e interromper após a expiração do temporizador. | Leitura/gravação |
| 11:4 | ApicVector – Controla o vetor de interrupção declarado no modo direto | Leitura/gravação |
| 3 | AutoEnable - Definir se gravar o contador correspondente implicitamente faz com que o temporizador seja habilitado | Leitura/gravação |
| 2 | Lento – Definir se o temporizador é lento | Leitura/gravação |
| 1 | Periódico – Definir se o temporizador é periódico | Leitura/gravação |
| 0 | Habilitado – definir se o temporizador está habilitado | Leitura/gravação |
Quando um processador virtual é criado e redefinido, o valor de todos os registros de configuração de temporizador sintético (HV_X64_MSR_STIMER0_CONFIG por meio de HV_X64_MSR_STIMER3_CONFIG) são definidos como 0x0000000000000000. Assim, todos os temporizadores sintéticos são desabilitados por padrão.
Se AutoEnable estiver definido, gravar um valor diferente de zero no registro de contagem correspondente fará com que Enable seja definido e ative o contador. Caso contrário, Habilitar deve ser definido depois de gravar o registro de contagem correspondente para ativar o contador. Para obter informações sobre o registro de contagem, consulte a seção a seguir.
Quando um temporizador de um tiro expira, ele é marcado automaticamente como desabilitado. Os temporizadores periódicos permanecem habilitados até desabilitados explicitamente.
Se um único tiro estiver habilitado e a contagem especificada estiver no passado, ela expirará imediatamente.
Não é permitido definir o campo SINTx como zero para um temporizador habilitado (que não está no modo direto). Se tentar, o temporizador será marcado como desabilitado (ou seja, bit 0 limpo) imediatamente.
Gravar o registro de configuração de um temporizador que já está habilitado pode resultar em um comportamento indefinido. Por exemplo, apenas alterar um temporizador de um tiro para periódico pode não produzir o que se pretende. Os temporizadores sempre devem ser desabilitados antes de alterar outras propriedades.
Registro de contagem de temporizador sintético
| Bits | Description | Attributes |
|---|---|---|
| 63:0 | Contagem – tempo de expiração para temporizadores de um tiro, duração para temporizadores periódicos | Leitura/gravação |
O valor programado no registro de contagem é um valor de tempo medido em 100 unidades nanossegundos. Gravar o valor zero no registro de Contagem interromperá o contador, desabilitando o temporizador, independentemente da configuração de AutoEnable no registro de configuração.
Observe que o registro count tem permissão para encapsular. A disposição não terá efeito sobre o comportamento do temporizador, independentemente de qualquer propriedade de temporizador.
Para temporizadores de um tiro, ele representa o tempo de expiração absoluto do temporizador. O temporizador expira quando o contador de referência da partição é igual ou maior que o valor de contagem especificado.
Para temporizadores periódicos, a contagem representa o período do temporizador. O primeiro período começa quando o temporizador sintético está habilitado.
Mensagem de expiração do temporizador sintético
As mensagens de expiração do temporizador são enviadas quando um evento de temporizador é acionado. Consulte o HV_TIMER_MESSAGE_PAYLOAD para obter a definição do conteúdo da mensagem.
Registros de temporizador de Time-Unhalted sintético
Os registros de temporizador de Time-Unhalted sintéticos estarão disponíveis em plataformas x64 se uma partição tiver o privilégio AccessSyntheticTimerRegs. A disponibilidade é indicada pelo EDX bit 23 no 0x40000003 folha CPUID de Identificação de Recursos do Hipervisor. Esse recurso não está disponível em plataformas ARM64.
O software convidado pode programar o tempo não inalado sintético para gerar uma interrupção periódica após a execução por um período especificado em 100ns unidades. Quando a interrupção for disparada, o campo SyntheticTimeUnhaltedTimerExpired na Página de Assistência de VP será definido como TRUE. O software convidado pode redefinir esse campo para FALSE. Ao contrário dos contadores de desempenho de arquitetura, o temporizador sintético nunca é redefinido pelo hipervisor e é executado continuamente entre interrupções. Se o campo Vector estiver definido como 2 (o vetor NMI x64), o temporizador fornecerá uma interrupção não mascarada; caso contrário, ele fornece uma interrupção fixa usando o vetor especificado.
Ao contrário dos temporizadores sintéticos regulares que acumulam tempo quando o convidado foi interrompido (ou seja: ficou ocioso), o Temporizador de Time-Unhalted Sintético acumula tempo somente enquanto o convidado não é interrompido.
Em plataformas x64
Em plataformas x64, o temporizador não inalado sintético é acessado por meio de MSRs usando as instruções RDMSR e WRMSR.
| Endereço MSR | Nome do Registro | Description |
|---|---|---|
| 0x40000114 | HV_X64_MSR_STIME_UNHALTED_TIMER_CONFIG | Configuração do temporizador de Time-Unhalted sintético |
| 0x40000115 | HV_X64_MSR_STIME_UNHALTED_TIMER_COUNT | Contagem de temporizador de Time-Unhalted sintético |
Registrar Layout
Registro de configuração do temporizador de Time-Unhalted sintético
| Bits | Description | Attributes |
|---|---|---|
| 63:9 | RsvdZ (o valor deve ser definido como zero) | Leitura/gravação |
| 8 | Enabled | Leitura/gravação |
| 7:0 | Vector | Leitura/gravação |
O campo Vector deve ser 2 (para entregar um NMI) ou um valor ≥ 16 (para entregar uma interrupção fixa). Outros valores são inválidos.
Registro de contagem de temporizador de Time-Unhalted sintético
| Bits | Description | Attributes |
|---|---|---|
| 63:0 | Taxa periódica de interrupções em 100 ns unidades | Leitura/gravação |