首页/目录/全部文章

全部文章

八个专题的源码、算法与协议笔记都在这里。

笔记列表

VFIO Core、设备组与 Container 模型

VFIO Core、设备组与 Container 模型

1. Device注册

VFIO driver:

1
2
3
4
5
6
7
vfio_init_group_dev()
-> initialize vfio_device/ref/completion
vfio_register_group_dev()
-> obtain iommu_group
-> create/find vfio_group
-> add device
-> create group cdev

现代 helper也可组合初始化/注册。

2. Group类型

包括正常 IOMMU group和 no-IOMMU/emulated等类型。类型影响 viable、container attach和安全语义。

3. Group节点

Core为 group创建字符设备,通常由 udev生成 /dev/vfio/N。Group fd处理:

  • GET_STATUS;
  • SET/UNSET_CONTAINER;
  • GET_DEVICE_FD。

4. Viable

本树 VFIO_GROUP_GET_STATUS在 group尚未挂 container时,以 IOMMU group的 DMA ownership是否已被其它主体 claim判断 viable;挂入 container后同时报告 container-set和 viable。实际部署仍必须确保组内相关设备已解绑 host DMA driver或由 VFIO接管。Bridge、multifunction function或同组设备遗漏可能阻止安全使用。

5. Container

打开 /dev/vfio/vfio获得 container fd:

1
2
3
VFIO_GET_API_VERSION
VFIO_CHECK_EXTENSION
VFIO_SET_IOMMU

Group通过 SET_CONTAINER挂入。多个 group可在兼容 domain条件下共享 container/IOVA空间。

6. Device fd

GET_DEVICE_FD:

-按 name查 group device;
-检查 viable/container;

  • open device;
    -创建 anon inode fd;
    -持有 device/group/container引用。

7. Open count

Core在首次 open调用 device open_device,最后 release调用 close_device。Device set可协调一组相关 device的打开计数和锁。

8. Unregister

Driver remove先阻止新打开,等待现有引用关闭,再从 group移除。若用户仍持 fd,错误的 remove顺序可能死锁或 use-after-free。

9. 锁

Group/container/device分别有 mutex/refcount;设备 open、group attach、driver unregister和 DMA map可并发。锁顺序必须遵循 Core路径。

10. 隔离含义

Group只是 IOMMU拓扑给出的最小边界,不保证 reset、interrupt remapping、firmware或 peer-to-peer路径一定安全;VFIO还依赖平台硬件质量。

UAPI 打开、绑定与 IOCTL 调用链

UAPI 打开、绑定与 IOCTL 调用链

1. Legacy流程

1
2
3
4
5
6
7
8
9
10
11
12
13
open("/dev/vfio/vfio")
-> VFIO_GET_API_VERSION
-> VFIO_CHECK_EXTENSION(VFIO_TYPE1_IOMMU)

open("/dev/vfio/N")
-> VFIO_GROUP_GET_STATUS
-> VFIO_GROUP_SET_CONTAINER(container_fd)

container ioctl:
-> VFIO_SET_IOMMU(VFIO_TYPE1_IOMMU)

group ioctl:
-> VFIO_GROUP_GET_DEVICE_FD(name)

实际 attach与 SET_IOMMU顺序需遵循 UAPI示例和 backend状态。

2. Device ioctl

通用:

  • VFIO_DEVICE_GET_INFO
  • VFIO_DEVICE_GET_REGION_INFO
  • VFIO_DEVICE_GET_IRQ_INFO
  • VFIO_DEVICE_SET_IRQS
  • VFIO_DEVICE_RESET
  • VFIO_DEVICE_FEATURE

随后可 read/write/mmap region。

3. argsz和flags

VFIO结构以 argsz支持 ABI扩展。用户应:

1.初始化 argsz;
2.检查返回 flags/capability chain;
3.必要时按所需大小重试;
4.忽略未知可跳过 capability。

不能假设所有 driver支持同一 feature。

4. Region offset

Device fd的 file offset编码 region index和内部 offset。PCI config、BAR、ROM、vendor region各有独立 index/flags。

5. IRQ

VFIO_DEVICE_SET_IRQS通过 index/start/count/flags:

  • DATA_NONE/BOOL/EVENTFD;
  • ACTION_MASK/UNMASK/TRIGGER。

MSI/MSI-X常把 eventfd数组关联 vector。

6. Feature

本树 Core处理 migration、migration state、DMA logging start/stop/report等 feature;PCI core另处理 low power和 VF token。是否可用由 device ops和 feature probe决定。

