Linux 6.9-rc1
[linux-2.6-microblaze.git] / drivers / iommu / intel / dmar.c
index 70d324c..36d7427 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/pci.h>
 #include <linux/dmar.h>
 #include <linux/iova.h>
-#include <linux/intel-iommu.h>
 #include <linux/timer.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/numa.h>
 #include <linux/limits.h>
 #include <asm/irq_remapping.h>
-#include <trace/events/intel_iommu.h>
 
+#include "iommu.h"
 #include "../irq_remapping.h"
 #include "perf.h"
+#include "trace.h"
+#include "perfmon.h"
 
 typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *);
 struct dmar_res_callback {
@@ -60,7 +61,7 @@ LIST_HEAD(dmar_drhd_units);
 
 struct acpi_table_header * __initdata dmar_tbl;
 static int dmar_dev_scope_status = 1;
-static unsigned long dmar_seq_ids[BITS_TO_LONGS(DMAR_UNITS_SUPPORTED)];
+static DEFINE_IDA(dmar_seq_ids);
 
 static int alloc_iommu(struct dmar_drhd_unit *drhd);
 static void free_iommu(struct intel_iommu *iommu);
@@ -126,8 +127,6 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event)
        struct pci_dev *tmp;
        struct dmar_pci_notify_info *info;
 
-       BUG_ON(dev->is_virtfn);
-
        /*
         * Ignore devices that have a domain number higher than what can
         * be looked up in DMAR, e.g. VMD subdevices with domain 0x10000
@@ -263,7 +262,8 @@ int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
                                                   get_device(dev));
                                return 1;
                        }
-               BUG_ON(i >= devices_cnt);
+               if (WARN_ON(i >= devices_cnt))
+                       return -EINVAL;
        }
 
        return 0;
@@ -382,7 +382,7 @@ static int dmar_pci_bus_notifier(struct notifier_block *nb,
 
 static struct notifier_block dmar_pci_bus_nb = {
        .notifier_call = dmar_pci_bus_notifier,
-       .priority = INT_MIN,
+       .priority = 1,
 };
 
 static struct dmar_drhd_unit *
@@ -427,6 +427,8 @@ static int dmar_parse_one_drhd(struct acpi_dmar_header *header, void *arg)
        memcpy(dmaru->hdr, header, header->length);
        dmaru->reg_base_addr = drhd->address;
        dmaru->segment = drhd->segment;
+       /* The size of the register set is 2 ^ N 4 KB pages. */
+       dmaru->reg_size = 1UL << (drhd->size + 12);
        dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
        dmaru->devices = dmar_alloc_dev_scope((void *)(drhd + 1),
                                              ((void *)drhd) + drhd->header.length,
@@ -820,6 +822,7 @@ int __init dmar_dev_scope_init(void)
                        info = dmar_alloc_pci_notify_info(dev,
                                        BUS_NOTIFY_ADD_DEVICE);
                        if (!info) {
+                               pci_dev_put(dev);
                                return dmar_dev_scope_status;
                        } else {
                                dmar_pci_bus_add_dev(info);
@@ -955,17 +958,18 @@ static void unmap_iommu(struct intel_iommu *iommu)
 /**
  * map_iommu: map the iommu's registers
  * @iommu: the iommu to map
- * @phys_addr: the physical address of the base resgister
+ * @drhd: DMA remapping hardware definition structure
  *
  * Memory map the iommu's registers.  Start w/ a single page, and
  * possibly expand if that turns out to be insufficent.
  */
-static int map_iommu(struct intel_iommu *iommu, u64 phys_addr)
+static int map_iommu(struct intel_iommu *iommu, struct dmar_drhd_unit *drhd)
 {
+       u64 phys_addr = drhd->reg_base_addr;
        int map_size, err=0;
 
        iommu->reg_phys = phys_addr;
-       iommu->reg_size = VTD_PAGE_SIZE;
+       iommu->reg_size = drhd->reg_size;
 
        if (!request_mem_region(iommu->reg_phys, iommu->reg_size, iommu->name)) {
                pr_err("Can't reserve memory\n");
@@ -988,8 +992,6 @@ static int map_iommu(struct intel_iommu *iommu, u64 phys_addr)
                warn_invalid_dmar(phys_addr, " returns all ones");
                goto unmap;
        }
-       if (ecap_vcs(iommu->ecap))
-               iommu->vccap = dmar_readq(iommu->reg + DMAR_VCCAP_REG);
 
        /* the registers might be more than one page */
        map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
@@ -1012,6 +1014,16 @@ static int map_iommu(struct intel_iommu *iommu, u64 phys_addr)
                        goto release;
                }
        }
+
+       if (cap_ecmds(iommu->cap)) {
+               int i;
+
+               for (i = 0; i < DMA_MAX_NUM_ECMDCAP; i++) {
+                       iommu->ecmdcap[i] = dmar_readq(iommu->reg + DMAR_ECCAP_REG +
+                                                      i * DMA_ECMD_REG_STEP);
+               }
+       }
+
        err = 0;
        goto out;
 
@@ -1023,28 +1035,6 @@ out:
        return err;
 }
 
