12

I'd like to verify on any given Linux machine if PCI passthrough is supported. After a bit of googling, I found that I should rather check if IOMMU is supported, and I did so by running:

dmesg | grep IOMMU   

If it supports IOMMU (and not IOMMUv2), I would get:

IOMMU                                                          
[    0.000000] DMAR: IOMMU enabled
[    0.049734] DMAR-IR: IOAPIC id 8 under DRHD base  0xfbffc000 IOMMU 0
[    0.049735] DMAR-IR: IOAPIC id 9 under DRHD base  0xfbffc000 IOMMU 0
[    1.286567] AMD IOMMUv2 driver by Joerg Roedel <jroedel@suse.de>
[    1.286568] AMD IOMMUv2 functionality not available on this system

...where DMAR: IOMMU enabled is what I'm looking for.

Now, if the machine has been running for days without a reboot, that first message [ 0.000000] DMAR: IOMMU enabled might not appear any more in the log with the previous command.

Is there any way to check for IOMMU support when that message disappears from the log?

Ricky Robinson
  • 21,798
  • 42
  • 129
  • 185
  • 2
    Kernel dmesg is logged to some file in `/var/log`: kern.log and/or messages. Check also /sys/class/iommu directory – osgx May 31 '17 at 13:55
  • 5
    I'm voting to close this question as off-topic because it should go to https://unix.stackexchange.com/ – Basile Starynkevitch May 31 '17 at 13:55
  • 2
    Better then checking the kernel log is using the command: virt-host-validate. I agree this belongs on unix.stackexchange.com, but this question is still the first hit when googling for 'linux check iommu support'. – Andreas Raster Dec 13 '17 at 20:51
  • Thanks! I didn't know about that command. In its 1.2.20 version it doesn't tell me much, but I just checked with version 2.2.0 and it's a lot more helpful: `QEMU: Checking for device assignment IOMMU support : PASS QEMU: Checking if IOMMU is enabled by kernel : WARN (IOMMU appears to be disabled in kernel. Add intel_iommu=on to kernel cmdline arguments) ` – Ricky Robinson Dec 14 '17 at 13:33

1 Answers1

8

Since 2014 enabled iommu are registered in /sys (sysfs) special file system as class iommu (documented at ABI/testing/sysfs-class-iommu): https://patchwork.kernel.org/patch/4345491/ "[2/3] iommu/intel: Make use of IOMMU sysfs support" - June 12, 2014

Register our DRHD IOMMUs, cross link devices, and provide a base set of attributes for the IOMMU. ... On a typical desktop system, this provides the following (pruned):

$ find /sys | grep dmar
/sys/devices/virtual/iommu/dmar0
...
/sys/class/iommu/dmar0
/sys/class/iommu/dmar1

The code is iommu_device_create (http://elixir.free-electrons.com/linux/v4.5/ident/iommu_device_create, around 4.5) or iommu_device_sysfs_add (http://elixir.free-electrons.com/linux/v4.11/ident/iommu_device_sysfs_add) in more recent kernels.

/*
 * Create an IOMMU device and return a pointer to it.  IOMMU specific
 * attributes can be provided as an attribute group, allowing a unique
 * namespace per IOMMU type.
 */
struct device *iommu_device_create(struct device *parent, void *drvdata,
                   const struct attribute_group **groups,
                   const char *fmt, ...)

Registration is done only for enabled IOMMU. DMAR:

if (intel_iommu_enabled) {
    iommu->iommu_dev = iommu_device_create(NULL, iommu,
                           intel_iommu_groups,
                           "%s", iommu->name);

AMD IOMMU:

static int iommu_init_pci(struct amd_iommu *iommu)
{ ...
    if (!iommu->dev)
        return -ENODEV;
...
    iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu,
                           amd_iommu_groups, "ivhd%d",
                           iommu->index);

Intel:

int __init intel_iommu_init(void)
{ ...
    pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
...
    for_each_active_iommu(iommu, drhd)
        iommu->iommu_dev = iommu_device_create(NULL, iommu,
                               intel_iommu_groups,
                               "%s", iommu->name);

With 4.11 linux kernel version iommu_device_sysfs_add is referenced in many IOMMU drivers, so checking /sys/class/iommu is better (more universal) way to programmatically detect enabled IOMMU than parsing dmesg output or searching in /var/log/kern.log or /var/log/messages for driver-specific enable messages:

Referenced in 10 files:

  • drivers/iommu/amd_iommu_init.c, line 1640
  • drivers/iommu/arm-smmu-v3.c, line 2709
  • drivers/iommu/arm-smmu.c, line 2163
  • drivers/iommu/dmar.c, line 1083
  • drivers/iommu/exynos-iommu.c, line 623
  • drivers/iommu/intel-iommu.c, line 4878
  • drivers/iommu/iommu-sysfs.c, line 57
  • drivers/iommu/msm_iommu.c, line 797
  • drivers/iommu/mtk_iommu.c, line 581
osgx
  • 90,338
  • 53
  • 357
  • 513
  • Thanks. So ideally I would just have to check for a given PCI device if its PCI address appears in `/sys/devices/virtual/iommu/dmar0/devices/` ? I don't understand why you include several snippets of code in the rest of your answer. – Ricky Robinson May 31 '17 at 14:10
  • 1
    Also check your PCI folder in sysfs, it may has iommu or iommu_group links to the specific IOMMU. (Checking for DMAR is not too portable, it will not work on ARM). Code snippets to show that iommu files/dirs in sysfs will be registered only when IOMMU is enabled. – osgx May 31 '17 at 14:15
  • 1
    Ok, thanks. I noticed that on machines where PCI passthrough is not supported, the folder `/sys/class/iommu` exists but it's empty, whereas on machines where it is supported it contains a folder `dmar0`, which itself contains `devices intel-iommu power subsystem uevent`. So checking if `/sys/class/iommu` is empty or not should already yield some answer. How should I perform the second check in `sysfs`? I'm not sure I understand where and what to check... Thanks!!! – Ricky Robinson May 31 '17 at 14:24
  • 2
    Ricky, yes, the `/sys/class/iommu` folder is almost always there (when sysfs is mounted). You should do ls (readdir) of its subfolders: `ls -l /sys/class/iommu/*`, or event `ls -l /sys/class/iommu/*/devices` to find devices which have iommu enabled. – osgx May 31 '17 at 14:53
  • will DMAR present in AMD also? – Alok Prasad Nov 23 '20 at 06:37