Архитектура AVF

Android предоставляет эталонную реализацию всех компонентов, необходимых для внедрения Android Virtualization Framework. В настоящее время эта реализация ограничена ARM64. На этой странице объясняется архитектура фреймворка.

Фон

Архитектура Arm допускает до четырех уровней исключений, причем уровень исключений 0 (EL0) является наименее привилегированным, а уровень исключений 3 (EL3) — наиболее. Большая часть кодовой базы Android (все компоненты пользовательского пространства) работает на уровне EL0. Остальная часть того, что обычно называют «Android», — это ядро ​​Linux, которое работает на уровне EL1.

Уровень EL2 позволяет внедрить гипервизор, который позволяет изолировать память и устройства в отдельные виртуальные машины (pVM) на уровнях EL1/EL0 с гарантией высокой конфиденциальности и целостности.

Гипервизор

Защищенная виртуальная машина на базе ядра (pKVM) создана на основе гипервизора Linux KVM , который был расширен за счет возможности ограничивать доступ к полезным нагрузкам, запущенным на гостевых виртуальных машинах, помеченных как «защищенные» во время создания.

KVM/arm64 поддерживает различные режимы выполнения в зависимости от доступности определенных функций ЦП, а именно Virtualization Host Extensions (VHE) (ARMv8.1 и более поздние версии). В одном из этих режимов, обычно известном как режим non-VHE, код гипервизора отделяется от образа ядра во время загрузки и устанавливается на EL2, тогда как само ядро ​​работает на EL1. Хотя компонент EL2 KVM является частью кодовой базы Linux, он представляет собой небольшой компонент, отвечающий за переключение между несколькими EL1. Компонент гипервизора скомпилирован с Linux, но находится в отдельном, выделенном разделе памяти образа vmlinux . pKVM использует эту конструкцию, расширяя код гипервизора новыми функциями, позволяющими ему накладывать ограничения на ядро ​​хоста Android и пользовательское пространство, а также ограничивать доступ хоста к гостевой памяти и гипервизору.

модули поставщика pKVM

Модуль поставщика pKVM — это аппаратно-зависимый модуль, содержащий специфичные для устройства функции, такие как драйверы блока управления памятью ввода-вывода (IOMMU). Эти модули позволяют вам переносить функции безопасности, требующие доступа уровня исключений 2 (EL2) к pKVM.

Чтобы узнать, как реализовать и загрузить модуль поставщика pKVM, обратитесь к разделу Реализация модуля поставщика pKVM .

Процедура загрузки

На следующем рисунке изображена процедура загрузки pKVM:

Процедура загрузки pKVM

Рисунок 1. Процедура загрузки pKVM

  1. Загрузчик входит в общее ядро ​​на уровне EL2.
  2. Универсальное ядро ​​обнаруживает, что оно работает на уровне EL2, и лишает себя привилегий до уровня EL1, в то время как pKVM и его модули продолжают работать на уровне EL2. Кроме того, в это время загружаются модули поставщиков pKVM.
  3. Универсальное ядро ​​продолжает загружаться нормально, загружая все необходимые драйверы устройств, пока не достигнет пользовательского пространства. На этом этапе pKVM находится на месте и обрабатывает таблицы страниц этапа 2.

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

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

Более того, внедрение GKI в экосистему Android автоматически позволяет развертывать гипервизор pKVM на устройствах Android в том же двоичном файле, что и ядро.

Защита доступа к памяти ЦП

Архитектура Arm определяет блок управления памятью (MMU), разделенный на два независимых этапа, каждый из которых может использоваться для реализации трансляции адресов и управления доступом к различным частям памяти. MMU этапа 1 управляется EL1 и допускает первый уровень трансляции адресов. MMU этапа 1 используется Linux для управления виртуальным адресным пространством, предоставляемым каждому процессу пользовательского пространства, и его собственным виртуальным адресным пространством.

