Since v4 [1] I addressed some of Will's comment.
Still missing and will be submitted as follow-up patches:
* write STE.V with WRITE_ONCE() (patch 7)
* batch submission of CD invalidation (patch 7)
* Remove WARN_ON_ONCE() in add_device() (patch 13)
Pending Robin's input.
So I think patches 1-10 should be good to go, but anything in between
would be good too, and I'll send the rest for 5.7.
Thanks,
Jean
[1]
https://lore.kernel.org/linux-iommu/20191219163033.2608177-1-jean-phili...@linaro.org/
Jean-Philippe Brucker (13):
iommu/arm-smmu-v3: Drop __GFP_ZERO flag from DMA allocation
dt-bindings: document PASID property for IOMMU masters
iommu/arm-smmu-v3: Parse PASID devicetree property of platform devices
ACPI/IORT: Parse SSID property of named component node
iommu/arm-smmu-v3: Prepare arm_smmu_s1_cfg for SSID support
iommu/arm-smmu-v3: Add context descriptor tables allocators
iommu/arm-smmu-v3: Add support for Substream IDs
iommu/arm-smmu-v3: Propagate ssid_bits
iommu/arm-smmu-v3: Prepare for handling arm_smmu_write_ctx_desc()
failure
iommu/arm-smmu-v3: Add second level of context descriptor table
iommu/arm-smmu-v3: Improve add_device() error handling
PCI/ATS: Add PASID stubs
iommu/arm-smmu-v3: Add support for PCI PASID
.../devicetree/bindings/iommu/iommu.txt | 6 +
drivers/acpi/arm64/iort.c | 18 +
drivers/iommu/arm-smmu-v3.c | 464 +++---
drivers/iommu/of_iommu.c | 6 +-
include/linux/iommu.h | 2 +
include/linux/pci-ats.h | 3 +
6 files changed, 439 insertions(+), 60 deletions(-)
Diff since v4 (large due to structures refactoring):
#diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 8e95ecad4c9a..f42454512e87 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -275,7 +275,7 @@
#define CTXDESC_L2_ENTRIES (1 << CTXDESC_SPLIT)
#define CTXDESC_L1_DESC_DWORDS 1
-#define CTXDESC_L1_DESC_VALID 1
+#define CTXDESC_L1_DESC_V (1UL << 0)
#define CTXDESC_L1_DESC_L2PTR_MASK GENMASK_ULL(51, 12)
#define CTXDESC_CD_DWORDS 8
@@ -583,18 +583,20 @@ struct arm_smmu_ctx_desc {
u64 mair;
};
-struct arm_smmu_cd_table {
- __le64 *ptr;
- dma_addr_t ptr_dma;
+struct arm_smmu_l1_ctx_desc {
+ __le64 *l2ptr;
+ dma_addr_t l2ptr_dma;
+};
+
+struct arm_smmu_ctx_desc_cfg {
+ __le64 *cdtab;
+ dma_addr_t cdtab_dma;
+ struct arm_smmu_l1_ctx_desc *l1_desc;
+ unsigned intnum_l1_ents;
};
struct arm_smmu_s1_cfg {
- /* Leaf tables or linear table */
- struct arm_smmu_cd_table*tables;
- size_t num_tables;
- /* First level tables, when two levels are used */
- __le64 *l1ptr;
- dma_addr_t l1ptr_dma;
+ struct arm_smmu_ctx_desc_cfgcdcfg;
struct arm_smmu_ctx_desccd;
u8 s1fmt;
u8 s1cdmax;
@@ -1519,14 +1521,13 @@ static void arm_smmu_sync_cd(struct arm_smmu_domain
*smmu_domain,
}
static int arm_smmu_alloc_cd_leaf_table(struct arm_smmu_device *smmu,
- struct arm_smmu_cd_table *table,
- size_t num_entries)
+ struct arm_smmu_l1_ctx_desc *l1_desc)
{
- size_t size = num_entries * (CTXDESC_CD_DWORDS << 3);
+ size_t size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3);
- table->ptr = dmam_alloc_coherent(smmu->dev, size, >ptr_dma,
-GFP_KERNEL);
- if (!table->ptr) {
+ l1_desc->l2ptr = dmam_alloc_coherent(smmu->dev, size,
+_desc->l2ptr_dma, GFP_KERNEL);
+ if (!l1_desc->l2ptr) {
dev_warn(smmu->dev,
"failed to allocate context descriptor table\n");
return -ENOMEM;
@@ -1534,22 +1535,11 @@ static int arm_smmu_alloc_cd_leaf_table(struct
arm_smmu_device *smmu,
return 0;
}
-static void arm_smmu_free_cd_leaf_table(struct arm_smmu_device *smmu,
- struct arm_smmu_cd_table *table,
- size_t num_entries)
-{
- size_t size = num_entries * (CTXDESC_CD_DWORDS << 3);
-
- if (!table->ptr)
- return;
- dmam_free_coherent(smmu->dev, size, table->ptr, table->ptr_dma);
-}
-
static void arm_smmu_write_cd_l1_desc(__le64 *dst,
- struct arm_smmu_cd_table *table)
+