aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/dmar.c
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2014-06-12 18:12:31 -0400
committerJoerg Roedel <jroedel@suse.de>2014-07-04 06:35:59 -0400
commita5459cfece880e82778a60e6290ad6c0dd688a06 (patch)
treef032c49a317bc56b2d3a9883933b1b154a037fdf /drivers/iommu/dmar.c
parentc61959ecbbc6bf9034e65c8e8ef03fa9d1066f05 (diff)
iommu/vt-d: Make use of IOMMU sysfs support
Register our DRHD IOMMUs, cross link devices, and provide a base set of attributes for the IOMMU. Note that IRQ remapping support parses the DMAR table very early in boot, well before the iommu_class can reasonably be setup, so our registration is split between intel_iommu_init(), which occurs later, and alloc_iommu(), which typically occurs much earlier, but may happen at any time later with IOMMU hot-add support. On a typical desktop system, this provides the following (pruned): $ find /sys | grep dmar /sys/devices/virtual/iommu/dmar0 /sys/devices/virtual/iommu/dmar0/devices /sys/devices/virtual/iommu/dmar0/devices/0000:00:02.0 /sys/devices/virtual/iommu/dmar0/intel-iommu /sys/devices/virtual/iommu/dmar0/intel-iommu/cap /sys/devices/virtual/iommu/dmar0/intel-iommu/ecap /sys/devices/virtual/iommu/dmar0/intel-iommu/address /sys/devices/virtual/iommu/dmar0/intel-iommu/version /sys/devices/virtual/iommu/dmar1 /sys/devices/virtual/iommu/dmar1/devices /sys/devices/virtual/iommu/dmar1/devices/0000:00:00.0 /sys/devices/virtual/iommu/dmar1/devices/0000:00:01.0 /sys/devices/virtual/iommu/dmar1/devices/0000:00:16.0 /sys/devices/virtual/iommu/dmar1/devices/0000:00:1a.0 /sys/devices/virtual/iommu/dmar1/devices/0000:00:1b.0 /sys/devices/virtual/iommu/dmar1/devices/0000:00:1c.0 ... /sys/devices/virtual/iommu/dmar1/intel-iommu /sys/devices/virtual/iommu/dmar1/intel-iommu/cap /sys/devices/virtual/iommu/dmar1/intel-iommu/ecap /sys/devices/virtual/iommu/dmar1/intel-iommu/address /sys/devices/virtual/iommu/dmar1/intel-iommu/version /sys/class/iommu/dmar0 /sys/class/iommu/dmar1 (devices also link back to the dmar units) This makes address, version, capabilities, and extended capabilities available, just like printed on boot. I've tried not to duplicate data that can be found in the DMAR table, with the exception of the address, which provides an easy way to associate the sysfs device with a DRHD entry in the DMAR. It's tempting to add scopes and RMRR data here, but the full DMAR table is already exposed under /sys/firmware/ and therefore already provides a way for userspace to learn such details. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/dmar.c')
-rw-r--r--drivers/iommu/dmar.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 9a4f05e5b23f..6744e2d4ff6f 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -38,6 +38,7 @@
38#include <linux/tboot.h> 38#include <linux/tboot.h>
39#include <linux/dmi.h> 39#include <linux/dmi.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/iommu.h>
41#include <asm/irq_remapping.h> 42#include <asm/irq_remapping.h>
42#include <asm/iommu_table.h> 43#include <asm/iommu_table.h>
43 44
@@ -980,6 +981,12 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
980 raw_spin_lock_init(&iommu->register_lock); 981 raw_spin_lock_init(&iommu->register_lock);
981 982
982 drhd->iommu = iommu; 983 drhd->iommu = iommu;
984
985 if (intel_iommu_enabled)
986 iommu->iommu_dev = iommu_device_create(NULL, iommu,
987 intel_iommu_groups,
988 iommu->name);
989
983 return 0; 990 return 0;
984 991
985 err_unmap: 992 err_unmap:
@@ -991,6 +998,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
991 998
992static void free_iommu(struct intel_iommu *iommu) 999static void free_iommu(struct intel_iommu *iommu)
993{ 1000{
1001 iommu_device_destroy(iommu->iommu_dev);
1002
994 if (iommu->irq) { 1003 if (iommu->irq) {
995 free_irq(iommu->irq, iommu); 1004 free_irq(iommu->irq, iommu);
996 irq_set_handler_data(iommu->irq, NULL); 1005 irq_set_handler_data(iommu->irq, NULL);