таймеры

Гипервизор предоставляет простые службы времени. Они основаны на источнике ссылочного времени постоянной частоты (обычно таймер ACPI в системах x64).

Предоставляются следующие службы таймера:

  • Счетчик времени на секцию.
  • Четыре искусственных таймера на виртуальный процессор. Каждый искусственный таймер — это однократный или периодический таймер, который доставляет сообщение или утверждает прерывание при истечении срока действия.
  • Один виртуальный таймер APIC на виртуальный процессор.
  • Представление времени ссылки на секцию, основанное на поддержке платформы узла для счетчика меток времени (iTSC).

Счетчик ссылок

Гипервизор поддерживает счетчик времени ссылки на секции. Он имеет характеристику, что последовательный доступ к нему возвращает строго монотонно увеличивающиеся (время) значения, как видно на всех и всех виртуальных процессорах секции. Кроме того, счетчик ссылок является константой скорости и не зависит от переходов скорости процессора или шины или глубоких состояний экономии мощности процессора. Счетчик времени ссылки секции инициализируется до нуля при создании секции. Счетчик ссылок для всех секций с одинаковой скоростью, но в любое время их абсолютные значения обычно отличаются, так как секции будут иметь разные периоды создания.

Счетчик ссылок продолжает подсчитывать до тех пор, пока хотя бы один виртуальный процессор не приостановлен явным образом.

Регистрация счетчика ссылок на секции

На платформах x64

На платформах x64 доступ к счетчику ссылок секции можно получить с помощью MSR на уровне секции.

АДРЕС MSR Имя регистрации Description
0x40000020 HV_X64_MSR_TIME_REF_COUNT Число ссылок на время (на уровне секций)

На платформах ARM64

На платформах ARM64 счетчик ссылок секции осуществляется через искусственный регистр HvRegisterTimeRefCount с помощью гипермасштабирования HvCallGetVpRegisters и HvCallSetVpRegisters.

Имя регистрации Description
HvRegisterTimeRefCount Число ссылок на время (на уровне секций)

Поведение регистрации

При создании секции значение регистра счетчика ссылок имеет значение 0x0000000000000000. Это значение нельзя изменить виртуальным процессором. На платформах x64 любая попытка записи в MSR приводит к сбою #GP. На платформах ARM64 попытки записи с помощью HvCallSetVpRegisters возвращают HV_STATUS_INVALID_PARAMETER.

Просвещение времени ссылки на секции

Представление времени ссылки на секцию представляет источник времени ссылки на секцию, для которой не требуется перехват в гипервизор. Это просвещение доступно только в том случае, если базовая платформа обеспечивает поддержку инвариантного счетчика меток времени процессора (TSC) или iTSC. На таких платформах частота TSC процессора остается постоянной независимо от изменений частоты часов процессора из-за использования состояний управления питанием, таких как состояния производительности процессора ACPI, состояния простоя процессора (состояния C-состояний ACPI) и т. д.

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

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

Страница счетчика меток времени секции

Гипервизор предоставляет страницу TSC на уровне секций, которая накладывается на пространство GPA секции. На странице счетчика меток времени ссылки на секцию осуществляется доступ к странице счетчика ссылок TSC MSR.

Эталонная страница TSC определяется с помощью следующей структуры:

typedef struct
{
   volatile UINT32 TscSequence;
   UINT32 Reserved1;
   volatile UINT64 TscScale;
   volatile INT64 TscOffset;
   UINT64 Reserved2[509];
} HV_REFERENCE_TSC_PAGE;

Регистрация страницы счетчика меток времени (TSC)

Гостевой пользователь, желающий получить доступ к ссылке на страницу TSC, должен использовать искусственный регистр. Секция, обладающая привилегией AccessPartitionReferenceTsc, может получить доступ к регистру.

На платформах x64

На платформах x64 доступ к эталонной странице TSC осуществляется через MSR.

