Поделиться через


Интерфейс Hypercall

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

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

При необходимости для подмножества гипермасштабирования можно использовать третье соглашение о вызовах гиперконференций, где входной блок параметра составляет до 112 байт. При использовании этого соглашения о вызовах входные параметры передаются в регистры, включая переменные регистры XMM.

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

Для выходных данных гипервизор может перезаписать области заполнения (но не гарантируется). Если он перезаписывает области заполнения, он будет записывать нули.

Классы Hypercall

Существует два класса гипермасштабирования: simple и rep (сокращение от "repeat"). Простой гиперкалл выполняет одну операцию и имеет набор входных и выходных параметров фиксированного размера. Гиперколл rep действует как ряд простых гипермасштабирования. Помимо набора входных и выходных параметров фиксированного размера, гипермасштабирование rep включает список входных и (или) выходных элементов фиксированного размера.

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

При последующих вызовах гиперкела rep индекс запуска указывает, сколько элементов было завершено ( и в сочетании со значением счетчика rep — сколько элементов осталось). Например, если вызывающий объект указывает число повторений 25, а в течение ограничений времени выполняется только 20 итераций, гиперкел возвращает управление обратно вызывающему виртуальному процессору после обновления индекса запуска rep до 20. При повторном выполнении гиперкала гипервизор возобновится в элементе 20 и завершит остальные 5 элементов.

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

Продолжение hypercall

Гиперкалл можно рассматривать как сложную инструкцию, которая принимает множество циклов. Гипервизор пытается ограничить выполнение гиперколла до 50 м или меньше, прежде чем возвращать управление виртуальному процессору, который вызвал гиперколл. Некоторые операции гиперкалла достаточно сложны, что 50μs гарантии трудно сделать. Поэтому гипервизор использует механизм продолжения гиперкаллов для некоторых гипермасштабируемых гипермасштабирования, включая все формы hypercall rep.

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

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

Атомарность и упорядочение hypercall

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

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

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

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

Гипермасштабирование можно вызывать только из наиболее привилегированного режима гостевого процессора. На 64 platfoms это означает защищенный режим с текущим уровнем привилегий (CPL) нулевого. Хотя код в реальном режиме выполняется с эффективным CPL с нулевым значением, гипермасштабирование не допускается в реальном режиме. Попытка вызова гиперкела в недопустимом режиме процессора создаст исключение #UD (неопределенной операции).

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

Требования к выравниванию

Вызывающие абоненты должны указать 64-разрядный физический адрес гостевого физического адреса (GPA) входных и (или) выходных параметров. Указатели GPA должны быть выровнены по 8 байтам. Если гиперклаг не включает входные или выходные параметры, гипервизор игнорирует соответствующий указатель GPA.

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

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

Входные данные Hypercall

Вызывающие абоненты указывают гиперкел с помощью 64-разрядного значения, называемого входным значением hypercall. Он имеет следующий формат:

Поле Bits Предоставленные сведения
Код вызова 15-0 Указывает, какой гиперкласк запрашивается
быстрый; 16 Указывает, использует ли гиперклалл соглашение о вызовах на основе регистра: 0 = память, 1 = на основе регистра.
Размер заголовка переменной 26-17 Размер заголовка переменной в QWORDS.
RsvdZ 30-27 Должно быть равно нулю
Вложено 31 Указывает, что гиперкел должен обрабатываться гипервизором L0 в вложенной среде.
Число повторений 43-32 Общее количество повторений (для вызова rep, должно быть равно нулю в противном случае)
RsvdZ 47-44 Должно быть равно нулю
Повторная начальная индекс 59-48 Начальный индекс (для вызова rep должен быть равен нулю в противном случае)
RsvdZ 63-60 Должно быть равно нулю

Для гипермасштабирования rep поле счетчика указывает общее количество повторений. Индекс запуска rep указывает на конкретное повторение относительно начала списка (ноль указывает, что необходимо обработать первый элемент в списке). Таким образом, значение счетчика rep всегда должно быть больше индекса запуска rep.

Зарегистрируйте сопоставление для входных данных hypercall, если флаг Fast равен нулю:

X64 x86 Предоставленные сведения
RCX EDX:EAX Входное значение Hypercall
RDX EBX:ECX Входные параметры GPA
R8 EDI:ESI GPA выходных параметров

Входное значение hypercall передается в регистрах вместе с GPA, указывающим на входные и выходные параметры.

В x64 сопоставления регистров зависят от того, работает ли вызывающий объект в 32-разрядном (x86) или 64-разрядном режиме (x64). Гипервизор определяет режим вызывающего объекта на основе значения EFER. LMA и CS.L. Если оба этих флага заданы, вызывающий объект считается 64-разрядным вызывающим.

Зарегистрируйте сопоставление для входных данных hypercall, если флаг Fast имеет одно значение:

X64 x86 Предоставленные сведения
RCX EDX:EAX Входное значение Hypercall
RDX EBX:ECX Входной параметр
R8 EDI:ESI Выходной параметр

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

Входные заголовки hypercall с переменным размером