MMU этапа 2 управляется EL2 и позволяет применять вторую трансляцию адреса к выходному адресу MMU этапа 1, что приводит к физическому адресу (PA). Трансляция этапа 2 может использоваться гипервизорами для управления и трансляции доступа к памяти со всех гостевых виртуальных машин. Как показано на рисунке 2, когда включены обе стадии трансляции, выходной адрес этапа 1 называется промежуточным физическим адресом (IPA). Примечание: виртуальный адрес (VA) транслируется в IPA, а затем в PA.

Защита доступа к памяти ЦП

Рисунок 2. Защита доступа к памяти ЦП

Исторически KVM работает с включенной трансляцией стадии 2 во время работы гостей и с отключенной стадией 2 во время работы ядра Linux хоста. Эта архитектура позволяет доступу к памяти из MMU стадии 1 хоста проходить через MMU стадии 2, тем самым обеспечивая неограниченный доступ хоста к страницам гостевой памяти. С другой стороны, pKVM обеспечивает защиту стадии 2 даже в контексте хоста и возлагает ответственность за защиту страниц гостевой памяти на гипервизор вместо хоста.

KVM полностью использует трансляцию адресов на этапе 2 для реализации сложных отображений IPA/PA для гостей, что создает иллюзию непрерывной памяти для гостей, несмотря на физическую фрагментацию. Однако использование MMU этапа 2 для хоста ограничено только контролем доступа. Этап 2 хоста отображает идентификацию, гарантируя, что непрерывная память в пространстве IPA хоста является непрерывной в пространстве PA. Эта архитектура позволяет использовать большие отображения в таблице страниц и, следовательно, снижает нагрузку на буфер поиска трансляции (TLB). Поскольку отображение идентификационной информации может быть проиндексировано PA, этап 2 хоста также используется для отслеживания владельца страницы непосредственно в таблице страниц.

Защита прямого доступа к памяти (DMA)

Как было описано ранее, отмена отображения гостевых страниц из хоста Linux в таблицах страниц ЦП является необходимым, но недостаточным шагом для защиты гостевой памяти. pKVM также необходимо защищать от доступа к памяти, осуществляемого устройствами с поддержкой DMA под управлением ядра хоста, и от возможности атаки DMA, инициированной вредоносным хостом. Чтобы предотвратить доступ такого устройства к гостевой памяти, pKVM требует аппаратного обеспечения блока управления памятью ввода-вывода (IOMMU) для каждого устройства с поддержкой DMA в системе, как показано на рисунке 3.

Защита доступа к памяти DMA

Рисунок 3. Защита доступа к памяти DMA

Как минимум, оборудование IOMMU обеспечивает средства предоставления и отзыва доступа на чтение/запись для устройства к физической памяти на уровне детализации страницы. Однако это оборудование IOMMU ограничивает использование устройств в pVM, поскольку они предполагают этап 2 с сопоставлением идентификаторов.

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

Кроме того, сокращение объема кода, специфичного для SoC, на уровне EL2 является ключевой стратегией для сокращения общей доверенной вычислительной базы (TCB) pKVM и противоречит включению драйверов IOMMU в гипервизор. Чтобы смягчить эту проблему, хост на уровне EL1 отвечает за вспомогательные задачи управления IOMMU, такие как управление питанием, инициализация и, при необходимости, обработка прерываний.

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

Стандартным и хорошо поддерживаемым IOMMU для устройств Arm, который делает возможным как изоляцию, так и прямое назначение, является архитектура Arm System Memory Management Unit (SMMU). Эта архитектура является рекомендуемым эталонным решением.

Право собственности на память

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

Связь между хостом и гостями становится возможной благодаря контролируемому разделению памяти между ними. Гостям разрешено делиться некоторыми своими страницами с хостом с помощью гипервызова, который инструктирует гипервизор переназначить эти страницы в таблице страниц второго этапа хоста. Аналогично, связь хоста с TrustZone становится возможной благодаря операциям по разделению памяти и/или предоставлению взаймы, все из которых тщательно отслеживаются и контролируются pKVM с использованием спецификации Firmware Framework for Arm (FF-A) .

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

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

