Таймеры

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

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

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

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

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

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

MSR счетчика ссылок на секции

Доступ к счетчику ссылок секции можно получить через MSR для всей секции.

Адрес MSR Имя регистрации Описание
0x40000020 HV_X64_MSR_TIME_REF_COUNT Количество ссылок на время (на уровне секций)

При создании секции для TIME_REF_COUNT MSR устанавливается значение 0x0000000000000000. Это значение не может быть изменено виртуальным процессором. Любая попытка записи в нее приводит к сбою #GP.

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

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

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

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

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

Гипервизор предоставляет страницу TSC виртуальной ссылки на секции, которая накладывается на пространство GPA секции. Доступ к странице счетчика эталонной метки времени секции осуществляется через msr reference TSC.

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

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

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

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

Адрес MSR Имя регистрации Описание
0x40000021 HV_X64_MSR_REFERENCE_TSC Эталонная страница TSC
Bits Описание Атрибуты
63:12 Номер страницы GPA Чтение и запись
11:1 RsvdP (значение должно быть сохранено) Чтение и запись
0 Включить Чтение и запись

Во время создания гостевого раздела значение ссылки TSC MSR 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 (источник искусственного прерывания) по истечении срока действия или утверждает прерывание в зависимости от того, как оно настроено.

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

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

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

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

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

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

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

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

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

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

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

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

Адрес MSR Имя регистрации Описание
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_STIMER4_COUNT Время истечения срока действия или период для искусственного таймера 3.

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

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

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

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

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

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

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

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

Регистр количества искусственных таймеров

Bits Описание Атрибуты
63:0 Count — время истечения срока действия для однократных таймеров, длительность для периодических таймеров Чтение и запись

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

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

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

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

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

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

Синтетическая Time-Unhalted таймер msr

Искусственные Time-Unhalted таймера доступны, если раздел имеет привилегию AccessSyntheticTimerRegs и бит EDX 23 в конечной 0x40000003 идентификатора ЦП идентификации компонентов гипервизора. Гостевое программное обеспечение может запрограммировать искусственный таймер, не задохнутый по времени, чтобы создать периодическое прерывание после выполнения в течение указанного периода времени в 100 единицах. При срабатывании прерывания для поля SyntheticTimeUnhaltedTimerExpired на странице поддержки VP будет задано значение TRUE. Гостевая программа может сбросить это поле на FALSE. В отличие от счетчиков производительности архитектуры, искусственный таймер никогда не сбрасывается гипервизором и непрерывно выполняется между прерываниями. Векторы ==2 отправляют NMI, другие векторы отправляют фиксированное прерывание.

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

Адрес MSR Имя регистрации Описание
0x40000114 HV_X64_MSR_STIME_UNHALTED_TIMER_CONFIG MSR конфигурации таймера искусственного Time-Unhalted
0x40000115 HV_X64_MSR_STIME_UNHALTED_TIMER_COUNT Счетчик таймера искусственного Time-Unhalted MSR

MSR конфигурации таймера искусственного Time-Unhalted

Bits Описание Атрибуты
63:9 RsvdZ (значение должно быть равно нулю) Чтение и запись
8 Активировано Чтение и запись
7:0 Вектор Чтение и запись

Счетчик таймера искусственного Time-Unhalted MSR

Bits Описание Атрибуты
63:0 Периодическая частота прерываний в 100 единицах нс Чтение и запись