7. 错误

  • -EINVAL:argsz/flags/index/state;
  • -ENODEV:device消失;
  • -EBUSY:group不 viable或已绑定;
  • -ENOTTY:不支持 ioctl;
  • -EFAULT:用户指针;
  • -ENOMEM:pin/map资源。

8. Compat

32位用户态在64位 kernel上通过 compat ioctl。所有用户 pointer和 size必须按 UAPI类型处理,不能复制内核私有结构布局。

Type1 IOMMU 与 DMA 映射

Type1 IOMMU 与 DMA 映射

1. 作用

Type1把用户虚拟内存映射到 device可见 IOVA:

1
2
3
4
5
userspace VA
-> pin user pages
-> physical pages
-> iommu_map(domain, IOVA)
-> device DMA

它不是普通 CPU page table映射。

2. 初始化

VFIO_SET_IOMMU(VFIO_TYPE1_IOMMU)选择 backend。Group attach时检查:

  • IOMMU group;
    -可用 domain;
    -domain几何和 page sizes;
    -reserved regions;
    -group/domain兼容;
    -DMA ownership。

3. MAP_DMA

VFIO_IOMMU_MAP_DMA输入:

  • vaddr;
  • iova;
  • size;
  • READ/WRITE。

检查对齐、overflow、重叠、访问权限和 address range,再 pin并 iommu_map。

4. UNMAP_DMA

按 IOVA/size解除映射:

-从 DMA interval tree移除/切分;
-iommu_unmap;
-dirty处理;
-unpin pages;
-更新 locked memory accounting。

Unmap返回实际 unmapped size。

5. Page size

映射按 IOMMU支持 bitmap和用户页连续性选择粒度。大页可减少 IOTLB压力,但用户 VA、IOVA和物理页必须满足对齐/连续条件。

6. Reserved regions

MSI doorbell、firmware carveout或 identity regions不可与普通用户 IOVA冲突。Backend读取 group reserved regions并限制 map。

7. Domain共享

多个 group可共享 container domain,前提是 bus/domain geometry兼容。共享方便 VM统一 IOVA,但故障影响面更大。

8. v2语义

Type1 v2扩展改善 unmap和 DMA accounting等行为。用户必须先 VFIO_CHECK_EXTENSION,不能硬编码 backend能力。

9. Fault

设备访问未映射或权限错误 IOVA产生 IOMMU fault。应关联:

  • requester/device;
  • IOVA;
  • read/write;
    -当前 mappings;
    -设备是否仍 DMA;
    -unmap race。

10. RK3588

ROCKCHIP_IOMMU=y只说明 integrated IP IOMMU driver存在。具体 device必须有 iommus关联并形成可用于 VFIO的 group;PCIe endpoint还需要 host bridge IOMMU映射,本树 DTS未体现。

内存钉扎、Dirty Logging 与迁移

内存钉扎、Dirty Logging 与迁移

1. Pinning

DMA mapping需把用户页长期钉住,防止 reclaim/migration后设备仍访问旧物理地址。Type1使用长期 pin语义并记录每个 DMA mapping的 pages。

2. Accounting

锁页受 RLIMIT_MEMLOCK、进程权限和 mm accounting约束。QEMU通常需足够 memlock限制;盲目 unlimited扩大资源耗尽风险。

3. 页生命周期

1
2
3
4
map -> pin -> iommu_map
DMA active
stop device DMA
unmap -> iommu_unmap -> dirty/account -> unpin

必须先停止 DMA再 unmap,单纯关闭用户映射不停止硬件。

4. MM归属

本 Type1实现为每个 DMA mapping保存 group leader和 mm_struct引用,用于 locked-memory accounting,即使创建 mapping的 task退出也能完成记账和释放。Mdev外部 pinning路径还支持使 vaddr失效及重新设置;此文件没有注册通用 mmu_notifier

5. Dirty tracking

迁移需知道 device DMA写过哪些 guest pages。本树通过:

  • IOMMU dirty bitmap能力;
  • device DMA logging feature;
    -软件 bitmap/ranges;

组合提供 dirty报告,具体设备/backend不一定支持。

6. IOVA bitmap

iova_bitmap.c在 IOVA范围与用户 bitmap之间迭代和设置 bits,处理 page size、范围和用户复制。

7. Migration states

VFIO device migration feature表达 running、stop、stop-copy、resuming等状态及 data fd。合法转换由 driver实现,Core检查 feature格式。

