Kiến trúc AVF

Android cung cấp cách triển khai tham chiếu của tất cả các thành phần cần thiết để triển khai Khung ảo hóa Android. Hiện tại việc triển khai này được giới hạn ở ARM64. Trang này giải thích kiến ​​trúc khung.

Lý lịch

Kiến trúc Arm cho phép tối đa bốn cấp độ ngoại lệ, trong đó cấp độ ngoại lệ 0 (EL0) là ít đặc quyền nhất và cấp độ ngoại lệ 3 (EL3) là nhiều nhất. Phần lớn nhất của cơ sở mã Android (tất cả các thành phần không gian người dùng) chạy ở EL0. Phần còn lại của cái thường được gọi là "Android" là nhân Linux, chạy ở EL1.

Lớp EL2 cho phép giới thiệu một trình ảo hóa cho phép cách ly bộ nhớ và thiết bị thành các pVM riêng lẻ tại EL1/EL0, với sự đảm bảo tính toàn vẹn và bảo mật mạnh mẽ.

Trình giám sát ảo

Máy ảo dựa trên nhân được bảo vệ (pKVM) được xây dựng dựa trên bộ ảo hóa KVM Linux , đã được mở rộng với khả năng hạn chế quyền truy cập vào các tải trọng đang chạy trong các máy ảo khách được đánh dấu là 'được bảo vệ' tại thời điểm tạo.

KVM/arm64 hỗ trợ các chế độ thực thi khác nhau tùy thuộc vào tính khả dụng của một số tính năng CPU nhất định, cụ thể là Tiện ích mở rộng máy chủ ảo hóa (VHE) (ARMv8.1 trở lên). Ở một trong những chế độ đó, thường được gọi là chế độ không phải VHE, mã bộ điều khiển ảo hóa được tách ra khỏi hình ảnh hạt nhân trong khi khởi động và được cài đặt tại EL2, trong khi chính hạt nhân chạy ở EL1. Mặc dù là một phần của cơ sở mã Linux, thành phần EL2 của KVM là một thành phần nhỏ chịu trách nhiệm chuyển đổi giữa nhiều EL1 và hoàn toàn được điều khiển bởi nhân của máy chủ. Thành phần hypervisor được biên dịch bằng Linux, nhưng nằm trong một phần bộ nhớ chuyên dụng, riêng biệt của hình ảnh vmlinux . pKVM tận dụng thiết kế này bằng cách mở rộng mã bộ ảo hóa với các tính năng mới cho phép nó đặt các hạn chế đối với nhân máy chủ Android và không gian người dùng, đồng thời hạn chế quyền truy cập của máy chủ vào bộ nhớ khách và bộ ảo hóa.

mô-đun nhà cung cấp pKVM

Mô-đun nhà cung cấp pKVM là mô-đun dành riêng cho phần cứng chứa chức năng dành riêng cho thiết bị, chẳng hạn như trình điều khiển đơn vị quản lý bộ nhớ đầu vào-đầu ra (IOMMU). Các mô-đun này cho phép bạn chuyển các tính năng bảo mật yêu cầu quyền truy cập ngoại lệ cấp 2 (EL2) vào pKVM.

Để tìm hiểu cách triển khai và tải mô-đun nhà cung cấp pKVM, hãy tham khảo Triển khai mô-đun nhà cung cấp pKVM .

Thủ tục khởi động

Hình dưới đây mô tả quy trình khởi động pKVM:

thủ tục khởi động pKVM

Hình 1. Quy trình khởi động pKVM

  1. Bộ nạp khởi động vào kernel chung tại EL2.
  2. Nhân chung phát hiện rằng nó đang chạy ở EL2 và tự tước quyền thành EL1 trong khi pKVM và các mô-đun của nó tiếp tục chạy ở EL2. Ngoài ra, các mô-đun nhà cung cấp pKVM được tải vào thời điểm này.
  3. Nhân chung tiến hành khởi động bình thường, tải tất cả các trình điều khiển thiết bị cần thiết cho đến khi đạt đến không gian người dùng. Tại thời điểm này, pKVM đã sẵn sàng và xử lý các bảng trang giai đoạn 2.

Quy trình khởi động tin tưởng bộ nạp khởi động sẽ duy trì tính toàn vẹn của hình ảnh hạt nhân chỉ trong quá trình khởi động sớm. Khi hạt nhân bị mất đặc quyền, nó không còn được nhà giám sát ảo coi là đáng tin cậy nữa, khi đó bộ ảo hóa sẽ chịu trách nhiệm tự bảo vệ ngay cả khi hạt nhân bị xâm phạm.