Хост должен гарантировать, что он не пытается получить доступ к страницам, которые были сделаны недоступными гипервизором. Незаконный доступ к хосту приводит к тому, что гипервизор вводит в хост синхронное исключение, что может привести либо к получению ответственной задачей пользовательского пространства сигнала SEGV, либо к сбою ядра хоста. Чтобы предотвратить случайный доступ, страницы, предоставленные гостям, делаются непригодными для подкачки или слияния ядром хоста.

Обработка прерываний и таймеры

Прерывания являются неотъемлемой частью способа взаимодействия гостя с устройствами и для связи между ЦП, где межпроцессорные прерывания (IPI) являются основным механизмом связи. Модель KVM заключается в том, чтобы делегировать все управление виртуальными прерываниями хосту в EL1, который для этой цели ведет себя как недоверенная часть гипервизора.

pKVM предлагает полную эмуляцию Generic Interrupt Controller версии 3 (GICv3) на основе существующего кода KVM. Таймер и IPI обрабатываются как часть этого ненадежного кода эмуляции.

Поддержка GICv3

Интерфейс между EL1 и EL2 должен гарантировать, что полное состояние прерывания видимо хосту EL1, включая копии регистров гипервизора, связанных с прерываниями. Такая видимость обычно достигается с помощью разделяемых областей памяти, по одной на виртуальный ЦП (vCPU).

Код поддержки системного регистра времени выполнения можно упростить, чтобы поддерживать только регистр прерывания Software Generated Interrupt Register (SGIR) и Deactivate Interrupt Register (DIR). Архитектура предписывает, чтобы эти регистры всегда выполняли прерывание EL2, в то время как другие прерывания до сих пор были полезны только для смягчения ошибок. Все остальное обрабатывается аппаратно.

На стороне MMIO все эмулируется на EL1, повторно используя всю текущую инфраструктуру в KVM. Наконец, Wait for Interrupt (WFI) всегда ретранслируется на EL1, поскольку это один из основных примитивов планирования, используемых KVM.

Поддержка таймера

Значение компаратора для виртуального таймера должно быть выставлено EL1 на каждом прерывании WFI, чтобы EL1 мог вводить прерывания таймера, пока vCPU заблокирован. Физический таймер полностью эмулируется, и все прерывания ретранслируются на EL1.

Обработка MMIO

Для связи с монитором виртуальной машины (VMM) и выполнения эмуляции GIC ловушки MMIO должны быть переданы обратно на хост в EL1 для дальнейшей обработки. Для pKVM требуется следующее:

  • IPA и размер доступа
  • Данные в случае записи
  • Порядок байтов ЦП в точке перехвата

Кроме того, ловушки с регистром общего назначения (GPR) в качестве источника/назначения ретранслируются с использованием абстрактного псевдорегистра передачи.

Гостевые интерфейсы

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

Общие гипервызовы

  • PSCI предоставляет гостю стандартный механизм управления жизненным циклом его виртуальных ЦП, включая включение, выключение и выключение системы.
  • TRNG предоставляет стандартный механизм для гостя, чтобы запросить энтропию из pKVM, который передает вызов EL3. Этот механизм особенно полезен, когда хосту нельзя доверять виртуализацию аппаратного генератора случайных чисел (RNG).

гипервызовы pKVM

  • Разделение памяти с хостом. Вся гостевая память изначально недоступна хосту, но доступ хоста необходим для связи с разделяемой памятью и для паравиртуализированных устройств, которые полагаются на разделяемые буферы. Гипервызовы для совместного использования и отмены совместного использования страниц с хостом позволяют гостю решать, какие именно части памяти будут доступны для остальной части Android без необходимости рукопожатия.
  • Передача памяти хосту. Вся гостевая память обычно принадлежит гостю, пока не будет уничтожена. Это состояние может быть недостаточным для долгоживущих виртуальных машин с требованиями к памяти, которые меняются со временем. Гипервызов relinquish позволяет гостю явно передать право собственности на страницы обратно хосту, не требуя завершения гостя.
  • Перехват доступа к памяти на хосте. Традиционно, если гость KVM обращается к адресу, который не соответствует допустимой области памяти, поток vCPU выходит на хост, и доступ обычно используется для MMIO и эмулируется VMM в пользовательском пространстве. Чтобы облегчить эту обработку, pKVM должен объявить подробности об инструкции, вызвавшей ошибку, такие как ее адрес, параметры регистра и потенциально их содержимое, обратно на хост, что может непреднамеренно раскрыть конфиденциальные данные от защищенного гостя, если ловушка не была ожидаемой. pKVM решает эту проблему, рассматривая эти ошибки как фатальные, если только гость ранее не выполнил гипервызов для определения диапазона IPA, вызвавшего ошибку, как того, для которого разрешен доступ с обратным перехватом на хосте. Это решение называется защитой MMIO .