8. Vendor migration

mlx5和 HiSilicon accelerator VFIO PCI driver实现设备特定 state save/restore和 dirty tracking,不表示通用 vfio-pci可迁移所有 PCI设备。

9. 风险

-设备内部状态不可完整保存;
-DMA未 quiesce;
-dirty bitmap漏记;
-目标硬件/firmware不兼容;
-migration data不可信;
-大规模 pin导致 host内存压力。

10. RK3588

本树未见适用于 RK3588集成设备的 mdev/migration parent driver。普通 platform VFIO不能自动提供 live migration。

Eventfd、中断与 Virqfd 机制

Eventfd、中断与 Virqfd 机制

1. 数据路径

1
2
3
4
5
physical IRQ/MSI
-> VFIO handler
-> eventfd_signal()
-> QEMU
-> KVM irqfd/guest interrupt

反向控制可通过 eventfd触发 mask/unmask或 resample。

2. Virqfd

virqfd.c把 eventfd waitqueue与 VFIO callback关联:

  • enable;
  • wakeup;
  • thread callback;
  • disable;
  • flush。

关闭 eventfd或 device时必须安全摘除 waitqueue,避免 callback访问释放对象。

3. PCI INTx

Legacy level interrupt需要 mask、EOI/resample和 host共享处理。VFIO可自动 mask避免中断风暴,由用户/guest完成后 unmask。

4. MSI/MSI-X

每个 vector可关联 eventfd。vfio-pci配置 host MSI/MSI-X但向用户暴露受控 ABI,不能允许 guest任意编程 host message address。

5. Platform IRQ

VFIO platform为每个 IRQ resource提供 index,支持 maskable/automasked flags和 eventfd trigger。

6. IRQ bypass

支持时,KVM irq bypass可减少 userspace中转,使 host producer直接连接 guest irq consumer,降低延迟。

7. 禁用顺序

1
2
3
4
mask hardware
-> detach eventfd/irq bypass
-> synchronize_irq/work
-> free IRQ

否则会发生 use-after-free或中断风暴。

8. 安全

-限制 vector count;
-验证 index/start/count;
-配置空间 MSI capability需虚拟化;
-设备 reset后重建 IRQ state;
-恶意设备仍可高频中断造成 DoS;
-中断隔离不替代 DMA IOMMU。

9. RK3588

PCIe root使用 GIC ITS msi-map,说明 MSI路由存在;这不等于 DMA有 IOMMU隔离。MSI可用和安全 passthrough是两个独立条件。

VFIO PCI 配置空间、BAR 与 Reset

VFIO PCI 配置空间、BAR 与 Reset

1. 组成

  • vfio_pci.c:generic PCI driver绑定;
  • vfio_pci_core.c:device ops和生命周期;
  • vfio_pci_config.c:config space虚拟化;
  • vfio_pci_rdwr.c:region read/write;
  • vfio_pci_intrs.c:INTx/MSI/MSI-X;
  • vendor/arch extensions。

2. Region

标准 index包括:

  • PCI config;
  • BAR0–BAR5;
  • ROM;
  • VGA/PCI vendor regions。

GET_REGION_INFO返回 size、offset、flags和 sparse mmap capability。

3. MMAP

可 mmap BAR需:

  • region允许;
  • page对齐;
    -范围合法;
    -非禁止 I/O/config区域;
    -平台支持。

Sparse mmap只开放安全/可映射子范围。

4. Config space

Driver维护 virtual config:

-拦截 command;
-BAR sizing/assignment;
-MSI/MSI-X;
-PCIe capabilities;
-ROM;
-reset/power相关 bits。

用户读写不会无条件直达硬件。

5. Reset

可能使用:

  • Function Level Reset;
  • PM reset;
  • bus/slot reset;
  • vendor reset;
    -hot reset。

若 reset影响同 bus其他设备,必须把相关设备纳入协调范围。

6. Open

Open启用 device、保存状态、设置 power、初始化 config/IRQ。Close禁用 IRQ、reset并恢复 host可接受状态。

7. SR-IOV

PF/VF关系、VF token和 reset隔离很关键。把 VF交出不代表 PF管理面不受信任;PF driver和 firmware必须支持安全隔离。

8. Binding

可通过 PCI ID表或 driver_override=vfio-pci绑定。切换前必须:

-停止原 driver业务;
-unbind;
-确认 group;
-确认 reset;
-绑定组内全部必要 function。

9. RK3588