Việc có nhân Android và trình ảo hóa trong cùng một hình ảnh nhị phân cho phép giao diện liên lạc được liên kết rất chặt chẽ giữa chúng. Sự kết hợp chặt chẽ này đảm bảo cập nhật nguyên tử của hai thành phần, giúp tránh nhu cầu giữ giao diện giữa chúng ổn định và mang lại tính linh hoạt cao mà không ảnh hưởng đến khả năng bảo trì lâu dài. Sự kết hợp chặt chẽ cũng cho phép tối ưu hóa hiệu suất khi cả hai thành phần có thể hợp tác mà không ảnh hưởng đến các đảm bảo bảo mật được cung cấp bởi bộ ảo hóa.

Hơn nữa, việc áp dụng GKI trong hệ sinh thái Android sẽ tự động cho phép bộ ảo hóa pKVM được triển khai trên các thiết bị Android ở cùng hệ nhị phân với kernel.

Bảo vệ truy cập bộ nhớ CPU

Kiến trúc Arm chỉ định việc chia đơn vị quản lý bộ nhớ (MMU) thành hai giai đoạn độc lập, cả hai đều có thể được sử dụng để thực hiện dịch địa chỉ và kiểm soát truy cập vào các phần khác nhau của bộ nhớ. MMU giai đoạn 1 được điều khiển bởi EL1 và cho phép dịch địa chỉ cấp độ đầu tiên. MMU giai đoạn 1 được Linux sử dụng để quản lý không gian địa chỉ ảo được cung cấp cho từng quy trình không gian người dùng và không gian địa chỉ ảo của chính nó.

MMU giai đoạn 2 được điều khiển bởi EL2 và cho phép ứng dụng dịch địa chỉ thứ hai trên địa chỉ đầu ra của MMU giai đoạn 1, tạo ra địa chỉ vật lý (PA). Bản dịch giai đoạn 2 có thể được các nhà ảo hóa sử dụng để kiểm soát và dịch các quyền truy cập bộ nhớ từ tất cả các máy ảo khách. Như minh họa trong hình 2, khi cả hai giai đoạn dịch thuật được bật, địa chỉ đầu ra của giai đoạn 1 được gọi là địa chỉ vật lý trung gian (IPA) Lưu ý: Địa chỉ ảo (VA) được dịch sang IPA và sau đó thành PA.

Bảo vệ truy cập bộ nhớ CPU

Hình 2. Bảo vệ truy cập bộ nhớ CPU

Về mặt lịch sử, KVM chạy với tính năng dịch giai đoạn 2 được bật khi chạy khách và bị tắt giai đoạn 2 khi chạy nhân Linux máy chủ. Kiến trúc này cho phép truy cập bộ nhớ từ MMU giai đoạn 1 của máy chủ để đi qua MMU giai đoạn 2, do đó cho phép truy cập không hạn chế từ máy chủ đến các trang bộ nhớ của khách. Mặt khác, pKVM cho phép bảo vệ giai đoạn 2 ngay cả trong bối cảnh máy chủ và giao cho bộ ảo hóa chịu trách nhiệm bảo vệ các trang bộ nhớ của khách thay vì máy chủ.

KVM tận dụng tối đa khả năng dịch địa chỉ ở giai đoạn 2 để triển khai ánh xạ IPA/PA phức tạp cho khách, điều này tạo ra ảo giác về bộ nhớ liền kề cho khách bất chấp sự phân mảnh vật lý. Tuy nhiên, việc sử dụng MMU giai đoạn 2 cho máy chủ chỉ bị hạn chế ở mức kiểm soát truy cập. Giai đoạn 2 của máy chủ được ánh xạ danh tính, đảm bảo rằng bộ nhớ liền kề trong không gian IPA của máy chủ liền kề trong không gian PA. Kiến trúc này cho phép sử dụng các ánh xạ lớn trong bảng trang và do đó làm giảm áp lực lên bộ đệm tra cứu dịch thuật (TLB). Vì ánh xạ nhận dạng có thể được PA lập chỉ mục nên máy chủ giai đoạn 2 cũng được sử dụng để theo dõi quyền sở hữu trang trực tiếp trong bảng trang.

Bảo vệ truy cập bộ nhớ trực tiếp (DMA)

Như đã mô tả trước đây, việc hủy ánh xạ các trang khách khỏi máy chủ Linux trong bảng trang CPU là một bước cần thiết nhưng chưa đủ để bảo vệ bộ nhớ khách. pKVM cũng cần bảo vệ chống lại các truy cập bộ nhớ được thực hiện bởi các thiết bị có khả năng DMA dưới sự kiểm soát của nhân máy chủ và khả năng xảy ra một cuộc tấn công DMA do máy chủ độc hại khởi xướng. Để ngăn thiết bị như vậy truy cập vào bộ nhớ khách, pKVM yêu cầu phần cứng đơn vị quản lý bộ nhớ đầu vào-đầu ra (IOMMU) cho mọi thiết bị có khả năng DMA trong hệ thống, như trong hình 3.