Виртуальное устройство ввода-вывода (virtio)

Virtio — популярный, переносимый и зрелый стандарт для реализации и взаимодействия с паравиртуализированными устройствами. Большинство устройств, подвергающихся воздействию защищенных гостей, реализованы с использованием virtio. Virtio также лежит в основе реализации vsock, используемой для связи между защищенным гостем и остальной частью Android.

Устройства Virtio обычно реализуются в пользовательском пространстве хоста с помощью VMM, который перехватывает захваченные доступы к памяти от гостя к интерфейсу MMIO устройства virtio и эмулирует ожидаемое поведение. Доступ MMIO относительно дорог, поскольку каждый доступ к устройству требует кругового обхода к VMM и обратно, поэтому большая часть фактической передачи данных между устройством и гостем происходит с использованием набора virtqueues в памяти. Ключевое предположение virtio заключается в том, что хост может получать доступ к гостевой памяти произвольно. Это предположение очевидно в конструкции virtqueue, которая может содержать указатели на буферы в госте, к которым эмуляция устройства должна иметь прямой доступ.

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

Виртуальное устройство

Рисунок 4. Устройство Virtio

Взаимодействие с TrustZone

Хотя гости не могут напрямую взаимодействовать с TrustZone, хост все равно должен иметь возможность отправлять вызовы SMC в защищенный мир. Эти вызовы могут указывать физически адресуемые буферы памяти, которые недоступны хосту. Поскольку защищенное программное обеспечение, как правило, не знает о доступности буфера, вредоносный хост может использовать этот буфер для выполнения атаки с перепутанным заместителем (аналогично атаке DMA). Чтобы предотвратить такие атаки, pKVM перехватывает все вызовы SMC хоста в EL2 и действует как прокси между хостом и защищенным монитором в EL3.

Вызовы PSCI с хоста перенаправляются в прошивку EL3 с минимальными изменениями. В частности, точка входа для ЦП, входящего в режим онлайн или возобновляющего работу из режима ожидания, переписывается так, чтобы таблица страниц этапа 2 устанавливалась в EL2 перед возвратом хосту в EL1. Во время загрузки эта защита обеспечивается pKVM.

Эта архитектура основана на поддержке PSCI SoC, предпочтительно посредством использования актуальной версии TF-A в качестве прошивки EL3.

Firmware Framework for Arm (FF-A) стандартизирует взаимодействие между нормальным и безопасным мирами, особенно при наличии безопасного гипервизора. Основная часть спецификации определяет механизм совместного использования памяти с безопасным миром, используя как общий формат сообщений, так и четко определенную модель разрешений для базовых страниц. pKVM проксирует сообщения FF-A, чтобы гарантировать, что хост не пытается совместно использовать память с безопасной стороной, для которой у него нет достаточных разрешений.

Эта архитектура опирается на программное обеспечение безопасного мира, которое обеспечивает модель доступа к памяти, чтобы гарантировать, что доверенные приложения и любое другое программное обеспечение, работающее в безопасном мире, могут получить доступ к памяти, только если оно либо принадлежит исключительно безопасному миру, либо было явно предоставлено ему с помощью FF-A. В системе с S-EL2 обеспечение модели доступа к памяти должно осуществляться ядром Secure Partition Manager Core (SPMC), таким как Hafnium , который поддерживает таблицы страниц второго этапа для безопасного мира. В системе без S-EL2 TEE может вместо этого обеспечить модель доступа к памяти через свои таблицы страниц первого этапа.

