* [PATCH 0/7] Add PCI ATS support to SMMUv3
@ 2017-05-24 18:01 Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 1/7] PCI: Move ATS declarations outside of CONFIG_PCI Jean-Philippe Brucker
` (2 more replies)
0 siblings, 3 replies; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-24 18:01 UTC (permalink / raw)
To: linux-pci, devicetree, linux-acpi, linux-arm-kernel, iommu
Cc: bhelgaas, robh+dt, mark.rutland, lorenzo.pieralisi, hanjun.guo,
sudeep.holla, rjw, lenb, will.deacon, robin.murphy, joro, okaya,
sunil.kovvuri, thunder.leizhen, tn
PCIe devices can implement their own TLB, named Address Translation Cache
(ATC). In order to support Address Translation Service (ATS), the
following changes are needed in software:
* Enable ATS on endpoints when the system supports it. Both PCI root
complex and associated SMMU must implement the ATS protocol.
* When unmapping an IOVA, send an ATC invalidate request to the endpoint
in addition to the usual SMMU IOTLB invalidations.
I previously sent this as part of a lengthy RFC [1] adding SVM (ATS +
PASID + PRI) support to SMMUv3. The next PASID/PRI version is almost
ready, but isn't likely to get merged because it needs hardware testing,
so I will send it later. PRI depends on ATS, but ATS should be useful on
its own.
Without PASID and PRI, ATS is used for accelerating transactions. Instead
of having all memory accesses go through SMMU translation, the endpoint
can translate IOVA->PA once, store the result in its ATC, then issue
subsequent transactions using the PA, partially bypassing the SMMU. So in
theory it should be faster while keeping the advantages of an IOMMU,
namely scatter-gather and access control.
The ATS patches can now be tested on some hardware, even though the lack
of compatible PCI endpoints makes it difficult to assess what performance
optimizations we need. That's why the ATS implementation is a bit rough at
the moment, and we will work on optimizing things like invalidation ranges
later.
Since the RFC [1]:
* added DT and ACPI patches,
* added invalidate-all on domain detach,
* removed smmu_group again,
* removed invalidation print from the fast path,
* disabled tagged pointers for good,
* some style changes.
These patches are based on Linux v4.12-rc2
[1] https://www.spinics.net/lists/linux-pci/msg58650.html
Jean-Philippe Brucker (7):
PCI: Move ATS declarations outside of CONFIG_PCI
dt-bindings: PCI: Describe ATS property for root complex nodes
iommu/of: Check ATS capability in root complex nodes
ACPI/IORT: Check ATS capability in root complex nodes
iommu/arm-smmu-v3: Link domains and devices
iommu/arm-smmu-v3: Add support for PCI ATS
iommu/arm-smmu-v3: Disable tagged pointers
.../devicetree/bindings/pci/pci-iommu.txt | 8 +
drivers/acpi/arm64/iort.c | 10 +
drivers/iommu/arm-smmu-v3.c | 258 ++++++++++++++++++++-
drivers/iommu/of_iommu.c | 8 +
include/linux/iommu.h | 4 +
include/linux/pci.h | 26 +--
6 files changed, 293 insertions(+), 21 deletions(-)
--
2.12.1
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 1/7] PCI: Move ATS declarations outside of CONFIG_PCI
2017-05-24 18:01 [PATCH 0/7] Add PCI ATS support to SMMUv3 Jean-Philippe Brucker
@ 2017-05-24 18:01 ` Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 3/7] iommu/of: Check ATS capability in root complex nodes Jean-Philippe Brucker
[not found] ` <20170524180143.19855-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2 siblings, 0 replies; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-24 18:01 UTC (permalink / raw)
To: linux-pci, devicetree, linux-acpi, linux-arm-kernel, iommu
Cc: bhelgaas, robh+dt, mark.rutland, lorenzo.pieralisi, hanjun.guo,
sudeep.holla, rjw, lenb, will.deacon, robin.murphy, joro, okaya,
sunil.kovvuri, thunder.leizhen, tn
Currently ATS helpers like pci_enable_ats are only defined when CONFIG_PCI
is enabled. The ARM SMMU driver might get built with CONFIG_PCI disabled.
It would thus have to wrap any use of ATS helpers around #ifdef
CONFIG_PCI, which isn't ideal.
A nicer solution is to always define these helpers. Since CONFIG_PCI_ATS
is only enabled in association with CONFIG_PCI, move defines outside of
CONFIG_PCI to prevent build failure when PCI is disabled.
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
include/linux/pci.h | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 33c2b0b77429..775d495ef8d7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1415,19 +1415,6 @@ int ht_create_irq(struct pci_dev *dev, int idx);
void ht_destroy_irq(unsigned int irq);
#endif /* CONFIG_HT_IRQ */
-#ifdef CONFIG_PCI_ATS
-/* Address Translation Service */
-void pci_ats_init(struct pci_dev *dev);
-int pci_enable_ats(struct pci_dev *dev, int ps);
-void pci_disable_ats(struct pci_dev *dev);
-int pci_ats_queue_depth(struct pci_dev *dev);
-#else
-static inline void pci_ats_init(struct pci_dev *d) { }
-static inline int pci_enable_ats(struct pci_dev *d, int ps) { return -ENODEV; }
-static inline void pci_disable_ats(struct pci_dev *d) { }
-static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; }
-#endif
-
#ifdef CONFIG_PCIE_PTM
int pci_enable_ptm(struct pci_dev *dev, u8 *granularity);
#else
@@ -1613,6 +1600,19 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
#define dev_is_pf(d) (false)
#endif /* CONFIG_PCI */
+#ifdef CONFIG_PCI_ATS
+/* Address Translation Service */
+void pci_ats_init(struct pci_dev *dev);
+int pci_enable_ats(struct pci_dev *dev, int ps);
+void pci_disable_ats(struct pci_dev *dev);
+int pci_ats_queue_depth(struct pci_dev *dev);
+#else
+static inline void pci_ats_init(struct pci_dev *d) { }
+static inline int pci_enable_ats(struct pci_dev *d, int ps) { return -ENODEV; }
+static inline void pci_disable_ats(struct pci_dev *d) { }
+static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; }
+#endif
+
/* Include architecture-dependent settings and functions */
#include <asm/pci.h>
--
2.12.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 2/7] dt-bindings: PCI: Describe ATS property for root complex nodes
[not found] ` <20170524180143.19855-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
@ 2017-05-24 18:01 ` Jean-Philippe Brucker
2017-05-30 10:01 ` Joerg Roedel
[not found] ` <20170524180143.19855-3-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-05-24 18:01 ` [PATCH 4/7] ACPI/IORT: Check ATS capability in " Jean-Philippe Brucker
` (4 subsequent siblings)
5 siblings, 2 replies; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-24 18:01 UTC (permalink / raw)
To: linux-pci-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: mark.rutland-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA,
rjw-LthD3rsA81gm4RdzfppkhA, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, sudeep.holla-5wv7dgnIgG8,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w, lenb-DgEjT+Ai2ygdnm+yROfE0A
Address Translation Service (ATS) is an extension to PCIe allowing
endpoints to manage their own IOTLB, called Address Translation Cache
(ATC). Instead of having every memory transaction processed by the IOMMU,
the endpoint can first send an Address Translation Requests for an IOVA,
obtain the corresponding Physical Address from the IOMMU and store it in
its ATC. Subsequent transactions to this memory region can be performed on
the PA, in which case they are marked 'translated' and (partially) bypass
the IOMMU.
Since the extension uses fields that were previously reserved in the
PCIe Translation Layer Packet, it seems ill-advised to enabled it on a
system that doesn't fully support ATS.
To "old" root complexes that simply ignored the new AT field, an Address
Translation Request will look exactly like a Memory Read Request, so the
root bridge will forward a memory read to the IOMMU instead of a
translation request. If the access succeeds, the RC will send a Read
Completion, which looks like a Translation Completion, back to the
endpoint. As a result the endpoint might end up storing the content of
memory instead of a physical address in its ATC. In reality, it's more
likely that the size fields will be invalid and either end will detect the
error, but in any case, it is undesirable.
Add a way for firmware to tell the OS that ATS is supported by the PCI
root complex.
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
---
Documentation/devicetree/bindings/pci/pci-iommu.txt | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/pci/pci-iommu.txt b/Documentation/devicetree/bindings/pci/pci-iommu.txt
index 0def586fdcdf..f21a68ec471a 100644
--- a/Documentation/devicetree/bindings/pci/pci-iommu.txt
+++ b/Documentation/devicetree/bindings/pci/pci-iommu.txt
@@ -44,6 +44,14 @@ Optional properties
- iommu-map-mask: A mask to be applied to each Requester ID prior to being
mapped to an IOMMU specifier per the iommu-map property.
+- ats-supported: if present, the root complex supports the Address
+ Translation Service (ATS). It is able to interpret the AT field in PCIe
+ Transaction Layer Packets, and forward Translation Completions or
+ Invalidation Requests to endpoints.
+
+ Device drivers should not enable ATS in endpoints unless this property
+ is present.
+
Example (1)
===========
--
2.12.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 3/7] iommu/of: Check ATS capability in root complex nodes
2017-05-24 18:01 [PATCH 0/7] Add PCI ATS support to SMMUv3 Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 1/7] PCI: Move ATS declarations outside of CONFIG_PCI Jean-Philippe Brucker
@ 2017-05-24 18:01 ` Jean-Philippe Brucker
[not found] ` <20170524180143.19855-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2 siblings, 0 replies; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-24 18:01 UTC (permalink / raw)
To: linux-pci, devicetree, linux-acpi, linux-arm-kernel, iommu
Cc: bhelgaas, robh+dt, mark.rutland, lorenzo.pieralisi, hanjun.guo,
sudeep.holla, rjw, lenb, will.deacon, robin.murphy, joro, okaya,
sunil.kovvuri, thunder.leizhen, tn
The PCI root complex node in DT has a property indicating whether it
supports ATS. Store this bit in the IOMMU fwspec when initializing a
device, so it can be accessed later by an IOMMU driver.
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
---
drivers/iommu/of_iommu.c | 8 ++++++++
include/linux/iommu.h | 4 ++++
2 files changed, 12 insertions(+)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 9f44ee8ea1bc..3d8168e80634 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -147,6 +147,11 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
return iommu_spec->np == pdev->bus->dev.of_node;
}
+static bool of_pci_rc_supports_ats(struct device_node *rc_node)
+{
+ return of_property_read_bool(rc_node, "ats-supported");
+}
+
static const struct iommu_ops
*of_pci_iommu_init(struct pci_dev *pdev, struct device_node *bridge_np)
{
@@ -175,6 +180,9 @@ static const struct iommu_ops
ops = of_iommu_xlate(&pdev->dev, &iommu_spec);
+ if (!IS_ERR_OR_NULL(ops) && of_pci_rc_supports_ats(bridge_np))
+ pdev->dev.iommu_fwspec->flags |= IOMMU_FWSPEC_PCI_RC_SUPPORTS_ATS;
+
of_node_put(iommu_spec.np);
return ops;
}
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 2cb54adc4a33..206821b9044c 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -360,6 +360,7 @@ extern struct iommu_group *generic_device_group(struct device *dev);
* @ops: ops for this device's IOMMU
* @iommu_fwnode: firmware handle for this device's IOMMU
* @iommu_priv: IOMMU driver private data for this device
+ * @flags: miscellaneous properties for this device
* @num_ids: number of associated device IDs
* @ids: IDs which this device may present to the IOMMU
*/
@@ -367,10 +368,13 @@ struct iommu_fwspec {
const struct iommu_ops *ops;
struct fwnode_handle *iommu_fwnode;
void *iommu_priv;
+ u32 flags;
unsigned int num_ids;
u32 ids[1];
};
+#define IOMMU_FWSPEC_PCI_RC_SUPPORTS_ATS (1 << 0)
+
int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
const struct iommu_ops *ops);
void iommu_fwspec_free(struct device *dev);
--
2.12.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 4/7] ACPI/IORT: Check ATS capability in root complex nodes
[not found] ` <20170524180143.19855-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-05-24 18:01 ` [PATCH 2/7] dt-bindings: PCI: Describe ATS property for " Jean-Philippe Brucker
@ 2017-05-24 18:01 ` Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 5/7] iommu/arm-smmu-v3: Link domains and devices Jean-Philippe Brucker
` (3 subsequent siblings)
5 siblings, 0 replies; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-24 18:01 UTC (permalink / raw)
To: linux-pci-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: mark.rutland-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA,
rjw-LthD3rsA81gm4RdzfppkhA, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, sudeep.holla-5wv7dgnIgG8,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w, lenb-DgEjT+Ai2ygdnm+yROfE0A
Root complex node in IORT has a bit telling whether it supports ATS or
not. Store this bit in the IOMMU fwspec when setting up a device, so it
can be accessed later by an IOMMU driver.
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
---
drivers/acpi/arm64/iort.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c5fecf97ee2f..e7d2d156d78f 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -720,6 +720,14 @@ void iort_set_dma_mask(struct device *dev)
dev->dma_mask = &dev->coherent_dma_mask;
}
+static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
+{
+ struct acpi_iort_root_complex *pci_rc;
+
+ pci_rc = (struct acpi_iort_root_complex *)node->node_data;
+ return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
+}
+
/**
* iort_iommu_configure - Set-up IOMMU configuration for a device.
*
@@ -752,6 +760,8 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
ops = iort_iommu_xlate(dev, parent, streamid);
+ if (!IS_ERR_OR_NULL(ops) && iort_pci_rc_supports_ats(node))
+ dev->iommu_fwspec->flags |= IOMMU_FWSPEC_PCI_RC_SUPPORTS_ATS;
} else {
int i = 0;
--
2.12.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 5/7] iommu/arm-smmu-v3: Link domains and devices
[not found] ` <20170524180143.19855-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-05-24 18:01 ` [PATCH 2/7] dt-bindings: PCI: Describe ATS property for " Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 4/7] ACPI/IORT: Check ATS capability in " Jean-Philippe Brucker
@ 2017-05-24 18:01 ` Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 6/7] iommu/arm-smmu-v3: Add support for PCI ATS Jean-Philippe Brucker
` (2 subsequent siblings)
5 siblings, 0 replies; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-24 18:01 UTC (permalink / raw)
To: linux-pci-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: mark.rutland-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA,
rjw-LthD3rsA81gm4RdzfppkhA, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, sudeep.holla-5wv7dgnIgG8,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w, lenb-DgEjT+Ai2ygdnm+yROfE0A
When removing a mapping from a domain, we need to send an invalidation to
all devices that might have stored it in their Address Translation Cache
(ATC). In addition with SVM, we'll need to invalidate context descriptors
of all devices attached to a domain.
Maintain a list of devices in each domain, protected by a spinlock. It is
updated every time we attach or detach devices to and from domains.
It needs to be a spinlock because we'll invalidate ATC entries from
within hardirq-safe contexts, but it may be possible to relax the read
side with RCU later.
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
---
drivers/iommu/arm-smmu-v3.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 380969aa60d5..524e1b051962 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -630,6 +630,9 @@ struct arm_smmu_device {
struct arm_smmu_master_data {
struct arm_smmu_device *smmu;
struct arm_smmu_strtab_ent ste;
+
+ struct arm_smmu_domain *domain;
+ struct list_head list; /* domain->devices */
};
/* SMMU private data for an IOMMU domain */
@@ -654,6 +657,9 @@ struct arm_smmu_domain {
};
struct iommu_domain domain;
+
+ struct list_head devices;
+ spinlock_t devices_lock;
};
struct arm_smmu_option_prop {
@@ -1407,6 +1413,9 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
mutex_init(&smmu_domain->init_mutex);
spin_lock_init(&smmu_domain->pgtbl_lock);
+ INIT_LIST_HEAD(&smmu_domain->devices);
+ spin_lock_init(&smmu_domain->devices_lock);
+
return &smmu_domain->domain;
}
@@ -1609,7 +1618,17 @@ static void arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec)
static void arm_smmu_detach_dev(struct device *dev)
{
+ unsigned long flags;
struct arm_smmu_master_data *master = dev->iommu_fwspec->iommu_priv;
+ struct arm_smmu_domain *smmu_domain = master->domain;
+
+ if (smmu_domain) {
+ spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+ list_del(&master->list);
+ spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
+
+ master->domain = NULL;
+ }
master->ste.assigned = false;
arm_smmu_install_ste_for_dev(dev->iommu_fwspec);
@@ -1618,6 +1637,7 @@ static void arm_smmu_detach_dev(struct device *dev)
static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
{
int ret = 0;
+ unsigned long flags;
struct arm_smmu_device *smmu;
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_master_data *master;
@@ -1653,6 +1673,11 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
}
ste->assigned = true;
+ master->domain = smmu_domain;
+
+ spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+ list_add(&master->list, &smmu_domain->devices);
+ spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
if (smmu_domain->stage == ARM_SMMU_DOMAIN_BYPASS) {
ste->s1_cfg = NULL;
--
2.12.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 6/7] iommu/arm-smmu-v3: Add support for PCI ATS
[not found] ` <20170524180143.19855-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
` (2 preceding siblings ...)
2017-05-24 18:01 ` [PATCH 5/7] iommu/arm-smmu-v3: Link domains and devices Jean-Philippe Brucker
@ 2017-05-24 18:01 ` Jean-Philippe Brucker
[not found] ` <20170524180143.19855-7-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-05-24 18:01 ` [PATCH 7/7] iommu/arm-smmu-v3: Disable tagged pointers Jean-Philippe Brucker
2017-05-31 15:27 ` [PATCH 0/7] Add PCI ATS support to SMMUv3 Nate Watterson
5 siblings, 1 reply; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-24 18:01 UTC (permalink / raw)
To: linux-pci-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: mark.rutland-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA,
rjw-LthD3rsA81gm4RdzfppkhA, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, sudeep.holla-5wv7dgnIgG8,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w, lenb-DgEjT+Ai2ygdnm+yROfE0A
PCIe devices can implement their own TLB, named Address Translation Cache
(ATC). Enable Address Translation Service (ATS) for devices that support
it and send them invalidation requests whenever we invalidate the IOTLBs.
Range calculation
-----------------
The invalidation packet itself is a bit awkward: range must be naturally
aligned, which means that the start address is a multiple of the range
size. In addition, the size must be a power of two number of 4k pages. We
have a few options to enforce this constraint:
(1) Find the smallest naturally aligned region that covers the requested
range. This is simple to compute and only takes one ATC_INV, but it
will spill on lots of neighbouring ATC entries.
(2) Align the start address to the region size (rounded up to a power of
two), and send a second invalidation for the next range of the same
size. Still not great, but reduces spilling.
(3) Cover the range exactly with the smallest number of naturally aligned
regions. This would be interesting to implement but as for (2),
requires multiple ATC_INV.
As I suspect ATC invalidation packets will be a very scarce resource, I'll
go with option (1) for now, and only send one big invalidation. We can
move to (2), which is both easier to read and more gentle with the ATC,
once we've observed on real systems that we can send multiple smaller
Invalidation Requests for roughly the same price as a single big one.
Note that with io-pgtable, the unmap function is called for each page, so
this doesn't matter. The problem shows up when sharing page tables with
the MMU.
Timeout
-------
ATC invalidation is allowed to take up to 90 seconds, according to the
PCIe spec, so it is possible to hit the SMMU command queue timeout during
normal operations.
Some SMMU implementations will raise a CERROR_ATC_INV_SYNC when a CMD_SYNC
fails because of an ATC invalidation. Some will just abort the CMD_SYNC.
Others might let CMD_SYNC complete and have an asynchronous IMPDEF
mechanism to record the error. When we receive a CERROR_ATC_INV_SYNC, we
could retry sending all ATC_INV since last successful CMD_SYNC. When a
CMD_SYNC fails without CERROR_ATC_INV_SYNC, we could retry sending *all*
commands since last successful CMD_SYNC.
We cannot afford to wait 90 seconds in iommu_unmap, let alone MMU
notifiers. So we'd have to introduce a more clever system if this timeout
becomes a problem, like keeping hold of mappings and invalidating in the
background. Implementing safe delayed invalidations is a very complex
problem and deserves a series of its own. We'll assess whether more work
is needed to properly handle ATC invalidation timeouts once this code runs
on real hardware.
Misc
----
I didn't put ATC and TLB invalidations in the same functions for three
reasons:
* TLB invalidation by range is batched and committed with a single sync.
Batching ATC invalidation is inconvenient, endpoints limit the number of
inflight invalidations. We'd have to count the number of invalidations
queued and send a sync periodically. In addition, I suspect we always
need a sync between TLB and ATC invalidation for the same page.
* Doing ATC invalidation outside tlb_inv_range also allows to send less
requests, since TLB invalidations are done per page or block, while ATC
invalidations target IOVA ranges.
* TLB invalidation by context is performed when freeing the domain, at
which point there isn't any device attached anymore.
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
---
drivers/iommu/arm-smmu-v3.c | 232 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 225 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 524e1b051962..87ed6239b9a6 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -35,6 +35,7 @@
#include <linux/of_iommu.h>
#include <linux/of_platform.h>
#include <linux/pci.h>
+#include <linux/pci-ats.h>
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
@@ -102,6 +103,7 @@
#define IDR5_OAS_48_BIT (5 << IDR5_OAS_SHIFT)
#define ARM_SMMU_CR0 0x20
+#define CR0_ATSCHK (1 << 4)
#define CR0_CMDQEN (1 << 3)
#define CR0_EVTQEN (1 << 2)
#define CR0_PRIQEN (1 << 1)
@@ -343,6 +345,7 @@
#define CMDQ_ERR_CERROR_NONE_IDX 0
#define CMDQ_ERR_CERROR_ILL_IDX 1
#define CMDQ_ERR_CERROR_ABT_IDX 2
+#define CMDQ_ERR_CERROR_ATC_INV_IDX 3
#define CMDQ_0_OP_SHIFT 0
#define CMDQ_0_OP_MASK 0xffUL
@@ -364,6 +367,15 @@
#define CMDQ_TLBI_1_VA_MASK ~0xfffUL
#define CMDQ_TLBI_1_IPA_MASK 0xfffffffff000UL
+#define CMDQ_ATC_0_SSID_SHIFT 12
+#define CMDQ_ATC_0_SSID_MASK 0xfffffUL
+#define CMDQ_ATC_0_SID_SHIFT 32
+#define CMDQ_ATC_0_SID_MASK 0xffffffffUL
+#define CMDQ_ATC_0_GLOBAL (1UL << 9)
+#define CMDQ_ATC_1_SIZE_SHIFT 0
+#define CMDQ_ATC_1_SIZE_MASK 0x3fUL
+#define CMDQ_ATC_1_ADDR_MASK ~0xfffUL
+
#define CMDQ_PRI_0_SSID_SHIFT 12
#define CMDQ_PRI_0_SSID_MASK 0xfffffUL
#define CMDQ_PRI_0_SID_SHIFT 32
@@ -417,6 +429,11 @@ module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO);
MODULE_PARM_DESC(disable_bypass,
"Disable bypass streams such that incoming transactions from devices that are not attached to an iommu domain will report an abort back to the device and will not be allowed to pass through the SMMU.");
+static bool disable_ats_check;
+module_param_named(disable_ats_check, disable_ats_check, bool, S_IRUGO);
+MODULE_PARM_DESC(disable_ats_check,
+ "By default, the SMMU checks whether each incoming transaction marked as translated is allowed by the stream configuration. This option disables the check.");
+
enum pri_resp {
PRI_RESP_DENY,
PRI_RESP_FAIL,
@@ -485,6 +502,16 @@ struct arm_smmu_cmdq_ent {
u64 addr;
} tlbi;
+ #define CMDQ_OP_ATC_INV 0x40
+ #define ATC_INV_SIZE_ALL 52
+ struct {
+ u32 sid;
+ u32 ssid;
+ u64 addr;
+ u8 size;
+ bool global;
+ } atc;
+
#define CMDQ_OP_PRI_RESP 0x41
struct {
u32 sid;
@@ -631,6 +658,7 @@ struct arm_smmu_master_data {
struct arm_smmu_device *smmu;
struct arm_smmu_strtab_ent ste;
+ struct device *dev;
struct arm_smmu_domain *domain;
struct list_head list; /* domain->devices */
};
@@ -835,6 +863,14 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
case CMDQ_OP_TLBI_S12_VMALL:
cmd[0] |= (u64)ent->tlbi.vmid << CMDQ_TLBI_0_VMID_SHIFT;
break;
+ case CMDQ_OP_ATC_INV:
+ cmd[0] |= ent->substream_valid ? CMDQ_0_SSV : 0;
+ cmd[0] |= ent->atc.global ? CMDQ_ATC_0_GLOBAL : 0;
+ cmd[0] |= ent->atc.ssid << CMDQ_ATC_0_SSID_SHIFT;
+ cmd[0] |= (u64)ent->atc.sid << CMDQ_ATC_0_SID_SHIFT;
+ cmd[1] |= ent->atc.size << CMDQ_ATC_1_SIZE_SHIFT;
+ cmd[1] |= ent->atc.addr & CMDQ_ATC_1_ADDR_MASK;
+ break;
case CMDQ_OP_PRI_RESP:
cmd[0] |= ent->substream_valid ? CMDQ_0_SSV : 0;
cmd[0] |= ent->pri.ssid << CMDQ_PRI_0_SSID_SHIFT;
@@ -870,6 +906,7 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
[CMDQ_ERR_CERROR_NONE_IDX] = "No error",
[CMDQ_ERR_CERROR_ILL_IDX] = "Illegal command",
[CMDQ_ERR_CERROR_ABT_IDX] = "Abort on command fetch",
+ [CMDQ_ERR_CERROR_ATC_INV_IDX] = "ATC invalidate timeout",
};
int i;
@@ -889,6 +926,14 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
dev_err(smmu->dev, "retrying command fetch\n");
case CMDQ_ERR_CERROR_NONE_IDX:
return;
+ case CMDQ_ERR_CERROR_ATC_INV_IDX:
+ /*
+ * ATC Invalidation Completion timeout. CONS is still pointing
+ * at the CMD_SYNC. Attempt to complete other pending commands
+ * by repeating the CMD_SYNC, though we might well end up back
+ * here since the ATC invalidation may still be pending.
+ */
+ return;
case CMDQ_ERR_CERROR_ILL_IDX:
/* Fallthrough */
default:
@@ -1084,9 +1129,6 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
STRTAB_STE_1_S1C_CACHE_WBRA
<< STRTAB_STE_1_S1COR_SHIFT |
STRTAB_STE_1_S1C_SH_ISH << STRTAB_STE_1_S1CSH_SHIFT |
-#ifdef CONFIG_PCI_ATS
- STRTAB_STE_1_EATS_TRANS << STRTAB_STE_1_EATS_SHIFT |
-#endif
STRTAB_STE_1_STRW_NSEL1 << STRTAB_STE_1_STRW_SHIFT);
if (smmu->features & ARM_SMMU_FEAT_STALLS)
@@ -1115,6 +1157,10 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid,
val |= STRTAB_STE_0_CFG_S2_TRANS;
}
+ if (IS_ENABLED(CONFIG_PCI_ATS))
+ dst[1] |= cpu_to_le64(STRTAB_STE_1_EATS_TRANS
+ << STRTAB_STE_1_EATS_SHIFT);
+
arm_smmu_sync_ste_for_sid(smmu, sid);
dst[0] = cpu_to_le64(val);
arm_smmu_sync_ste_for_sid(smmu, sid);
@@ -1374,6 +1420,106 @@ static const struct iommu_gather_ops arm_smmu_gather_ops = {
.tlb_sync = arm_smmu_tlb_sync,
};
+static bool arm_smmu_master_has_ats(struct arm_smmu_master_data *master)
+{
+ return dev_is_pci(master->dev) && to_pci_dev(master->dev)->ats_enabled;
+}
+
+static void
+arm_smmu_atc_inv_to_cmd(int ssid, unsigned long iova, size_t size,
+ struct arm_smmu_cmdq_ent *cmd)
+{
+ size_t log2_span;
+ size_t span_mask;
+ /* ATC invalidates are always on 4096 bytes pages */
+ size_t inval_grain_shift = 12;
+ unsigned long page_start, page_end;
+
+ *cmd = (struct arm_smmu_cmdq_ent) {
+ .opcode = CMDQ_OP_ATC_INV,
+ .substream_valid = !!ssid,
+ .atc.ssid = ssid,
+ };
+
+ if (!size) {
+ cmd->atc.size = ATC_INV_SIZE_ALL;
+ return;
+ }
+
+ page_start = iova >> inval_grain_shift;
+ page_end = (iova + size - 1) >> inval_grain_shift;
+
+ /*
+ * Find the smallest power of two that covers the range. Most
+ * significant differing bit between start and end address indicates the
+ * required span, ie. fls(start ^ end). For example:
+ *
+ * We want to invalidate pages [8; 11]. This is already the ideal range:
+ * x = 0b1000 ^ 0b1011 = 0b11
+ * span = 1 << fls(x) = 4
+ *
+ * To invalidate pages [7; 10], we need to invalidate [0; 15]:
+ * x = 0b0111 ^ 0b1010 = 0b1101
+ * span = 1 << fls(x) = 16
+ */
+ log2_span = fls_long(page_start ^ page_end);
+ span_mask = (1ULL << log2_span) - 1;
+
+ page_start &= ~span_mask;
+
+ cmd->atc.addr = page_start << inval_grain_shift;
+ cmd->atc.size = log2_span;
+}
+
+static int arm_smmu_atc_inv_master(struct arm_smmu_master_data *master,
+ struct arm_smmu_cmdq_ent *cmd)
+{
+ int i;
+ struct iommu_fwspec *fwspec = master->dev->iommu_fwspec;
+ struct arm_smmu_cmdq_ent sync_cmd = {
+ .opcode = CMDQ_OP_CMD_SYNC,
+ };
+
+ if (!arm_smmu_master_has_ats(master))
+ return 0;
+
+ for (i = 0; i < fwspec->num_ids; i++) {
+ cmd->atc.sid = fwspec->ids[i];
+ arm_smmu_cmdq_issue_cmd(master->smmu, cmd);
+ }
+
+ arm_smmu_cmdq_issue_cmd(master->smmu, &sync_cmd);
+
+ return 0;
+}
+
+static int arm_smmu_atc_inv_master_all(struct arm_smmu_master_data *master,
+ int ssid)
+{
+ struct arm_smmu_cmdq_ent cmd;
+
+ arm_smmu_atc_inv_to_cmd(ssid, 0, 0, &cmd);
+ return arm_smmu_atc_inv_master(master, &cmd);
+}
+
+static size_t
+arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
+ unsigned long iova, size_t size)
+{
+ unsigned long flags;
+ struct arm_smmu_cmdq_ent cmd;
+ struct arm_smmu_master_data *master;
+
+ arm_smmu_atc_inv_to_cmd(ssid, iova, size, &cmd);
+
+ spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+ list_for_each_entry(master, &smmu_domain->devices, list)
+ arm_smmu_atc_inv_master(master, &cmd);
+ spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
+
+ return size;
+}
+
/* IOMMU API */
static bool arm_smmu_capable(enum iommu_cap cap)
{
@@ -1623,6 +1769,8 @@ static void arm_smmu_detach_dev(struct device *dev)
struct arm_smmu_domain *smmu_domain = master->domain;
if (smmu_domain) {
+ arm_smmu_atc_inv_master_all(master, 0);
+
spin_lock_irqsave(&smmu_domain->devices_lock, flags);
list_del(&master->list);
spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
@@ -1727,7 +1875,11 @@ arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
spin_lock_irqsave(&smmu_domain->pgtbl_lock, flags);
ret = ops->unmap(ops, iova, size);
+
+ if (ret && smmu_domain->smmu->features & ARM_SMMU_FEAT_ATS)
+ ret = arm_smmu_atc_inv_domain(smmu_domain, 0, iova, size);
spin_unlock_irqrestore(&smmu_domain->pgtbl_lock, flags);
+
return ret;
}
@@ -1778,6 +1930,48 @@ static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
return sid < limit;
}
+static int arm_smmu_enable_ats(struct arm_smmu_master_data *master)
+{
+ int ret;
+ size_t stu;
+ struct pci_dev *pdev;
+ struct arm_smmu_device *smmu = master->smmu;
+ struct iommu_fwspec *fwspec = master->dev->iommu_fwspec;
+
+ if (!(smmu->features & ARM_SMMU_FEAT_ATS) || !dev_is_pci(master->dev) ||
+ !(fwspec->flags & IOMMU_FWSPEC_PCI_RC_SUPPORTS_ATS))
+ return -ENOSYS;
+
+ pdev = to_pci_dev(master->dev);
+
+ /* Smallest Translation Unit: log2 of the smallest supported granule */
+ stu = __ffs(smmu->pgsize_bitmap);
+
+ ret = pci_enable_ats(pdev, stu);
+ if (ret)
+ return ret;
+
+ dev_dbg(&pdev->dev, "enabled ATS (STU=%zu, QDEP=%d)\n", stu,
+ pci_ats_queue_depth(pdev));
+
+ return 0;
+}
+
+static void arm_smmu_disable_ats(struct arm_smmu_master_data *master)
+{
+ struct pci_dev *pdev;
+
+ if (!dev_is_pci(master->dev))
+ return;
+
+ pdev = to_pci_dev(master->dev);
+
+ if (!pdev->ats_enabled)
+ return;
+
+ pci_disable_ats(pdev);
+}
+
static struct iommu_ops arm_smmu_ops;
static int arm_smmu_add_device(struct device *dev)
@@ -1807,6 +2001,7 @@ static int arm_smmu_add_device(struct device *dev)
return -ENOMEM;
master->smmu = smmu;
+ master->dev = dev;
fwspec->iommu_priv = master;
}
@@ -1825,13 +2020,23 @@ static int arm_smmu_add_device(struct device *dev)
}
}
+ arm_smmu_enable_ats(master);
+
group = iommu_group_get_for_dev(dev);
- if (!IS_ERR(group)) {
- iommu_group_put(group);
- iommu_device_link(&smmu->iommu, dev);
+ if (IS_ERR(group)) {
+ ret = PTR_ERR(group);
+ goto err_disable_ats;
}
- return PTR_ERR_OR_ZERO(group);
+ iommu_group_put(group);
+ iommu_device_link(&smmu->iommu, dev);
+
+ return 0;
+
+err_disable_ats:
+ arm_smmu_disable_ats(master);
+
+ return ret;
}
static void arm_smmu_remove_device(struct device *dev)
@@ -1847,6 +2052,9 @@ static void arm_smmu_remove_device(struct device *dev)
smmu = master->smmu;
if (master && master->ste.assigned)
arm_smmu_detach_dev(dev);
+
+ arm_smmu_disable_ats(master);
+
iommu_group_remove_device(dev);
iommu_device_unlink(&smmu->iommu, dev);
kfree(master);
@@ -2417,6 +2625,16 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
}
}
+ if (smmu->features & ARM_SMMU_FEAT_ATS && !disable_ats_check) {
+ enables |= CR0_ATSCHK;
+ ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
+ ARM_SMMU_CR0ACK);
+ if (ret) {
+ dev_err(smmu->dev, "failed to enable ATS check\n");
+ return ret;
+ }
+ }
+
ret = arm_smmu_setup_irqs(smmu);
if (ret) {
dev_err(smmu->dev, "failed to setup irqs\n");
--
2.12.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 7/7] iommu/arm-smmu-v3: Disable tagged pointers
[not found] ` <20170524180143.19855-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
` (3 preceding siblings ...)
2017-05-24 18:01 ` [PATCH 6/7] iommu/arm-smmu-v3: Add support for PCI ATS Jean-Philippe Brucker
@ 2017-05-24 18:01 ` Jean-Philippe Brucker
2017-05-31 15:27 ` [PATCH 0/7] Add PCI ATS support to SMMUv3 Nate Watterson
5 siblings, 0 replies; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-24 18:01 UTC (permalink / raw)
To: linux-pci-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: mark.rutland-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA,
rjw-LthD3rsA81gm4RdzfppkhA, okaya-sgV2jX0FEOL9JmXXK+q4OQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, sudeep.holla-5wv7dgnIgG8,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w, lenb-DgEjT+Ai2ygdnm+yROfE0A
The ARM architecture has a "Top Byte Ignore" (TBI) option that makes the
MMU mask out bits [63:56] of an address, allowing a userspace application
to store data in its pointers. This option is incompatible with PCI ATS.
If TBI is enabled in the SMMU and userspace triggers DMA transactions on
tagged pointers, the endpoint might create ATC entries for addresses that
include a tag. Software would then have to send ATC invalidation packets
for each 255 possible alias of an address, or just wipe the whole address
space. This is not a viable option, so disable TBI.
The impact of this change is unclear, since there are very few users of
tagged pointers, much less SVM. But the requirement introduced by this
patch doesn't seem excessive: a userspace application using both tagged
pointers and SVM should now sanitize addresses (clear the tag) before
using them for device DMA.
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
---
drivers/iommu/arm-smmu-v3.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 87ed6239b9a6..0b2674f8ba0f 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -997,7 +997,6 @@ static u64 arm_smmu_cpu_tcr_to_cd(u64 tcr)
val |= ARM_SMMU_TCR2CD(tcr, EPD0);
val |= ARM_SMMU_TCR2CD(tcr, EPD1);
val |= ARM_SMMU_TCR2CD(tcr, IPS);
- val |= ARM_SMMU_TCR2CD(tcr, TBI0);
return val;
}
--
2.12.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 2/7] dt-bindings: PCI: Describe ATS property for root complex nodes
2017-05-24 18:01 ` [PATCH 2/7] dt-bindings: PCI: Describe ATS property for " Jean-Philippe Brucker
@ 2017-05-30 10:01 ` Joerg Roedel
2017-05-30 10:58 ` Jean-Philippe Brucker
[not found] ` <20170524180143.19855-3-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
1 sibling, 1 reply; 20+ messages in thread
From: Joerg Roedel @ 2017-05-30 10:01 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: linux-pci, devicetree, linux-acpi, linux-arm-kernel, iommu,
bhelgaas, robh+dt, mark.rutland, lorenzo.pieralisi, hanjun.guo,
sudeep.holla, rjw, lenb, will.deacon, robin.murphy, okaya,
sunil.kovvuri, thunder.leizhen, tn
On Wed, May 24, 2017 at 07:01:38PM +0100, Jean-Philippe Brucker wrote:
> +- ats-supported: if present, the root complex supports the Address
> + Translation Service (ATS). It is able to interpret the AT field in PCIe
> + Transaction Layer Packets, and forward Translation Completions or
> + Invalidation Requests to endpoints.
> +
> + Device drivers should not enable ATS in endpoints unless this property
> + is present.
Device drivers should never enable ATS, this is the job of the IOMMU
driver. This should be clarified in the text.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 6/7] iommu/arm-smmu-v3: Add support for PCI ATS
[not found] ` <20170524180143.19855-7-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
@ 2017-05-30 10:28 ` Joerg Roedel
2017-05-30 10:58 ` Jean-Philippe Brucker
0 siblings, 1 reply; 20+ messages in thread
From: Joerg Roedel @ 2017-05-30 10:28 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, lorenzo.pieralisi-5wv7dgnIgG8,
hanjun.guo-QSEj5FYQhm4dnm+yROfE0A, sudeep.holla-5wv7dgnIgG8,
rjw-LthD3rsA81gm4RdzfppkhA, lenb-DgEjT+Ai2ygdnm+yROfE0A,
will.deacon-5wv7dgnIgG8, robin.murphy-5wv7dgnIgG8,
okaya-sgV2jX0FEOL9JmXXK+q4OQ,
sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA, tn-nYOzD4b6Jr9Wk0Htik3J/w
On Wed, May 24, 2017 at 07:01:42PM +0100, Jean-Philippe Brucker wrote:
> * TLB invalidation by range is batched and committed with a single sync.
> Batching ATC invalidation is inconvenient, endpoints limit the number of
> inflight invalidations. We'd have to count the number of invalidations
> queued and send a sync periodically. In addition, I suspect we always
> need a sync between TLB and ATC invalidation for the same page.
This sounds like the number of outstanding ATS invalidations is not
managed by the SMMU hardware, is that right?
Joerg
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 6/7] iommu/arm-smmu-v3: Add support for PCI ATS
2017-05-30 10:28 ` Joerg Roedel
@ 2017-05-30 10:58 ` Jean-Philippe Brucker
0 siblings, 0 replies; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-30 10:58 UTC (permalink / raw)
To: Joerg Roedel
Cc: linux-pci, devicetree, linux-acpi, linux-arm-kernel, iommu,
bhelgaas, robh+dt, mark.rutland, lorenzo.pieralisi, hanjun.guo,
sudeep.holla, rjw, lenb, will.deacon, robin.murphy, okaya,
sunil.kovvuri, thunder.leizhen, tn
On 30/05/17 11:28, Joerg Roedel wrote:
> On Wed, May 24, 2017 at 07:01:42PM +0100, Jean-Philippe Brucker wrote:
>> * TLB invalidation by range is batched and committed with a single sync.
>> Batching ATC invalidation is inconvenient, endpoints limit the number of
>> inflight invalidations. We'd have to count the number of invalidations
>> queued and send a sync periodically. In addition, I suspect we always
>> need a sync between TLB and ATC invalidation for the same page.
>
> This sounds like the number of outstanding ATS invalidations is not
> managed by the SMMU hardware, is that right?
Yes, the hardware doesn't know about ATS queue depth, it simply forwards
invalidations to the root complex. Doing a sync on the SMMU command queue
waits for all completions of outstanding ATS invalidations, but it is up
to the driver to limit ATS invalidations according to queue depth.
Thanks,
Jean
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/7] dt-bindings: PCI: Describe ATS property for root complex nodes
2017-05-30 10:01 ` Joerg Roedel
@ 2017-05-30 10:58 ` Jean-Philippe Brucker
[not found] ` <035be7ba-e850-a5a9-08fa-802a04feb600-5wv7dgnIgG8@public.gmane.org>
0 siblings, 1 reply; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-05-30 10:58 UTC (permalink / raw)
To: Joerg Roedel
Cc: linux-pci, devicetree, linux-acpi, linux-arm-kernel, iommu,
bhelgaas, robh+dt, mark.rutland, lorenzo.pieralisi, hanjun.guo,
sudeep.holla, rjw, lenb, will.deacon, robin.murphy, okaya,
sunil.kovvuri, thunder.leizhen, tn
On 30/05/17 11:01, Joerg Roedel wrote:
> On Wed, May 24, 2017 at 07:01:38PM +0100, Jean-Philippe Brucker wrote:
>> +- ats-supported: if present, the root complex supports the Address
>> + Translation Service (ATS). It is able to interpret the AT field in PCIe
>> + Transaction Layer Packets, and forward Translation Completions or
>> + Invalidation Requests to endpoints.
>> +
>> + Device drivers should not enable ATS in endpoints unless this property
>> + is present.
>
> Device drivers should never enable ATS, this is the job of the IOMMU
> driver. This should be clarified in the text.
Right, I will change this.
Thanks,
Jean
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/7] Add PCI ATS support to SMMUv3
[not found] ` <20170524180143.19855-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
` (4 preceding siblings ...)
2017-05-24 18:01 ` [PATCH 7/7] iommu/arm-smmu-v3: Disable tagged pointers Jean-Philippe Brucker
@ 2017-05-31 15:27 ` Nate Watterson
2017-06-01 12:23 ` Jean-Philippe Brucker
5 siblings, 1 reply; 20+ messages in thread
From: Nate Watterson @ 2017-05-31 15:27 UTC (permalink / raw)
To: Jean-Philippe Brucker, linux-pci-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
Cc: mark.rutland-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
sudeep.holla-5wv7dgnIgG8, rjw-LthD3rsA81gm4RdzfppkhA,
okaya-sgV2jX0FEOL9JmXXK+q4OQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w, lenb-DgEjT+Ai2ygdnm+yROfE0A
Hi Jean-Philippe,
On 5/24/2017 2:01 PM, Jean-Philippe Brucker wrote:
> PCIe devices can implement their own TLB, named Address Translation Cache
> (ATC). In order to support Address Translation Service (ATS), the
> following changes are needed in software:
>
> * Enable ATS on endpoints when the system supports it. Both PCI root
> complex and associated SMMU must implement the ATS protocol.
>
> * When unmapping an IOVA, send an ATC invalidate request to the endpoint
> in addition to the usual SMMU IOTLB invalidations.
>
> I previously sent this as part of a lengthy RFC [1] adding SVM (ATS +
> PASID + PRI) support to SMMUv3. The next PASID/PRI version is almost
> ready, but isn't likely to get merged because it needs hardware testing,
> so I will send it later. PRI depends on ATS, but ATS should be useful on
> its own.
>
> Without PASID and PRI, ATS is used for accelerating transactions. Instead
> of having all memory accesses go through SMMU translation, the endpoint
> can translate IOVA->PA once, store the result in its ATC, then issue
> subsequent transactions using the PA, partially bypassing the SMMU. So in
> theory it should be faster while keeping the advantages of an IOMMU,
> namely scatter-gather and access control.
>
> The ATS patches can now be tested on some hardware, even though the lack
> of compatible PCI endpoints makes it difficult to assess what performance
> optimizations we need. That's why the ATS implementation is a bit rough at
> the moment, and we will work on optimizing things like invalidation ranges
> later.
Sinan and I have tested this series on a QDF2400 development platform
using a PCIe exerciser card as the ATS capable endpoint. We were able
to verify that ATS requests complete with a valid translated address
and that DMA transactions using the pre-translated address "bypass"
the SMMU. Testing ATC invalidations was a bit more difficult as we
could not figure out how to get the exerciser card to automatically
send the completion message. We ended up having to write a debugger
script that would monitor the CMDQ and tell the exerciser to send
the completion when a hanging CMD_SYNC following a CMD_ATC_INV was
detected. Hopefully we'll get some real ATS capable endpoints to
test with soon.
>
> Since the RFC [1]:
> * added DT and ACPI patches,
> * added invalidate-all on domain detach,
> * removed smmu_group again,
> * removed invalidation print from the fast path,
> * disabled tagged pointers for good,
> * some style changes.
>
> These patches are based on Linux v4.12-rc2
>
> [1] https://www.spinics.net/lists/linux-pci/msg58650.html
>
> Jean-Philippe Brucker (7):
> PCI: Move ATS declarations outside of CONFIG_PCI
> dt-bindings: PCI: Describe ATS property for root complex nodes
> iommu/of: Check ATS capability in root complex nodes
> ACPI/IORT: Check ATS capability in root complex nodes
> iommu/arm-smmu-v3: Link domains and devices
> iommu/arm-smmu-v3: Add support for PCI ATS
> iommu/arm-smmu-v3: Disable tagged pointers
>
> .../devicetree/bindings/pci/pci-iommu.txt | 8 +
> drivers/acpi/arm64/iort.c | 10 +
> drivers/iommu/arm-smmu-v3.c | 258 ++++++++++++++++++++-
> drivers/iommu/of_iommu.c | 8 +
> include/linux/iommu.h | 4 +
> include/linux/pci.h | 26 +--
> 6 files changed, 293 insertions(+), 21 deletions(-)
>
--
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/7] dt-bindings: PCI: Describe ATS property for root complex nodes
[not found] ` <035be7ba-e850-a5a9-08fa-802a04feb600-5wv7dgnIgG8@public.gmane.org>
@ 2017-05-31 17:17 ` Rob Herring
0 siblings, 0 replies; 20+ messages in thread
From: Rob Herring @ 2017-05-31 17:17 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-pci-u79uwXL29TY76Z2rM5mHXA,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA,
rjw-LthD3rsA81gm4RdzfppkhA, will.deacon-5wv7dgnIgG8,
okaya-sgV2jX0FEOL9JmXXK+q4OQ, linux-acpi-u79uwXL29TY76Z2rM5mHXA,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
sudeep.holla-5wv7dgnIgG8, bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
tn-nYOzD4b6Jr9Wk0Htik3J/w, sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
lenb-DgEjT+Ai2ygdnm+yROfE0A
On Tue, May 30, 2017 at 11:58:50AM +0100, Jean-Philippe Brucker wrote:
> On 30/05/17 11:01, Joerg Roedel wrote:
> > On Wed, May 24, 2017 at 07:01:38PM +0100, Jean-Philippe Brucker wrote:
> >> +- ats-supported: if present, the root complex supports the Address
> >> + Translation Service (ATS). It is able to interpret the AT field in PCIe
> >> + Transaction Layer Packets, and forward Translation Completions or
> >> + Invalidation Requests to endpoints.
> >> +
> >> + Device drivers should not enable ATS in endpoints unless this property
> >> + is present.
> >
> > Device drivers should never enable ATS, this is the job of the IOMMU
> > driver. This should be clarified in the text.
>
> Right, I will change this.
Driver details should not be in DT to begin with.
Rob
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/7] dt-bindings: PCI: Describe ATS property for root complex nodes
[not found] ` <20170524180143.19855-3-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
@ 2017-05-31 17:23 ` Rob Herring
2017-06-01 12:28 ` Jean-Philippe Brucker
0 siblings, 1 reply; 20+ messages in thread
From: Rob Herring @ 2017-05-31 17:23 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-pci-u79uwXL29TY76Z2rM5mHXA,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA,
rjw-LthD3rsA81gm4RdzfppkhA, will.deacon-5wv7dgnIgG8,
okaya-sgV2jX0FEOL9JmXXK+q4OQ, linux-acpi-u79uwXL29TY76Z2rM5mHXA,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
sudeep.holla-5wv7dgnIgG8, bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
tn-nYOzD4b6Jr9Wk0Htik3J/w, sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
lenb-DgEjT+Ai2ygdnm+yROfE0A
On Wed, May 24, 2017 at 07:01:38PM +0100, Jean-Philippe Brucker wrote:
> Address Translation Service (ATS) is an extension to PCIe allowing
> endpoints to manage their own IOTLB, called Address Translation Cache
> (ATC). Instead of having every memory transaction processed by the IOMMU,
> the endpoint can first send an Address Translation Requests for an IOVA,
> obtain the corresponding Physical Address from the IOMMU and store it in
> its ATC. Subsequent transactions to this memory region can be performed on
> the PA, in which case they are marked 'translated' and (partially) bypass
> the IOMMU.
>
> Since the extension uses fields that were previously reserved in the
> PCIe Translation Layer Packet, it seems ill-advised to enabled it on a
> system that doesn't fully support ATS.
>
> To "old" root complexes that simply ignored the new AT field, an Address
> Translation Request will look exactly like a Memory Read Request, so the
> root bridge will forward a memory read to the IOMMU instead of a
> translation request. If the access succeeds, the RC will send a Read
> Completion, which looks like a Translation Completion, back to the
> endpoint. As a result the endpoint might end up storing the content of
> memory instead of a physical address in its ATC. In reality, it's more
> likely that the size fields will be invalid and either end will detect the
> error, but in any case, it is undesirable.
>
> Add a way for firmware to tell the OS that ATS is supported by the PCI
> root complex.
Can't firmware have already enabled ATS? Often for things like this, not
present means "use firmware setting".
>
> Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
> ---
> Documentation/devicetree/bindings/pci/pci-iommu.txt | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/pci/pci-iommu.txt b/Documentation/devicetree/bindings/pci/pci-iommu.txt
> index 0def586fdcdf..f21a68ec471a 100644
> --- a/Documentation/devicetree/bindings/pci/pci-iommu.txt
> +++ b/Documentation/devicetree/bindings/pci/pci-iommu.txt
> @@ -44,6 +44,14 @@ Optional properties
> - iommu-map-mask: A mask to be applied to each Requester ID prior to being
> mapped to an IOMMU specifier per the iommu-map property.
>
> +- ats-supported: if present, the root complex supports the Address
> + Translation Service (ATS). It is able to interpret the AT field in PCIe
> + Transaction Layer Packets, and forward Translation Completions or
> + Invalidation Requests to endpoints.
Why can't this be based on the compatible strings?
Rob
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/7] Add PCI ATS support to SMMUv3
2017-05-31 15:27 ` [PATCH 0/7] Add PCI ATS support to SMMUv3 Nate Watterson
@ 2017-06-01 12:23 ` Jean-Philippe Brucker
0 siblings, 0 replies; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-06-01 12:23 UTC (permalink / raw)
To: Nate Watterson, linux-pci, devicetree, linux-acpi,
linux-arm-kernel, iommu
Cc: mark.rutland, will.deacon, thunder.leizhen, rjw, okaya, robh+dt,
sudeep.holla, bhelgaas, tn, sunil.kovvuri, lenb
On 31/05/17 16:27, Nate Watterson wrote:
> Hi Jean-Philippe,
>
> On 5/24/2017 2:01 PM, Jean-Philippe Brucker wrote:
>> PCIe devices can implement their own TLB, named Address Translation Cache
>> (ATC). In order to support Address Translation Service (ATS), the
>> following changes are needed in software:
>>
>> * Enable ATS on endpoints when the system supports it. Both PCI root
>> complex and associated SMMU must implement the ATS protocol.
>>
>> * When unmapping an IOVA, send an ATC invalidate request to the endpoint
>> in addition to the usual SMMU IOTLB invalidations.
>>
>> I previously sent this as part of a lengthy RFC [1] adding SVM (ATS +
>> PASID + PRI) support to SMMUv3. The next PASID/PRI version is almost
>> ready, but isn't likely to get merged because it needs hardware testing,
>> so I will send it later. PRI depends on ATS, but ATS should be useful on
>> its own.
>>
>> Without PASID and PRI, ATS is used for accelerating transactions. Instead
>> of having all memory accesses go through SMMU translation, the endpoint
>> can translate IOVA->PA once, store the result in its ATC, then issue
>> subsequent transactions using the PA, partially bypassing the SMMU. So in
>> theory it should be faster while keeping the advantages of an IOMMU,
>> namely scatter-gather and access control.
>>
>> The ATS patches can now be tested on some hardware, even though the lack
>> of compatible PCI endpoints makes it difficult to assess what performance
>> optimizations we need. That's why the ATS implementation is a bit rough at
>> the moment, and we will work on optimizing things like invalidation ranges
>> later.
>
> Sinan and I have tested this series on a QDF2400 development platform
> using a PCIe exerciser card as the ATS capable endpoint. We were able
> to verify that ATS requests complete with a valid translated address
> and that DMA transactions using the pre-translated address "bypass"
> the SMMU. Testing ATC invalidations was a bit more difficult as we
> could not figure out how to get the exerciser card to automatically
> send the completion message. We ended up having to write a debugger
> script that would monitor the CMDQ and tell the exerciser to send
> the completion when a hanging CMD_SYNC following a CMD_ATC_INV was
> detected. Hopefully we'll get some real ATS capable endpoints to
> test with soon.
That's still a big step forward from my software tests, thanks a lot for
the report. If you get around testing a real endpoint, there are a few
data points that would be really useful to compare, if only to see whether
enabling ATS is at all viable, or if we end up getting stuck in
queue_poll_cons in normal conditions:
* ATS enabled/disabled in endpoint
* ATSCHK enabled/disabled in SMMU
* Invalidation duration when ATC entry is present/absent, and the range is
big/small
Knowing this would indicate if more work is needed on invalidation sizing,
batching, postponing or if we can optimize later.
Thanks,
Jean
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/7] dt-bindings: PCI: Describe ATS property for root complex nodes
2017-05-31 17:23 ` Rob Herring
@ 2017-06-01 12:28 ` Jean-Philippe Brucker
2017-06-05 17:20 ` Rob Herring
0 siblings, 1 reply; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-06-01 12:28 UTC (permalink / raw)
To: Rob Herring
Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-acpi-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, mark.rutland-5wv7dgnIgG8,
lorenzo.pieralisi-5wv7dgnIgG8, hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
sudeep.holla-5wv7dgnIgG8, rjw-LthD3rsA81gm4RdzfppkhA,
lenb-DgEjT+Ai2ygdnm+yROfE0A, will.deacon-5wv7dgnIgG8,
robin.murphy-5wv7dgnIgG8, joro-zLv9SwRftAIdnm+yROfE0A,
okaya-sgV2jX0FEOL9JmXXK+q4OQ,
sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA, tn-nYOzD4b6Jr9Wk0Htik3J/w
On 31/05/17 18:23, Rob Herring wrote:
> On Wed, May 24, 2017 at 07:01:38PM +0100, Jean-Philippe Brucker wrote:
>> Address Translation Service (ATS) is an extension to PCIe allowing
>> endpoints to manage their own IOTLB, called Address Translation Cache
>> (ATC). Instead of having every memory transaction processed by the IOMMU,
>> the endpoint can first send an Address Translation Requests for an IOVA,
>> obtain the corresponding Physical Address from the IOMMU and store it in
>> its ATC. Subsequent transactions to this memory region can be performed on
>> the PA, in which case they are marked 'translated' and (partially) bypass
>> the IOMMU.
>>
>> Since the extension uses fields that were previously reserved in the
>> PCIe Translation Layer Packet, it seems ill-advised to enabled it on a
>> system that doesn't fully support ATS.
>>
>> To "old" root complexes that simply ignored the new AT field, an Address
>> Translation Request will look exactly like a Memory Read Request, so the
>> root bridge will forward a memory read to the IOMMU instead of a
>> translation request. If the access succeeds, the RC will send a Read
>> Completion, which looks like a Translation Completion, back to the
>> endpoint. As a result the endpoint might end up storing the content of
>> memory instead of a physical address in its ATC. In reality, it's more
>> likely that the size fields will be invalid and either end will detect the
>> error, but in any case, it is undesirable.
>>
>> Add a way for firmware to tell the OS that ATS is supported by the PCI
>> root complex.
>
> Can't firmware have already enabled ATS? Often for things like this, not
> present means "use firmware setting".
I don't think it's up to firmware to enable ATS in endpoints, because it
depends on IOMMU properties (e.g. configured page size). It must also be
enabled after the PASID capability, which the OS may or may not want to
enable.
While endpoints have ATS capability and config register, there is no
architected mechanism in root complexes as far as I know. So firmware may
have a mechanism outside the OS scope to toggle ATS in the root complex.
If there is a bug and firmware cannot enable ATS, then the OS must be made
aware of it, so that it doesn't enable ATS in endpoints, or else we might
end up with silent memory corruption as described above. (Lack of ATS may
slow the system down but shouldn't be fatal.)
If the SMMU supports ATS, then the root complex attached to it will most
likely supports ATS. The switch in this patch simply allows firmware to
confirm that.
>> Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
>> ---
>> Documentation/devicetree/bindings/pci/pci-iommu.txt | 8 ++++++++
>> 1 file changed, 8 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pci/pci-iommu.txt b/Documentation/devicetree/bindings/pci/pci-iommu.txt
>> index 0def586fdcdf..f21a68ec471a 100644
>> --- a/Documentation/devicetree/bindings/pci/pci-iommu.txt
>> +++ b/Documentation/devicetree/bindings/pci/pci-iommu.txt
>> @@ -44,6 +44,14 @@ Optional properties
>> - iommu-map-mask: A mask to be applied to each Requester ID prior to being
>> mapped to an IOMMU specifier per the iommu-map property.
>>
>> +- ats-supported: if present, the root complex supports the Address
>> + Translation Service (ATS). It is able to interpret the AT field in PCIe
>> + Transaction Layer Packets, and forward Translation Completions or
>> + Invalidation Requests to endpoints.
>
> Why can't this be based on the compatible strings?
Host controllers like the generic ECAM one should be able to advertise
ATS, if for instance the virtual IOMMU in Qemu offers a channel for ATS
invalidation. In that case we would have pci-host-{e,}cam-generic{-ats,}
compatible strings and double the number of compatible strings each time
we add a similar capability.
Thanks,
Jean
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/7] dt-bindings: PCI: Describe ATS property for root complex nodes
2017-06-01 12:28 ` Jean-Philippe Brucker
@ 2017-06-05 17:20 ` Rob Herring
2017-06-06 11:11 ` Jean-Philippe Brucker
0 siblings, 1 reply; 20+ messages in thread
From: Rob Herring @ 2017-06-05 17:20 UTC (permalink / raw)
To: Jean-Philippe Brucker
Cc: linux-pci, devicetree, linux-acpi, linux-arm-kernel, iommu,
bhelgaas, mark.rutland, lorenzo.pieralisi, hanjun.guo,
sudeep.holla, rjw, lenb, will.deacon, robin.murphy, joro, okaya,
sunil.kovvuri, thunder.leizhen, tn
On Thu, Jun 01, 2017 at 01:28:01PM +0100, Jean-Philippe Brucker wrote:
> On 31/05/17 18:23, Rob Herring wrote:
> > On Wed, May 24, 2017 at 07:01:38PM +0100, Jean-Philippe Brucker wrote:
> >> Address Translation Service (ATS) is an extension to PCIe allowing
> >> endpoints to manage their own IOTLB, called Address Translation Cache
> >> (ATC). Instead of having every memory transaction processed by the IOMMU,
> >> the endpoint can first send an Address Translation Requests for an IOVA,
> >> obtain the corresponding Physical Address from the IOMMU and store it in
> >> its ATC. Subsequent transactions to this memory region can be performed on
> >> the PA, in which case they are marked 'translated' and (partially) bypass
> >> the IOMMU.
> >>
> >> Since the extension uses fields that were previously reserved in the
> >> PCIe Translation Layer Packet, it seems ill-advised to enabled it on a
> >> system that doesn't fully support ATS.
> >>
> >> To "old" root complexes that simply ignored the new AT field, an Address
> >> Translation Request will look exactly like a Memory Read Request, so the
> >> root bridge will forward a memory read to the IOMMU instead of a
> >> translation request. If the access succeeds, the RC will send a Read
> >> Completion, which looks like a Translation Completion, back to the
> >> endpoint. As a result the endpoint might end up storing the content of
> >> memory instead of a physical address in its ATC. In reality, it's more
> >> likely that the size fields will be invalid and either end will detect the
> >> error, but in any case, it is undesirable.
> >>
> >> Add a way for firmware to tell the OS that ATS is supported by the PCI
> >> root complex.
> >
> > Can't firmware have already enabled ATS? Often for things like this, not
> > present means "use firmware setting".
>
> I don't think it's up to firmware to enable ATS in endpoints, because it
> depends on IOMMU properties (e.g. configured page size). It must also be
> enabled after the PASID capability, which the OS may or may not want to
> enable.
>
> While endpoints have ATS capability and config register, there is no
> architected mechanism in root complexes as far as I know. So firmware may
> have a mechanism outside the OS scope to toggle ATS in the root complex.
> If there is a bug and firmware cannot enable ATS, then the OS must be made
> aware of it, so that it doesn't enable ATS in endpoints, or else we might
> end up with silent memory corruption as described above. (Lack of ATS may
> slow the system down but shouldn't be fatal.)
>
> If the SMMU supports ATS, then the root complex attached to it will most
> likely supports ATS. The switch in this patch simply allows firmware to
> confirm that.
>
> >> Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
> >> ---
> >> Documentation/devicetree/bindings/pci/pci-iommu.txt | 8 ++++++++
> >> 1 file changed, 8 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/pci/pci-iommu.txt b/Documentation/devicetree/bindings/pci/pci-iommu.txt
> >> index 0def586fdcdf..f21a68ec471a 100644
> >> --- a/Documentation/devicetree/bindings/pci/pci-iommu.txt
> >> +++ b/Documentation/devicetree/bindings/pci/pci-iommu.txt
> >> @@ -44,6 +44,14 @@ Optional properties
> >> - iommu-map-mask: A mask to be applied to each Requester ID prior to being
> >> mapped to an IOMMU specifier per the iommu-map property.
> >>
> >> +- ats-supported: if present, the root complex supports the Address
> >> + Translation Service (ATS). It is able to interpret the AT field in PCIe
> >> + Transaction Layer Packets, and forward Translation Completions or
> >> + Invalidation Requests to endpoints.
> >
> > Why can't this be based on the compatible strings?
>
> Host controllers like the generic ECAM one should be able to advertise
> ATS, if for instance the virtual IOMMU in Qemu offers a channel for ATS
> invalidation. In that case we would have pci-host-{e,}cam-generic{-ats,}
> compatible strings and double the number of compatible strings each time
> we add a similar capability.
It would not double the compatibles. A given SoC will either support ATS
or not, right? A given compatible will imply whether ATS is supported or
not.
pci-host-{e,}cam-generic is a special case. I'm okay with having a
property for that I suppose. We should not require this property though
and allow for it to be implied by the SoC specific compatible as well.
Rob
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/7] dt-bindings: PCI: Describe ATS property for root complex nodes
2017-06-05 17:20 ` Rob Herring
@ 2017-06-06 11:11 ` Jean-Philippe Brucker
[not found] ` <65aea93f-d516-f045-f216-3f56e96bdeb6-5wv7dgnIgG8@public.gmane.org>
0 siblings, 1 reply; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-06-06 11:11 UTC (permalink / raw)
To: Rob Herring
Cc: linux-pci, devicetree, linux-acpi, linux-arm-kernel, iommu,
bhelgaas, mark.rutland, lorenzo.pieralisi, hanjun.guo,
sudeep.holla, rjw, lenb, will.deacon, robin.murphy, joro, okaya,
sunil.kovvuri, thunder.leizhen, tn
On 05/06/17 18:20, Rob Herring wrote:
> On Thu, Jun 01, 2017 at 01:28:01PM +0100, Jean-Philippe Brucker wrote:
>> On 31/05/17 18:23, Rob Herring wrote:
>>> On Wed, May 24, 2017 at 07:01:38PM +0100, Jean-Philippe Brucker wrote:
>>>> Address Translation Service (ATS) is an extension to PCIe allowing
>>>> endpoints to manage their own IOTLB, called Address Translation Cache
>>>> (ATC). Instead of having every memory transaction processed by the IOMMU,
>>>> the endpoint can first send an Address Translation Requests for an IOVA,
>>>> obtain the corresponding Physical Address from the IOMMU and store it in
>>>> its ATC. Subsequent transactions to this memory region can be performed on
>>>> the PA, in which case they are marked 'translated' and (partially) bypass
>>>> the IOMMU.
>>>>
>>>> Since the extension uses fields that were previously reserved in the
>>>> PCIe Translation Layer Packet, it seems ill-advised to enabled it on a
>>>> system that doesn't fully support ATS.
>>>>
>>>> To "old" root complexes that simply ignored the new AT field, an Address
>>>> Translation Request will look exactly like a Memory Read Request, so the
>>>> root bridge will forward a memory read to the IOMMU instead of a
>>>> translation request. If the access succeeds, the RC will send a Read
>>>> Completion, which looks like a Translation Completion, back to the
>>>> endpoint. As a result the endpoint might end up storing the content of
>>>> memory instead of a physical address in its ATC. In reality, it's more
>>>> likely that the size fields will be invalid and either end will detect the
>>>> error, but in any case, it is undesirable.
>>>>
>>>> Add a way for firmware to tell the OS that ATS is supported by the PCI
>>>> root complex.
>>>
>>> Can't firmware have already enabled ATS? Often for things like this, not
>>> present means "use firmware setting".
>>
>> I don't think it's up to firmware to enable ATS in endpoints, because it
>> depends on IOMMU properties (e.g. configured page size). It must also be
>> enabled after the PASID capability, which the OS may or may not want to
>> enable.
>>
>> While endpoints have ATS capability and config register, there is no
>> architected mechanism in root complexes as far as I know. So firmware may
>> have a mechanism outside the OS scope to toggle ATS in the root complex.
>> If there is a bug and firmware cannot enable ATS, then the OS must be made
>> aware of it, so that it doesn't enable ATS in endpoints, or else we might
>> end up with silent memory corruption as described above. (Lack of ATS may
>> slow the system down but shouldn't be fatal.)
>>
>> If the SMMU supports ATS, then the root complex attached to it will most
>> likely supports ATS. The switch in this patch simply allows firmware to
>> confirm that.
>>
>>>> Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
>>>> ---
>>>> Documentation/devicetree/bindings/pci/pci-iommu.txt | 8 ++++++++
>>>> 1 file changed, 8 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/pci/pci-iommu.txt b/Documentation/devicetree/bindings/pci/pci-iommu.txt
>>>> index 0def586fdcdf..f21a68ec471a 100644
>>>> --- a/Documentation/devicetree/bindings/pci/pci-iommu.txt
>>>> +++ b/Documentation/devicetree/bindings/pci/pci-iommu.txt
>>>> @@ -44,6 +44,14 @@ Optional properties
>>>> - iommu-map-mask: A mask to be applied to each Requester ID prior to being
>>>> mapped to an IOMMU specifier per the iommu-map property.
>>>>
>>>> +- ats-supported: if present, the root complex supports the Address
>>>> + Translation Service (ATS). It is able to interpret the AT field in PCIe
>>>> + Transaction Layer Packets, and forward Translation Completions or
>>>> + Invalidation Requests to endpoints.
>>>
>>> Why can't this be based on the compatible strings?
>>
>> Host controllers like the generic ECAM one should be able to advertise
>> ATS, if for instance the virtual IOMMU in Qemu offers a channel for ATS
>> invalidation. In that case we would have pci-host-{e,}cam-generic{-ats,}
>> compatible strings and double the number of compatible strings each time
>> we add a similar capability.
>
> It would not double the compatibles. A given SoC will either support ATS
> or not, right? A given compatible will imply whether ATS is supported or
> not.
>
> pci-host-{e,}cam-generic is a special case. I'm okay with having a
> property for that I suppose. We should not require this property though
> and allow for it to be implied by the SoC specific compatible as well.
The property isn't useful for host-generic since a host like Qemu can
easily disable ATS in the IOMMU. It would only be here for consistency.
Changing IOMMU registers wouldn't be as simple for a firmware running on
real hardware.
The ats-supported property aimed to provide a mechanism identical to what
IORT provides in root complex nodes, since I have to add support for that
in Linux anyway. But it is not clear what their rationale is.
I couldn't see any more reason to add it, so I'll gladly drop the patch
and replace it with something based on compatible, if you think that the
case I described above (bug in hardware, firmware cannot enable ATS in
root complex) is superfluous.
Thanks,
Jean
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/7] dt-bindings: PCI: Describe ATS property for root complex nodes
[not found] ` <65aea93f-d516-f045-f216-3f56e96bdeb6-5wv7dgnIgG8@public.gmane.org>
@ 2017-06-20 11:38 ` Jean-Philippe Brucker
0 siblings, 0 replies; 20+ messages in thread
From: Jean-Philippe Brucker @ 2017-06-20 11:38 UTC (permalink / raw)
To: Rob Herring
Cc: mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-pci-u79uwXL29TY76Z2rM5mHXA, will.deacon-5wv7dgnIgG8,
sudeep.holla-5wv7dgnIgG8, rjw-LthD3rsA81gm4RdzfppkhA,
okaya-sgV2jX0FEOL9JmXXK+q4OQ, linux-acpi-u79uwXL29TY76Z2rM5mHXA,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
thunder.leizhen-hv44wF8Li93QT0dZR+AlfA,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tn-nYOzD4b6Jr9Wk0Htik3J/w,
sunil.kovvuri-Re5JQEeQqe8AvxtiuMwx3w,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
lenb-DgEjT+Ai2ygdnm+yROfE0A
On 06/06/2017 12:11 PM, Jean-Philippe Brucker wrote:
> On 05/06/17 18:20, Rob Herring wrote:
>> pci-host-{e,}cam-generic is a special case. I'm okay with having a
>> property for that I suppose. We should not require this property though
>> and allow for it to be implied by the SoC specific compatible as well.
>
> The property isn't useful for host-generic since a host like Qemu can
> easily disable ATS in the IOMMU. It would only be here for consistency.
> Changing IOMMU registers wouldn't be as simple for a firmware running on
> real hardware.
Sorry I was mistaken here. AMD Seattle hardware, for instance, implements
a pure host-ecam-generic. So it's not exclusively used by Qemu. A quick
search in the kernel also brings up alpine and thunder2. So I guess I'll
move ats-supported documentation to host-generic-pci.txt.
Thanks,
Jean
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2017-06-20 11:38 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-24 18:01 [PATCH 0/7] Add PCI ATS support to SMMUv3 Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 1/7] PCI: Move ATS declarations outside of CONFIG_PCI Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 3/7] iommu/of: Check ATS capability in root complex nodes Jean-Philippe Brucker
[not found] ` <20170524180143.19855-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-05-24 18:01 ` [PATCH 2/7] dt-bindings: PCI: Describe ATS property for " Jean-Philippe Brucker
2017-05-30 10:01 ` Joerg Roedel
2017-05-30 10:58 ` Jean-Philippe Brucker
[not found] ` <035be7ba-e850-a5a9-08fa-802a04feb600-5wv7dgnIgG8@public.gmane.org>
2017-05-31 17:17 ` Rob Herring
[not found] ` <20170524180143.19855-3-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-05-31 17:23 ` Rob Herring
2017-06-01 12:28 ` Jean-Philippe Brucker
2017-06-05 17:20 ` Rob Herring
2017-06-06 11:11 ` Jean-Philippe Brucker
[not found] ` <65aea93f-d516-f045-f216-3f56e96bdeb6-5wv7dgnIgG8@public.gmane.org>
2017-06-20 11:38 ` Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 4/7] ACPI/IORT: Check ATS capability in " Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 5/7] iommu/arm-smmu-v3: Link domains and devices Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 6/7] iommu/arm-smmu-v3: Add support for PCI ATS Jean-Philippe Brucker
[not found] ` <20170524180143.19855-7-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-05-30 10:28 ` Joerg Roedel
2017-05-30 10:58 ` Jean-Philippe Brucker
2017-05-24 18:01 ` [PATCH 7/7] iommu/arm-smmu-v3: Disable tagged pointers Jean-Philippe Brucker
2017-05-31 15:27 ` [PATCH 0/7] Add PCI ATS support to SMMUv3 Nate Watterson
2017-06-01 12:23 ` Jean-Philippe Brucker
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).