Bảo vệ truy cập bộ nhớ Dma

Hình 3. Bảo vệ truy cập bộ nhớ DMA

Ở mức tối thiểu, phần cứng IOMMU cung cấp phương tiện cấp và thu hồi quyền truy cập đọc/ghi của thiết bị vào bộ nhớ vật lý ở mức độ chi tiết của trang. Tuy nhiên, phần cứng IOMMU này hạn chế việc sử dụng các thiết bị trong pVM vì chúng giả định giai đoạn 2 được ánh xạ nhận dạng.

Để đảm bảo sự tách biệt giữa các máy ảo, các giao dịch bộ nhớ được tạo thay mặt cho các thực thể khác nhau phải được IOMMU phân biệt để có thể sử dụng bộ bảng trang thích hợp cho việc dịch.

Ngoài ra, việc giảm số lượng mã dành riêng cho SoC tại EL2 là một chiến lược quan trọng nhằm giảm cơ sở điện toán đáng tin cậy tổng thể (TCB) của pKVM và đi ngược lại việc đưa trình điều khiển IOMMU vào bộ ảo hóa. Để giảm thiểu vấn đề này, máy chủ tại EL1 chịu trách nhiệm thực hiện các nhiệm vụ quản lý IOMMU phụ trợ, chẳng hạn như quản lý nguồn, khởi tạo và xử lý ngắt khi thích hợp.

Tuy nhiên, việc đặt máy chủ kiểm soát trạng thái thiết bị sẽ đặt ra các yêu cầu bổ sung trên giao diện lập trình của phần cứng IOMMU để đảm bảo rằng việc kiểm tra quyền không thể bị bỏ qua bằng các phương tiện khác, chẳng hạn như sau khi đặt lại thiết bị.

Một IOMMU tiêu chuẩn và được hỗ trợ tốt dành cho các thiết bị Arm có thể thực hiện cả cách ly và gán trực tiếp là kiến ​​trúc Đơn vị quản lý bộ nhớ hệ thống cánh tay (SMMU). Kiến trúc này là giải pháp tham khảo được đề xuất.

Quyền sở hữu bộ nhớ

Vào thời điểm khởi động, tất cả bộ nhớ không phải của bộ ảo hóa được coi là thuộc sở hữu của máy chủ và được bộ ảo hóa theo dõi như vậy. Khi một pVM được tạo ra, máy chủ cung cấp các trang bộ nhớ để cho phép nó khởi động và trình ảo hóa sẽ chuyển quyền sở hữu các trang đó từ máy chủ sang pVM. Do đó, trình ảo hóa đặt các hạn chế kiểm soát truy cập vào bảng trang giai đoạn 2 của máy chủ để ngăn nó truy cập lại các trang, cung cấp tính bảo mật cho khách.

Việc liên lạc giữa máy chủ và khách được thực hiện bằng cách chia sẻ bộ nhớ có kiểm soát giữa họ. Khách được phép chia sẻ lại một số trang của họ với máy chủ bằng cách sử dụng siêu giám sát, hướng dẫn bộ ảo hóa ánh xạ lại các trang đó trong bảng trang giai đoạn 2 của máy chủ. Tương tự, việc liên lạc của máy chủ với TrustZone được thực hiện bằng các hoạt động chia sẻ và/hoặc cho mượn bộ nhớ, tất cả đều được pKVM giám sát và kiểm soát chặt chẽ bằng cách sử dụng đặc tả Firmware Framework for Arm (FF-A) .

Vì yêu cầu bộ nhớ của pVM có thể thay đổi theo thời gian nên một siêu cuộc gọi được cung cấp cho phép quyền sở hữu các trang được chỉ định thuộc về người gọi sẽ được trả lại cho máy chủ. Trong thực tế, hypercall này được sử dụng với giao thức bong bóng virtio để cho phép VMM yêu cầu trả lại bộ nhớ từ pVM và để pVM thông báo cho VMM về các trang bị từ bỏ, theo cách được kiểm soát.

Trình ảo hóa chịu trách nhiệm theo dõi quyền sở hữu của tất cả các trang bộ nhớ trong hệ thống và liệu chúng có được chia sẻ hay cho các thực thể khác mượn hay không. Hầu hết việc theo dõi trạng thái này được thực hiện bằng cách sử dụng siêu dữ liệu được gắn vào bảng trang giai đoạn 2 của máy chủ và khách, sử dụng các bit dành riêng trong các mục trong bảng trang (PTE), như tên cho thấy, được dành riêng cho việc sử dụng phần mềm.