Если вызов SMC к EL2 не является вызовом PSCI или сообщением, определенным FF-A, необработанные SMC пересылаются в EL3. Предполагается, что (обязательно доверенная) защищенная прошивка может безопасно обрабатывать необработанные SMC, поскольку прошивка понимает меры предосторожности, необходимые для поддержания изоляции pVM.

Монитор виртуальной машины

crosvm — это монитор виртуальных машин (VMM), который запускает виртуальные машины через интерфейс KVM Linux. Уникальность crosvm заключается в его фокусе на безопасности с использованием языка программирования Rust и песочницы вокруг виртуальных устройств для защиты ядра хоста. Подробнее о crosvm см. в его официальной документации здесь .

Файловые дескрипторы и ioctl

KVM предоставляет символьное устройство /dev/kvm в пользовательское пространство с помощью ioctl, которые составляют API KVM. ioctl относятся к следующим категориям:

  • Системные ioctl-вызовы запрашивают и устанавливают глобальные атрибуты, которые влияют на всю подсистему KVM, а также создают pVM.
  • VM ioctl запрашивает и устанавливает атрибуты, которые создают виртуальные ЦП (vCPU) и устройства, а также влияют на всю pVM, например, включая структуру памяти и количество виртуальных ЦП (vCPU) и устройств.
  • vCPU ioctl запрашивает и устанавливает атрибуты, управляющие работой одного виртуального ЦП.
  • Устройства ioctl запрашивают и устанавливают атрибуты, управляющие работой одного виртуального устройства.

Каждый процесс crosvm запускает ровно один экземпляр виртуальной машины. Этот процесс использует системный ioctl KVM_CREATE_VM для создания файлового дескриптора VM, который может использоваться для выдачи ioctl pVM. Ioctl KVM_CREATE_VCPU или KVM_CREATE_DEVICE на VM FD создает vCPU/устройство и возвращает файловый дескриптор, указывающий на новый ресурс. ioctl на vCPU или устройстве FD можно использовать для управления устройством, которое было создано с помощью ioctl на VM FD. Для vCPU это включает важную задачу запуска гостевого кода.

Внутри себя crosvm регистрирует файловые дескрипторы виртуальной машины в ядре с помощью интерфейса epoll , запускаемого по фронту. Затем ядро ​​уведомляет crosvm всякий раз, когда в каком-либо из файловых дескрипторов ожидается новое событие.

pKVM добавляет новую возможность KVM_CAP_ARM_PROTECTED_VM , которую можно использовать для получения информации о среде pVM и настройки защищенного режима для виртуальной машины. crosvm использует ее во время создания pVM, если передан флаг --protected-vm , для запроса и резервирования соответствующего объема памяти для прошивки pVM, а затем для включения защищенного режима.

Распределение памяти

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

FDT в обычном режиме PHYS_MEMORY_END - 0x200000
Свободное место ...
Рамдиск ALIGN_UP(KERNEL_END, 0x1000000)
Ядро 0x80080000
Загрузчик 0x80200000
FDT в режиме BIOS 0x80000000
База физической памяти 0x80000000
прошивка pVM 0x7FE00000
Память устройства 0x10000 - 0x40000000

Физическая память выделяется с помощью mmap , и память передается виртуальной машине для заполнения ее областей памяти, называемых memslots , с помощью ioctl KVM_SET_USER_MEMORY_REGION . Таким образом, вся гостевая память pVM приписывается экземпляру crosvm, который ею управляет, и может привести к завершению процесса (завершению виртуальной машины), если у хоста заканчивается свободная память. Когда виртуальная машина останавливается, память автоматически очищается гипервизором и возвращается ядру хоста.