АДРЕС MSR Имя регистрации Description
0x40000021 HV_X64_MSR_REFERENCE_TSC Страница "Справочник по TSC"
На платформах ARM64

На платформах ARM64 доступ к эталонной странице TSC осуществляется с помощью искусственного регистра HvRegisterReferenceTsc с помощью гипермасштабирования HvCallGetVpRegisters и HvCallSetVpRegisters.

Имя регистрации Description
HvRegisterReferenceTsc Страница "Справочник по TSC"
Регистрация макета
Биты Description Attributes
63:12 Номер страницы GPA Чтение и запись
11:1 RsvdP (значение должно быть сохранено) Чтение и запись
0 Enable Чтение и запись

Во время создания гостевой секции значение ссылочного MSR TSC 0x0000000000000000. Таким образом, ссылка на страницу TSC отключена по умолчанию. Гость должен включить эталонную страницу TSC, установив бит 0. Если указанный базовый адрес выходит за пределы пространства GPA секции, ссылка на страницу TSC не будет доступна для гостя. При изменении регистра гости должны сохранить значение зарезервированных битов (от 1 до 11) для обеспечения будущей совместимости.

Механизм TSC ссылки на секции

Время ссылки на секцию вычисляется следующей формулой:

ReferenceTime = ((VirtualTsc * TscScale) >> 64) + TscOffset

Умножение — это 64-разрядное умножение, которое приводит к 128-разрядному числу, которое затем сдвигается 64 раза вправо, чтобы получить высокие 64 бита.

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

Значение TscSequence используется для синхронизации доступа к просвещенному времени ссылки, если поля смещения изменяются во время сохранения и восстановления или динамической миграции. Это поле служит порядковым номером, который увеличивается при изменении полей смещения и (или) смещения. Особое значение 0x0 используется для указания того, что этот объект больше не является надежным источником ссылочного времени, и виртуальная машина должна вернуться к другому источнику.

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

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;

Искусственные таймеры

Искусственные таймеры предоставляют механизм создания прерывания после определенного времени в будущем. Поддерживаются одноразовые и периодические таймеры. Искусственный таймер отправляет сообщение в указанный synIC SINTx (искусственный источник прерываний) по истечении срока действия или утверждает прерывание в зависимости от того, как оно настроено.

Гипервизор гарантирует, что сигнал истечения срока действия таймера никогда не будет доставлен до истечения срока действия. Сигнал может поступать в любое время после истечения срока действия.

Периодические таймеры

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

Если виртуальный процессор недоступен в течение достаточно длительного периода времени, полный период времени может быть пропущен. В этом случае гипервизор использует один из двух методов.

Первый метод включает в себя модуляцию периода таймера, в результате сокращая период до таймера "догоняет". Если пропущено значительное количество сигналов таймера, гипервизор может быть не в состоянии компенсировать с помощью модуляции периода. В этом случае некоторые сигналы истечения срока действия таймера могут быть пропущены полностью.

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

Порядок окончания срока действия таймера

Искусственные и виртуализированные таймеры создают прерывания в течение определенного срока действия или рядом с ним. Из-за аппаратного и другого взаимодействия планирования прерывания могут быть отложены. Между любым набором таймеров нельзя предполагать упорядочение.

Прямые искусственные таймеры

Искусственные таймеры direct утверждают прерывание по истечении срока действия таймера вместо отправки сообщения в источник синтетических прерываний SynIc. Для искусственного таймера задан режим direct, задав поле DirectMode конфигурации искусственного таймера MSR. Поле ApicVector управляет вектором прерываний, который утверждается по истечении срока действия таймера.

Искусственные регистры таймера

Искусственные таймеры настраиваются с помощью синтетических регистров, связанных с каждым виртуальным процессором. Каждый из четырех синтетических таймеров имеет связанную пару регистров (конфигурации и подсчета).

На платформах x64