Máy chủ phải đảm bảo rằng nó không cố gắng truy cập các trang mà trình ảo hóa không thể truy cập được. Quyền truy cập máy chủ bất hợp pháp khiến cho trình ảo hóa đưa một ngoại lệ đồng bộ vào máy chủ, điều này có thể dẫn đến tác vụ không gian người dùng có trách nhiệm nhận được tín hiệu SEGV hoặc nhân máy chủ bị lỗi. Để ngăn chặn các truy cập vô tình, các trang được tặng cho khách sẽ không đủ điều kiện để hoán đổi hoặc hợp nhất bởi hạt nhân máy chủ.

Xử lý ngắt và hẹn giờ

Ngắt là một phần thiết yếu trong cách khách tương tác với các thiết bị và liên lạc giữa các CPU, trong đó ngắt của bộ liên xử lý (IPI) là cơ chế giao tiếp chính. Mô hình KVM sẽ ủy quyền tất cả việc quản lý ngắt ảo cho máy chủ trong EL1, vì mục đích đó nó hoạt động như một phần không đáng tin cậy của bộ ảo hóa.

pKVM cung cấp mô phỏng Bộ điều khiển ngắt chung phiên bản 3 (GICv3) đầy đủ dựa trên mã KVM hiện có. Bộ hẹn giờ và IPI được xử lý như một phần của mã mô phỏng không đáng tin cậy này.

Hỗ trợ GICv3

Giao diện giữa EL1 và EL2 phải đảm bảo rằng máy chủ EL1 hiển thị trạng thái ngắt đầy đủ, bao gồm các bản sao của các thanh ghi ảo hóa liên quan đến các ngắt. Khả năng hiển thị này thường được thực hiện bằng cách sử dụng các vùng bộ nhớ dùng chung, mỗi vùng cho mỗi CPU ảo (vCPU).

Mã hỗ trợ thời gian chạy của thanh ghi hệ thống có thể được đơn giản hóa để chỉ hỗ trợ bẫy đăng ký Thanh ghi ngắt được tạo bằng phần mềm (SGIR) và Thanh ghi ngắt kích hoạt (DIR). Kiến trúc yêu cầu các thanh ghi này luôn bẫy EL2, trong khi các bẫy khác cho đến nay chỉ hữu ích để giảm thiểu lỗi. Mọi thứ khác đang được xử lý trong phần cứng.

Về phía MMIO, mọi thứ đều được mô phỏng tại EL1, sử dụng lại tất cả cơ sở hạ tầng hiện tại trong KVM. Cuối cùng, Chờ ngắt (WFI) luôn được chuyển tiếp tới EL1, vì đây là một trong những nguyên tắc lập lịch cơ bản mà KVM sử dụng.

Hỗ trợ hẹn giờ

Giá trị so sánh cho bộ định thời ảo phải được hiển thị với EL1 trên mỗi WFI bẫy để EL1 có thể đưa vào các ngắt bộ định thời trong khi vCPU bị chặn. Bộ đếm thời gian vật lý được mô phỏng hoàn toàn và tất cả các bẫy được chuyển tiếp đến EL1.

xử lý MMIO

Để giao tiếp với trình giám sát máy ảo (VMM) và thực hiện mô phỏng GIC, bẫy MMIO phải được chuyển tiếp trở lại máy chủ trong EL1 để phân loại thêm. pKVM yêu cầu như sau:

  • IPA và kích thước của quyền truy cập
  • Dữ liệu trong trường hợp ghi
  • Độ bền của CPU tại thời điểm bẫy

Ngoài ra, các bẫy có thanh ghi mục đích chung (GPR) làm nguồn/đích được chuyển tiếp bằng cách sử dụng thanh ghi giả truyền trừu tượng.

Giao diện khách

Khách có thể liên lạc với khách được bảo vệ bằng cách sử dụng kết hợp siêu cuộc gọi và quyền truy cập bộ nhớ vào các vùng bị mắc kẹt. Các siêu cuộc gọi được hiển thị theo tiêu chuẩn SMCCC , với phạm vi dành riêng cho sự phân bổ của nhà cung cấp bởi KVM. Các siêu cuộc gọi sau đây có tầm quan trọng đặc biệt đối với khách pKVM.

Siêu cuộc gọi chung

  • PSCI cung cấp cơ chế tiêu chuẩn để khách kiểm soát vòng đời của vCPU bao gồm trực tuyến, ngoại tuyến và tắt hệ thống.
  • TRNG cung cấp một cơ chế tiêu chuẩn để khách yêu cầu entropy từ pKVM để chuyển tiếp cuộc gọi đến EL3. Cơ chế này đặc biệt hữu ích khi không thể tin cậy máy chủ để ảo hóa bộ tạo số ngẫu nhiên phần cứng (RNG).

