Hi,
IOMMU provides a page table mapping between device and memory address. It restricts a particular device to access physical memory potentially out of its range. From the Intel Direct IO manual, I understand that the IOMMU table is indexed by bus number in root-entry table and devfn at context-entry table to point to an address translation structure.
For a CPU to write to a memory address (ex: RAM), the IO request has source id as root complex (Bus=0 ,devfn=0).
I assume CPU write to memory also needs to go through the IOMMU. This write request is first validated by IOMMU table with the root complex source id (bus=0, devfn=0). Others devices goes through the same process to read/write memory space.
My question is: In x86 Linux, is it possible to create a virtual driver (without any physical device exists), assign it with a fake available id (ex: Bus=0, devfn=8). And when this driver sends a read/write request, does it lookups the IOMMU table using this fake source id?
This comes to another question: how does a PCI device know its id? or it doesn't? If it does, the BIOS/Kernel needs to write the id to each device registers so that device DMA request contains its own id.
Thanks!
William
IOMMU for memory protection
Re: IOMMU for memory protection
I found the answer in the book "PCI Express System Architecture", chapter 21.
The root complex performs a device enumeration when starts up (mostly BIOS does this enumeration and pass to kernel). After enumeration, the kernel/BIOS has a complete view of PCI topology, consisting of all the device id, bridge id, and their physical location. But this is the information inside kernel/BIOS, how does the device know its own id (bus, dev, fn)?
Each time the root complex initiates a configuration write, it must supply the destination device id (bus, dev, fn) in the TLP. The receiving device learns the id of itself from this TLP and saved in a function-specific manner. In brief, the id of a device is tied with the physical topology and assigned by root complex when doing configuration write. So it's impossible to create a virtual driver and assign an arbitrary id to it.
Hope this information is helpful for others.
William
The root complex performs a device enumeration when starts up (mostly BIOS does this enumeration and pass to kernel). After enumeration, the kernel/BIOS has a complete view of PCI topology, consisting of all the device id, bridge id, and their physical location. But this is the information inside kernel/BIOS, how does the device know its own id (bus, dev, fn)?
Each time the root complex initiates a configuration write, it must supply the destination device id (bus, dev, fn) in the TLP. The receiving device learns the id of itself from this TLP and saved in a function-specific manner. In brief, the id of a device is tied with the physical topology and assigned by root complex when doing configuration write. So it's impossible to create a virtual driver and assign an arbitrary id to it.
Hope this information is helpful for others.
William