I/O MMU

2019-08-15 Aditya Basu (mitthu)

Contents

  • Acronyms
  • I/O MMU Workings
    • IOTLB shootdowns
  • Running Akaros in QEMU
  • Example Interaction via sysfs

Acronyms

  • IEC: Interrupt Entry Cache
  • RWBF: Required Write-Buffer Flushing
  • IVT: Invalidate IOTLB

I/O MMU Workings

IOTLB Shootdowns / flushing

  • If RWBF set in capability, then perform write buffer flushing.
  • If IOTLB is present, then we can perform one of the following:
    • global shootdown
    • DID specific shootdown (We perform this!)
    • page-specific shootdown for a specific DID

Running Akaors in QEMU

  • Currently running in QEMU requires a recompilation. This is to allow 4-level paging for the IOMMU. Do the following:
    • For qemu version 4.0.50, we need to modify line 52 of “include/hw/i386/intel_iommu.h”.
    • The macro VTD_HOST_ADDRESS_WIDTH will be VTD_HOST_AW_39BIT. Change it to VTD_HOST_AW_48BIT and recompile.
# Prepare device for passthrough (on Linux host)
# - unbind from existing driver
# - make sure the VFIO module is loaded
# - make sure all virtual functions are released by the driver
# - bind to VFIO driver for passthrough
$ PCIDEVICE_BDF=0000:00:04.*
$ echo $(PCIDEVICE_BDF) | sudo tee /sys/bus/pci/devices/$(PCIDEVICE_BDF)/driver/unbind
$ sudo modprobe vfio-pci
$ sudo rmmod ioatdma
$ echo $(PCIDEVICE_ID) | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id

# Standard run
$ sudo $(QEMU) \
    -enable-kvm \
    -cpu host \
    -smp 8 \
    -m 4096 \
    -nographic \
    -net nic,model=e1000 \
    -net user,hostfwd=tcp::5555-:22 \
    -machine q35,accel=kvm,kernel-irqchip=split \
    -device intel-iommu,intremap=off,caching-mode=on,device-iotlb=on \
    -device vfio-pci,host=00:04.0 \
    -kernel obj/kern/akaros-kernel

# Trace QEMU calls (for debugging)
$ echo -n '' >/tmp/qemu-trace
$ echo 'vfio_pci_read_config' >>/tmp/qemu-trace
$ echo 'vfio_pci_write_config' >>/tmp/qemu-trace
$ echo 'vfio_region_read' >>/tmp/qemu-trace
$ echo 'vfio_region_write' >>/tmp/qemu-trace
$ echo 'pci_data_read' >>/tmp/qemu-trace

$ sudo $(QEMU) \
    -trace events=/tmp/qemu-trace \
    -enable-kvm \
    -cpu host \
    -smp 8 \
    -m 4096 \
    -nographic \
    -net nic,model=e1000 \
    -net user,hostfwd=tcp::5555-:22 \
    -device vfio-pci,host=00:04.0 \
    -kernel obj/kern/akaros-kernel

Example Interaction via sysfs

# Mount the device
bash-4.3$ mkdir -p /sys/iommu
bash-4.3$ /bin/bind \#iommu /sys/iommu
bash-4.3$ cd /sys/iommu/

# All files
bash-4.3$ ls
attach    detach    info      mappings  power

# Attach devices
bash-4.3$ echo 0:3.0 1 >attach
bash-4.3$ echo 0:0.0 22 >attach
bash-4.3$ echo 0:1:0 22 >attach
bash-4.3$ echo 0:2.0 26 >attach

# Display mappings
bash-4.3$ cat mappings
Mappings for iommu@0xffff8001090acce8
        pid = 1
                device = 0:3.0
        pid = 22
                device = 0:0.0
                device = 0:1.0
        pid = 26
                device = 0:2.0

# Detach devices
bash-4.3$ echo 0:2.0 >detach
bash-4.3$ echo 0:1:0 >detach
bash-4.3$ cat mappings
Mappings for iommu@0xffff8001090acce8
        pid = 1
                device = 0:3.0
        pid = 22
                device = 0:0.0

# Display IOMMU information
bash-4.3$ cat info
driver info:
        default did = 1
        status = enabled

iommu@0xffff8001090ab0e8
        rba = 0x00000000fed90000
        supported = yes
        num_assigned_devs = 0
        regspace = 0xfffffff000000000
        host addr width (dmar) = 48
        host addr width (cap[mgaw]) = 48
        version = 0x10
        capabilities = 0x00d2008c222f0686
                mgaw: 48
                sagaw (paging level): 0x6
                caching mode: yes (1)
                zlr: 0x0
                rwbf: not required
                num domains: 65536
                supports protected high-memory region: no
                supports Protected low-memory region: no
        ext. capabilities = 0x0000000000000f46
                pass through: yes
                device iotlb: yes
                iotlb register offset: 0xf0
                snoop control: no
                coherency: no
                queue invalidation support: yes
                interrupt remapping support: no
                extended interrupt mode: 0x0
        global status = 0xc0000000
                translation: enabled
                root table: set
        root entry table = 0x00000001090aa000 (phy) or 0xffff8001090aa000 (vir)

# Turn off IOMMU (global)
bash-4.3$ cat power
IOMMU status: enabled
Write 'enable' or 'disable' OR 'on' or 'off' to change status

bash-4.3$ echo -n off >power

bash-4.3$ cat power
IOMMU status: disabled
Write 'enable' or 'disable' OR 'on' or 'off' to change status