PCIe endpoint可能支持 BAR/MSI/reset,但本 DTS root complex无 iommu-map。即使 vfio-pci能 bind,也可能没有安全 Type1 DMA domain,不能用于生产直通。

VFIO Platform 与 AMBA 设备

VFIO Platform 与 AMBA 设备

1. 目标

Platform VFIO把非PCI MMIO设备的 resources和 IRQ导出给用户态。ARM/ARM64可选。

2. 对象

vfio_platform_device保存:

  • vfio_device;
  • platform/AMBA parent;
  • regions;
  • IRQs;
  • reset callback/module;
  • open count;
  • locks。

3. Probe

1
2
3
4
5
vfio-platform driver binds
-> initialize vfio device
-> enumerate resources
-> discover reset
-> vfio_register_group_dev

只有具备 IOMMU group和可安全接管条件的 device才适合。

4. Region

Platform memory resources变成 VFIO regions,支持 GET_REGION_INFO和 read/write/mmap。Resource flags和 page边界决定 mmap能力。

5. IRQ

每个 platform IRQ是一个 VFIO IRQ index,通过 eventfd触发;level IRQ可 automask,用户完成后 unmask。

6. Reset

本树 reset插件只包含:

  • Calxeda XGMAC;
  • AMD XGBE;
  • Broadcom FlexRM。

没有 Rockchip通用 reset插件。vfio-platform模块参数 reset_required默认是 true;找不到/执行 reset失败会使 device open失败。AMBA路径明确把 reset_required设为 false,但这只是接口策略差异,不证明设备可安全交接。

7. Driver override

Platform VFIO通常不能像 PCI按 vendor/device自动安全匹配任意设备;通过 override/bind操作接管必须确保原 driver、clocks、power domain和 child全部处理。

8. AMBA

vfio_amba.c复用 platform base,适用于 AMBA device模型;RK3588多数 IP是 platform device,不是 AMBA PrimeCell枚举。

9. RK3588困难

集成 IP常依赖:

-多个 clocks/resets;
-power domain;
-IOMMU;
-firmware;
-共享 GRF;
-多个子设备;
-vendor kernel API。

通用 VFIO platform只导出 MMIO/IRQ,不能自动虚拟化这些控制面。

10. 结论

不要把 NPU/VPU/ISP绑定 vfio-platform就视为可透传。需要专用 reset、PM、IOMMU和 guest设备模型设计。

Mdev 与厂商迁移驱动

Mdev 与厂商迁移驱动

1. Mediated device

Mdev让 parent driver把物理设备切成软件管理实例:

1
2
3
4
5
6
physical parent
-> supported_type
-> create UUID instance
-> mdev device
-> vfio mdev driver
-> userspace/QEMU

隔离由 parent driver实现,不是 IOMMU自动完成。

2. Sysfs

Parent注册 supported types,用户向 create写 UUID;实例目录可 remove。Available instances和类型属性由 parent提供。

3. Mdev bus

mdev_core.c管理 parent/type/device生命周期;mdev_driver.c管理 mdev driver匹配和 probe/remove。

4. VFIO

具体 parent/mdev driver提供 region、IRQ、DMA、reset和 migration行为。只有注册一个 mdev对象并不自动生成完整设备模型。

5. 厂商 VFIO PCI

本树:

  • mlx5 VFIO PCI;
  • HiSilicon accelerator VFIO PCI。

它们基于 vfio-pci core增加 migration、state transfer和 dirty tracking,绑定范围由 PCI ID和硬件能力限定。

6. Migration

Vendor driver负责:

  • freeze/quiesce;
    -保存 device state;
    -导出 migration data;
    -恢复;
    -版本/firmware兼容;
    -dirty DMA报告。

7. 安全

Parent必须保证各实例:

-DMA隔离;
-MMIO/register过滤;
-IRQ隔离;
-资源配额;
-reset互不影响;
-迁移数据验证。

实现缺陷可跨 VM泄露。

8. RK3588

主树中未发现为 Rockchip NPU/VPU/GPU/ISP实现的 mdev parent。CONFIG_VFIO_MDEV即使开启也不会自动产生可用 mediated device。

9. GPU概念

Mdev不等于 SR-IOV;SR-IOV由硬件 PF创建 VF。也不应把任何 GPU切分能力泛称“GPU SR-IOV类”,具体隔离机制必须按 driver确认。

No-IOMMU 模式与安全边界

No-IOMMU 模式与安全边界

1. 定义