-static int dmar_alloc_seq_id(struct intel_iommu *iommu)
-{
-       iommu->seq_id = find_first_zero_bit(dmar_seq_ids,
-                                           DMAR_UNITS_SUPPORTED);
-       if (iommu->seq_id >= DMAR_UNITS_SUPPORTED) {
-               iommu->seq_id = -1;
-       } else {
-               set_bit(iommu->seq_id, dmar_seq_ids);
-               sprintf(iommu->name, "dmar%d", iommu->seq_id);
-       }
-
-       return iommu->seq_id;
-}
-
-static void dmar_free_seq_id(struct intel_iommu *iommu)
-{
-       if (iommu->seq_id >= 0) {
-               clear_bit(iommu->seq_id, dmar_seq_ids);
-               iommu->seq_id = -1;
-       }
-}
-
 static int alloc_iommu(struct dmar_drhd_unit *drhd)
 {
        struct intel_iommu *iommu;
@@ -1062,20 +1052,24 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
        if (!iommu)
                return -ENOMEM;
 
-       if (dmar_alloc_seq_id(iommu) < 0) {
+       iommu->seq_id = ida_alloc_range(&dmar_seq_ids, 0,
+                                       DMAR_UNITS_SUPPORTED - 1, GFP_KERNEL);
+       if (iommu->seq_id < 0) {
                pr_err("Failed to allocate seq_id\n");
-               err = -ENOSPC;
+               err = iommu->seq_id;
                goto error;
        }
+       sprintf(iommu->name, "dmar%d", iommu->seq_id);
 
-       err = map_iommu(iommu, drhd->reg_base_addr);
+       err = map_iommu(iommu, drhd);
        if (err) {
                pr_err("Failed to map %s\n", iommu->name);
                goto error_free_seq_id;
        }
 
        err = -EINVAL;
-       if (cap_sagaw(iommu->cap) == 0) {
+       if (!cap_sagaw(iommu->cap) &&
+           (!ecap_smts(iommu->ecap) || ecap_slts(iommu->ecap))) {
                pr_info("%s: No supported address widths. Not attempting DMA translation.\n",
                        iommu->name);
                drhd->ignored = 1;
@@ -1101,7 +1095,9 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
        iommu->agaw = agaw;
        iommu->msagaw = msagaw;
        iommu->segment = drhd->segment;
-
+       iommu->device_rbtree = RB_ROOT;
+       spin_lock_init(&iommu->device_rbtree_lock);
+       mutex_init(&iommu->iopf_lock);
        iommu->node = NUMA_NO_NODE;
 
        ver = readl(iommu->reg + DMAR_VER_REG);
@@ -1121,8 +1117,18 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
        if (sts & DMA_GSTS_QIES)
                iommu->gcmd |= DMA_GCMD_QIE;
 
+       if (alloc_iommu_pmu(iommu))
+               pr_debug("Cannot alloc PMU for iommu (seq_id = %d)\n", iommu->seq_id);
+
        raw_spin_lock_init(&iommu->register_lock);
 
+       /*
+        * A value of N in PSS field of eCap register indicates hardware
+        * supports PASID field of N+1 bits.
+        */
+       if (pasid_supported(iommu))
+               iommu->iommu.max_pasids = 2UL << ecap_pss(iommu->ecap);
+
        /*
         * This is only for hotplug; at boot time intel_iommu_enabled won't
         * be set yet. When intel_iommu_init() runs, it registers the units
@@ -1138,6 +1144,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
                err = iommu_device_register(&iommu->iommu, &intel_iommu_ops, NULL);
                if (err)
                        goto err_sysfs;
+
+               iommu_pmu_register(iommu);
        }
 
        drhd->iommu = iommu;
@@ -1148,9 +1156,10 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
 err_sysfs:
        iommu_device_sysfs_remove(&iommu->iommu);
 err_unmap:
+       free_iommu_pmu(iommu);
        unmap_iommu(iommu);
 error_free_seq_id:
-       dmar_free_seq_id(iommu);
+       ida_free(&dmar_seq_ids, iommu->seq_id);
 error:
        kfree(iommu);
        return err;
@@ -1159,10 +1168,13 @@ error:
 static void free_iommu(struct intel_iommu *iommu)
 {
        if (intel_iommu_enabled && !iommu->drhd->ignored) {
+               iommu_pmu_unregister(iommu);
                iommu_device_unregister(&iommu->iommu);
                iommu_device_sysfs_remove(&iommu->iommu);
        }
 
+       free_iommu_pmu(iommu);
+
        if (iommu->irq) {
                if (iommu->pr_irq) {
                        free_irq(iommu->pr_irq, iommu);
@@ -1183,7 +1195,7 @@ static void free_iommu(struct intel_iommu *iommu)
        if (iommu->reg)
                unmap_iommu(iommu);
 
-       dmar_free_seq_id(iommu);
+       ida_free(&dmar_seq_ids, iommu->seq_id);
        kfree(iommu);
 }
 
@@ -1261,6 +1273,8 @@ static int qi_check_fault(struct intel_iommu *iommu, int index, int wait_index)
 {
        u32 fault;
        int head, tail;
+       struct device *dev;
+       u64 iqe_err, ite_sid;
        struct q_inval *qi = iommu->qi;
        int shift = qi_shift(iommu);
 
@@ -1305,6 +1319,13 @@ static int qi_check_fault(struct intel_iommu *iommu, int index, int wait_index)
                tail = readl(iommu->reg + DMAR_IQT_REG);
                tail = ((tail >> shift) - 1 + QI_LENGTH) % QI_LENGTH;
 
+               /*
+                * SID field is valid only when the ITE field is Set in FSTS_REG
+                * see Intel VT-d spec r4.1, section 11.4.9.9
+                */
+               iqe_err = dmar_readq(iommu->reg + DMAR_IQER_REG);
+               ite_sid = DMAR_IQER_REG_ITESID(iqe_err);
+
                writel(DMA_FSTS_ITE, iommu->reg + DMAR_FSTS_REG);
                pr_info("Invalidation Time-out Error (ITE) cleared\n");
 
@@ -1314,6 +1335,19 @@ static int qi_check_fault(struct intel_iommu *iommu, int index, int wait_index)
                        head = (head - 2 + QI_LENGTH) % QI_LENGTH;
                } while (head != tail);
 
+               /*
+                * If device was released or isn't present, no need to retry
+                * the ATS invalidate request anymore.
+                *
+                * 0 value of ite_sid means old VT-d device, no ite_sid value.
+                * see Intel VT-d spec r4.1, section 11.4.9.9
+                */
+               if (ite_sid) {
+                       dev = device_rbtree_find(iommu, ite_sid);
+                       if (!dev || !dev_is_pci(dev) ||
+                           !pci_device_is_present(to_pci_dev(dev)))
+                               return -ETIMEDOUT;
+               }
                if (qi->desc_status[wait_index] == QI_ABORT)
                        return -EAGAIN;
        }
@@ -1512,6 +1546,15 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
 {
        struct qi_desc desc;
 
+       /*
+        * VT-d spec, section 4.3:
+        *
+        * Software is recommended to not submit any Device-TLB invalidation
+        * requests while address remapping hardware is disabled.
+        */
+       if (!(iommu->gcmd & DMA_GCMD_TE))
+               return;
+
        if (mask) {
                addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1;
                desc.qw1 = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE;
@@ -1577,6 +1620,15 @@ void qi_flush_dev_iotlb_pasid(struct intel_iommu *iommu, u16 sid, u16 pfsid,
        unsigned long mask = 1UL << (VTD_PAGE_SHIFT + size_order - 1);
        struct qi_desc desc = {.qw1 = 0, .qw2 = 0, .qw3 = 0};
 
+       /*
+        * VT-d spec, section 4.3:
+        *
+        * Software is recommended to not submit any Device-TLB invalidation
+        * requests while address remapping hardware is disabled.
+        */
+       if (!(iommu->gcmd & DMA_GCMD_TE))
+               return;
+
        desc.qw0 = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) |
                QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE |
                QI_DEV_IOTLB_PFSID(pfsid);
@@ -1677,7 +1729,7 @@ static void __dmar_enable_qi(struct intel_iommu *iommu)
         * is present.
         */
        if (ecap_smts(iommu->ecap))
-               val |= (1 << 11) | 1;
+               val |= BIT_ULL(11) | BIT_ULL(0);
 
        raw_spin_lock_irqsave(&iommu->register_lock, flags);
 
@@ -1870,6 +1922,8 @@ static inline int dmar_msi_reg(struct intel_iommu *iommu, int irq)
                return DMAR_FECTL_REG;
        else if (iommu->pr_irq == irq)
                return DMAR_PECTL_REG;
+       else if (iommu->perf_irq == irq)
+               return DMAR_PERFINTRCTL_REG;
        else
                BUG();
 }
@@ -1946,7 +2000,7 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, int type,
                return 0;
        }
 
-       if (pasid == INVALID_IOASID)
+       if (pasid == IOMMU_PASID_INVALID)
                pr_err("[%s NO_PASID] Request device [%02x:%02x.%d] fault addr 0x%llx [fault reason 0x%02x] %s\n",
                       type ? "DMA Read" : "DMA Write",
                       source_id >> 8, PCI_SLOT(source_id & 0xFF),
@@ -2027,7 +2081,7 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
                if (!ratelimited)
                        /* Using pasid -1 if pasid is not present */
                        dmar_fault_do_one(iommu, type, fault_reason,
-                                         pasid_present ? pasid : INVALID_IOASID,
+                                         pasid_present ? pasid : IOMMU_PASID_INVALID,
                                          source_id, guest_addr);
 
                fault_index++;