siêu cuộc gọi pKVM

  • Chia sẻ bộ nhớ với máy chủ. Tất cả bộ nhớ khách ban đầu không thể truy cập được vào máy chủ, nhưng quyền truy cập máy chủ là cần thiết để liên lạc với bộ nhớ dùng chung và cho các thiết bị ảo hóa phụ thuộc vào bộ đệm dùng chung. Các siêu lệnh chia sẻ và hủy chia sẻ trang với máy chủ cho phép khách quyết định chính xác phần nào của bộ nhớ được phép truy cập vào phần còn lại của Android mà không cần bắt tay.
  • Trao trả bộ nhớ cho máy chủ. Tất cả bộ nhớ của khách thường thuộc về khách cho đến khi nó bị phá hủy. Trạng thái này có thể không phù hợp đối với các máy ảo tồn tại lâu dài với yêu cầu bộ nhớ thay đổi theo thời gian. Hypercall relinquish cho phép khách chuyển quyền sở hữu các trang trở lại máy chủ một cách rõ ràng mà không yêu cầu khách chấm dứt.
  • Bẫy truy cập bộ nhớ vào máy chủ. Theo truyền thống, nếu khách KVM truy cập vào một địa chỉ không tương ứng với vùng bộ nhớ hợp lệ thì luồng vCPU sẽ thoát ra máy chủ và quyền truy cập thường được sử dụng cho MMIO và được mô phỏng bởi VMM trong không gian người dùng. Để tạo điều kiện thuận lợi cho việc xử lý này, pKVM được yêu cầu quảng cáo thông tin chi tiết về hướng dẫn bị lỗi như địa chỉ, đăng ký tham số và có khả năng nội dung của chúng quay lại máy chủ, điều này có thể vô tình làm lộ dữ liệu nhạy cảm từ khách được bảo vệ nếu không lường trước được bẫy. pKVM giải quyết vấn đề này bằng cách coi những lỗi này là nghiêm trọng trừ khi khách trước đó đã đưa ra một siêu lệnh để xác định phạm vi IPA bị lỗi là phạm vi mà quyền truy cập được phép quay lại máy chủ. Giải pháp này được gọi là bảo vệ MMIO .

Thiết bị I/O ảo (virtio)

Virtio là một tiêu chuẩn phổ biến, di động và hoàn thiện để triển khai và tương tác với các thiết bị ảo hóa. Phần lớn các thiết bị tiếp xúc với khách được bảo vệ đều được triển khai bằng virtio. Virtio cũng củng cố việc triển khai vsock dùng để liên lạc giữa khách được bảo vệ và phần còn lại của Android.

Các thiết bị Virtio thường được VMM triển khai trong không gian người dùng của máy chủ, thiết bị này sẽ chặn các truy cập bộ nhớ bị mắc kẹt từ khách đến giao diện MMIO của thiết bị virtio và mô phỏng hành vi dự kiến. Truy cập MMIO tương đối tốn kém vì mỗi lần truy cập vào thiết bị yêu cầu một chuyến đi khứ hồi tới VMM và ngược lại, do đó hầu hết việc truyền dữ liệu thực tế giữa thiết bị và khách đều xảy ra bằng cách sử dụng một tập hợp các đặc tính trong bộ nhớ. Giả định chính của virtio là máy chủ có thể truy cập bộ nhớ khách một cách tùy ý. Giả định này được thể hiện rõ trong thiết kế của Virtqueue, có thể chứa các con trỏ tới bộ đệm trong máy khách mà mô phỏng thiết bị dự định truy cập trực tiếp.

Mặc dù các siêu lệnh chia sẻ bộ nhớ được mô tả trước đây có thể được sử dụng để chia sẻ bộ đệm dữ liệu virtio từ máy khách đến máy chủ, việc chia sẻ này nhất thiết phải được thực hiện ở mức độ chi tiết của trang và cuối cùng có thể làm lộ nhiều dữ liệu hơn mức cần thiết nếu kích thước bộ đệm nhỏ hơn kích thước của một trang . Thay vào đó, khách được cấu hình để phân bổ cả hàng đợi đặc tính và bộ đệm dữ liệu tương ứng của chúng từ một cửa sổ cố định của bộ nhớ dùng chung, với dữ liệu được sao chép (trả lại) đến và từ cửa sổ theo yêu cầu.

Thiết bị ảo

Hình 4. Thiết bị Virtio

Tương tác với TrustZone