CONFIG_VFIO_NOIOMMU允许无 IOMMU设备复用 VFIO接口,但设备 DMA仍使用主机物理地址,没有内存隔离。

2. 启用

通常还需模块参数允许 unsafe no-IOMMU。使用会 taint kernel,Kconfig明确标记 unsupported。

3. 权限

Core要求高权限,如 CAP_SYS_RAWIO。这只是访问控制,不会让 DMA变安全。

4. 风险

设备或用户程序可:

-读写任意主机 RAM;
-修改内核代码/凭据;
-读取其他进程密钥;
-破坏文件缓存;
-绕过 VM隔离;
-造成不可恢复系统损坏。

5. 不能用于VM安全直通

Kconfig明确说明 no-IOMMU不提供 DMA translation,不能作为安全 VM assignment方案。即便 QEMU能打开接口,也不构成隔离。

6. 适用范围

仅可考虑:

-完全可信、隔离实验机;
-开发原型;
-无 DMA能力设备;
-设备 DMA由外部硬件防火墙限制且经过独立验证。

生产、多租户、联网设备不应启用。

7. 与UIO

No-IOMMU VFIO可能提供更统一 region/IRQ接口,但安全性并不优于未隔离的 UIO DMA。选择接口不能替代威胁模型。

8. RK3588

由于 PCIe root未见 IOMMU映射,启用 no-IOMMU可能看似能让 vfio-pci工作,但这是绕过问题,不是解决问题。

9. 加固

  • kernel config关闭 VFIO_NOIOMMU;
    -禁止 unsafe module parameter;
    -限制 /dev/vfio权限;
    -模块签名;
    -禁用无用 vfio driver;
    -审计 driver_override/bind;
    -监控 kernel taint。

RK3588 IOMMU 与 PCIe 透传可行性

RK3588 IOMMU 与 PCIe 透传可行性

1. 配置现状

rockchip_linux_defconfig

  • PCI/PCIe Rockchip host开启;
  • Rockchip IOMMU开启;
    -未显式开启 VFIO、VFIO PCI、VFIO platform和 KVM。

因此默认镜像不能直接使用 VFIO。

2. Rockchip IOMMU连接

rk3588s.dtsiiommus主要出现在:

  • NPU;
  • VPU/JPEG/IEP/RGA;
  • ISP/CIF/FEC;
  • VOP。

这些是集成 multimedia IP的专用 MMU。

3. MMU-600节点

rk3588s.dtsi还声明了 mmu600_pciemmu600_php两个 ARM SMMUv3节点,但它们默认 status = "disabled"。在 RK3588 DTS范围内未发现设备引用这两个节点,也未发现 PCIe iommu-map

4. PCIe关键事实

本树 RK3588 PCIe root nodes包含:

  • ranges;
  • MSI msi-map到 GIC ITS;
  • clocks/PHY/power domain;

但未发现 iommu-map。因此 downstream PCIe requester ID没有映射到 Rockchip IOMMU/SMMU。

5. 结论

不能因为 ROCKCHIP_IOMMU=y就宣称 PCIe endpoint可安全 vfio-pci直通。PCIe ATU inbound/outbound window也不是按 guest IOVA提供隔离的通用 IOMMU。

6. IOMMU Group检查

实际运行必须验证:

1
2
3
readlink -f /sys/bus/pci/devices/0000:*/iommu_group
find /sys/kernel/iommu_groups -type l
dmesg | grep -Ei 'iommu|rockchip.*iommu'

没有 group或只有 no-IOMMU group,不能使用 Type1安全映射。

7. Integrated IP

集成 IP虽有 iommus,仍不等于能直接 vfio-platform:

-缺 Rockchip reset插件;
-power/clock/firmware复杂;
-可能共享 IOMMU或资源;
-guest无标准设备模型;
-host vendor driver可能管理多个 blocks;
-secure firmware/GRF依赖。

8. MSI

msi-map只把 PCI requester MSI路由到 ITS。它解决中断地址翻译,不限制普通 DMA。

9. KVM

要做 ARM64 VM直通还需:

  • KVM host;
  • userspace VMM/QEMU;
    -完整 IOMMU;
    -irqchip/ITS支持;
    -guest资源描述;
    -reset;
    -group isolation。

本 defconfig未显示 KVM,需产品配置补齐。

10. 推荐

RK3588产品优先使用 virtio/共享内存/专用后端暴露加速能力,而不是直接 platform passthrough。PCIe安全直通需 SoC/板级硬件明确提供 IOMMU路径后再评估。