HyperVisor 设计思路
基于硬件指纹的 GPU
将一体机中的 GPU 提前运行若干指纹提取程序和指纹转换程序,收录一系列指纹和对应的公钥
在特定内存区域以表格的形式存放程序编号和对应公钥
② 验证设备步骤:
主机侧将指纹提取程序和指纹转换程序以及一个随机数发送给 GPU,GPU 运行指纹提取程序和指纹转换程序后通过生成的私钥加密随机数,将起返回主机
主机通过验证公钥是否可以解密随机数判断 GPU 是否为原本 GPU
框架设计思路
主机和设备交换数据有三种方式:DMA, MMIO, I/O ports
GPU -> 保护的设备
c-device -> 恶意设备
c-OS -> 恶意操作系统
HV -> HyperVisor
untrust-app -> 不受信任的应用进程
trust-app -> 受信任的应用进程,需要访问 GPU
设备枚举与初始化 —— 保护设备配置空间
设备配置空间是保护 MMIO/DMA/IO-port 的基础,如果无法保证 GPU 的 BARs 寄存器中数据的真实性,对访问设备的数据通路的任何加强都没有意义。
对于设备配置空间的访问一般通过 MMIO/IO-port 方式,看似出现了依赖环路,但由于 PCIe RC 转发设备配置空间访问事务包根据设备的 BDF 以及在系统架构中的物理位置进行路由,故 HV 首要目标是正确初始化设备配置空间并防止任何非法修改。
主机-设备通信的三种途径 —— I/O Ports | MMIO | DMA
I/O Ports 传输方式几乎不会被使用
- c-OS/untrust-app 直接访问 GPU I/O ports | DMA | MMIO
- c-OS 恶意篡改 c-device 的 I/O ports | DMA | MMIO 地址信息
对于 I/O ports,HV 可以配置 VMCS 中的 I/O port-access-interception bitmap,拦截 c-OS/untrust-app 访问 GPU 端口。
对于 MMIO | DMA,其本质是内存地址的一部分,故 HV 可以通过设置 EPT trapping,拦截 c-OS/untrust-app 访问相关内存地址。设备配置空间的保护是保证这些内存地址的真实性的基础。
HV 在 G-enclave 运行前可以进行一次检查,遍历所有设备的 I/O ports,防止和 GPU 的 I/O ports 重叠;遍历所有设备的 MMIO region,防止和 GPU 的 MMIO region 重叠。
-----------------------------------------------------------------------------------------------------------------------------------
GECS contains the control information regarding the GPU enclave including the hardware GPU number and GPU enclave ID. TGMR contains the virtual and physical address mapping information of the GPU MMIO region.
—— 《Heterogeneous Isolated Execution for Commodity GPUs》
使用数据结构存储 GPU MMIO 信息(例如 HIX 的 GECS/TGMR,GEVisor 的 MRTable),并在 EPT 中将这些内存区域设置为触发 EPT trapping,防止 c-OS/untrust-app 直接访问 GPU MMIO region。原本的地址信息存在 Driver 中,HV 会根据数据结构中的信息进行验证。
DMA Buffer 和 MMIO Buffer 不同,DMA Buffer 是由驱动动态分配的:
- DMA 请求通过写入设备寄存器完成,写入过程使用 MMIO | I/O ports 方式,使用之前的方法可拦截 DMA 请求
- 设置 EPT trapping => HV 可以保证 c-OS 无法访问 DMA Buffer
- 设置数据结构 => HV 可以保证 c-OS 无法通过篡改 DMA 地址信息来攻击
- 设置 IOMMU => 可以保证 c-device 无法访问 GPU DMA Buffer
G-Enclave | GPU-Driver
借助 Intel SGX 的功能

将 GPU Runtime 分成两部分:UNTRUSTED RUNTIME 和 ENCLAVE GPU RUNTIME,前者存放在非 enclave 内存区域,负责和 GPU Driver 交互来创建 GPU 上下文以及分配 MMIO/DMA Buffer 等;后者存放在 enclave 内存区域,负责和 GPU 通信,将数据从 enclave 复制到 MMIO/DMA Buffer 中。

将 GPU Driver 分成两部分,一部分运行在 G-enclave 中,唯一控制 GPU 并提供 GPU 访问接口;另一部分运行在 c-OS 中,提供良性的内核服务。
本质上都是将 GPU Driver 分割成两部分:
- 一部分运行在 SGX enclave 中,负责控制和保护 trust-app 和 GPU 的交互过程
- 一部分运行在 c-OS 中,提供良性的内核服务,例如分配 DMA | MMIO buffer 等
- HV 负责转发和管理 trust-app, G-enclave, GPU 之间的通信
- trust-app 通过 ENCLAVE GPU RUNTIME 提供的 API 访问内存地址 0x1000 - 0x1004 后触发 EPT trapping 或主动发起 HyperCall,被 HV 拦截
- HV 根据数据结构中的信息,判断访问是否合法(根据 Eclave-ID, PA, VA 等),不合法则丢弃
- HV 访问 GPU 对应数据,将数据返回给 trust-app
- ENCLAVE GPU RUNTIME 和 HV 的通信需要使用加密信道
I/O 中断保护 —— HI | MSI | IPI
- c-OS/untrust-app 恶意篡改中断路由,使中断信息无法正确从 GPU 送往 trust-app
- c-OS/untrust-app 恶意制造虚假中断,将其描述为 GPU 发出,送往 trust-app
对于 HI 类型中断,主要经历下面几个阶段:
- 设备通过 IOAPIC 的某一个管脚发送中断信号
- IOAPIC 根据重定向路由表,构建一条规范化的中断信息(包括目标 CPU,中断向量号,触发模式,传递模式等等),构建完毕后通过总线发送出去
- LAPIC 收到中断后存入中断请求队列 IRR 中,根据中断优先级和 CPU 状态决定是否交给 CPU 处理,若处理写入 ISR
- CPU 根据中断向量号查找 IDT,拿到对应中断处理程序的入口地址
- 处理完毕后,发送 EOI 信号通知 LAPIC
- LAPIC 和 IOAPIC 清除相关中断信号或电平
HV 需要保护三个部分:重定向路由表、中断控制寄存器、IDT,这三部分均存放于物理内存中,故可以通过前文的方法进行保护
对于 MSI 类型中断,主要经历下面几个阶段:
- 设备向特定内存区域写入特定的值
- 处理器和中断控制器监控这些特定的内存区域,对于写入操作,视为设备发起了中断