linux用户态驱动--VFIO(一)

linux⽤户态驱动--VFIO(⼀)
序⾔
设备驱动可以运⾏在内核态,也可以运⾏在⽤户态,不管⽤户态驱动还是内核态驱动,他们都有各⾃的缺点。内核态驱动的问题是:系统调⽤开销⼤;学习曲线陡峭;接⼝稳定性差;调试困难;bug致命;编程语⾔选择受限;⽽⽤户态驱动⾯临的挑战是:如何中断处理;如何DMA;如何管理设备的依赖关系;⽆法使⽤内核服务等。对此,《》 ⼀⽂有较详细描述。
可能是为了性能优化,或者为了故障隔离,或者为了逃避开源许可证的约束,不管是基于何种⽬的,linux已有多种⽤户态驱动的实现,如UIO,VFIO、USB⽤户态驱动等。它们在处理中断、DMA、设备依赖管理等⽅⾯的设计⽅案和实现细节上各有千秋,这是《User-Space Device Drivers in Linux: A First Look》 没有提到的,也是本⽂的重点。
UIO
UIO 框架导出sysfs和/dev/uioX 2套⽤户态接⼝,⽤户对设备节点/dev/uioX进⾏设备控制,mmap()接⼝⽤于映射设备寄存器空
另眼看羽球间,write()接⼝⽤于控制中断关闭/打开,read()接⼝⽤于等待⼀个设备中断。
因为对于设备中断的应答必须在内核空间进⾏,所以在内核空间有⼀⼩部分代码⽤来应答中断和禁⽌中断,其余的⼯作全部留给⽤户空间处理。如果⽤户空间要等待⼀个设备中断,它只需要简单的阻塞在对 /dev/uioX的read()操作上。 当设备产⽣中断时,read()操作⽴即返回。UIO 也实现了poll()系统调⽤,你可以使⽤ select()来等待中断的发⽣。select()有⼀个超时参数可以⽤来实现有限时间内等待中断。
UIO的⼏个特点:
冠东集装箱码头⼀个UIO设备最多⽀持5个mem和portio空间mmap映射。
UIO设备的中断⽤户态通信机制基于wait_queue实现。
⼀个UIO设备只⽀持⼀个中断号注册,⽀持中断共享。
总的来说,UIO框架适⽤于简单设备的驱动,因为它不⽀持DMA,不能⽀持多个中断线,缺乏逻辑设备抽象能⼒。
IOMMU
李维淼
这⾥IOMMU是指位于北桥上的IOMMU,那种设备⾃带IOMMU的情况我还不了解。
在没有IOMMU的情况下,设备(指32bit或64bit设备,⽼的16bit的不提)的DMA操作可以访问整个物理地址空间,所以理论上设备可以向操作系统的代码段、数据段等内存区域做DMA,从⽽破坏整个系统。当然,通常来说不会有这样的设备。IOMMU的出现,可以实现地址空间上的隔离,使设备只能访问规定的内存区域。下⾯简要说⼀下intel的IOMMU怎么做到这点的:
⽬前PC架构最多有256PCI总线,于是IOMMU⽤⼀个称为root entry的数据结构描述PCI总线,总共256个root entry构成⼀张表。每条PCI总线最多允许256个设备,IOMMU⽤context entry描述⼀个PCI设备(或者是PCI桥),256个context entry构成⼀张表。所以就有了如图的关系。我们知道,PCI设
陶相礼
备⽤ {BUSEV:FUNC}(当然,还有个segment,不过似乎PC架构都只有⼀个segment,这个暂时忽略)描述⼀个设备。所以对于⼀个特定设备,⽤bus号做索引root entry表,⽤dev号索引context entry表可以到描述该设备的的context entry。context entry中有⼀个指针指向⼀章I/O页表,当设备发起DMA操作时,IOMMU会根据该页表把设备的DMA地址转换成该设备可以访问内存区域的地址。
所以只要为设备建⼀张I/O页表,就可以使设备只能访问规定的内存区域了。当然,也可以把该页表当成跳板,让只能寻址32bit地址空间的设备访问到64bit地址空间中去。
VFIO
胡德利
上⽂提到,UIO不⽀持DMA,所以通过DMA传输⼤流量数据的IO设备,如⽹卡、显卡等设备,⽆法使⽤UIO框架,VFIO做为UIO的升级版,主要就是解决了这个问题。通过⽤户态配置IOMMU接⼝,可以将DMA地址空间映射限制在进程虚拟空间中。这对⾼性能驱动和虚拟化场景device passthrough尤其重要。
在VFIO框架中,有⼏个核⼼概念或对象:IOMMU、/dev/vfio、container、iommu_group。
IOMMU是⼀个硬件单元,它可以把设备的IO地址映射成虚拟地址,为设备提供页表映射,设备通过IOMMU将数据直接DMA写到⽤户空间。之所以不共⽤MMU单元,是为了保证和进程的页表相互独⽴,防⽌设备访问进程的任意地址空间。所以VFIO的IOMMU功能保障了安全的⾮特权级别的⽤户态设备驱动机制。
/dev/vfio是⼀个设备⽂件,作为⼀个IOMMU设备的⽤户态呈现。
container是内核对象,表⽰⼀个IOMMU设备,是⼀个IOMMU设备的内核态呈现。所以在VFIO中,container是IOMMU操作的最⼩对象。
在虚拟化场景下,⼀个物理⽹卡可能要虚拟成⼏个虚拟⽹卡,或者说虚拟功能设备(VF),这⼏个VF共⽤⼀个IOMMU,所以VFIO模型增加⼀个iommu_group的概念,⽤来表⽰共享同⼀个IOMMU的⼀组device。
VFIO的⼏个特点:
VFIO设备⽀持多中断号注册。
设备的中断⽤户态通信机制基于eventfd/irqfd实现。⽤户通过/dev/vfio设备select/poll/epoll,从⽽实现中断从内核态到⽤户态的异步事件通知。
⽀持对物理设备进⾏逻辑抽象。
仅⽀持pci intx中断共享,其他类型中断不⽀持共享。
VFIO仅⽀持特定IOMMU设备,如x86与PowerPC平台的PCI设备和ARM平台的platform设备。
USB⽤户态驱动春藕斋
usbfs(USB file system)提供了⼀些在⽤户空间下操作USB设备的函数接⼝和数据结构, 在开发⽤户态驱动时, 可以直接利⽤这些函数接⼝来实现对 USB 设备的控制和数据传输。
libusb对usb file system提供的函数接⼝和数据结构进⾏了封装, 可以有效减少程序中函数和数据结构使⽤不当造成的错误。Libusb 对USB 设备的访问提供了两种机制, 同步访问和异步访问。
khubd是内核后台线程,⽤来管理监视USB HUB的状态, ⼀旦发⽣热插拔就会唤醒这个线程, 进⽽添加或者移除设备,并发送netlink消息传递给⽤户态空间。
USB ⽤户态驱动框架的⼏个特点:
设备的中断⽤户态通信机制基于netlink实现。
USB设备以usbdevfs(后改名为usbfs)⽂件系统的形式(如/proc/bus/usb/BBB/DDD)对⽤户态呈现。
对usb的所有访问通过usbfs ioctl实现,如control transfer, bulk transfer, reset等。
仅⽀持USB设备

本文发布于:2024-09-25 04:35:07,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/349528.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:设备   中断   户态   驱动
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议