На платформах x64 искусственные таймеры получают доступ через MSR с помощью инструкций RDMSR и WRMSR.

АДРЕС MSR Имя регистрации Description
0x400000B0 HV_X64_MSR_STIMER0_CONFIG Регистрация конфигурации для искусственного таймера 0.
0x400000B1 HV_X64_MSR_STIMER0_COUNT Время окончания срока действия или период для искусственного таймера 0.
0x400000B2 HV_X64_MSR_STIMER1_CONFIG Регистрация конфигурации для искусственного таймера 1.
0x400000B3 HV_X64_MSR_STIMER1_COUNT Время окончания срока действия или период для искусственного таймера 1.
0x400000B4 HV_X64_MSR_STIMER2_CONFIG Регистрация конфигурации для искусственного таймера 2.
0x400000B5 HV_X64_MSR_STIMER2_COUNT Время окончания срока действия или период для искусственного таймера 2.
0x400000B6 HV_X64_MSR_STIMER3_CONFIG Регистрация конфигурации для искусственного таймера 3.
0x400000B7 HV_X64_MSR_STIMER3_COUNT Время окончания срока действия или период для искусственного таймера 3.

На платформах ARM64

На платформах ARM64 искусственные таймеры получают доступ через искусственные регистры с помощью гипермасштабирования HvCallGetVpRegisters и HvCallSetVpRegisters.

Имя регистрации Description
HvRegisterStimer0Config Регистрация конфигурации для искусственного таймера 0.
HvRegisterStimer0Count Время окончания срока действия или период для искусственного таймера 0.
HvRegisterStimer1Config Регистрация конфигурации для искусственного таймера 1.
HvRegisterStimer1Count Время окончания срока действия или период для искусственного таймера 1.
HvRegisterStimer2Config Регистрация конфигурации для искусственного таймера 2.
HvRegisterStimer2Count Время окончания срока действия или период для искусственного таймера 2.
HvRegisterStimer3Config Регистрация конфигурации для искусственного таймера 3.
HvRegisterStimer3Count Время окончания срока действия или период для искусственного таймера 3.

Примечание: В ARM64 искусственные таймеры являются необязательными, так как универсальный таймер ARM (GIT) можно использовать непосредственно без накладных расходов на виртуализацию. Гостевые операционные системы должны использовать универсальный таймер архитектуры для повышения производительности.

Регистрация макета

Регистрация конфигурации искусственного таймера
Биты Description Attributes
63:20 RsvdZ (значение должно быть равно нулю) Чтение и запись
19:16 SINTx — искусственный источник прерываний Чтение и запись
15:13 RsvdZ (значение должно быть равно нулю) Чтение и запись
12 Прямой режим — утверждение и прерывание по истечении срока действия таймера. Чтение и запись
11:4 ApicVector — управляет вектором утверждений прерываний в прямом режиме Чтение и запись
3 AutoEnable — если запись соответствующего счетчика неявно приводит к включению таймера. Чтение и запись
2 Ленивый — задать, если таймер ленив Чтение и запись
1 Периодический — установка времени, если таймер периодически Чтение и запись
0 Включено— задать, если таймер включен Чтение и запись

При создании и сбросе виртуального процессора для всех регистров конфигурации искусственного таймера (HV_X64_MSR_STIMER0_CONFIG через HV_X64_MSR_STIMER3_CONFIG) устанавливается значение 0x0000000000000000. Таким образом, все искусственные таймеры отключены по умолчанию.

Если задан параметр AutoEnable, то запись ненулевого значения в соответствующий регистр счетчика приведет к настройке и активации счетчика. В противном случае включить следует задать после записи соответствующего регистра счетчика для активации счетчика. Сведения о регистре count см. в следующем разделе.

Когда истекает срок действия однократного таймера, он автоматически помечается как отключенный. Периодические таймеры остаются включенными до явного отключения.

Если один снимок включен, и указанное число находится в прошлом, срок действия истекает немедленно.

