Архитектура 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 и более поздние версии). В одном из этих режимов, обычно известном как режим без 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 готов к работе и обрабатывает таблицы страниц второго этапа.

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

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

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

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

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

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

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

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

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

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

Защита прямого доступа к памяти (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. Таким образом, гипервизор устанавливает ограничения доступа в таблице страниц второго этапа хоста, предотвращая повторный доступ к страницам, обеспечивая конфиденциальность гостевой системы.

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

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

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

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

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

Обработка MMIO

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Эта архитектура основана на программном обеспечении безопасного мира, реализующем модель доступа к памяти. Это гарантирует, что доверенные приложения и любое другое программное обеспечение, работающее в безопасном мире, смогут получить доступ к памяти только в том случае, если оно либо принадлежит исключительно безопасному миру, либо явно предоставлено ему с помощью FF-A. В системе с S-EL2 реализация модели доступа к памяти должна осуществляться ядром диспетчера защищенных разделов (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) и устройств.
  • Запросы ioctl vCPU и установка атрибутов, управляющих работой одного виртуального ЦП.
  • Запросы ioctl устройств и установка атрибутов, управляющих работой одного виртуального устройства.

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

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 хоста. Поток вызывает ioctl-вызов KVM_RUN на виртуальном физическом диске vCPU, что приводит к переключению гипервизора в контекст гостевого 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). Остальные регистры зарезервированы и являются частью ABI hypervisor-pvmfw.

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

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