Mặc dù khách không thể tương tác trực tiếp với TrustZone nhưng máy chủ vẫn phải có khả năng thực hiện cuộc gọi SMC vào thế giới bảo mật. Các cuộc gọi này có thể chỉ định bộ đệm bộ nhớ có địa chỉ vật lý mà máy chủ không thể truy cập được. Bởi vì phần mềm bảo mật thường không biết về khả năng truy cập của bộ đệm nên máy chủ độc hại có thể sử dụng bộ đệm này để thực hiện một cuộc tấn công nhầm lẫn (tương tự như một cuộc tấn công DMA). Để ngăn chặn các cuộc tấn công như vậy, pKVM bẫy tất cả các cuộc gọi SMC của máy chủ đến EL2 và hoạt động như một proxy giữa máy chủ và màn hình an toàn tại EL3.

Các cuộc gọi PSCI từ máy chủ được chuyển tiếp đến phần sụn EL3 với những sửa đổi tối thiểu. Cụ thể, điểm vào cho CPU trực tuyến hoặc tiếp tục sau khi tạm dừng được viết lại để bảng trang giai đoạn 2 được cài đặt tại EL2 trước khi quay lại máy chủ tại EL1. Trong quá trình khởi động, biện pháp bảo vệ này được thực thi bởi pKVM.

Kiến trúc này dựa trên SoC hỗ trợ PSCI, tốt nhất là thông qua việc sử dụng phiên bản cập nhật của TF-A làm phần sụn EL3.

Firmware Framework for Arm (FF-A) chuẩn hóa các tương tác giữa thế giới bình thường và thế giới an toàn, đặc biệt khi có sự hiện diện của bộ ảo hóa an toàn. Phần chính của đặc tả xác định cơ chế chia sẻ bộ nhớ với thế giới an toàn, sử dụng cả định dạng thông báo chung và mô hình quyền được xác định rõ ràng cho các trang cơ bản. pKVM ủy quyền các thông báo FF-A để đảm bảo rằng máy chủ không cố gắng chia sẻ bộ nhớ với bên bảo mật mà nó không có đủ quyền.

Kiến trúc này dựa trên phần mềm thế giới bảo mật thực thi mô hình truy cập bộ nhớ, để đảm bảo rằng các ứng dụng đáng tin cậy và bất kỳ phần mềm nào khác chạy trong thế giới bảo mật chỉ có thể truy cập bộ nhớ nếu nó được sở hữu độc quyền bởi thế giới bảo mật hoặc đã được chia sẻ rõ ràng với nó bằng FF -MỘT. Trên hệ thống có S-EL2, việc thực thi mô hình truy cập bộ nhớ phải được thực hiện bởi Lõi quản lý phân vùng an toàn (SPMC), chẳng hạn như Hafnium , duy trì các bảng trang giai đoạn 2 cho thế giới bảo mật. Trên hệ thống không có S-EL2, TEE có thể thực thi mô hình truy cập bộ nhớ thông qua các bảng trang giai đoạn 1 của nó.

Nếu cuộc gọi SMC tới EL2 không phải là cuộc gọi PSCI hoặc tin nhắn được xác định FF-A thì các SMC chưa được xử lý sẽ được chuyển tiếp tới EL3. Giả định là chương trình cơ sở bảo mật (nhất thiết phải tin cậy) có thể xử lý các SMC chưa được xử lý một cách an toàn vì chương trình cơ sở hiểu các biện pháp phòng ngừa cần thiết để duy trì cách ly pVM.

Màn hình máy ảo

crosvm là trình giám sát máy ảo (VMM) chạy các máy ảo thông qua giao diện KVM của Linux. Điều làm cho crosvm trở nên độc đáo là nó tập trung vào sự an toàn khi sử dụng ngôn ngữ lập trình Rust và hộp cát xung quanh các thiết bị ảo để bảo vệ nhân máy chủ. Để biết thêm về crosvm, hãy xem tài liệu chính thức của nó tại đây .

Bộ mô tả tập tin và ioctls

KVM hiển thị thiết bị ký tự /dev/kvm cho không gian người dùng bằng ioctls tạo nên API KVM. Các ioctls thuộc các loại sau:

  • Truy vấn ioctls hệ thống và đặt các thuộc tính chung ảnh hưởng đến toàn bộ hệ thống con KVM và tạo pVM.
  • VM ioctls truy vấn và đặt các thuộc tính tạo CPU ảo (vCPU) và thiết bị, đồng thời ảnh hưởng đến toàn bộ pVM, chẳng hạn như bao gồm bố cục bộ nhớ, số lượng CPU và thiết bị ảo (vCPU).
  • vCPU ioctls truy vấn và đặt các thuộc tính kiểm soát hoạt động của một CPU ảo.
  • Truy vấn ioctls của thiết bị và đặt các thuộc tính kiểm soát hoạt động của một thiết bị ảo.

