Виртуальный контроллер прерываний

Гипервизор виртуализирует доставку прерываний виртуальным процессорам. Это делается с помощью искусственного контроллера прерываний (SynIC), который является расширением виртуализированного локального APIC; то есть каждый виртуальный процессор имеет локальный экземпляр APIC с расширениями SynIC. Эти расширения предоставляют простой механизм межсекционного взаимодействия, который описан в следующей главе. Прерывания, доставляемые в секцию, делятся на две категории: внешние и внутренние. Внешние прерывания исходят из других секций или устройств, а внутренние — из самой секции.

Внешние прерывания создаются в следующих ситуациях:

  • Физическое аппаратное устройство создает аппаратное прерывание.
  • Родительская секция утверждает виртуальное прерывание (обычно в процессе эмуляции аппаратного устройства).
  • Низкоуровневая оболочка доставляет сообщение (например, из-за перехвата) в секцию.
  • Другая секция публикует сообщение.
  • Другая секция сигнализирует о событии.

Внутренние прерывания создаются в следующих ситуациях:

  • Виртуальный процессор обращается к регистру команд прерывания APIC (ICR).
  • Истекает срок действия искусственного таймера.

Локальный APIC

SynIC — это надмножество локального APIC. Интерфейс для этого APIC предоставляется набором 32-разрядных регистров, сопоставленных с памятью. Этот локальный APIC (включая поведение сопоставленных регистров памяти) в целом совместим с локальным APIC в системах P4/Xeon, как описано в документации Intel и AMD.

Локальная виртуализация APIC низкоуровневой оболочки может отличаться от физической операции APIC следующими незначительными способами:

  • В физических системах IA32_APIC_BASE MSR могут отличаться для каждого процессора в системе. Для низкоуровневой оболочки может потребоваться, чтобы этот MSR содержал одинаковое значение для всех виртуальных процессоров в секции. Таким образом, этот MSR может рассматриваться как значение для всей секции. Если виртуальный процессор изменяет этот регистр, значение может эффективно распространяться на все виртуальные процессоры в секции.
  • IA32_APIC_BASE MSR определяет бит "глобального включения" для включения или отключения APIC. Виртуализированный APIC всегда может быть включен. Если это так, этот бит всегда будет иметь значение 1.
  • Локальный APIC низкоуровневой оболочки может не создавать виртуальные SMI (прерывания управления системой).
  • Если нескольким виртуальным процессорам в секции назначены одинаковые идентификаторы APIC, поведение целевой доставки прерываний не определено. Это значит, что низкоуровневая оболочка может доставить прерывание только одному виртуальному процессору, всем виртуальным процессорам с указанным идентификатором APIC или без виртуальных процессоров. Эта ситуация считается ошибкой гостевого программирования.
  • Некоторые из сопоставленных в памяти регистров APIC можно получить с помощью виртуальных MSR.
  • Гипервизор может не позволить гостевой машине изменять свои идентификаторы APIC.

В остальных частях этого раздела описываются только те аспекты функций SynIC, которые являются расширениями локального APIC.

Локальные доступы MSR APIC

Гипервизор обеспечивает ускоренный доступ MSR к регистрам APIC, сопоставленным с высокой нагрузкой памяти. Это регистры TPR, EOI и ICR. Низкие регистры ICR и высокие регистры ICR объединяются в один MSR. Из соображений производительности гостевая операционная система должна следовать рекомендациям гипервизора для использования MSR APIC.

Адрес MSR Имя регистрации Описание
0x40000070 HV_X64_MSR_EOI Обращается к APIC EOI
0x40000071 HV_X64_MSR_ICR Обращается к APIC ICR-high и ICR-low
0x40000072 HV_X64_MSR_TPR Доступ к TPR APIC

HV_X64_MSR_EOI

Bits Описание Атрибуты
63:32 RsvdZ (зарезервировано, должно быть равно нулю) запись
31:0 Значение EOI запись

HV_X64_MSR_ICR

Bits Описание Атрибуты
63:32 Высокая ценность ICR Чтение и запись
31:0 Низкое значение ICR Чтение и запись

HV_X64_MSR_TPR

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

Этот MSR предназначен для ускорения доступа к TPR в гостевых разделах в 32-разрядном режиме. Гостевые секции в 64-разрядном режиме должны задавать TPR с помощью CR8.

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

Гипервизор поддерживает гипермасштабирования, которые позволяют отправлять виртуальные фиксированные прерывания произвольному набору виртуальных процессоров.

Гипервызов Описание
HvCallSendSyntheticClusterIpi Отправляет виртуальное фиксированное прерывание в указанный набор виртуальных процессоров.
HvCallSendSyntheticClusterIpiEx Как и HvCallSendSyntheticClusterIpi, в качестве входных данных принимает разреженный набор VP.

EOI Assist

Одним из полей на странице поддержки виртуального процессора является поле EOI Assist. Поле EOI Assist находится на смещении 0 страницы наложения и имеет размер 32 бита. Формат поля поддержки EOI выглядит следующим образом:

Bits Описание Атрибуты
31:1 RsvdZ Чтение и запись
0 EOI не требуется Чтение и запись

Гостевая ОС выполняет EOI, атомарным образом записывая ноль в поле EOI Assist на странице поддержки виртуального виртуального пользователя и проверяя, было ли поле "Не требуется EOI" ранее равным нулю. Если это так, операционная система должна выполнять запись в HV_X64_APIC_EOI MSR, тем самым вызывая перехват в низкоуровневой оболочке. Для выполнения EOI рекомендуется использовать следующий код:

lea rcx, [VirtualApicAssistVa]
btr [rcx], 0
jc NoEoiRequired

mov ecx, HV_X64_APIC_EOI
wrmsr

NoEoiRequired:

Низкоуровневая оболочка задает бит "Не требуется EOI" при внедрении виртуального прерывания при выполнении следующих условий:

  • Виртуальное прерывание активируется по краям, и
  • Нет прерываний с более низким приоритетом, ожидающих

Если позже запрашивается прерывание с более низким приоритетом, гипервизор очищает значение "Не требуется EOI" таким образом, что последующий EOI вызывает перехват.

В случае вложенных прерываний перехват EOI избегается только для прерывания с наивысшим приоритетом. Это необходимо, так как количество EOIs, выполняемых ОС, не поддерживается. Таким образом, можно избежать только первого EOI, и так как первый EOI очищает бит "Нет обязательного EOI", следующий EOI создает перехват. Однако вложенные прерывания встречаются редко, поэтому в обычном случае это не проблема.

Обратите внимание, что устройствам и (или) apic ввода-вывода (физическому или искусственному) не нужно уведомлять об EOI для прерывания, активируемого ребром, — гипервизор перехватывает такие EOIS только для обновления состояния виртуального APIC. В некоторых случаях виртуальное состояние APIC может обновляться отложенно. В таких случаях бит NoEoiRequired задается гипервизором, указывающим на то, что перехват EOI не требуется. Позже гипервизор может получить состояние локального APIC в зависимости от текущего значения бита NoEoiRequired.

Включение и отключение этого просветления можно выполнить в любое время независимо от действия прерывания и состояния APIC в данный момент. Хотя просветление включено, обычные ЭОИ по-прежнему могут выполняться независимо от значения "No EOI required" (Не требуется EOI), но они не поймут преимущества просветления в производительности.