Большинство входных заголовков hypercall имеют фиксированный размер. Таким образом, объем данных заголовка, передаваемых от гостя в низкоуровневую оболочку, неявно определяется кодом гиперколла и не требуется указывать отдельно. Однако для некоторых гипермасштабирования требуется переменный объем данных заголовка. Эти гипермасштабирование обычно имеют заголовок с фиксированным размером и дополнительные входные данные заголовка, которые имеют переменный размер.

Заголовок переменной размера аналогичен фиксированному входу гиперколла (выровнен по 8 байтам и размеру до кратного 8 байт). Вызывающий объект должен указать объем данных, которые он предоставляет в качестве входных заголовков. Этот размер предоставляется как часть входного значения гиперкелла (см. раздел "Размер заголовка переменной" в таблице выше).

Так как фиксированный размер заголовка неявный, а не общий размер заголовка, в элементах управления входными данными предоставляется только переменная часть:

Variable Header Bytes = {Total Header Bytes - sizeof(Fixed Header)} rounded up to nearest multiple of 8

Variable HeaderSize = Variable Header Bytes / 8

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

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

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

Быстрый ввод Hypercall XMM

На платформах x64 гипервизор поддерживает использование гипермасштабирования XMM, что позволяет некоторым гипермасштабированиям воспользоваться преимуществами улучшенной производительности интерфейса быстрого гиперколла, даже если для них требуется более двух входных параметров. Интерфейс гиперколла XMM использует шесть регистров XMM, чтобы разрешить вызывающему объекту передавать блок входных параметров размером до 112 байт.

Доступность интерфейса быстрого гиперколла XMM указывается через конечный лист ЦПID гипервизора (0x40000003):

  • Бит 4. Доступна поддержка передачи входных данных гиперколла через регистры XMM.

Обратите внимание, что существует отдельный флаг, указывающий на поддержку быстрых выходных данных XMM. Любая попытка использовать этот интерфейс, если гипервизор не указывает на доступность, приведет к сбою #UD.

Сопоставление регистров (только входные данные)

X64 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 байт, все дополнительные байты в регистрах игнорируются.

Выходные данные Hypercall

Все гипермасштабирование возвращает 64-разрядное значение, называемое значением результата гиперклиа. Он имеет следующий формат:

Поле Bits Комментировать
Результат 15-0 HV_STATUS код, указывающий на успех или сбой
Rsvd 31-16 Вызывающие абоненты должны игнорировать значение в этих битах
Завершенные reps 43-32 Число успешно завершенных повторений
RsvdZ 63-40 Вызывающие абоненты должны игнорировать значение в этих битах

Для гипермасштабирования reps заполненное поле — общее количество завершенных повторений, а не относительно индекса запуска rep. Например, если вызывающий объект указал индекс запуска rep 5, а число повторений равное 10, то после успешного завершения будет указано значение 10.

Значение результата гиперкела передается обратно в регистрах. Сопоставление регистров зависит от того, работает ли вызывающий объект в 32-разрядном (x86) или 64-разрядном (x64) режиме (см. выше). Сопоставление регистров для выходных данных hypercall выглядит следующим образом:

X64 x86 Предоставленные сведения
RAX EDX:EAX Значение результата Hypercall

Выходные данные hypercall XMM Fast

Аналогично тому, как гипервизор поддерживает быстрые входные данные XMM, одни и те же регистры можно совместно использовать для возврата выходных данных. Это поддерживается только на платформах x64.

Возможность возвращать выходные данные через регистры XMM указывается с помощью конечной параметров ЦПID гипервизора (0x40000003):

  • Бит 15: доступна поддержка возврата выходных данных гиперкликса через регистры XMM.

Обратите внимание, что существует отдельный флаг, указывающий на поддержку быстрых входных данных XMM. Любая попытка использовать этот интерфейс, если низкоуровневая оболочка не указывает на доступность, приведет к ошибке #UD.

Сопоставление регистров (входные и выходные данные)

Регистры, которые не используются для передачи входных параметров, можно использовать для возврата выходных данных. Другими словами, если блок входных параметров меньше 112 байт (округляется до ближайшего 16 байтов, выровненного фрагмента), остальные регистры возвращают выходные данные гиперкела.

x64 Предоставленные сведения
RDX Блок ввода или вывода
R8 Блок ввода или вывода
XMM0 Блок ввода или вывода
XMM1 Блок ввода или вывода
XMM2 Блок ввода или вывода
XMM3 Блок ввода или вывода
XMM4 Блок ввода или вывода
XMM5 Блок ввода или вывода

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

Переменные регистры

Гипермасштабирование изменяет только указанные значения регистра в следующих условиях:

  1. RAX (x64) и EDX:EAX (x86) всегда перезаписываются с помощью значения результата гиперкликса и выходных параметров, если таковые имеются.
  2. Гипермасштабирование rep изменит RCX (x64) и EDX:EAX (x86) с новым индексом запуска rep.
  3. HvCallSetVpRegisters может изменять любые регистры, поддерживаемые этим гиперклалом.
  4. RDX, R8 и XMM0 по XMM5, если они используются для быстрого ввода гиперклакса, остаются неизменимыми. Однако регистры, используемые для быстрого вывода гиперкликса, можно изменять, включая RDX, R8 и XMM0 по XMM5. Hyper-V изменит эти регистры только для быстрых выходных данных hypercall, что ограничено x64.

Ограничения 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) перед вызовом гипермасштабирования. Этот MSR является секционированием и является общим для всех виртуальных процессоров.

Изначально это значение регистра равно нулю. Ненулевое значение должно быть записано в MSR идентификатора гостевой ОС перед включением кодовой страницы гиперклала (см. раздел "Установка интерфейса Hypercall"). Если этот регистр впоследствии будет обнулен, кодовая страница гиперкалл будет отключена.

#define HV_X64_MSR_GUEST_OS_ID 0x40000000

Удостоверение гостевой ОС для собственных операционных систем

Ниже приведена рекомендуемая кодировка для этого MSR. Некоторые поля могут не применяться для некоторых гостевых ОС.

Bits Поле Описание
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).

Vendor Значение
пиринг Майкрософт. 0x0001
HPE 0x0002
LANCOM 0x0200

MsR для удостоверения гостевой ОС для операционных систем с открытым исходным кодом

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

Bits Поле Описание
15:0 Номер сборки Дополнительные сведения
47:16 Версия Сведения о версии вышестоящего ядра.
55:48 Идентификатор ОС Дополнительные сведения о поставщике
62:56 Тип ОС Тип ОС (например, Linux, FreeBSD и т. д.). См. список известных типов ОС ниже
63 Открытый исходный код Значение 1 указывает открытый код ОС.

Значения типа ОС выделяются корпорацией Майкрософт. Чтобы запросить новый тип ОС, сообщите о проблеме в репозитории документации по виртуализации GitHub (https://aka.ms/VirtualizationDocumentationIssuesTLFS).

Тип ОС Значение
Linux 0x1
FreeBSD 0x2
Xen 0x3
Illumos 0x4

Установка интерфейса Hypercall

Гипермасштабирование вызывается с помощью специального кода операции. Так как этот код операций отличается от реализаций виртуализации, гипервизор необходимо абстрагировать это различие. Это делается через специальную страницу гиперкалл. Эта страница предоставляется гипервизором и отображается в пространстве GPA гостя. Гость требуется для указания расположения страницы путем программирования MSR guest Hypercall.

#define HV_X64_MSR_HYPERCALL 0x40000001
Bits Описание Атрибуты
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). После включения страницы hypercall вызов гиперклаля просто включает вызов к началу страницы.

Ниже приведен подробный список шагов, связанных с установкой страницы гиперколла.

  1. Гость считывает cpuID leaf 1 и определяет, присутствует ли гипервизор, проверив бит 31 регистра ECX.
  2. Гость считывает конечный 0x40000000 ЦПП ЦП, чтобы определить максимальный конечный ЦПID гипервизора (возвращенный в регистре EAX) и конечный 0x40000001 CPUID, чтобы определить сигнатуру интерфейса (возвращенную в регистре EAX). Он проверяет, что максимальное конечное значение не менее 0x40000005 и что сигнатура интерфейса равна "Hv#1". Эта сигнатура подразумевает, HV_X64_MSR_HYPERCALL что HV_X64_MSR_GUEST_OS_IDи HV_X64_MSR_VP_INDEX реализованы.
  3. Гость записывает свое удостоверение ОС в MSR HV_X64_MSR_GUEST_OS_ID , если этот регистр равен нулю.
  4. Гость считывает MSR Hypercall (HV_X64_MSR_HYPERCALL).
  5. Гость проверяет бит "Включить страницу Hypercall". Если он задан, интерфейс уже активен, а шаги 6 и 7 должны быть пропущены.
  6. Гость находит страницу в пространстве GPA, предпочтительно ту, которая не занята ОЗУ, MMIO и т. д. Если страница занята, гость не должен использовать базовую страницу для других целей.
  7. Гость записывает новое значение в hypercall MSR (HV_X64_MSR_HYPERCALL), который включает GPA из шага 6 и задает бит "Включить страницу Hypercall", чтобы включить интерфейс.
  8. Гость создает сопоставление исполняемого va с GPA-страницей hypercall.
  9. Гость обращается к конечным 0x40000003 CPUID, чтобы определить, какие средства гипервизора доступны для него. После установки интерфейса гость может инициировать гиперколл. Для этого он заполняет регистры по протоколу гиперколла и выдает вызов в начало страницы гиперколла. Гость должен предположить, что страница гиперколла выполняет эквивалент близкого возврата (0xC3), чтобы вернуться вызывающей объекту. Таким образом, гиперколл должен вызываться с допустимым стеком.

Расширенный интерфейс Hypercall

Гипермасштабирование с кодами вызовов выше 0x8000 называются расширенными гипермасштабированием. Расширенные гипермасштабирования используют то же соглашение о вызовах, что и обычные гипермасштабирования, и отображаются идентичными с точки зрения гостевой виртуальной машины. Расширенные гипермасштабирования обрабатываются по-разному в гипервизоре Hyper-V.

Расширенные возможности hypercall можно запрашивать с помощью HvExtCallQueryCapabilities.