В обычном KVM VMM сохраняет доступ ко всей гостевой памяти. С pKVM гостевая память не отображается из физического адресного пространства хоста, когда она передается гостю. Единственным исключением является память, явно предоставленная гостем обратно, например, для устройств virtio.

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

Планирование

Каждый виртуальный ЦП представлен потоком POSIX и запланирован планировщиком Linux хоста. Поток вызывает KVM_RUN ioctl на vCPU FD, в результате чего гипервизор переключается на гостевой контекст vCPU. Планировщик хоста учитывает время, проведенное в гостевом контексте, как время, использованное соответствующим потоком vCPU. KVM_RUN возвращается, когда есть событие, которое должно быть обработано VMM, например, ввод-вывод, конец прерывания или остановка vCPU. VMM обрабатывает событие и снова вызывает KVM_RUN .

Во время KVM_RUN поток остается вытесняемым планировщиком хоста, за исключением выполнения кода гипервизора EL2, который не является вытесняемым. Сама гостевая pVM не имеет механизма для управления этим поведением.

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

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

crosvm поддерживает ряд устройств, включая следующие:

  • virtio-blk для составных образов дисков, только для чтения или для чтения и записи
  • vhost-vsock для связи с хостом
  • virtio-pci как транспорт virtio
  • pl030 часы реального времени (RTC)
  • 16550a UART для последовательной связи

прошивка pVM

Прошивка pVM (pvmfw) — это первый код, выполняемый pVM, аналогичный загрузочному ПЗУ физического устройства. Основная цель pvmfw — инициализация безопасной загрузки и получение уникального секрета pVM. pvmfw не ограничена использованием с какой-либо конкретной ОС, например Microdroid , при условии, что эта ОС поддерживается Crosvm и надлежащим образом подписана.

Двоичный файл pvmfw хранится в одноименном разделе флэш-памяти и обновляется с помощью OTA .

Загрузка устройства

В процедуру загрузки устройства с поддержкой pKVM добавляется следующая последовательность шагов:

  1. Загрузчик Android (ABL) загружает pvmfw из своего раздела в память и проверяет образ.
  2. ABL получает секреты своего механизма составления идентификаторов устройств (DICE) (составные идентификаторы устройств (CDI) и цепочку сертификатов DICE) из Root of Trust.
  3. ABL извлекает необходимые CDI для pvmfw и добавляет их к двоичному файлу pvmfw.
  4. ABL добавляет узел зарезервированной области памяти linux,pkvm-guest-firmware-memory в DT, описывая расположение и размер двоичного файла pvmfw, а также секреты, полученные на предыдущем этапе.
  5. ABL передает управление Linux, и Linux инициализирует pKVM.
  6. pKVM отменяет сопоставление области памяти pvmfw с таблицами страниц второго этапа хоста и защищает ее от хоста (и гостей) на протяжении всего времени работы устройства.

После загрузки устройства Microdroid загружается в соответствии с шагами, описанными в разделе «Последовательность загрузки» документа Microdroid .

загрузка pVM

При создании pVM crosvm (или другой VMM) должен создать достаточно большой memslot для заполнения его образом pvmfw гипервизором. VMM также ограничен в списке регистров, начальное значение которых он может установить (x0-x14 для первичного vCPU, ни одного для вторичных vCPU). Остальные регистры зарезервированы и являются частью hypervisor-pvmfw ABI.

При запуске pVM гипервизор сначала передает управление основным vCPU pvmfw. Прошивка ожидает, что crosvm загрузит подписанное AVB ядро, которое может быть загрузчиком или любым другим образом, и неподписанный FDT в память по известным смещениям. pvmfw проверяет подпись AVB и, в случае успеха, генерирует доверенное дерево устройств из полученного FDT, стирает свои секреты из памяти и переходит к точке входа полезной нагрузки. Если один из шагов проверки не пройден, прошивка выдает гипервызов PSCI SYSTEM_RESET .

Между загрузками информация об экземпляре pVM хранится в разделе (устройство virtio-blk) и шифруется с помощью секрета pvmfw, чтобы гарантировать, что после перезагрузки секрет будет предоставлен правильному экземпляру.