Mỗi quy trình crosvm chạy chính xác một phiên bản của máy ảo. Quá trình này sử dụng ioctl hệ thống KVM_CREATE_VM để tạo một bộ mô tả tệp VM có thể được sử dụng để phát hành ioctls pVM. KVM_CREATE_VCPU hoặc KVM_CREATE_DEVICE ioctl trên VM FD tạo vCPU/thiết bị và trả về bộ mô tả tệp trỏ đến tài nguyên mới. ioctls trên vCPU hoặc FD thiết bị có thể được sử dụng để điều khiển thiết bị được tạo bằng ioctl trên VM FD. Đối với vCPU, điều này bao gồm nhiệm vụ quan trọng là chạy mã khách.

Trong nội bộ, crosvm đăng ký các bộ mô tả tệp của VM với kernel bằng giao diện epoll được kích hoạt ở cạnh. Sau đó, hạt nhân sẽ thông báo cho crosvm bất cứ khi nào có một sự kiện mới đang chờ xử lý trong bất kỳ bộ mô tả tệp nào.

pKVM bổ sung một khả năng mới, KVM_CAP_ARM_PROTECTED_VM , có thể được sử dụng để lấy thông tin về môi trường pVM và thiết lập chế độ được bảo vệ cho VM. crosvm sử dụng điều này trong quá trình tạo pVM nếu cờ --protected-vm được thông qua, để truy vấn và dự trữ lượng bộ nhớ thích hợp cho chương trình cơ sở pVM, sau đó bật chế độ được bảo vệ.

Cấp phát bộ nhớ

Một trong những trách nhiệm chính của VMM là phân bổ bộ nhớ của VM và quản lý bố cục bộ nhớ của nó. crosvm tạo bố cục bộ nhớ cố định được mô tả lỏng lẻo trong bảng bên dưới.

FDT ở chế độ bình thường PHYS_MEMORY_END - 0x200000
Không gian trông ...
Đĩa RAM ALIGN_UP(KERNEL_END, 0x1000000)
hạt nhân 0x80080000
Bộ nạp khởi động 0x80200000
FDT ở chế độ BIOS 0x80000000
Cơ sở bộ nhớ vật lý 0x80000000
phần mềm pVM 0x7FE00000
Bộ nhớ thiết bị 0x10000 - 0x40000000

Bộ nhớ vật lý được phân bổ bằng mmap và bộ nhớ được cấp cho VM để điền vào các vùng bộ nhớ của nó, được gọi là memslots , với KVM_SET_USER_MEMORY_REGION ioctl. Do đó, tất cả bộ nhớ pVM khách được phân bổ cho phiên bản crosvm quản lý nó và có thể dẫn đến quá trình bị hủy (chấm dứt VM) nếu máy chủ bắt đầu hết bộ nhớ trống. Khi máy ảo bị dừng, bộ nhớ sẽ tự động bị bộ ảo hóa xóa sạch và trả về kernel máy chủ.

Trong KVM thông thường, VMM giữ quyền truy cập vào tất cả bộ nhớ khách. Với pKVM, bộ nhớ của khách sẽ không được ánh xạ khỏi không gian địa chỉ vật lý của máy chủ khi nó được cấp cho khách. Ngoại lệ duy nhất là bộ nhớ được khách chia sẻ lại một cách rõ ràng, chẳng hạn như đối với các thiết bị virtio.

Các vùng MMIO trong không gian địa chỉ của khách không được ánh xạ. Quyền truy cập vào các khu vực này của khách bị kẹt và dẫn đến sự kiện I/O trên VM FD. Cơ chế này được sử dụng để triển khai các thiết bị ảo. Ở chế độ được bảo vệ, khách phải xác nhận rằng một vùng trong không gian địa chỉ của nó được sử dụng cho MMIO bằng cách sử dụng siêu cuộc gọi, để giảm nguy cơ rò rỉ thông tin do vô tình.

Lên lịch

Mỗi CPU ảo được biểu thị bằng một luồng POSIX và được lập lịch bởi bộ lập lịch Linux của máy chủ. Luồng này gọi KVM_RUN ioctl trên vCPU FD, dẫn đến bộ điều khiển ảo hóa chuyển sang ngữ cảnh vCPU khách. Bộ lập lịch máy chủ tính thời gian dành cho ngữ cảnh khách là thời gian được sử dụng bởi luồng vCPU tương ứng. KVM_RUN trả về khi có một sự kiện phải được VMM xử lý, chẳng hạn như I/O, kết thúc ngắt hoặc vCPU bị tạm dừng. VMM xử lý sự kiện và gọi lại KVM_RUN .

Trong KVM_RUN , luồng vẫn được bộ lập lịch máy chủ ưu tiên, ngoại trừ việc thực thi mã bộ ảo hóa EL2, vốn không được ưu tiên. Bản thân pVM khách không có cơ chế kiểm soát hành vi này.

