[PATCH] iommu/arm-smmu-v2: Workaround for ThunderX errata#27704
Due to Errata#27704 CN88xx SMMUv2,supports only shared ASID and VMID namespaces; specifically within a given node SMMU0 and SMMU1 share, as does SMMU2 and SMMU3. This patch address these issuee by supplying asid and vmid while calculating ASID and VMID for Thunder SMMUv2. NOTE: resending with commit message fix. changes from V2: - removed *_base from DT, and replaced with compatible string changes from V1: - rebased on top of 16 bit VMID patch - removed redundent options from DT - insted of transform, DT now supplies starting ASID/VMID Signed-off-by: Tirumalesh ChalamarlaSigned-off-by: Akula Geethasowjanya --- .../devicetree/bindings/iommu/arm,smmu.txt | 1 + drivers/iommu/arm-smmu.c | 48 +- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index 7180745..19fe6f2 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -16,6 +16,7 @@ conditions. "arm,mmu-400" "arm,mmu-401" "arm,mmu-500" +"cavium,smmu-v2" depending on the particular implementation and/or the version of the architecture implemented. diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 247a469..c704f88 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -326,6 +326,12 @@ struct arm_smmu_device { struct list_headlist; struct rb_root masters; + /* +*The following fields are specific to Cavium, Thunder +*/ + u32 cavium_smmu_id; + u32 cavium_id_base; + }; struct arm_smmu_cfg { @@ -335,8 +341,8 @@ struct arm_smmu_cfg { }; #define INVALID_IRPTNDX0xff -#define ARM_SMMU_CB_ASID(cfg) ((cfg)->cbndx) -#define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1) +#define ARM_SMMU_CB_ASID(smmu, cfg) ((u16)(smmu)->cavium_id_base + (cfg)->cbndx) +#define ARM_SMMU_CB_VMID(smmu, cfg) ((u16)(smmu)->cavium_id_base + (cfg)->cbndx + 1) enum arm_smmu_domain_stage { ARM_SMMU_DOMAIN_S1 = 0, @@ -364,6 +370,8 @@ struct arm_smmu_option_prop { const char *prop; }; +static int cavium_smmu_count; + static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" }, { 0, NULL}, @@ -575,11 +583,11 @@ static void arm_smmu_tlb_inv_context(void *cookie) if (stage1) { base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); - writel_relaxed(ARM_SMMU_CB_ASID(cfg), + writel_relaxed(ARM_SMMU_CB_ASID(smmu, cfg), base + ARM_SMMU_CB_S1_TLBIASID); } else { base = ARM_SMMU_GR0(smmu); - writel_relaxed(ARM_SMMU_CB_VMID(cfg), + writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg), base + ARM_SMMU_GR0_TLBIVMID); } @@ -601,7 +609,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, if (!IS_ENABLED(CONFIG_64BIT) || smmu->version == ARM_SMMU_V1) { iova &= ~12UL; - iova |= ARM_SMMU_CB_ASID(cfg); + iova |= ARM_SMMU_CB_ASID(smmu, cfg); do { writel_relaxed(iova, reg); iova += granule; @@ -609,7 +617,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, #ifdef CONFIG_64BIT } else { iova >>= 12; - iova |= (u64)ARM_SMMU_CB_ASID(cfg) << 48; + iova |= (u64)ARM_SMMU_CB_ASID(smmu, cfg) << 48; do { writeq_relaxed(iova, reg); iova += granule >> 12; @@ -629,7 +637,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, #endif } else { reg = ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_TLBIVMID; - writel_relaxed(ARM_SMMU_CB_VMID(cfg), reg); + writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg), reg); } } @@ -738,7 +746,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, #endif /* if 16bit VMID supported set VMID in CBA2R */ if (smmu->features & ARM_SMMU_FEAT_VMID16) - reg |= ARM_SMMU_CB_VMID(cfg) << CBA2R_VMID_SHIFT; + reg |= ARM_SMMU_CB_VMID(smmu, cfg) <<
[PATCH v4 6/6] PCI: Squash pci_dev_flags to remove holes
From: Jacek LawrynowiczAfter removing PCI_DEV_FLAGS_DMA_ALIAS_DEVFN, the (1 << 4) value was unused. Squash the other values so all the bits are adjacent. No functional change intended. (I'm not sure this is worth doing. We have 16 flag bits and we're not even close to exhausting them. But if we do squash them, it should be in a separate patch so we don't clutter up the main patches.) --- include/linux/pci.h |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/pci.h b/include/linux/pci.h index d9e0c84..4e36024 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -173,13 +173,13 @@ enum pci_dev_flags { /* Flag for quirk use to store if quirk-specific ACS is enabled */ PCI_DEV_FLAGS_ACS_ENABLED_QUIRK = (__force pci_dev_flags_t) (1 << 3), /* Use a PCIe-to-PCI bridge alias even if !pci_is_pcie */ - PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS = (__force pci_dev_flags_t) (1 << 5), + PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS = (__force pci_dev_flags_t) (1 << 4), /* Do not use bus resets for device */ - PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6), + PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 5), /* Do not use PM reset even if device advertises NoSoftRst- */ - PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 7), + PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 6), /* Get VPD from function 0 VPD */ - PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 << 8), + PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 << 7), }; enum pci_irq_reroute_variant { ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v4 5/6] pci: Add DMA alias quirk for mic_x200_dma
From: Jacek LawrynowiczMIC x200 NTB forwards PCIe traffic using multiple alien RID. They have to be added as aliases to the DMA device in order to allow buffer access when IOMMU is enabled. Signed-off-by: Jacek Lawrynowicz Acked-by: David Woodhouse --- drivers/pci/quirks.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index cf023ea..ac23a30 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3696,6 +3696,19 @@ DECLARE_PCI_FIXUP_HEADER(0x1283, 0x8892, quirk_use_pcie_bridge_dma_alias); DECLARE_PCI_FIXUP_HEADER(0x8086, 0x244e, quirk_use_pcie_bridge_dma_alias); /* + * MIC x200 NTB forwards PCIe traffic using multiple alien RID. They have to + * be added as aliases to the DMA device in order to allow buffer access + * when IOMMU is enabled. + */ +static void quirk_mic_x200_dma_alias(struct pci_dev *pdev) +{ + pci_add_dma_alias(pdev, PCI_DEVFN(0x10, 0x0)); + pci_add_dma_alias(pdev, PCI_DEVFN(0x11, 0x0)); + pci_add_dma_alias(pdev, PCI_DEVFN(0x12, 0x3)); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2264, quirk_mic_x200_dma_alias); + +/* * Intersil/Techwell TW686[4589]-based video capture cards have an empty (zero) * class code. Fix it. */ ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v4 4/6] PCI: Rename dma_alias_is_enabled() to pci_devs_are_dma_aliases()
This should be folded into the previous patch. I left it separate to show the interface difference more clearly. Also, pci_devs_are_dma_aliases() uses PCI internals (dma_alias_mask), so I think it should be in PCI code instead of in IOMMU code. That would mean both it and pci_add_dma_alias() should probably be declared in include/linux/pci.h (but not exported to modules with EXPORT_SYMBOL()). --- drivers/iommu/iommu.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index a214e19..031d06b 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -659,10 +659,12 @@ static struct iommu_group *get_pci_function_alias_group(struct pci_dev *pdev, return NULL; } -static bool dma_alias_is_enabled(struct pci_dev *dev, u8 devfn) +static bool pci_devs_are_dma_aliases(struct pci_dev *pdev1, struct pci_dev *pdev2) { - return dev->dma_alias_mask && - test_bit(devfn, dev->dma_alias_mask); + return (pdev1->dma_alias_mask && + test_bit(pdev2->devfn, pdev1->dma_alias_mask)) || + (pdev2->dma_alias_mask && + test_bit(pdev1->devfn, pdev2->dma_alias_mask)); } /* @@ -692,8 +694,7 @@ static struct iommu_group *get_pci_alias_group(struct pci_dev *pdev, continue; /* We alias them or they alias us */ - if (dma_alias_is_enabled(pdev, tmp->devfn) || - dma_alias_is_enabled(tmp, pdev->devfn)) { + if (pci_devs_are_dma_aliases(pdev, tmp)) { group = get_pci_alias_group(tmp, devfns); if (group) { pci_dev_put(tmp); ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v4 0/6] PCI: Support multiple DMA aliases
This is a revision of Jacek's v3 posting: http://lkml.kernel.org/r/1454152012-46337-1-git-send-email-jacek.lawrynow...@intel.com The changes from v3 are: - Split into smaller patches for reviewability - Move printk when adding DMA alias - Change dma_alias_is_enabled() interface to take two pci_devs - Rename dma_alias_is_enabled() to indicate PCI context The only remaining thing I want to sort out is the dma_alias_is_enabled() vs pci_for_each_dma_alias() question Alex raised. I'll respond to the relevant part of the patch in this series with my specific questions. --- Bjorn Helgaas (1): PCI: Rename dma_alias_is_enabled() to pci_devs_are_dma_aliases() Jacek Lawrynowicz (5): PCI: Add pci_add_dma_alias() to abstract implementation PCI: Move informational printk to pci_add_dma_alias() PCI: Add support for multiple DMA aliases pci: Add DMA alias quirk for mic_x200_dma PCI: Squash pci_dev_flags to remove holes drivers/iommu/iommu.c | 18 +++--- drivers/pci/pci.c | 23 +++ drivers/pci/pci.h |2 ++ drivers/pci/probe.c |1 + drivers/pci/quirks.c | 34 +++--- drivers/pci/search.c | 14 +- include/linux/pci.h | 12 +--- 7 files changed, 70 insertions(+), 34 deletions(-) ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v4 1/6] PCI: Add pci_add_dma_alias() to abstract implementation
From: Jacek LawrynowiczAdd a pci_add_dma_alias() interface to encapsulate the details of adding an alias. No functional change intended. --- drivers/pci/pci.c| 14 ++ drivers/pci/pci.h|2 ++ drivers/pci/quirks.c | 19 +++ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 602eb42..7fccc8a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4568,6 +4568,20 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, return 0; } +/** + * pci_add_dma_alias - Add a DMA devfn alias for a device + * @dev: the PCI device for which alias is added + * @devfn: alias slot and function + * + * This helper encodes 8-bit devfn as bit number in dma_alias_mask. + * It should be called early, preferably as PCI fixup header quirk. + */ +void pci_add_dma_alias(struct pci_dev *dev, u8 devfn) +{ + dev->dma_alias_devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 0); + dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN; +} + bool pci_device_is_present(struct pci_dev *pdev) { u32 v; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 9a1660f..c5dc8dc 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -335,4 +335,6 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) } #endif +void pci_add_dma_alias(struct pci_dev *dev, u8 devfn); + #endif /* DRIVERS_PCI_H */ diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0575a1e..df28dce 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3581,10 +3581,8 @@ int pci_dev_specific_reset(struct pci_dev *dev, int probe) static void quirk_dma_func0_alias(struct pci_dev *dev) { - if (PCI_FUNC(dev->devfn) != 0) { - dev->dma_alias_devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 0); - dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN; - } + if (PCI_FUNC(dev->devfn) != 0) + pci_add_dma_alias(dev, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); } /* @@ -3597,10 +3595,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RICOH, 0xe476, quirk_dma_func0_alias); static void quirk_dma_func1_alias(struct pci_dev *dev) { - if (PCI_FUNC(dev->devfn) != 1) { - dev->dma_alias_devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 1); - dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN; - } + if (PCI_FUNC(dev->devfn) != 1) + pci_add_dma_alias(dev, PCI_DEVFN(PCI_SLOT(dev->devfn), 1)); } /* @@ -3667,11 +3663,10 @@ static void quirk_fixed_dma_alias(struct pci_dev *dev) id = pci_match_id(fixed_dma_alias_tbl, dev); if (id) { - dev->dma_alias_devfn = id->driver_data; - dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN; + pci_add_dma_alias(dev, id->driver_data); dev_info(>dev, "Enabling fixed DMA alias to %02x.%d\n", -PCI_SLOT(dev->dma_alias_devfn), -PCI_FUNC(dev->dma_alias_devfn)); +PCI_SLOT(id->driver_data), +PCI_FUNC(id->driver_data)); } } ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v4 2/6] PCI: Move informational printk to pci_add_dma_alias()
From: Jacek LawrynowiczOne of the quirks that adds DMA aliases logs an informational message in dmesg. Move that to pci_add_dma_alias() so all users log the message consistently. No functional change intended (except extra message). --- drivers/pci/pci.c|2 ++ drivers/pci/quirks.c |6 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7fccc8a..8b0a637 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4580,6 +4580,8 @@ void pci_add_dma_alias(struct pci_dev *dev, u8 devfn) { dev->dma_alias_devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 0); dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN; + dev_info(>dev, "Enabling fixed DMA alias to %02x.%d\n", +PCI_SLOT(devfn), PCI_FUNC(devfn)); } bool pci_device_is_present(struct pci_dev *pdev) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index df28dce..cf023ea 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3662,12 +3662,8 @@ static void quirk_fixed_dma_alias(struct pci_dev *dev) const struct pci_device_id *id; id = pci_match_id(fixed_dma_alias_tbl, dev); - if (id) { + if (id) pci_add_dma_alias(dev, id->driver_data); - dev_info(>dev, "Enabling fixed DMA alias to %02x.%d\n", -PCI_SLOT(id->driver_data), -PCI_FUNC(id->driver_data)); - } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADAPTEC2, 0x0285, quirk_fixed_dma_alias); ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v4 3/6] PCI: Add support for multiple DMA aliases
From: Jacek Lawrynowicz--- drivers/iommu/iommu.c | 17 ++--- drivers/pci/pci.c | 11 +-- drivers/pci/probe.c |1 + drivers/pci/search.c | 14 +- include/linux/pci.h |4 +--- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 0e3b009..a214e19 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -659,9 +659,15 @@ static struct iommu_group *get_pci_function_alias_group(struct pci_dev *pdev, return NULL; } +static bool dma_alias_is_enabled(struct pci_dev *dev, u8 devfn) +{ + return dev->dma_alias_mask && + test_bit(devfn, dev->dma_alias_mask); +} + /* - * Look for aliases to or from the given device for exisiting groups. The - * dma_alias_devfn only supports aliases on the same bus, therefore the search + * Look for aliases to or from the given device for existing groups. DMA + * aliases are only supported on the same bus, therefore the search * space is quite small (especially since we're really only looking at pcie * device, and therefore only expect multiple slots on the root complex or * downstream switch ports). It's conceivable though that a pair of @@ -686,11 +692,8 @@ static struct iommu_group *get_pci_alias_group(struct pci_dev *pdev, continue; /* We alias them or they alias us */ - if (((pdev->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN) && -pdev->dma_alias_devfn == tmp->devfn) || - ((tmp->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN) && -tmp->dma_alias_devfn == pdev->devfn)) { - + if (dma_alias_is_enabled(pdev, tmp->devfn) || + dma_alias_is_enabled(tmp, pdev->devfn)) { group = get_pci_alias_group(tmp, devfns); if (group) { pci_dev_put(tmp); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8b0a637..eb4dd49 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4578,8 +4578,15 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, */ void pci_add_dma_alias(struct pci_dev *dev, u8 devfn) { - dev->dma_alias_devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), 0); - dev->dev_flags |= PCI_DEV_FLAGS_DMA_ALIAS_DEVFN; + if (!dev->dma_alias_mask) + dev->dma_alias_mask = kcalloc(BITS_TO_LONGS(U8_MAX), + sizeof(long), GFP_KERNEL); + if (!dev->dma_alias_mask) { + dev_warn(>dev, "Unable to allocate DMA alias mask\n"); + return; + } + + set_bit(devfn, dev->dma_alias_mask); dev_info(>dev, "Enabling fixed DMA alias to %02x.%d\n", PCI_SLOT(devfn), PCI_FUNC(devfn)); } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6d7ab9b..23fc397 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1503,6 +1503,7 @@ static void pci_release_dev(struct device *dev) pcibios_release_device(pci_dev); pci_bus_put(pci_dev->bus); kfree(pci_dev->driver_override); + kfree(pci_dev->dma_alias_mask); kfree(pci_dev); } diff --git a/drivers/pci/search.c b/drivers/pci/search.c index a20ce7d..33e0f03 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -40,11 +40,15 @@ int pci_for_each_dma_alias(struct pci_dev *pdev, * If the device is broken and uses an alias requester ID for * DMA, iterate over that too. */ - if (unlikely(pdev->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN)) { - ret = fn(pdev, PCI_DEVID(pdev->bus->number, -pdev->dma_alias_devfn), data); - if (ret) - return ret; + if (unlikely(pdev->dma_alias_mask)) { + u8 devfn; + + for_each_set_bit(devfn, pdev->dma_alias_mask, U8_MAX) { + ret = fn(pdev, PCI_DEVID(pdev->bus->number, devfn), +data); + if (ret) + return ret; + } } for (bus = pdev->bus; !pci_is_root_bus(bus); bus = bus->parent) { diff --git a/include/linux/pci.h b/include/linux/pci.h index 27df4a6..d9e0c84 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -172,8 +172,6 @@ enum pci_dev_flags { PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) (1 << 2), /* Flag for quirk use to store if quirk-specific ACS is enabled */ PCI_DEV_FLAGS_ACS_ENABLED_QUIRK = (__force pci_dev_flags_t) (1 << 3), - /* Flag to indicate the device uses dma_alias_devfn */ - PCI_DEV_FLAGS_DMA_ALIAS_DEVFN = (__force pci_dev_flags_t) (1 << 4), /* Use a PCIe-to-PCI bridge alias even if !pci_is_pcie */ PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS = (__force pci_dev_flags_t) (1 << 5),
[PATCH V3] iommu/arm-smmu-v2: Workaround for ThunderX errata#27704
Due to Errata#27704 CN88xx SMMUv2,supports only shared ASID and VMID namespaces; specifically within a given node SMMU0 and SMMU1 share, as does SMMU2 and SMMU3. This patch tries to address these issuee by supplying asid and vmid base from devicetree. changes from V2: - removed *_base from DT, and replaced with compatible string changes from V1: - rebased on top of 16 bit VMID patch - removed redundent options from DT - insted of transform, DT now supplies starting ASID/VMID Signed-off-by: Tirumalesh ChalamarlaSigned-off-by: Akula Geethasowjanya --- .../devicetree/bindings/iommu/arm,smmu.txt | 1 + drivers/iommu/arm-smmu.c | 48 +- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index 7180745..19fe6f2 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -16,6 +16,7 @@ conditions. "arm,mmu-400" "arm,mmu-401" "arm,mmu-500" +"cavium,smmu-v2" depending on the particular implementation and/or the version of the architecture implemented. diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 247a469..f2287a5 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -326,6 +326,12 @@ struct arm_smmu_device { struct list_headlist; struct rb_root masters; + /* +*The follwoing fields are specific to Cavium, Thunder +*/ + u32 cavium_smmu_id; + u32 cavium_id_base; + }; struct arm_smmu_cfg { @@ -335,8 +341,8 @@ struct arm_smmu_cfg { }; #define INVALID_IRPTNDX0xff -#define ARM_SMMU_CB_ASID(cfg) ((cfg)->cbndx) -#define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1) +#define ARM_SMMU_CB_ASID(smmu, cfg) ((u16)(smmu)->cavium_id_base + (cfg)->cbndx) +#define ARM_SMMU_CB_VMID(smmu, cfg) ((u16)(smmu)->cavium_id_base + (cfg)->cbndx + 1) enum arm_smmu_domain_stage { ARM_SMMU_DOMAIN_S1 = 0, @@ -364,6 +370,8 @@ struct arm_smmu_option_prop { const char *prop; }; +static int cavium_smmu_count; + static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" }, { 0, NULL}, @@ -575,11 +583,11 @@ static void arm_smmu_tlb_inv_context(void *cookie) if (stage1) { base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); - writel_relaxed(ARM_SMMU_CB_ASID(cfg), + writel_relaxed(ARM_SMMU_CB_ASID(smmu, cfg), base + ARM_SMMU_CB_S1_TLBIASID); } else { base = ARM_SMMU_GR0(smmu); - writel_relaxed(ARM_SMMU_CB_VMID(cfg), + writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg), base + ARM_SMMU_GR0_TLBIVMID); } @@ -601,7 +609,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, if (!IS_ENABLED(CONFIG_64BIT) || smmu->version == ARM_SMMU_V1) { iova &= ~12UL; - iova |= ARM_SMMU_CB_ASID(cfg); + iova |= ARM_SMMU_CB_ASID(smmu, cfg); do { writel_relaxed(iova, reg); iova += granule; @@ -609,7 +617,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, #ifdef CONFIG_64BIT } else { iova >>= 12; - iova |= (u64)ARM_SMMU_CB_ASID(cfg) << 48; + iova |= (u64)ARM_SMMU_CB_ASID(smmu, cfg) << 48; do { writeq_relaxed(iova, reg); iova += granule >> 12; @@ -629,7 +637,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, #endif } else { reg = ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_TLBIVMID; - writel_relaxed(ARM_SMMU_CB_VMID(cfg), reg); + writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg), reg); } } @@ -738,7 +746,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, #endif /* if 16bit VMID supported set VMID in CBA2R */ if (smmu->features & ARM_SMMU_FEAT_VMID16) - reg |= ARM_SMMU_CB_VMID(cfg) << CBA2R_VMID_SHIFT; + reg |= ARM_SMMU_CB_VMID(smmu, cfg) << CBA2R_VMID_SHIFT; writel_relaxed(reg, gr1_base +
Re: [PATCH V2] iommu/arm-smmu-v2: Workaround for ThunderX errata#27704
On 02/24/2016 11:10 AM, Mark Rutland wrote: On Wed, Feb 24, 2016 at 03:54:48PM +, Chalamarla, Tirumalesh wrote: On 2/24/16, 3:32 AM, "Mark Rutland"wrote: On Tue, Feb 23, 2016 at 03:50:21PM -0800, Tirumalesh Chalamarla wrote: in Summary, if i change asid-base to cavium,asid-base and still use DT for supplying base value, is this a solution that will be accepted, No. The property is _insufficient_, regardless of its name. This has been pointed out more than once. A base alone does not tell you what set of IDs it is valid to use without risking a clash. The OS is well within its rights to allocate _any_ ID above that base. It is not a requirement of the hardware nor the binding that the OS allocate a contiguous set of IDs starting at the base. Consider: smmu_a { whatver,*id-base = <128>; }; smmu_b { whatever,*id-base = <64>; }; In both cases, the *IDs 129+ could be allocated on both SMMUs. Does adding a check to see if base + number of contexts supported will not overlap with each other Make it acceptable. Or do you want the size be provided from DT also? At this point I think Robin's suggestion of giving the ThunderX SMMU a different compatible string and treating that as a separate case entirely is the best thing to do. Then the only requirement is that _all_ the ThunderX SMMUs with shared TLBs are under the control of the OS, and it can allocate IDs as it chooses, so long as it ensures that there are no conflicts across all the SMMUs it is in control of. yes, resending based on the suggestions. Mark. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH V2] iommu/arm-smmu-v2: Workaround for ThunderX errata#27704
On Wed, Feb 24, 2016 at 03:54:48PM +, Chalamarla, Tirumalesh wrote: > > On 2/24/16, 3:32 AM, "Mark Rutland"wrote: > > >On Tue, Feb 23, 2016 at 03:50:21PM -0800, Tirumalesh Chalamarla wrote: > >> in Summary, > >> > >> if i change asid-base to cavium,asid-base and still use DT for > >> supplying base value, is this a solution that will be accepted, > > > >No. The property is _insufficient_, regardless of its name. This has > >been pointed out more than once. > > > >A base alone does not tell you what set of IDs it is valid to use > >without risking a clash. The OS is well within its rights to allocate > >_any_ ID above that base. It is not a requirement of the hardware nor > >the binding that the OS allocate a contiguous set of IDs starting at the > >base. > > > >Consider: > > > >smmu_a { > > whatver,*id-base = <128>; > >}; > > > >smmu_b { > > whatever,*id-base = <64>; > >}; > > > >In both cases, the *IDs 129+ could be allocated on both SMMUs. > > Does adding a check to see if base + number of contexts supported will not > overlap with each other > Make it acceptable. > Or do you want the size be provided from DT also? At this point I think Robin's suggestion of giving the ThunderX SMMU a different compatible string and treating that as a separate case entirely is the best thing to do. Then the only requirement is that _all_ the ThunderX SMMUs with shared TLBs are under the control of the OS, and it can allocate IDs as it chooses, so long as it ensures that there are no conflicts across all the SMMUs it is in control of. Mark. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH V2] iommu/arm-smmu-v2: Workaround for ThunderX errata#27704
On 02/24/2016 05:38 AM, Robin Murphy wrote: On 23/02/16 23:56, Tirumalesh Chalamarla wrote: On 02/23/2016 04:19 AM, Robin Murphy wrote: On 18/02/16 18:29, tchalama...@caviumnetworks.com wrote: From: Tirumalesh ChalamarlaDue to Errata#27704 CN88xx SMMUv2,supports only shared ASID and VMID namespaces; specifically within a given node SMMU0 and SMMU1 share, as does SMMU2 and SMMU3. This patch tries to address these issuee by supplying asid and vmid base from devicetree. changes from V1: - rebased on top of 16 bit VMID patch - removed redundent options from DT - insted of transform, DT now supplies starting ASID/VMID Signed-off-by: Akula Geethasowjanya Signed-off-by: Tirumalesh Chalamarla --- .../devicetree/bindings/iommu/arm,smmu.txt | 8 + drivers/iommu/arm-smmu.c | 37 +++--- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index bb7e569..80b8484 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -57,6 +57,14 @@ conditions. - smmu-enable-vmid16 : Enable 16 bit VMID, if allowed. +- asid-base :Buggy SMMUv2 implementations which doesn't satisfy the +ASID namespace needs, use this field to specify starting +ASID for the SMMU. + +- vmid-base :Buggy SMMUv2 implementations which doesn't satisfy the VMID +namespace needs, use this field to specify starting VMID +for the SMMU. + From how you've described the situation, this is still just some arbitrary number for the sake of a driver workaround and not an actual property of the hardware. Either way there should be a proper compatible string for this implementation, e.g. something like "cavium,cn88xx-smmu". Given that, you then shouldn't actually need anything else, because you can simply keep track of how many Cavium SMMUs have been probed and automatically generate a suitable offset, e.g. (smmu->index * ARM_SMMU_MAX_CBS) to ensure global ASID/VMID uniqueness. This particular solution might not be accurate in all cases. what happens if SMMU stage 1 is used by a guest? Even if we supported passing through stage 1 contexts, which we don't, a malicious guest can freely ignore your arbitrary numbers in the DT, put whatever nonsense it feels like in the TTBRs, and corrupt I/O in other guests and/or the host. You cannot safely pass through raw stage 1 contexts on this hardware, so it's a non-issue. Agreed. will re post based on the suggestions. Robin. Example: smmu { diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 003c442..dc46b9a 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -320,6 +320,9 @@ struct arm_smmu_device { unsigned longipa_size; unsigned longpa_size; +u32asid_base; +u32vmid_base; + u32num_global_irqs; u32num_context_irqs; unsigned int*irqs; @@ -335,8 +338,8 @@ struct arm_smmu_cfg { }; #define INVALID_IRPTNDX0xff -#define ARM_SMMU_CB_ASID(cfg)((cfg)->cbndx) -#define ARM_SMMU_CB_VMID(cfg)((cfg)->cbndx + 1) +#define ARM_SMMU_CB_ASID(smmu, cfg)((u16)((smmu)->asid_base + (cfg)->cbndx)) +#define ARM_SMMU_CB_VMID(smmu, cfg)((u16)((smmu)->vmid_base + (cfg)->cbndx)) enum arm_smmu_domain_stage { ARM_SMMU_DOMAIN_S1 = 0, @@ -576,11 +579,11 @@ static void arm_smmu_tlb_inv_context(void *cookie) if (stage1) { base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); -writel_relaxed(ARM_SMMU_CB_ASID(cfg), +writel_relaxed(ARM_SMMU_CB_ASID(smmu, cfg), base + ARM_SMMU_CB_S1_TLBIASID); } else { base = ARM_SMMU_GR0(smmu); -writel_relaxed(ARM_SMMU_CB_VMID(cfg), +writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg), base + ARM_SMMU_GR0_TLBIVMID); } @@ -602,7 +605,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, if (!IS_ENABLED(CONFIG_64BIT) || smmu->version == ARM_SMMU_V1) { iova &= ~12UL; -iova |= ARM_SMMU_CB_ASID(cfg); +iova |= ARM_SMMU_CB_ASID(smmu, cfg); do { writel_relaxed(iova, reg); iova += granule; @@ -610,7 +613,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, #ifdef CONFIG_64BIT } else { iova >>= 12; -iova |= (u64)ARM_SMMU_CB_ASID(cfg) << 48; +iova |= (u64)ARM_SMMU_CB_ASID(smmu, cfg) << 48; do { writeq_relaxed(iova, reg);
Re: [PATCH V2] iommu/arm-smmu-v2: Workaround for ThunderX errata#27704
On 2/24/16, 3:32 AM, "Mark Rutland"wrote: >On Tue, Feb 23, 2016 at 03:50:21PM -0800, Tirumalesh Chalamarla wrote: >> in Summary, >> >> if i change asid-base to cavium,asid-base and still use DT for >> supplying base value, is this a solution that will be accepted, > >No. The property is _insufficient_, regardless of its name. This has >been pointed out more than once. > >A base alone does not tell you what set of IDs it is valid to use >without risking a clash. The OS is well within its rights to allocate >_any_ ID above that base. It is not a requirement of the hardware nor >the binding that the OS allocate a contiguous set of IDs starting at the >base. > >Consider: > >smmu_a { > whatver,*id-base = <128>; >}; > >smmu_b { > whatever,*id-base = <64>; >}; > >In both cases, the *IDs 129+ could be allocated on both SMMUs. Does adding a check to see if base + number of contexts supported will not overlap with each other Make it acceptable. Or do you want the size be provided from DT also? Thanks, Tirumalesh. > >Mark. > >> of course i will do range check to see we are not supplying 16bit VMID >> for 8 bit systems even though the property now indicates Cavium only. >> >> Thanks, >> Tirumalesh. >> >> On 02/23/2016 04:26 AM, Mark Rutland wrote: >> >On Thu, Feb 18, 2016 at 10:29:18AM -0800, tchalama...@caviumnetworks.com >> >wrote: >> >>From: Tirumalesh Chalamarla >> >> >> >>Due to Errata#27704 CN88xx SMMUv2,supports only shared ASID and VMID >> >>namespaces; specifically within a given node SMMU0 and SMMU1 share, >> >>as does SMMU2 and SMMU3. >> >> >> >>This patch tries to address these issuee by supplying asid and vmid >> >>base from devicetree. >> >> >> >>changes from V1: >> >> - rebased on top of 16 bit VMID patch >> >> - removed redundent options from DT >> >> - insted of transform, DT now supplies starting ASID/VMID >> >> >> >>Signed-off-by: Akula Geethasowjanya >> >> >> >>Signed-off-by: Tirumalesh Chalamarla >> >>--- >> >> .../devicetree/bindings/iommu/arm,smmu.txt | 8 + >> >> drivers/iommu/arm-smmu.c | 37 >> >> +++--- >> >> 2 files changed, 34 insertions(+), 11 deletions(-) >> >> >> >>diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt >> >>b/Documentation/devicetree/bindings/iommu/arm,smmu.txt >> >>index bb7e569..80b8484 100644 >> >>--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt >> >>+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt >> >>@@ -57,6 +57,14 @@ conditions. >> >> >> >> - smmu-enable-vmid16 : Enable 16 bit VMID, if allowed. >> >> >> >>+- asid-base : Buggy SMMUv2 implementations which doesn't satisfy the >> >>+ ASID namespace needs, use this field to specify starting >> >>+ ASID for the SMMU. >> >>+ >> >>+- vmid-base : Buggy SMMUv2 implementations which doesn't satisfy the >> >>VMID >> >>+ namespace needs, use this field to specify starting VMID >> >>+ for the SMMU. >> > >> >As has been pointed out, these are not strictly properties of the >> >hardware, and are insufficient to aovid the issue in general (adding an >> >arbitrary base does not enforce IDs fall within a particular range). >> > >> >So NAK for *-base properties alone. >> > >> >>+ if (of_property_read_u32(dev->of_node, "#asid-base", >> >>+ >asid_base)) { >> >>+ smmu->asid_base = 0; >> >>+ } >> >>+ >> >>+ if (of_property_read_u32(dev->of_node, "#vmid-base", >> >>+ >vmid_base)) { >> >>+ smmu->vmid_base = 1; >> >>+ } >> > >> >These do not match the documentation above. >> > >> >Mark. >> > >> ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH V2] iommu/arm-smmu-v2: Workaround for ThunderX errata#27704
On 23/02/16 23:56, Tirumalesh Chalamarla wrote: On 02/23/2016 04:19 AM, Robin Murphy wrote: On 18/02/16 18:29, tchalama...@caviumnetworks.com wrote: From: Tirumalesh ChalamarlaDue to Errata#27704 CN88xx SMMUv2,supports only shared ASID and VMID namespaces; specifically within a given node SMMU0 and SMMU1 share, as does SMMU2 and SMMU3. This patch tries to address these issuee by supplying asid and vmid base from devicetree. changes from V1: - rebased on top of 16 bit VMID patch - removed redundent options from DT - insted of transform, DT now supplies starting ASID/VMID Signed-off-by: Akula Geethasowjanya Signed-off-by: Tirumalesh Chalamarla --- .../devicetree/bindings/iommu/arm,smmu.txt | 8 + drivers/iommu/arm-smmu.c | 37 +++--- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index bb7e569..80b8484 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -57,6 +57,14 @@ conditions. - smmu-enable-vmid16 : Enable 16 bit VMID, if allowed. +- asid-base :Buggy SMMUv2 implementations which doesn't satisfy the +ASID namespace needs, use this field to specify starting +ASID for the SMMU. + +- vmid-base :Buggy SMMUv2 implementations which doesn't satisfy the VMID +namespace needs, use this field to specify starting VMID +for the SMMU. + From how you've described the situation, this is still just some arbitrary number for the sake of a driver workaround and not an actual property of the hardware. Either way there should be a proper compatible string for this implementation, e.g. something like "cavium,cn88xx-smmu". Given that, you then shouldn't actually need anything else, because you can simply keep track of how many Cavium SMMUs have been probed and automatically generate a suitable offset, e.g. (smmu->index * ARM_SMMU_MAX_CBS) to ensure global ASID/VMID uniqueness. This particular solution might not be accurate in all cases. what happens if SMMU stage 1 is used by a guest? Even if we supported passing through stage 1 contexts, which we don't, a malicious guest can freely ignore your arbitrary numbers in the DT, put whatever nonsense it feels like in the TTBRs, and corrupt I/O in other guests and/or the host. You cannot safely pass through raw stage 1 contexts on this hardware, so it's a non-issue. Robin. Example: smmu { diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 003c442..dc46b9a 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -320,6 +320,9 @@ struct arm_smmu_device { unsigned longipa_size; unsigned longpa_size; +u32asid_base; +u32vmid_base; + u32num_global_irqs; u32num_context_irqs; unsigned int*irqs; @@ -335,8 +338,8 @@ struct arm_smmu_cfg { }; #define INVALID_IRPTNDX0xff -#define ARM_SMMU_CB_ASID(cfg)((cfg)->cbndx) -#define ARM_SMMU_CB_VMID(cfg)((cfg)->cbndx + 1) +#define ARM_SMMU_CB_ASID(smmu, cfg)((u16)((smmu)->asid_base + (cfg)->cbndx)) +#define ARM_SMMU_CB_VMID(smmu, cfg)((u16)((smmu)->vmid_base + (cfg)->cbndx)) enum arm_smmu_domain_stage { ARM_SMMU_DOMAIN_S1 = 0, @@ -576,11 +579,11 @@ static void arm_smmu_tlb_inv_context(void *cookie) if (stage1) { base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); -writel_relaxed(ARM_SMMU_CB_ASID(cfg), +writel_relaxed(ARM_SMMU_CB_ASID(smmu, cfg), base + ARM_SMMU_CB_S1_TLBIASID); } else { base = ARM_SMMU_GR0(smmu); -writel_relaxed(ARM_SMMU_CB_VMID(cfg), +writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg), base + ARM_SMMU_GR0_TLBIVMID); } @@ -602,7 +605,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, if (!IS_ENABLED(CONFIG_64BIT) || smmu->version == ARM_SMMU_V1) { iova &= ~12UL; -iova |= ARM_SMMU_CB_ASID(cfg); +iova |= ARM_SMMU_CB_ASID(smmu, cfg); do { writel_relaxed(iova, reg); iova += granule; @@ -610,7 +613,7 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, #ifdef CONFIG_64BIT } else { iova >>= 12; -iova |= (u64)ARM_SMMU_CB_ASID(cfg) << 48; +iova |= (u64)ARM_SMMU_CB_ASID(smmu, cfg) << 48; do { writeq_relaxed(iova, reg); iova += granule >> 12; @@ -630,7 +633,7 @@ static void
Re: [PATCH V2] iommu/arm-smmu-v2: Workaround for ThunderX errata#27704
On Tue, Feb 23, 2016 at 03:50:21PM -0800, Tirumalesh Chalamarla wrote: > in Summary, > > if i change asid-base to cavium,asid-base and still use DT for > supplying base value, is this a solution that will be accepted, No. The property is _insufficient_, regardless of its name. This has been pointed out more than once. A base alone does not tell you what set of IDs it is valid to use without risking a clash. The OS is well within its rights to allocate _any_ ID above that base. It is not a requirement of the hardware nor the binding that the OS allocate a contiguous set of IDs starting at the base. Consider: smmu_a { whatver,*id-base = <128>; }; smmu_b { whatever,*id-base = <64>; }; In both cases, the *IDs 129+ could be allocated on both SMMUs. Mark. > of course i will do range check to see we are not supplying 16bit VMID > for 8 bit systems even though the property now indicates Cavium only. > > Thanks, > Tirumalesh. > > On 02/23/2016 04:26 AM, Mark Rutland wrote: > >On Thu, Feb 18, 2016 at 10:29:18AM -0800, tchalama...@caviumnetworks.com > >wrote: > >>From: Tirumalesh Chalamarla> >> > >>Due to Errata#27704 CN88xx SMMUv2,supports only shared ASID and VMID > >>namespaces; specifically within a given node SMMU0 and SMMU1 share, > >>as does SMMU2 and SMMU3. > >> > >>This patch tries to address these issuee by supplying asid and vmid > >>base from devicetree. > >> > >>changes from V1: > >>- rebased on top of 16 bit VMID patch > >>- removed redundent options from DT > >>- insted of transform, DT now supplies starting ASID/VMID > >> > >>Signed-off-by: Akula Geethasowjanya > >> > >>Signed-off-by: Tirumalesh Chalamarla > >>--- > >> .../devicetree/bindings/iommu/arm,smmu.txt | 8 + > >> drivers/iommu/arm-smmu.c | 37 > >> +++--- > >> 2 files changed, 34 insertions(+), 11 deletions(-) > >> > >>diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt > >>b/Documentation/devicetree/bindings/iommu/arm,smmu.txt > >>index bb7e569..80b8484 100644 > >>--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt > >>+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt > >>@@ -57,6 +57,14 @@ conditions. > >> > >> - smmu-enable-vmid16 : Enable 16 bit VMID, if allowed. > >> > >>+- asid-base : Buggy SMMUv2 implementations which doesn't satisfy the > >>+ ASID namespace needs, use this field to specify starting > >>+ ASID for the SMMU. > >>+ > >>+- vmid-base : Buggy SMMUv2 implementations which doesn't satisfy the > >>VMID > >>+ namespace needs, use this field to specify starting VMID > >>+ for the SMMU. > > > >As has been pointed out, these are not strictly properties of the > >hardware, and are insufficient to aovid the issue in general (adding an > >arbitrary base does not enforce IDs fall within a particular range). > > > >So NAK for *-base properties alone. > > > >>+ if (of_property_read_u32(dev->of_node, "#asid-base", > >>+>asid_base)) { > >>+ smmu->asid_base = 0; > >>+ } > >>+ > >>+ if (of_property_read_u32(dev->of_node, "#vmid-base", > >>+>vmid_base)) { > >>+ smmu->vmid_base = 1; > >>+ } > > > >These do not match the documentation above. > > > >Mark. > > > ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu