Виртуальный контроллер прерываний
Гипервизор виртуализирует доставку прерываний виртуальным процессорам. Это делается с помощью искусственного контроллера прерываний (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), но они не поймут преимущества просветления в производительности.