Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Гипервизор предоставляет механизм вызова для гостей. Такие вызовы называются гипермасштабированием. Каждый гиперкалл определяет набор входных и/или выходных параметров. Эти параметры задаются с точки зрения структуры данных на основе памяти. Все элементы входных и выходных структур данных заполняются естественными границами до 8 байт (т. е. двухбайтовые элементы должны находиться на двухбайтовых границах и т. д.).
При необходимости для подмножества гипермасштабирования можно использовать второе соглашение о вызове гиперклилов, в частности для тех, которые имеют два или меньше входных параметров и нет выходных параметров. При использовании этого соглашения о вызове входные параметры передаются в регистрах общего назначения.
При необходимости для подмножества гипермасштабирования можно использовать третье соглашение о вызове гиперклов, где входной блок параметров составляет до 112 байт. При использовании этого соглашения о вызове входные параметры передаются в регистрах, включая переменные регистры XMM.
Структуры входных и выходных данных должны размещаться в памяти на 8-байтовой границе и помещаться в кратное количество 8 байтов. Значения в регионах с заполнением игнорируются гипервизором.
Для выходных данных гипервизор разрешен (но не гарантируется) перезаписать области заполнения. Если он перезаписывает области заполнения, он будет записывать нули.
Классы Hypercall
Существует два класса гипермасштабирования: простой и rep (короткий для "повтор"). Простой гиперкел выполняет одну операцию и имеет набор входных и выходных параметров фиксированного размера. Гиперклюс rep действует как ряд простых гиперкалий. Помимо набора входных и выходных параметров фиксированного размера, гипермасштабирование гипермасштабирования включает список входных и /или выходных элементов фиксированного размера.
Когда вызывающий объект изначально вызывает гиперклакс реапс, он указывает количество повторов, указывающее количество элементов в списке входных и /или выходных параметров. Вызывающие элементы также указывают индекс запуска rep, указывающий следующий входной и /или выходной элемент, который следует использовать. Гипервизор обрабатывает параметры rep в порядке списка, т. е. путем увеличения индекса элемента.
Для последующих вызовов гиперкела rep в индексе запуска rep указывает, сколько элементов было завершено ( и, в сочетании со значением счетчика репсов, сколько элементов осталось). Например, если вызывающий объект указывает число повторений 25, а в течение ограничений времени выполняется только 20 итераций, гиперколл возвращает контроль обратно вызывающему виртуальному процессору после обновления индекса запуска rep до 20. При повторном выполнении гиперклага гипервизор возобновляется в элементе 20 и завершает оставшиеся 5 элементов.
Если при обработке элемента возникает ошибка, соответствующий код состояния предоставляется вместе с заполненным числом повторов, указывая количество элементов, которые были успешно обработаны до возникновения ошибки. Предположим, что указанное слово элемента управления гиперкликом является допустимым (см. следующее), а списки входных и выходных параметров доступны, гипервизор гарантированно пытается выполнить по крайней мере одну повторную попытку, но не требуется обрабатывать весь список перед возвратом элемента управления обратно вызывающему объекту.
Продолжение hypercall
Гиперкалл может рассматриваться как сложная инструкция, которая принимает много циклов. Гипервизор пытается ограничить выполнение гиперкаллов до 50 мг или меньше, прежде чем возвращать управление виртуальному процессору, вызвавшей гиперкалл. Некоторые операции гиперкела достаточно сложны, что гарантия 50 мкс трудно сделать. Поэтому гипервизор полагается на механизм продолжения гиперкаллов для некоторых гиперкалий, включая все формы гиперкела.
Механизм продолжения гиперкаллов в основном является прозрачным для вызывающего абонента. Если гиперкалл не может завершиться в течение заданного ограничения времени, элемент управления возвращается обратно вызывающему объекту, но указатель инструкции не является расширенным мимо инструкции, которая вызвала гиперколл. Это позволяет обрабатывать ожидающие прерывания и планировать другие виртуальные процессоры. Когда исходный вызывающий поток возобновляет выполнение, он повторно выполнит инструкцию гиперкела и перенаправит ход выполнения операции.
Большинство простых гипермасштабирования гарантированно завершаются в течение заданного срока. Однако для небольшого количества простых гипермасштабирования может потребоваться больше времени. Эти гиперкаллы используют продолжение гиперкаллов таким же образом, как и для гипермасштабирования. В таких случаях операция включает два или более внутренних состояний. Первый вызов помещает объект (например, секцию или виртуальный процессор) в одно состояние, а после повторяющихся вызовов состояние, наконец, переходит в состояние терминала. Для каждого гиперкалла, следующего за этим шаблоном, описаны видимые побочные эффекты промежуточных внутренних состояний.
Гиперкалл атомарность и упорядочение
За исключением случаев, когда указано, действие, выполняемое гиперклалом, является атомарным как в отношении всех других гостевых операций (например, инструкций, выполняемых в гостевой системе), так и всех других гиперкалий, выполняемых в системе. Простой гиперкалл выполняет одно атомарное действие; Гиперклип выполняет несколько независимых атомарных действий.
Простые гиперкаллы, использующие продолжение гиперкаллов, могут включать несколько внутренних состояний, которые отображаются на внешнем уровне. Такие вызовы включают несколько атомарных операций.
Каждое действие гиперкела может считывать входные параметры и /или записывать результаты. Входные данные для каждого действия можно считывать с любой степенью детализации и в любое время после выполнения гиперкалля и перед выполнением действия. Результаты (т. е. выходные параметры), связанные с каждым действием, могут быть записаны при любой детализации и в любое время после выполнения действия и до возврата гиперклала.
Гость должен избежать проверки и (или) манипуляции с любыми входным или выходными параметрами, связанными с выполнением гиперкела. Хотя виртуальный процессор, выполняющий гиперкалл, не сможет сделать это (так как его гостевое выполнение приостановлено до тех пор, пока гиперклалл не возвращается), нет ничего, чтобы предотвратить выполнение других виртуальных процессоров. Гости, которые ведут себя таким образом, могут сбоем или причиной повреждения в их разделе.
Юридические гиперклимы среды
Гипермасштабирование можно вызывать только из наиболее привилегированного режима гостевого процессора. На платформах x64 это означает защищенный режим с текущим уровнем привилегий (CPL) нуля. Хотя код реального режима выполняется с эффективным CPL нулевого уровня, гипермасштабирование не допускается в реальном режиме. Попытка вызвать гиперкалл в незаконном режиме процессора создаст исключение #UD (неопределенной операции) для x64 и неопределенное исключение инструкций в ARM64.
Все гиперкалили должны вызываться с помощью архитектурно-определенного интерфейса гиперкела (см. ниже). Попытка вызвать гиперкалл любым другим способом (например, копирование кода из кодовой страницы гиперкаллов в альтернативное расположение и выполнение его оттуда) может привести к исключению неопределенной операции (#UD). Гипервизор не гарантирует доставку этого исключения.
Требования к выравниванию
Вызывающие пользователи должны указать 64-разрядный физический адрес гостя (GPA) входных и /или выходных параметров. Указатели GPA должны быть выровнены по 8 байтам. Если гиперкалл не включает входные или выходные параметры, гипервизор игнорирует соответствующий указатель GPA.
Списки входных и выходных параметров не могут перекрываться или пересекать границы страниц. Ожидается, что страницы входных и выходных данных hypercall — это страницы GPA, а не страницы наложения. Если виртуальный процессор записывает входные параметры на страницу наложения и задает GPA на этой странице, доступ гипервизора к списку входных параметров не определен.
Гипервизор проверяет, может ли вызывающий раздел считывать с входной страницы перед выполнением запрошенного гиперкалля. Эта проверка состоит из двух проверок: указанная GPA сопоставлена, а GPA помечена как удобочитаемая. Если один из этих тестов завершается сбоем, гипервизор создает сообщение перехвата памяти. Для гиперкалий, имеющих выходные параметры, гипервизор проверяет, может ли секция записывать данные на выходную страницу. Эта проверка состоит из двух проверок: сопоставлена указанная GPA, а GPA помечена как записываемая.
Входные данные hypercall
Вызывающие серверы указывают гиперкалл по 64-разрядному значению, называемому входным значением гиперкаллов. Он форматируется следующим образом:
| Поле | Биты | Предоставленная информация |
|---|---|---|
| Код вызова | 15-0 | Указывает, какой гиперкалл запрашивается |
| Быстрый | 16 | Указывает, используется ли гиперкалл соглашения о вызове на основе регистра: 0 = память, 1 = регистрация |
| Размер заголовка переменной | 26-17 | Размер заголовка переменной в QWORDS. |
| RsvdZ | 30-27 | Должно быть равно нулю |
| Вложенный | 31 | Указывает гиперклюс должен обрабатываться гипервизором L0 в вложенной среде. |
| Число представителей | 43-32 | Общее количество повторений (для вызова rep, должно быть равно нулю в противном случае) |
| RsvdZ | 47-44 | Должно быть равно нулю |
| Индекс запуска rep | 59-48 | Начальный индекс (для вызова rep, должен быть равен нулю в противном случае) |
| RsvdZ | 63-60 | Должно быть равно нулю |
Для гипермасштабирования реапсов поле счетчика rep указывает общее количество повторений. Индекс запуска rep указывает на определенное повторение относительно начала списка (ноль указывает, что первый элемент в списке должен обрабатываться). Таким образом, значение счетчика реапсов всегда должно быть больше, чем индекс запуска rep.
Соглашения о регистрации Гиперкла (x86/x64)
В x86/x64 регистрируйте сопоставление для входных данных гиперкела, если флаг Fast равен нулю, как показано ниже.
| х64 | x86 | Предоставленная информация |
|---|---|---|
| RCX | EDX:EAX | Значение входных данных Hypercall |
| RDX | EBX:ECX | Входные параметры GPA |
| R8 | EDI:ESI | Выходные параметры GPA |
Входное значение гиперкаллов передается в регистрах вместе с GPA, который указывает на входные и выходные параметры.
Сопоставления регистров зависят от того, работает ли вызывающий объект в 32-разрядном (x86) или 64-разрядном режиме (x64). Гипервизор определяет режим вызывающего объекта на основе значения EFER. LMA и CS.L. Если оба этих флага заданы, вызывающий объект считается 64-разрядным вызывающим.
Зарегистрируйте сопоставление для входных данных гиперкела, если флаг Fast является одним из следующих значений:
| х64 | x86 | Предоставленная информация |
|---|---|---|
| RCX | EDX:EAX | Значение входных данных Hypercall |
| RDX | EBX:ECX | Входной параметр |
| R8 | EDI:ESI | Выходной параметр |
Входное значение гиперкела передается в регистрах вместе с входными параметрами.
Соглашения о регистрации Hypercall (ARM64 SMCCC)
В ARM64 гипермасштабирование выполняется с помощью инструкции HVC #0. Вызовы соответствуют соглашению о вызовах ARM64 SMCCC (SMC).
Сопоставление регистров для входных данных hypercall выглядит следующим образом:
| Register | Предоставленная информация |
|---|---|
| X0 | Идентификатор функции SMCCC |
| X1 | Значение входных данных Hypercall |
| X2 | Входные параметры GPA |
| X3 | Выходные параметры GPA |
Идентификатор функции SMCCC в X0 соответствует следующему формату:
| Биты | Поле | Ценность | Description |
|---|---|---|---|
| 31 | Получение вызова | 0 | Всегда 0 |
| 30 | Соглашение о вызовах | 1 | 1 для соглашений о вызовах HVC64 |
| 29:24 | Тип вызова службы | 6 | 6 для вызовов служб гипервизора для конкретного поставщика |
| 23:16 | Зарезервировано | 0 | Зарезервировано, должно быть равно нулю (Res0) |
| 15:0 | Номер функции | 1 | 1 указывает, что код вызова HV определен в X1 |
Полный формат идентификатора функции: 0x46000001
Соглашения о гиперклилле (ARM64 HVC #1)
По историческим причинам интерфейс гипервизора ARM64 также поддерживает другое соглашение о вызовах. Гипермасштабирование выполняется с помощью инструкции HVC #1. Мы рекомендуем использовать соглашение о вызовах SMCCC для нового кода.
Сопоставление регистров для входных данных hypercall выглядит следующим образом:
| Register | Предоставленная информация |
|---|---|
| X0 | Значение входных данных Hypercall |
| X1 | Входные параметры GPA |
| X2 | Выходные параметры GPA |
Заголовки входных данных размера переменной размера
Большинство заголовков ввода гиперкаллов имеют фиксированный размер. Таким образом, объем данных заголовка, передаваемых от гостя в гипервизор, неявно указывается в коде гиперкаллов и не нужно указывать отдельно. Однако для некоторых гипермасштабирования требуется переменный объем данных заголовка. Эти гипермасштабирование обычно имеют входной заголовок фиксированного размера и дополнительные входные данные заголовка, которые имеют размер переменной.
Заголовок размера переменной похож на фиксированные входные данные гиперкела (выровнены по 8 байтам и размеру до нескольких 8 байт). Вызывающий объект должен указать, сколько данных он предоставляет в качестве входных заголовков. Этот размер предоставляется как часть входного значения гиперкела (см. раздел "Размер заголовка переменной" в таблице выше).
Так как фиксированный размер заголовка неявен, а не предоставляет общий размер заголовка, в входных элементах управления предоставляется только переменная.
Variable Header Bytes = {Total Header Bytes - sizeof(Fixed Header)} rounded up to nearest multiple of 8
Variable Header Size = Variable Header Bytes / 8
Недопустимо указать размер заголовка переменной, отличного от нуля, для гиперкела, который явно не документирован как принимающие входные заголовки переменной размера. В таком случае гиперкалл приведет к возврату кода HV_STATUS_INVALID_HYPERCALL_INPUT.
Возможно, что для заданного вызова гиперклага, который принимает входные заголовки переменной размера, которые все входные данные заголовка помещаются полностью в заголовке фиксированного размера. В таких случаях входной заголовок размера переменной равен нулю, а соответствующие биты в входных данных гиперкела должны быть равны нулю.
Во всех остальных отношениях гиперкаллы, принимающие входные заголовки переменной размера, похожи на гипермасштабирование заголовков входных значений фиксированного размера относительно соглашений о вызовах. Кроме того, гиперкел заголовка размера переменной размера также поддерживает семантику rep. В таком случае элементы rep лежат после заголовка в обычном режиме, за исключением того, что общий размер заголовка включает как фиксированные, так и переменные части. Все остальные правила остаются одинаковыми, например первый элемент rep должен быть выровнен 8 байтов.
XMM Fast Hypercall Input (x86/x64)
На платформах x86/x64 гипервизор поддерживает использование гипермасштабирования XMM с высокой скоростью, что позволяет некоторым гиперкалилям воспользоваться преимуществами улучшенной производительности интерфейса быстрого гиперкликса, даже если требуются более двух входных параметров. Интерфейс гиперкела XMM использует шесть регистров XMM, чтобы разрешить вызывающему объекту передавать блок входных параметров размером до 112 байт.
Доступность интерфейса гиперкела XMM с помощью конечной части ЦПID (0x40000003):
- Бит 4. Доступна поддержка передачи входных данных гиперклакса через регистры XMM.
Обратите внимание, что существует отдельный флаг, указывающий на поддержку быстрых выходных данных XMM. Любая попытка использовать этот интерфейс, если гипервизор не указывает на доступность, приведет к сбою #UD.
Сопоставление регистров (только входные данные)
| х64 | x86 | Предоставленная информация |
|---|---|---|
| RCX | EDX:EAX | Значение входных данных Hypercall |
| RDX | EBX:ECX | Блок входных параметров |
| R8 | EDI:ESI | Блок входных параметров |
| XMM0 | XMM0 | Блок входных параметров |
| XMM1 | XMM1 | Блок входных параметров |
| XMM2 | XMM2 | Блок входных параметров |
| XMM3 | XMM3 | Блок входных параметров |
| XMM4 | XMM4 | Блок входных параметров |
| XMM5 | XMM5 | Блок входных параметров |
Входное значение гиперкела передается в регистрах вместе с входными параметрами. Сопоставления регистров зависят от того, работает ли вызывающий объект в 32-разрядном (x86) или 64-разрядном режиме (x64). Гипервизор определяет режим вызывающего объекта на основе значения EFER. LMA и CS.L. Если оба этих флага заданы, вызывающий объект считается 64-разрядным вызывающим. Если входной блок параметров меньше 112 байт, все дополнительные байты в регистрах игнорируются.
Регистрация быстрого вызова (ARM64 SMCCC)
На платформах ARM64 гипервизор поддерживает использование быстрых гипермасштабируемых регистров, что позволяет некоторым гиперкалилям воспользоваться преимуществами улучшенной производительности интерфейса быстрого гиперклаша, даже если требуются более двух входных параметров. В интерфейсе быстрого гиперкела регистрации используется 16 регистров общего назначения, чтобы вызывающий объект передавал блок входных параметров размером до 128 байт.
Сопоставление регистров (только входные данные)
| Register | Предоставленная информация |
|---|---|
| X0 | Идентификатор функции SMCCC |
| X1 | Значение входных данных Hypercall |
| X2 — X17 | Блок входных параметров |
Если входной блок параметров меньше 128 байт, все дополнительные байты в регистрах игнорируются.
Регистрация быстрого вызова (ARM64 HVC #1)
В интерфейсе быстрого гиперкаллирования регистров регистрации используется шестнадцать регистров общего назначения, которые позволяют вызывающему объекту передавать блок входных параметров размером до 128 байт.
Сопоставление регистров (только входные данные)
| Register | Предоставленная информация |
|---|---|
| X0 | Значение входных данных Hypercall |
| X1 — X17 | Блок входных параметров |
Если входной блок параметров меньше 128 байт, все дополнительные байты в регистрах игнорируются.
Выходные данные hypercall
Все гиперкаллы возвращают 64-разрядное значение, называемое значением результата гиперкела. Он форматируется следующим образом:
| Поле | Биты | Комментарий |
|---|---|---|
| Result | 15-0 |
HV_STATUS код, указывающий на успешность или сбой |
| Rsvd | 31-16 | Вызывающие абоненты должны игнорировать значение в этих битах |
| Республика завершена | 43-32 | Количество успешно завершенных повторений |
| RsvdZ | 63-40 | Вызывающие абоненты должны игнорировать значение в этих битах |
Для гипермасштабирования reps заполненное поле — общее количество завершенных повторений, а не относительно индекса запуска rep. Например, если вызывающий объект указал индекс запуска rep 5, а число повторений — 10, то после успешного завершения поля повторения будет указано 10.
Значение результата гиперкела передается обратно в регистры.
В x64 сопоставление регистра зависит от того, работает ли вызывающий объект в 32-разрядном (x86) или 64-разрядном режиме (x64) (см. выше). Сопоставление регистра для выходных данных гиперкела выглядит следующим образом:
| х64 | x86 | Предоставленная информация |
|---|---|---|
| RAX | EDX:EAX | Значение результата hypercall |
В ARM64 сопоставление регистра для выходных данных гиперкела выглядит следующим образом:
| Register | Предоставленная информация |
|---|---|
| X0 | Значение результата hypercall |
XMM Fast Hypercall Output (x86/x64)
Аналогично тому, как гипервизор поддерживает быстрые входные данные XMM, одни и те же регистры можно совместно использовать для возврата выходных данных. Это поддерживается только на платформах x64.
Возможность возвращать выходные данные с помощью регистров XMM указывается с помощью конечного листа ЦПП ЦП (0x40000003):
- Bit 15: доступна поддержка возврата выходных данных гиперклала через регистры XMM.
Обратите внимание, что существует отдельный флаг, указывающий на поддержку быстрых входных данных XMM. Любая попытка использовать этот интерфейс, если гипервизор не указывает на доступность, приведет к сбою #UD.
Сопоставление регистров (входные и выходные данные)
Регистры, которые не используются для передачи входных параметров, можно использовать для возврата выходных данных. Другими словами, если блок входных параметров меньше 112 байт (округляется до ближайшего 16 байтов, выровненных фрагментом), остальные регистры возвращают выходные данные гиперклава.
| х64 | Предоставленная информация |
|---|---|
| RDX | Блок ввода или вывода |
| R8 | Блок ввода или вывода |
| XMM0 | Блок ввода или вывода |
| XMM1 | Блок ввода или вывода |
| XMM2 | Блок ввода или вывода |
| XMM3 | Блок ввода или вывода |
| XMM4 | Блок ввода или вывода |
| XMM5 | Блок ввода или вывода |
Например, если входной блок параметров равен 20 байтам, гипервизор будет игнорировать следующие 12 байт. Оставшиеся 80 байт будут содержать выходные данные гиперкабля (если это применимо).
Регистрация выходных данных быстрого вызова (ARM64 SMCCC)
На платформах ARM64, аналогичных тому, как гипервизор поддерживает регистрацию быстрых входных данных гиперкела, одни и те же регистры можно совместно использовать для возврата выходных данных.
Сопоставление регистров (входные и выходные данные)
Регистры, которые не используются для передачи входных параметров, можно использовать для возврата выходных данных. Другими словами, если блок входных параметров меньше 128 байт (округляется до ближайшего 8 байтового выровненного блока), остальные регистры будут возвращать выходные данные гиперкаллов.
| Register | Предоставленная информация |
|---|---|
| X2 — X17 | Блок ввода или вывода |
Например, если входной блок параметров равен 20 байтам, гипервизор будет игнорировать следующие 4 байта. Остальные 104 байты будут содержать выходные данные гиперкаллов (если это применимо).
Регистрация выходных данных быстрого вызова (ARM64 HVC #1)
Как и в версиях SMCCC, интерфейс HVC #1 использует те же регистры для возврата выходных данных.
Сопоставление регистров (входные и выходные данные)
Регистры, которые не используются для передачи входных параметров, можно использовать для возврата выходных данных. Другими словами, если блок входных параметров меньше 128 байт (округляется до ближайшего 8 байтового выровненного блока), остальные регистры будут возвращать выходные данные гиперкаллов.
| Register | Предоставленная информация |
|---|---|
| X1 — X17 | Блок ввода или вывода |
Например, если входной блок параметров равен 20 байтам, гипервизор будет игнорировать следующие 4 байта. Остальные 104 байты будут содержать выходные данные гиперкаллов (если это применимо).
Переменные регистры (x86/x64)
Гиперкаллы будут изменять только указанные значения регистра в следующих условиях:
- RAX (x64) и EDX:EAX (x86) всегда перезаписываются со значением результата гиперкаллов и выходными параметрами, если таковые имеются.
- Hypercalls rep изменит RCX (x64) и EDX:EAX (x86) с новым индексом запуска rep.
- HvCallSetVpRegisters может изменять все регистры, поддерживаемые этим гиперклалом.
- RDX, R8 и XMM0 через XMM5 при использовании для быстрого ввода гиперклакса остаются неизменимыми. Однако регистры, используемые для быстрого вывода гиперклакса, могут быть изменены, включая RDX, R8 и XMM0 через XMM5. Hyper-V изменит только эти регистры для быстрого вывода гиперклакса, что ограничено x64.
Переменные регистры (ARM64 SMCCC)
Гиперкаллы будут изменять только указанные значения регистра в следующих условиях:
- X0 всегда перезаписывается со значением результата гиперкела и выходными параметрами, если таковые имеются.
- Hypercalls rep изменит X1 с новым индексом запуска rep.
- HvCallSetVpRegisters может изменять все регистры, поддерживаемые этим гиперклалом.
- X2 — X17, когда используется для быстрого ввода гиперклакса, остаются неизменимыми. Однако регистры, используемые для быстрого вывода гиперклакса, могут быть изменены, включая X2 - X17. Hyper-V эти регистры будут изменяться только для быстрого вывода гиперкела.
Переменные регистры (ARM64 HVC #1)
Гиперкаллы будут изменять только указанные значения регистра в следующих условиях:
- X0 всегда перезаписывается со значением результата гиперкела и выходными параметрами, если таковые имеются.
- Hypercalls rep изменит X0 с новым индексом запуска rep.
- HvCallSetVpRegisters может изменять все регистры, поддерживаемые этим гиперклалом.
- X1 — X17, если используется для быстрого ввода гиперклакса, остаются неизменимыми. Однако регистры, используемые для быстрого вывода гиперклакса, могут быть изменены, включая X1 - X17. Hyper-V эти регистры будут изменяться только для быстрого вывода гиперкела.
Ограничения hypercall
Гипермасштабирование может иметь связанные ограничения, которые должны быть удовлетворены для выполнения их предполагаемой функции. Если все ограничения не выполнены, гиперкласк завершится с соответствующей ошибкой. В списке будут указаны следующие ограничения, если они применяются:
- Вызывающий раздел должен иметь определенную привилегию
- Раздел, на который выполняется действие, должен находиться в определенном состоянии (например, "Активный")
Коды состояния Hypercall
Каждый гиперклюс задокументирован как возвращающий выходное значение, содержащее несколько полей. Поле значения состояния (типа HV_STATUS) используется для указания успешного или неудачного вызова.
Допустимость выходных параметров при неудачных гиперкальлях
Если явно не указано в противном случае, если гиперквал завершается ошибкой (т. е. поле результата гиперкела содержит значение, отличное HV_STATUS_SUCCESSот значения), содержимое всех выходных параметров не определено и не должно проверяться вызывающим элементом. Только в случае успешного выполнения гиперкалли все соответствующие выходные параметры содержат допустимые ожидаемые результаты.
Порядок условий ошибки
Порядок обнаружения ошибок и сообщения гипервизором не определен. Другими словами, если существует несколько ошибок, гипервизор должен выбрать условие ошибки для отчета. Приоритет должен быть предоставлен этим кодам ошибок, предлагающим большую безопасность, намерение предотвратить гипервизор от раскрытия информации вызывающим лицам, не имеющих достаточных привилегий. Например, код состояния является предпочтительным кодом HV_STATUS_ACCESS_DENIED состояния для одного, который будет отображать некоторые контекст или сведения о состоянии исключительно на основе привилегий.
Распространенные коды состояния Гиперклилла
Некоторые коды результатов являются общими для всех гиперкалий и поэтому не документируются для каждого гиперклюза по отдельности. К ним относятся следующие:
| Код состояния | Условие ошибки |
|---|---|
HV_STATUS_SUCCESS |
Вызов выполнен успешно. |
HV_STATUS_INVALID_HYPERCALL_CODE |
Код гиперкалл не распознается. |
HV_STATUS_INVALID_HYPERCALL_INPUT |
Неправильное число повторений (например, число ненулевых повторений передается в вызов, отличный от rep, или число отсчетов отсчетов передается в вызов rep). |
| Индекс запуска rep не меньше, чем число реапсов. | |
| Зарезервированный бит в указанном входном значении гиперкела не равен нулю. | |
HV_STATUS_INVALID_ALIGNMENT |
Указанный указатель на входные или выходные данные GPA не соответствует 8 байтам. |
| Указанный входной или выходной параметр содержит страницы диапазона. | |
| Указатель на входные или выходные данные GPA не находится в пределах пространства GPA. |
Код возврата HV_STATUS_SUCCESS указывает, что не обнаружено условия ошибки.
Создание отчетов о удостоверении гостевой ОС
Гостевая ОС, запущенная в разделе, должна идентифицировать себя в гипервизоре, написав ее сигнатуру и версию в MSR (HV_X64_MSR_GUEST_OS_ID/HvRegisterGuestOsId) перед вызовом гипермасштабирования. Этот MSR является секционированием и является общим для всех виртуальных процессоров.
Значение этого регистра изначально равно нулю.
В x86/x64 необходимо записать ненулевое значение в MSR с идентификатором гостевой ОС, прежде чем включить кодовую страницу гиперкалл (см. раздел "Установка интерфейса Hypercall" (x86/x64)). Если этот регистр впоследствии отсчитывается от нуля, то кодовая страница гиперкаллов будет отключена.
В ARM64 значение, отличное от нуля, должно быть записано в MSR идентификатора гостевой ОС перед вызовом кодов гиперкела. Исключением является гипермасштабирование HvCallSetVpRegisters/HvCallGetVpRegisters . Дополнительные сведения см. в соответствующей документации.
#define HV_X64_MSR_GUEST_OS_ID 0x40000000
#define HvRegisterGuestOsId 0x00090002
В ARM64 поддерживается только HvRegisterGuestOsId, который должен быть записан с помощью гиперколя HvCallSetVpRegisters на загрузочном процессоре.
Удостоверение гостевой ОС для собственных операционных систем
Ниже приведена рекомендуемая кодировка для этого MSR. Некоторые поля могут не применяться для некоторых гостевых OS.
| Биты | Поле | Description |
|---|---|---|
| 15:0 | Номер сборки | Указывает номер сборки ОС |
| 23:16 | Версия службы | Указывает версию службы (например, номер пакета обновления) |
| 31:24 | Малая версия | Указывает дополнительную версию ОС |
| 39:32 | Основная версия | Указывает основную версию ОС |
| 47:40 | Идентификатор ОС | Указывает вариант ОС. Кодировка уникальна для поставщика. Операционные системы Майкрософт кодируются следующим образом: 0=Undefined, 1=MS-DOS®, 2=Windows 3.x, 3=Windows®® 9x, 4=Windows NT (и производные), 5=Windows®® CE |
| 62:48 | Идентификатор поставщика | Указывает поставщика гостевой ОС. Значение 0 зарезервировано. См. список поставщиков ниже. |
| 63 | Тип ОС | Указывает тип ОС. Значение 0 представляет частную (закрытую исходную) ОС. Значение 1 представляет ОС с открытым исходным кодом. |
Значения поставщика выделяются корпорацией Майкрософт. Чтобы запросить нового поставщика, отправьте запрос о проблеме в репозитории документации по виртуализации GitHub (https://aka.ms/VirtualizationDocumentationIssuesTLFS).
| Поставщик | Ценность |
|---|---|
| Microsoft | 0x0001 |
| HPE | 0x0002 |
| BlackBerry | 0x0003 |
| LANCOM | 0x0200 |
MSR гостевого удостоверения ОС для операционных систем с открытым исходным кодом
Следующая кодировка предлагается в качестве руководства для поставщиков операционной системы с открытым исходным кодом, которые намерены соответствовать этой спецификации. Предполагается, что операционные системы с открытым исходным кодом принимают следующее соглашение.
| Биты | Поле | Description |
|---|---|---|
| 15:0 | Номер сборки | Сведения о распределении (например, номер сборки). |
| 47:16 | Версия | Сведения о версии вышестоящего ядра. |
| 55:48 | Идентификатор ОС | Дополнительные сведения о поставщике |
| 62:56 | Тип ОС | Тип ОС (например, Linux, FreeBSD и т. д.). См. список известных типов ОС ниже |
| 63 | Открытый исходный код | Значение 1 указывает ос с открытым исходным кодом. |
Значения типа ОС выделяются корпорацией Майкрософт. Чтобы запросить новый тип ОС, отправьте проблему в репозитории документации по виртуализации GitHub (https://aka.ms/VirtualizationDocumentationIssuesTLFS).
| Тип ОС | Ценность |
|---|---|
| Линукс | 0x1 |
| FreeBSD | 0x2 |
| Xen | 0x3 |
| Illumos | 0x4 |
Установка интерфейса Hypercall (x86/x64)
В x86/x64 гипермасштабирование вызывается с помощью специального кода opcode. Поскольку этот код опкода отличается от реализаций виртуализации, необходимо, чтобы гипервизор абстрагировать это различие. Это делается с помощью специальной страницы гиперкела. Эта страница предоставляется гипервизором и отображается в пространстве GPA гостя. Гостевой объект требуется для указания расположения страницы путем программирования msR гостевой hypercall.
#define HV_X64_MSR_HYPERCALL 0x40000001
| Биты | Description | Attributes |
|---|---|---|
| 63:12 | Hypercall GPFN — указывает номер гостевой физической страницы страницы гиперкела | Чтение и запись |
| 11:2 | RsvdP. Биты следует игнорировать при чтении и сохранении при записи. | Зарезервировано |
| 1 | Запертый. Указывает, является ли MSR неизменяемым. Если задано, эта MSR заблокирована таким образом, чтобы предотвратить перемещение страницы гиперкаллов. После установки только сброс системы может очистить бит. | Чтение и запись |
| 0 | Включение страницы гиперкела | Чтение и запись |
Страницу гиперкалл можно поместить в любое место в пространстве GPA гостя, но необходимо выровнять страницы. Если гость пытается переместить страницу гиперкаллов за пределы пространства GPA, то при записи MSR произойдет ошибка #GP.
Эта MSR — это msR на уровне секционирования. Другими словами, они совместно используются всеми виртуальными процессорами в секции. Если один виртуальный процессор успешно записывает в MSR, другой виртуальный процессор считывает то же значение.
Перед включением страницы гиперкела гостевая ОС должна сообщить о своем удостоверении, написав подпись версии в отдельную MSR (HV_X64_MSR_GUEST_OS_ID). Если удостоверение гостевой ОС не указано, попытки включить гиперклилл завершится ошибкой. Бит включения останется нулевым даже при написании одного в него. Кроме того, если удостоверение гостевой ОС очищается до нуля после включения страницы гиперкалл, она станет отключена.
Страница гиперкаллов отображается как "наложение" на пространство GPA; то есть он охватывает все остальное, сопоставленное с диапазоном GPA. Его содержимое доступно для чтения и исполняемого файла гостем. Попытки записи на страницу гиперкела приведет к исключению защиты (#GP). После включения страницы гиперкаллов вызов гиперкалл просто включает вызов к началу страницы.
Ниже приведен подробный список шагов, связанных с установкой страницы гиперкела:
- Гость считывает идентификатор ЦПИД 1 и определяет, присутствует ли гипервизор, проверив бит 31 регистрации ECX.
- Гость считывает конечные 0x40000000 ЦПID, чтобы определить максимальную конечную 0x40000001 ЦП ЦП (возвращенную в регистре EAX) и 0x40000001 ЦПID, чтобы определить сигнатуру интерфейса (возвращенную в регистре EAX). Он проверяет, что максимальное конечное значение по крайней мере 0x40000005 и что подпись интерфейса равна "Hv#1". Эта подпись подразумевает, что
HV_X64_MSR_GUEST_OS_IDHV_X64_MSR_HYPERCALLиHV_X64_MSR_VP_INDEXреализуется. - Гость записывает удостоверение ОС в MSR
HV_X64_MSR_GUEST_OS_ID, если этот регистр равен нулю. - Гость считывает MSR Hypercall (
HV_X64_MSR_HYPERCALL). - Гость проверяет бит "Включить страницу Hypercall". Если он задан, интерфейс уже активен, а шаги 6 и 7 должны быть пропущены.
- Гость находит страницу в пространстве GPA, предпочтительно ту, которая не занята ОЗУ, MMIO и т. д. Если страница занята, гость должен избегать использования базовой страницы для других целей.
- Гость записывает новое значение в hypercall MSR (
HV_X64_MSR_HYPERCALL), включающее GPA на шаге 6, и задает бит "Включить страницу Hypercall", чтобы включить интерфейс. - Гость создает сопоставление исполняемого VA со страницей GPA гиперкваля.
- Гость обращается к конечным 0x40000003 ЦПID, чтобы определить, какие средства гипервизора доступны для него. После установки интерфейса гость может инициировать гиперкел. Для этого он заполняет регистры для протокола гиперклиона и выдает вызов началу страницы гиперклиона. Гость должен предположить, что страница гиперкаллов выполняет эквивалент близкого возврата (0xC3), чтобы вернуться вызывающему объекту. Таким образом, гиперкел должен вызываться с допустимым стеком.
Установка интерфейса Hypercall (ARM64)
Так как ARM64 изначально поддерживает инструкцию HVC, гипервизор не требует дополнительной конфигурации для включения гипермасштабирования.
Расширенный интерфейс Hypercall
Гипермасштабирование с кодами вызовов выше 0x8000 называется расширенными гиперкалями. Расширенные гиперкаллы используют то же соглашение о вызовах, что и обычные гиперкалили, и отображаются идентичными с точки зрения гостевой виртуальной машины. Расширенные гиперкалии обрабатываются по-разному в Hyper-V гипервизора.
Расширенные возможности гиперкела можно запрашивать с помощью HvExtCallQueryCapabilities.