Не разрешено задать для поля SINTx нулевое значение для включенного таймера (не в прямом режиме). Если предпринята попытка, таймер будет помечен как отключен (то есть бит 0 очищается) немедленно.

Запись регистра конфигурации таймера, который уже включен, может привести к неопределенному поведению. Например, простое изменение таймера с одного выстрела на периодическое может не производить то, что предназначено. Таймеры всегда должны быть отключены перед изменением других свойств.

Регистрация числа искусственных таймеров
Биты Description Attributes
63:0 Количество— время истечения срока действия для однократных таймеров, длительность периодических таймеров Чтение и запись

Значение, запрограммированное в регистр count, — это значение времени, измеряемое в 100 единицах наносекунда. Запись значения нулевого значения в регистр count остановит счетчик, тем самым отключив таймер, независимо от параметра AutoEnable в регистре конфигурации.

Обратите внимание, что регистр Count разрешен для упаковки. Оболочка не влияет на поведение таймера независимо от любого свойства таймера.

Для однозастрелных таймеров он представляет абсолютное время истечения срока действия таймера. Срок действия таймера истекает, когда счетчик ссылок для секции равен или больше заданного значения счетчика.

Для периодических таймеров счетчик представляет период таймера. Первый период начинается, когда включен искусственный таймер.

Сообщение об истечении срока действия искусственного таймера

Сообщения об истечении срока действия таймера отправляются при срабатывании события таймера. Ознакомьтесь с HV_TIMER_MESSAGE_PAYLOAD определения полезных данных сообщения.

Искусственные регистры таймера Time-Unhalted

Искусственные регистры таймера Time-Unhalted доступны на платформах x64, если секция имеет привилегию AccessSyntheticTimerRegs. Доступность указывается EDX-битом 23 в 0x40000003 конечной 0x40000003 идентификации компонентов гипервизора. Эта функция недоступна на платформах ARM64.

Гостевое программное обеспечение может запрограммировать искусственный таймер без использования времени для создания периодического прерывания после выполнения в течение указанного периода времени в 100 000 единиц. При срабатывании прерывания поле SyntheticTimeUnhaltedTimerExpired на странице поддержки VP будет иметь значение TRUE. Гостевая программа может сбросить это поле на FALSE. В отличие от счетчиков производительности архитектуры, искусственный таймер никогда не сбрасывается гипервизором и выполняется непрерывно между прерываниями. Если для поля Vector задано значение 2 (вектор NMI x64), таймер предоставляет немаскируемые прерывания; в противном случае он обеспечивает фиксированное прерывание с помощью указанного вектора.

В отличие от обычных искусственных таймеров, которые накапливают время, когда гость остановился (т. е. прошло бездействия), искусственный Time-Unhalted Таймер накапливает время только в то время как гостевой не остановлен.

На платформах x64

На платформах x64 искусственный таймер неохлаченного времени осуществляется через MSR с помощью инструкций RDMSR и WRMSR.

АДРЕС MSR Имя регистрации Description
0x40000114 HV_X64_MSR_STIME_UNHALTED_TIMER_CONFIG Настройка искусственного Time-Unhalted таймера
0x40000115 HV_X64_MSR_STIME_UNHALTED_TIMER_COUNT Число искусственных Time-Unhalted таймера

Регистрация макета

Регистрация конфигурации искусственного Time-Unhalted таймера
Биты Description Attributes
63:9 RsvdZ (значение должно быть равно нулю) Чтение и запись
8 Включен Чтение и запись
7:0 Vector Чтение и запись

Поле Vector должно иметь значение 2 (для доставки NMI) или значения ≥ 16 (для доставки фиксированного прерывания). Другие значения недопустимы.

Регистрация числа искусственных Time-Unhalted таймера
Биты Description Attributes
63:0 Периодическая скорость прерываний в единицах 100 ns Чтение и запись