Vì tất cả các luồng vCPU đều được lên lịch giống như mọi tác vụ trong không gian người dùng khác nên chúng phải tuân theo tất cả các cơ chế QoS tiêu chuẩn. Cụ thể, mỗi luồng vCPU có thể được gắn với CPU vật lý, được đặt trong bộ CPU, được tăng cường hoặc giới hạn bằng cách sử dụng tính năng kẹp mức sử dụng, thay đổi chính sách ưu tiên/lập lịch, v.v.

Thiết bị ảo

crosvm hỗ trợ một số thiết bị, bao gồm:

  • virtio-blk dành cho ảnh đĩa tổng hợp, chỉ đọc hoặc đọc-ghi
  • vhost-vsock để liên lạc với máy chủ
  • virtio-pci là vận chuyển virtio
  • đồng hồ thời gian thực pl030 (RTC)
  • 16550a UART cho giao tiếp nối tiếp

phần mềm pVM

Phần sụn pVM (pvmfw) là mã đầu tiên được thực thi bởi pVM, tương tự như ROM khởi động của thiết bị vật lý. Mục tiêu chính của pvmfw là khởi động khả năng khởi động an toàn và tìm ra bí mật duy nhất của pVM. pvmfw không bị giới hạn sử dụng với bất kỳ hệ điều hành cụ thể nào, chẳng hạn như Microdroid , miễn là hệ điều hành đó được crosvm hỗ trợ và đã được ký hợp lệ.

Tệp nhị phân pvmfw được lưu trữ trong phân vùng flash cùng tên và được cập nhật bằng OTA .

Khởi động thiết bị

Trình tự các bước sau đây được thêm vào quy trình khởi động của thiết bị hỗ trợ pKVM:

  1. Bộ tải khởi động Android (ABL) tải pvmfw từ phân vùng của nó vào bộ nhớ và xác minh hình ảnh.
  2. ABL lấy các bí mật của Công cụ cấu thành mã định danh thiết bị (DICE) (Mã định danh thiết bị phức hợp (CDI) và Chuỗi chứng chỉ khởi động (BCC)) từ Gốc tin cậy.
  3. ABL thực hiện đo lường và lấy DICE các bí mật của pvmfw (CDI) và nối chúng vào tệp nhị phân pvmfw.
  4. ABL thêm nút vùng bộ nhớ dự trữ linux,pkvm-guest-firmware-memory vào DT, mô tả vị trí và kích thước của tệp nhị phân pvmfw cũng như các bí mật mà nó thu được ở bước trước.
  5. ABL trao quyền kiểm soát cho Linux và Linux khởi tạo pKVM.
  6. pKVM hủy ánh xạ vùng bộ nhớ pvmfw khỏi bảng trang giai đoạn 2 của máy chủ và bảo vệ vùng đó khỏi máy chủ (và khách) trong suốt thời gian hoạt động của thiết bị.

Sau khi khởi động thiết bị, Microdroid sẽ được khởi động theo các bước trong phần Trình tự khởi động của tài liệu Microdroid .

khởi động pVM

Khi tạo pVM, crosvm (hoặc một VMM khác) phải tạo một memslot đủ lớn để trình ảo hóa hiển thị hình ảnh pvmfw. VMM cũng bị hạn chế trong danh sách các thanh ghi có giá trị ban đầu mà nó có thể đặt (x0-x14 đối với vCPU chính, không có đối với vCPU phụ). Các thanh ghi còn lại được bảo lưu và là một phần của ABI hypervisor-pvmfw.

Khi pVM được chạy, trình ảo hóa trước tiên sẽ chuyển quyền kiểm soát vCPU chính cho pvmfw. Phần sụn dự kiến ​​crosvm đã tải hạt nhân có chữ ký AVB, hạt nhân này có thể là bộ tải khởi động hoặc bất kỳ hình ảnh nào khác và FDT không dấu vào bộ nhớ ở các độ lệch đã biết. pvmfw xác thực chữ ký AVB và nếu thành công, sẽ tạo một cây thiết bị đáng tin cậy từ FDT đã nhận, xóa bí mật của nó khỏi bộ nhớ và phân nhánh đến điểm vào của tải trọng. Nếu một trong các bước xác minh không thành công, chương trình cơ sở sẽ phát ra siêu lệnh gọi PSCI SYSTEM_RESET .

Giữa các lần khởi động, thông tin về phiên bản pVM được lưu trữ trong một phân vùng (thiết bị virtio-blk) và được mã hóa bằng bí mật của pvmfw để đảm bảo rằng, sau khi khởi động lại, bí mật sẽ được cung cấp cho đúng phiên bản.