diff options
-rw-r--r-- | Documentation/admin-guide/kernel-parameters.txt | 6 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/iommu/arm,smmu.txt | 28 | ||||
-rw-r--r-- | drivers/iommu/arm-smmu-v3.c | 76 | ||||
-rw-r--r-- | drivers/iommu/arm-smmu.c | 259 | ||||
-rw-r--r-- | drivers/iommu/io-pgtable-arm.c | 2 | ||||
-rw-r--r-- | drivers/iommu/iommu.c | 28 | ||||
-rw-r--r-- | include/linux/iommu.h | 11 |
7 files changed, 281 insertions, 129 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index facc20a3f962..cb91f26cc8bc 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt | |||
@@ -1644,6 +1644,12 @@ | |||
1644 | nobypass [PPC/POWERNV] | 1644 | nobypass [PPC/POWERNV] |
1645 | Disable IOMMU bypass, using IOMMU for PCI devices. | 1645 | Disable IOMMU bypass, using IOMMU for PCI devices. |
1646 | 1646 | ||
1647 | iommu.passthrough= | ||
1648 | [ARM64] Configure DMA to bypass the IOMMU by default. | ||
1649 | Format: { "0" | "1" } | ||
1650 | 0 - Use IOMMU translation for DMA. | ||
1651 | 1 - Bypass the IOMMU for DMA. | ||
1652 | unset - Use IOMMU translation for DMA. | ||
1647 | 1653 | ||
1648 | io7= [HW] IO7 for Marvel based alpha systems | 1654 | io7= [HW] IO7 for Marvel based alpha systems |
1649 | See comment before marvel_specify_io7 in | 1655 | See comment before marvel_specify_io7 in |
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index 6cdf32d037fc..8a6ffce12af5 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt | |||
@@ -60,6 +60,17 @@ conditions. | |||
60 | aliases of secure registers have to be used during | 60 | aliases of secure registers have to be used during |
61 | SMMU configuration. | 61 | SMMU configuration. |
62 | 62 | ||
63 | - stream-match-mask : For SMMUs supporting stream matching and using | ||
64 | #iommu-cells = <1>, specifies a mask of bits to ignore | ||
65 | when matching stream IDs (e.g. this may be programmed | ||
66 | into the SMRn.MASK field of every stream match register | ||
67 | used). For cases where it is desirable to ignore some | ||
68 | portion of every Stream ID (e.g. for certain MMU-500 | ||
69 | configurations given globally unique input IDs). This | ||
70 | property is not valid for SMMUs using stream indexing, | ||
71 | or using stream matching with #iommu-cells = <2>, and | ||
72 | may be ignored if present in such cases. | ||
73 | |||
63 | ** Deprecated properties: | 74 | ** Deprecated properties: |
64 | 75 | ||
65 | - mmu-masters (deprecated in favour of the generic "iommus" binding) : | 76 | - mmu-masters (deprecated in favour of the generic "iommus" binding) : |
@@ -109,3 +120,20 @@ conditions. | |||
109 | master3 { | 120 | master3 { |
110 | iommus = <&smmu2 1 0x30>; | 121 | iommus = <&smmu2 1 0x30>; |
111 | }; | 122 | }; |
123 | |||
124 | |||
125 | /* ARM MMU-500 with 10-bit stream ID input configuration */ | ||
126 | smmu3: iommu { | ||
127 | compatible = "arm,mmu-500", "arm,smmu-v2"; | ||
128 | ... | ||
129 | #iommu-cells = <1>; | ||
130 | /* always ignore appended 5-bit TBU number */ | ||
131 | stream-match-mask = 0x7c00; | ||
132 | }; | ||
133 | |||
134 | bus { | ||
135 | /* bus whose child devices emit one unique 10-bit stream | ||
136 | ID each, but may master through multiple SMMU TBUs */ | ||
137 | iommu-map = <0 &smmu3 0 0x400>; | ||
138 | ... | ||
139 | }; | ||
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 591bb96047c9..803352d78d43 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c | |||
@@ -554,9 +554,14 @@ struct arm_smmu_s2_cfg { | |||
554 | }; | 554 | }; |
555 | 555 | ||
556 | struct arm_smmu_strtab_ent { | 556 | struct arm_smmu_strtab_ent { |
557 | bool valid; | 557 | /* |
558 | 558 | * An STE is "assigned" if the master emitting the corresponding SID | |
559 | bool bypass; /* Overrides s1/s2 config */ | 559 | * is attached to a domain. The behaviour of an unassigned STE is |
560 | * determined by the disable_bypass parameter, whereas an assigned | ||
561 | * STE behaves according to s1_cfg/s2_cfg, which themselves are | ||
562 | * configured according to the domain type. | ||
563 | */ | ||
564 | bool assigned; | ||
560 | struct arm_smmu_s1_cfg *s1_cfg; | 565 | struct arm_smmu_s1_cfg *s1_cfg; |
561 | struct arm_smmu_s2_cfg *s2_cfg; | 566 | struct arm_smmu_s2_cfg *s2_cfg; |
562 | }; | 567 | }; |
@@ -632,6 +637,7 @@ enum arm_smmu_domain_stage { | |||
632 | ARM_SMMU_DOMAIN_S1 = 0, | 637 | ARM_SMMU_DOMAIN_S1 = 0, |
633 | ARM_SMMU_DOMAIN_S2, | 638 | ARM_SMMU_DOMAIN_S2, |
634 | ARM_SMMU_DOMAIN_NESTED, | 639 | ARM_SMMU_DOMAIN_NESTED, |
640 | ARM_SMMU_DOMAIN_BYPASS, | ||
635 | }; | 641 | }; |
636 | 642 | ||
637 | struct arm_smmu_domain { | 643 | struct arm_smmu_domain { |
@@ -1005,9 +1011,9 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid, | |||
1005 | * This is hideously complicated, but we only really care about | 1011 | * This is hideously complicated, but we only really care about |
1006 | * three cases at the moment: | 1012 | * three cases at the moment: |
1007 | * | 1013 | * |
1008 | * 1. Invalid (all zero) -> bypass (init) | 1014 | * 1. Invalid (all zero) -> bypass/fault (init) |
1009 | * 2. Bypass -> translation (attach) | 1015 | * 2. Bypass/fault -> translation/bypass (attach) |
1010 | * 3. Translation -> bypass (detach) | 1016 | * 3. Translation/bypass -> bypass/fault (detach) |
1011 | * | 1017 | * |
1012 | * Given that we can't update the STE atomically and the SMMU | 1018 | * Given that we can't update the STE atomically and the SMMU |
1013 | * doesn't read the thing in a defined order, that leaves us | 1019 | * doesn't read the thing in a defined order, that leaves us |
@@ -1046,11 +1052,15 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid, | |||
1046 | } | 1052 | } |
1047 | 1053 | ||
1048 | /* Nuke the existing STE_0 value, as we're going to rewrite it */ | 1054 | /* Nuke the existing STE_0 value, as we're going to rewrite it */ |
1049 | val = ste->valid ? STRTAB_STE_0_V : 0; | 1055 | val = STRTAB_STE_0_V; |
1056 | |||
1057 | /* Bypass/fault */ | ||
1058 | if (!ste->assigned || !(ste->s1_cfg || ste->s2_cfg)) { | ||
1059 | if (!ste->assigned && disable_bypass) | ||
1060 | val |= STRTAB_STE_0_CFG_ABORT; | ||
1061 | else | ||
1062 | val |= STRTAB_STE_0_CFG_BYPASS; | ||
1050 | 1063 | ||
1051 | if (ste->bypass) { | ||
1052 | val |= disable_bypass ? STRTAB_STE_0_CFG_ABORT | ||
1053 | : STRTAB_STE_0_CFG_BYPASS; | ||
1054 | dst[0] = cpu_to_le64(val); | 1064 | dst[0] = cpu_to_le64(val); |
1055 | dst[1] = cpu_to_le64(STRTAB_STE_1_SHCFG_INCOMING | 1065 | dst[1] = cpu_to_le64(STRTAB_STE_1_SHCFG_INCOMING |
1056 | << STRTAB_STE_1_SHCFG_SHIFT); | 1066 | << STRTAB_STE_1_SHCFG_SHIFT); |
@@ -1111,10 +1121,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_device *smmu, u32 sid, | |||
1111 | static void arm_smmu_init_bypass_stes(u64 *strtab, unsigned int nent) | 1121 | static void arm_smmu_init_bypass_stes(u64 *strtab, unsigned int nent) |
1112 | { | 1122 | { |
1113 | unsigned int i; | 1123 | unsigned int i; |
1114 | struct arm_smmu_strtab_ent ste = { | 1124 | struct arm_smmu_strtab_ent ste = { .assigned = false }; |
1115 | .valid = true, | ||
1116 | .bypass = true, | ||
1117 | }; | ||
1118 | 1125 | ||
1119 | for (i = 0; i < nent; ++i) { | 1126 | for (i = 0; i < nent; ++i) { |
1120 | arm_smmu_write_strtab_ent(NULL, -1, strtab, &ste); | 1127 | arm_smmu_write_strtab_ent(NULL, -1, strtab, &ste); |
@@ -1378,7 +1385,9 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) | |||
1378 | { | 1385 | { |
1379 | struct arm_smmu_domain *smmu_domain; | 1386 | struct arm_smmu_domain *smmu_domain; |
1380 | 1387 | ||
1381 | if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA) | 1388 | if (type != IOMMU_DOMAIN_UNMANAGED && |
1389 | type != IOMMU_DOMAIN_DMA && | ||
1390 | type != IOMMU_DOMAIN_IDENTITY) | ||
1382 | return NULL; | 1391 | return NULL; |
1383 | 1392 | ||
1384 | /* | 1393 | /* |
@@ -1509,6 +1518,11 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain) | |||
1509 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); | 1518 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1510 | struct arm_smmu_device *smmu = smmu_domain->smmu; | 1519 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
1511 | 1520 | ||
1521 | if (domain->type == IOMMU_DOMAIN_IDENTITY) { | ||
1522 | smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS; | ||
1523 | return 0; | ||
1524 | } | ||
1525 | |||
1512 | /* Restrict the stage to what we can actually support */ | 1526 | /* Restrict the stage to what we can actually support */ |
1513 | if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1)) | 1527 | if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1)) |
1514 | smmu_domain->stage = ARM_SMMU_DOMAIN_S2; | 1528 | smmu_domain->stage = ARM_SMMU_DOMAIN_S2; |
@@ -1579,7 +1593,7 @@ static __le64 *arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid) | |||
1579 | return step; | 1593 | return step; |
1580 | } | 1594 | } |
1581 | 1595 | ||
1582 | static int arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec) | 1596 | static void arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec) |
1583 | { | 1597 | { |
1584 | int i; | 1598 | int i; |
1585 | struct arm_smmu_master_data *master = fwspec->iommu_priv; | 1599 | struct arm_smmu_master_data *master = fwspec->iommu_priv; |
@@ -1591,17 +1605,14 @@ static int arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec) | |||
1591 | 1605 | ||
1592 | arm_smmu_write_strtab_ent(smmu, sid, step, &master->ste); | 1606 | arm_smmu_write_strtab_ent(smmu, sid, step, &master->ste); |
1593 | } | 1607 | } |
1594 | |||
1595 | return 0; | ||
1596 | } | 1608 | } |
1597 | 1609 | ||
1598 | static void arm_smmu_detach_dev(struct device *dev) | 1610 | static void arm_smmu_detach_dev(struct device *dev) |
1599 | { | 1611 | { |
1600 | struct arm_smmu_master_data *master = dev->iommu_fwspec->iommu_priv; | 1612 | struct arm_smmu_master_data *master = dev->iommu_fwspec->iommu_priv; |
1601 | 1613 | ||
1602 | master->ste.bypass = true; | 1614 | master->ste.assigned = false; |
1603 | if (arm_smmu_install_ste_for_dev(dev->iommu_fwspec) < 0) | 1615 | arm_smmu_install_ste_for_dev(dev->iommu_fwspec); |
1604 | dev_warn(dev, "failed to install bypass STE\n"); | ||
1605 | } | 1616 | } |
1606 | 1617 | ||
1607 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | 1618 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) |
@@ -1620,7 +1631,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1620 | ste = &master->ste; | 1631 | ste = &master->ste; |
1621 | 1632 | ||
1622 | /* Already attached to a different domain? */ | 1633 | /* Already attached to a different domain? */ |
1623 | if (!ste->bypass) | 1634 | if (ste->assigned) |
1624 | arm_smmu_detach_dev(dev); | 1635 | arm_smmu_detach_dev(dev); |
1625 | 1636 | ||
1626 | mutex_lock(&smmu_domain->init_mutex); | 1637 | mutex_lock(&smmu_domain->init_mutex); |
@@ -1641,10 +1652,12 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1641 | goto out_unlock; | 1652 | goto out_unlock; |
1642 | } | 1653 | } |
1643 | 1654 | ||
1644 | ste->bypass = false; | 1655 | ste->assigned = true; |
1645 | ste->valid = true; | ||
1646 | 1656 | ||
1647 | if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) { | 1657 | if (smmu_domain->stage == ARM_SMMU_DOMAIN_BYPASS) { |
1658 | ste->s1_cfg = NULL; | ||
1659 | ste->s2_cfg = NULL; | ||
1660 | } else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) { | ||
1648 | ste->s1_cfg = &smmu_domain->s1_cfg; | 1661 | ste->s1_cfg = &smmu_domain->s1_cfg; |
1649 | ste->s2_cfg = NULL; | 1662 | ste->s2_cfg = NULL; |
1650 | arm_smmu_write_ctx_desc(smmu, ste->s1_cfg); | 1663 | arm_smmu_write_ctx_desc(smmu, ste->s1_cfg); |
@@ -1653,10 +1666,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1653 | ste->s2_cfg = &smmu_domain->s2_cfg; | 1666 | ste->s2_cfg = &smmu_domain->s2_cfg; |
1654 | } | 1667 | } |
1655 | 1668 | ||
1656 | ret = arm_smmu_install_ste_for_dev(dev->iommu_fwspec); | 1669 | arm_smmu_install_ste_for_dev(dev->iommu_fwspec); |
1657 | if (ret < 0) | ||
1658 | ste->valid = false; | ||
1659 | |||
1660 | out_unlock: | 1670 | out_unlock: |
1661 | mutex_unlock(&smmu_domain->init_mutex); | 1671 | mutex_unlock(&smmu_domain->init_mutex); |
1662 | return ret; | 1672 | return ret; |
@@ -1807,7 +1817,7 @@ static void arm_smmu_remove_device(struct device *dev) | |||
1807 | 1817 | ||
1808 | master = fwspec->iommu_priv; | 1818 | master = fwspec->iommu_priv; |
1809 | smmu = master->smmu; | 1819 | smmu = master->smmu; |
1810 | if (master && master->ste.valid) | 1820 | if (master && master->ste.assigned) |
1811 | arm_smmu_detach_dev(dev); | 1821 | arm_smmu_detach_dev(dev); |
1812 | iommu_group_remove_device(dev); | 1822 | iommu_group_remove_device(dev); |
1813 | iommu_device_unlink(&smmu->iommu, dev); | 1823 | iommu_device_unlink(&smmu->iommu, dev); |
@@ -1837,6 +1847,9 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, | |||
1837 | { | 1847 | { |
1838 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); | 1848 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1839 | 1849 | ||
1850 | if (domain->type != IOMMU_DOMAIN_UNMANAGED) | ||
1851 | return -EINVAL; | ||
1852 | |||
1840 | switch (attr) { | 1853 | switch (attr) { |
1841 | case DOMAIN_ATTR_NESTING: | 1854 | case DOMAIN_ATTR_NESTING: |
1842 | *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); | 1855 | *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); |
@@ -1852,6 +1865,9 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, | |||
1852 | int ret = 0; | 1865 | int ret = 0; |
1853 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); | 1866 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1854 | 1867 | ||
1868 | if (domain->type != IOMMU_DOMAIN_UNMANAGED) | ||
1869 | return -EINVAL; | ||
1870 | |||
1855 | mutex_lock(&smmu_domain->init_mutex); | 1871 | mutex_lock(&smmu_domain->init_mutex); |
1856 | 1872 | ||
1857 | switch (attr) { | 1873 | switch (attr) { |
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index b493c99e17f7..dbd4998661c6 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -162,6 +162,7 @@ | |||
162 | #define ARM_SMMU_GR0_sTLBGSTATUS 0x74 | 162 | #define ARM_SMMU_GR0_sTLBGSTATUS 0x74 |
163 | #define sTLBGSTATUS_GSACTIVE (1 << 0) | 163 | #define sTLBGSTATUS_GSACTIVE (1 << 0) |
164 | #define TLB_LOOP_TIMEOUT 1000000 /* 1s! */ | 164 | #define TLB_LOOP_TIMEOUT 1000000 /* 1s! */ |
165 | #define TLB_SPIN_COUNT 10 | ||
165 | 166 | ||
166 | /* Stream mapping registers */ | 167 | /* Stream mapping registers */ |
167 | #define ARM_SMMU_GR0_SMR(n) (0x800 + ((n) << 2)) | 168 | #define ARM_SMMU_GR0_SMR(n) (0x800 + ((n) << 2)) |
@@ -216,8 +217,7 @@ enum arm_smmu_s2cr_privcfg { | |||
216 | #define CBA2R_VMID_MASK 0xffff | 217 | #define CBA2R_VMID_MASK 0xffff |
217 | 218 | ||
218 | /* Translation context bank */ | 219 | /* Translation context bank */ |
219 | #define ARM_SMMU_CB_BASE(smmu) ((smmu)->base + ((smmu)->size >> 1)) | 220 | #define ARM_SMMU_CB(smmu, n) ((smmu)->cb_base + ((n) << (smmu)->pgshift)) |
220 | #define ARM_SMMU_CB(smmu, n) ((n) * (1 << (smmu)->pgshift)) | ||
221 | 221 | ||
222 | #define ARM_SMMU_CB_SCTLR 0x0 | 222 | #define ARM_SMMU_CB_SCTLR 0x0 |
223 | #define ARM_SMMU_CB_ACTLR 0x4 | 223 | #define ARM_SMMU_CB_ACTLR 0x4 |
@@ -238,6 +238,8 @@ enum arm_smmu_s2cr_privcfg { | |||
238 | #define ARM_SMMU_CB_S1_TLBIVAL 0x620 | 238 | #define ARM_SMMU_CB_S1_TLBIVAL 0x620 |
239 | #define ARM_SMMU_CB_S2_TLBIIPAS2 0x630 | 239 | #define ARM_SMMU_CB_S2_TLBIIPAS2 0x630 |
240 | #define ARM_SMMU_CB_S2_TLBIIPAS2L 0x638 | 240 | #define ARM_SMMU_CB_S2_TLBIIPAS2L 0x638 |
241 | #define ARM_SMMU_CB_TLBSYNC 0x7f0 | ||
242 | #define ARM_SMMU_CB_TLBSTATUS 0x7f4 | ||
241 | #define ARM_SMMU_CB_ATS1PR 0x800 | 243 | #define ARM_SMMU_CB_ATS1PR 0x800 |
242 | #define ARM_SMMU_CB_ATSR 0x8f0 | 244 | #define ARM_SMMU_CB_ATSR 0x8f0 |
243 | 245 | ||
@@ -344,7 +346,7 @@ struct arm_smmu_device { | |||
344 | struct device *dev; | 346 | struct device *dev; |
345 | 347 | ||
346 | void __iomem *base; | 348 | void __iomem *base; |
347 | unsigned long size; | 349 | void __iomem *cb_base; |
348 | unsigned long pgshift; | 350 | unsigned long pgshift; |
349 | 351 | ||
350 | #define ARM_SMMU_FEAT_COHERENT_WALK (1 << 0) | 352 | #define ARM_SMMU_FEAT_COHERENT_WALK (1 << 0) |
@@ -404,18 +406,20 @@ enum arm_smmu_context_fmt { | |||
404 | struct arm_smmu_cfg { | 406 | struct arm_smmu_cfg { |
405 | u8 cbndx; | 407 | u8 cbndx; |
406 | u8 irptndx; | 408 | u8 irptndx; |
409 | union { | ||
410 | u16 asid; | ||
411 | u16 vmid; | ||
412 | }; | ||
407 | u32 cbar; | 413 | u32 cbar; |
408 | enum arm_smmu_context_fmt fmt; | 414 | enum arm_smmu_context_fmt fmt; |
409 | }; | 415 | }; |
410 | #define INVALID_IRPTNDX 0xff | 416 | #define INVALID_IRPTNDX 0xff |
411 | 417 | ||
412 | #define ARM_SMMU_CB_ASID(smmu, cfg) ((u16)(smmu)->cavium_id_base + (cfg)->cbndx) | ||
413 | #define ARM_SMMU_CB_VMID(smmu, cfg) ((u16)(smmu)->cavium_id_base + (cfg)->cbndx + 1) | ||
414 | |||
415 | enum arm_smmu_domain_stage { | 418 | enum arm_smmu_domain_stage { |
416 | ARM_SMMU_DOMAIN_S1 = 0, | 419 | ARM_SMMU_DOMAIN_S1 = 0, |
417 | ARM_SMMU_DOMAIN_S2, | 420 | ARM_SMMU_DOMAIN_S2, |
418 | ARM_SMMU_DOMAIN_NESTED, | 421 | ARM_SMMU_DOMAIN_NESTED, |
422 | ARM_SMMU_DOMAIN_BYPASS, | ||
419 | }; | 423 | }; |
420 | 424 | ||
421 | struct arm_smmu_domain { | 425 | struct arm_smmu_domain { |
@@ -569,49 +573,67 @@ static void __arm_smmu_free_bitmap(unsigned long *map, int idx) | |||
569 | } | 573 | } |
570 | 574 | ||
571 | /* Wait for any pending TLB invalidations to complete */ | 575 | /* Wait for any pending TLB invalidations to complete */ |
572 | static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu) | 576 | static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, |
577 | void __iomem *sync, void __iomem *status) | ||
573 | { | 578 | { |
574 | int count = 0; | 579 | unsigned int spin_cnt, delay; |
575 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | 580 | |
576 | 581 | writel_relaxed(0, sync); | |
577 | writel_relaxed(0, gr0_base + ARM_SMMU_GR0_sTLBGSYNC); | 582 | for (delay = 1; delay < TLB_LOOP_TIMEOUT; delay *= 2) { |
578 | while (readl_relaxed(gr0_base + ARM_SMMU_GR0_sTLBGSTATUS) | 583 | for (spin_cnt = TLB_SPIN_COUNT; spin_cnt > 0; spin_cnt--) { |
579 | & sTLBGSTATUS_GSACTIVE) { | 584 | if (!(readl_relaxed(status) & sTLBGSTATUS_GSACTIVE)) |
580 | cpu_relax(); | 585 | return; |
581 | if (++count == TLB_LOOP_TIMEOUT) { | 586 | cpu_relax(); |
582 | dev_err_ratelimited(smmu->dev, | ||
583 | "TLB sync timed out -- SMMU may be deadlocked\n"); | ||
584 | return; | ||
585 | } | 587 | } |
586 | udelay(1); | 588 | udelay(delay); |
587 | } | 589 | } |
590 | dev_err_ratelimited(smmu->dev, | ||
591 | "TLB sync timed out -- SMMU may be deadlocked\n"); | ||
592 | } | ||
593 | |||
594 | static void arm_smmu_tlb_sync_global(struct arm_smmu_device *smmu) | ||
595 | { | ||
596 | void __iomem *base = ARM_SMMU_GR0(smmu); | ||
597 | |||
598 | __arm_smmu_tlb_sync(smmu, base + ARM_SMMU_GR0_sTLBGSYNC, | ||
599 | base + ARM_SMMU_GR0_sTLBGSTATUS); | ||
600 | } | ||
601 | |||
602 | static void arm_smmu_tlb_sync_context(void *cookie) | ||
603 | { | ||
604 | struct arm_smmu_domain *smmu_domain = cookie; | ||
605 | struct arm_smmu_device *smmu = smmu_domain->smmu; | ||
606 | void __iomem *base = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx); | ||
607 | |||
608 | __arm_smmu_tlb_sync(smmu, base + ARM_SMMU_CB_TLBSYNC, | ||
609 | base + ARM_SMMU_CB_TLBSTATUS); | ||
588 | } | 610 | } |
589 | 611 | ||
590 | static void arm_smmu_tlb_sync(void *cookie) | 612 | static void arm_smmu_tlb_sync_vmid(void *cookie) |
591 | { | 613 | { |
592 | struct arm_smmu_domain *smmu_domain = cookie; | 614 | struct arm_smmu_domain *smmu_domain = cookie; |
593 | __arm_smmu_tlb_sync(smmu_domain->smmu); | 615 | |
616 | arm_smmu_tlb_sync_global(smmu_domain->smmu); | ||
594 | } | 617 | } |
595 | 618 | ||
596 | static void arm_smmu_tlb_inv_context(void *cookie) | 619 | static void arm_smmu_tlb_inv_context_s1(void *cookie) |
597 | { | 620 | { |
598 | struct arm_smmu_domain *smmu_domain = cookie; | 621 | struct arm_smmu_domain *smmu_domain = cookie; |
599 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; | 622 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
600 | struct arm_smmu_device *smmu = smmu_domain->smmu; | 623 | void __iomem *base = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx); |
601 | bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS; | ||
602 | void __iomem *base; | ||
603 | 624 | ||
604 | if (stage1) { | 625 | writel_relaxed(cfg->asid, base + ARM_SMMU_CB_S1_TLBIASID); |
605 | base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); | 626 | arm_smmu_tlb_sync_context(cookie); |
606 | writel_relaxed(ARM_SMMU_CB_ASID(smmu, cfg), | 627 | } |
607 | base + ARM_SMMU_CB_S1_TLBIASID); | ||
608 | } else { | ||
609 | base = ARM_SMMU_GR0(smmu); | ||
610 | writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg), | ||
611 | base + ARM_SMMU_GR0_TLBIVMID); | ||
612 | } | ||
613 | 628 | ||
614 | __arm_smmu_tlb_sync(smmu); | 629 | static void arm_smmu_tlb_inv_context_s2(void *cookie) |
630 | { | ||
631 | struct arm_smmu_domain *smmu_domain = cookie; | ||
632 | struct arm_smmu_device *smmu = smmu_domain->smmu; | ||
633 | void __iomem *base = ARM_SMMU_GR0(smmu); | ||
634 | |||
635 | writel_relaxed(smmu_domain->cfg.vmid, base + ARM_SMMU_GR0_TLBIVMID); | ||
636 | arm_smmu_tlb_sync_global(smmu); | ||
615 | } | 637 | } |
616 | 638 | ||
617 | static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, | 639 | static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, |
@@ -619,31 +641,28 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, | |||
619 | { | 641 | { |
620 | struct arm_smmu_domain *smmu_domain = cookie; | 642 | struct arm_smmu_domain *smmu_domain = cookie; |
621 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; | 643 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
622 | struct arm_smmu_device *smmu = smmu_domain->smmu; | ||
623 | bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS; | 644 | bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS; |
624 | void __iomem *reg; | 645 | void __iomem *reg = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx); |
625 | 646 | ||
626 | if (stage1) { | 647 | if (stage1) { |
627 | reg = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); | ||
628 | reg += leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA; | 648 | reg += leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA; |
629 | 649 | ||
630 | if (cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) { | 650 | if (cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) { |
631 | iova &= ~12UL; | 651 | iova &= ~12UL; |
632 | iova |= ARM_SMMU_CB_ASID(smmu, cfg); | 652 | iova |= cfg->asid; |
633 | do { | 653 | do { |
634 | writel_relaxed(iova, reg); | 654 | writel_relaxed(iova, reg); |
635 | iova += granule; | 655 | iova += granule; |
636 | } while (size -= granule); | 656 | } while (size -= granule); |
637 | } else { | 657 | } else { |
638 | iova >>= 12; | 658 | iova >>= 12; |
639 | iova |= (u64)ARM_SMMU_CB_ASID(smmu, cfg) << 48; | 659 | iova |= (u64)cfg->asid << 48; |
640 | do { | 660 | do { |
641 | writeq_relaxed(iova, reg); | 661 | writeq_relaxed(iova, reg); |
642 | iova += granule >> 12; | 662 | iova += granule >> 12; |
643 | } while (size -= granule); | 663 | } while (size -= granule); |
644 | } | 664 | } |
645 | } else if (smmu->version == ARM_SMMU_V2) { | 665 | } else { |
646 | reg = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); | ||
647 | reg += leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L : | 666 | reg += leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L : |
648 | ARM_SMMU_CB_S2_TLBIIPAS2; | 667 | ARM_SMMU_CB_S2_TLBIIPAS2; |
649 | iova >>= 12; | 668 | iova >>= 12; |
@@ -651,16 +670,40 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, | |||
651 | smmu_write_atomic_lq(iova, reg); | 670 | smmu_write_atomic_lq(iova, reg); |
652 | iova += granule >> 12; | 671 | iova += granule >> 12; |
653 | } while (size -= granule); | 672 | } while (size -= granule); |
654 | } else { | ||
655 | reg = ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_TLBIVMID; | ||
656 | writel_relaxed(ARM_SMMU_CB_VMID(smmu, cfg), reg); | ||
657 | } | 673 | } |
658 | } | 674 | } |
659 | 675 | ||
660 | static const struct iommu_gather_ops arm_smmu_gather_ops = { | 676 | /* |
661 | .tlb_flush_all = arm_smmu_tlb_inv_context, | 677 | * On MMU-401 at least, the cost of firing off multiple TLBIVMIDs appears |
678 | * almost negligible, but the benefit of getting the first one in as far ahead | ||
679 | * of the sync as possible is significant, hence we don't just make this a | ||
680 | * no-op and set .tlb_sync to arm_smmu_inv_context_s2() as you might think. | ||
681 | */ | ||
682 | static void arm_smmu_tlb_inv_vmid_nosync(unsigned long iova, size_t size, | ||
683 | size_t granule, bool leaf, void *cookie) | ||
684 | { | ||
685 | struct arm_smmu_domain *smmu_domain = cookie; | ||
686 | void __iomem *base = ARM_SMMU_GR0(smmu_domain->smmu); | ||
687 | |||
688 | writel_relaxed(smmu_domain->cfg.vmid, base + ARM_SMMU_GR0_TLBIVMID); | ||
689 | } | ||
690 | |||
691 | static const struct iommu_gather_ops arm_smmu_s1_tlb_ops = { | ||
692 | .tlb_flush_all = arm_smmu_tlb_inv_context_s1, | ||
662 | .tlb_add_flush = arm_smmu_tlb_inv_range_nosync, | 693 | .tlb_add_flush = arm_smmu_tlb_inv_range_nosync, |
663 | .tlb_sync = arm_smmu_tlb_sync, | 694 | .tlb_sync = arm_smmu_tlb_sync_context, |
695 | }; | ||
696 | |||
697 | static const struct iommu_gather_ops arm_smmu_s2_tlb_ops_v2 = { | ||
698 | .tlb_flush_all = arm_smmu_tlb_inv_context_s2, | ||
699 | .tlb_add_flush = arm_smmu_tlb_inv_range_nosync, | ||
700 | .tlb_sync = arm_smmu_tlb_sync_context, | ||
701 | }; | ||
702 | |||
703 | static const struct iommu_gather_ops arm_smmu_s2_tlb_ops_v1 = { | ||
704 | .tlb_flush_all = arm_smmu_tlb_inv_context_s2, | ||
705 | .tlb_add_flush = arm_smmu_tlb_inv_vmid_nosync, | ||
706 | .tlb_sync = arm_smmu_tlb_sync_vmid, | ||
664 | }; | 707 | }; |
665 | 708 | ||
666 | static irqreturn_t arm_smmu_context_fault(int irq, void *dev) | 709 | static irqreturn_t arm_smmu_context_fault(int irq, void *dev) |
@@ -673,7 +716,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev) | |||
673 | struct arm_smmu_device *smmu = smmu_domain->smmu; | 716 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
674 | void __iomem *cb_base; | 717 | void __iomem *cb_base; |
675 | 718 | ||
676 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); | 719 | cb_base = ARM_SMMU_CB(smmu, cfg->cbndx); |
677 | fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR); | 720 | fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR); |
678 | 721 | ||
679 | if (!(fsr & FSR_FAULT)) | 722 | if (!(fsr & FSR_FAULT)) |
@@ -726,7 +769,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, | |||
726 | 769 | ||
727 | gr1_base = ARM_SMMU_GR1(smmu); | 770 | gr1_base = ARM_SMMU_GR1(smmu); |
728 | stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS; | 771 | stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS; |
729 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); | 772 | cb_base = ARM_SMMU_CB(smmu, cfg->cbndx); |
730 | 773 | ||
731 | if (smmu->version > ARM_SMMU_V1) { | 774 | if (smmu->version > ARM_SMMU_V1) { |
732 | if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64) | 775 | if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64) |
@@ -735,7 +778,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, | |||
735 | reg = CBA2R_RW64_32BIT; | 778 | reg = CBA2R_RW64_32BIT; |
736 | /* 16-bit VMIDs live in CBA2R */ | 779 | /* 16-bit VMIDs live in CBA2R */ |
737 | if (smmu->features & ARM_SMMU_FEAT_VMID16) | 780 | if (smmu->features & ARM_SMMU_FEAT_VMID16) |
738 | reg |= ARM_SMMU_CB_VMID(smmu, cfg) << CBA2R_VMID_SHIFT; | 781 | reg |= cfg->vmid << CBA2R_VMID_SHIFT; |
739 | 782 | ||
740 | writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx)); | 783 | writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx)); |
741 | } | 784 | } |
@@ -754,34 +797,15 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, | |||
754 | (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT); | 797 | (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT); |
755 | } else if (!(smmu->features & ARM_SMMU_FEAT_VMID16)) { | 798 | } else if (!(smmu->features & ARM_SMMU_FEAT_VMID16)) { |
756 | /* 8-bit VMIDs live in CBAR */ | 799 | /* 8-bit VMIDs live in CBAR */ |
757 | reg |= ARM_SMMU_CB_VMID(smmu, cfg) << CBAR_VMID_SHIFT; | 800 | reg |= cfg->vmid << CBAR_VMID_SHIFT; |
758 | } | 801 | } |
759 | writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx)); | 802 | writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx)); |
760 | 803 | ||
761 | /* TTBRs */ | 804 | /* |
762 | if (stage1) { | 805 | * TTBCR |
763 | u16 asid = ARM_SMMU_CB_ASID(smmu, cfg); | 806 | * We must write this before the TTBRs, since it determines the |
764 | 807 | * access behaviour of some fields (in particular, ASID[15:8]). | |
765 | if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) { | 808 | */ |
766 | reg = pgtbl_cfg->arm_v7s_cfg.ttbr[0]; | ||
767 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0); | ||
768 | reg = pgtbl_cfg->arm_v7s_cfg.ttbr[1]; | ||
769 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1); | ||
770 | writel_relaxed(asid, cb_base + ARM_SMMU_CB_CONTEXTIDR); | ||
771 | } else { | ||
772 | reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0]; | ||
773 | reg64 |= (u64)asid << TTBRn_ASID_SHIFT; | ||
774 | writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR0); | ||
775 | reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1]; | ||
776 | reg64 |= (u64)asid << TTBRn_ASID_SHIFT; | ||
777 | writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR1); | ||
778 | } | ||
779 | } else { | ||
780 | reg64 = pgtbl_cfg->arm_lpae_s2_cfg.vttbr; | ||
781 | writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR0); | ||
782 | } | ||
783 | |||
784 | /* TTBCR */ | ||
785 | if (stage1) { | 809 | if (stage1) { |
786 | if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) { | 810 | if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) { |
787 | reg = pgtbl_cfg->arm_v7s_cfg.tcr; | 811 | reg = pgtbl_cfg->arm_v7s_cfg.tcr; |
@@ -800,6 +824,27 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, | |||
800 | } | 824 | } |
801 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR); | 825 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBCR); |
802 | 826 | ||
827 | /* TTBRs */ | ||
828 | if (stage1) { | ||
829 | if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) { | ||
830 | reg = pgtbl_cfg->arm_v7s_cfg.ttbr[0]; | ||
831 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0); | ||
832 | reg = pgtbl_cfg->arm_v7s_cfg.ttbr[1]; | ||
833 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1); | ||
834 | writel_relaxed(cfg->asid, cb_base + ARM_SMMU_CB_CONTEXTIDR); | ||
835 | } else { | ||
836 | reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0]; | ||
837 | reg64 |= (u64)cfg->asid << TTBRn_ASID_SHIFT; | ||
838 | writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR0); | ||
839 | reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1]; | ||
840 | reg64 |= (u64)cfg->asid << TTBRn_ASID_SHIFT; | ||
841 | writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR1); | ||
842 | } | ||
843 | } else { | ||
844 | reg64 = pgtbl_cfg->arm_lpae_s2_cfg.vttbr; | ||
845 | writeq_relaxed(reg64, cb_base + ARM_SMMU_CB_TTBR0); | ||
846 | } | ||
847 | |||
803 | /* MAIRs (stage-1 only) */ | 848 | /* MAIRs (stage-1 only) */ |
804 | if (stage1) { | 849 | if (stage1) { |
805 | if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) { | 850 | if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) { |
@@ -833,11 +878,18 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
833 | enum io_pgtable_fmt fmt; | 878 | enum io_pgtable_fmt fmt; |
834 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); | 879 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
835 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; | 880 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
881 | const struct iommu_gather_ops *tlb_ops; | ||
836 | 882 | ||
837 | mutex_lock(&smmu_domain->init_mutex); | 883 | mutex_lock(&smmu_domain->init_mutex); |
838 | if (smmu_domain->smmu) | 884 | if (smmu_domain->smmu) |
839 | goto out_unlock; | 885 | goto out_unlock; |
840 | 886 | ||
887 | if (domain->type == IOMMU_DOMAIN_IDENTITY) { | ||
888 | smmu_domain->stage = ARM_SMMU_DOMAIN_BYPASS; | ||
889 | smmu_domain->smmu = smmu; | ||
890 | goto out_unlock; | ||
891 | } | ||
892 | |||
841 | /* | 893 | /* |
842 | * Mapping the requested stage onto what we support is surprisingly | 894 | * Mapping the requested stage onto what we support is surprisingly |
843 | * complicated, mainly because the spec allows S1+S2 SMMUs without | 895 | * complicated, mainly because the spec allows S1+S2 SMMUs without |
@@ -904,6 +956,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
904 | ias = min(ias, 32UL); | 956 | ias = min(ias, 32UL); |
905 | oas = min(oas, 32UL); | 957 | oas = min(oas, 32UL); |
906 | } | 958 | } |
959 | tlb_ops = &arm_smmu_s1_tlb_ops; | ||
907 | break; | 960 | break; |
908 | case ARM_SMMU_DOMAIN_NESTED: | 961 | case ARM_SMMU_DOMAIN_NESTED: |
909 | /* | 962 | /* |
@@ -922,12 +975,15 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
922 | ias = min(ias, 40UL); | 975 | ias = min(ias, 40UL); |
923 | oas = min(oas, 40UL); | 976 | oas = min(oas, 40UL); |
924 | } | 977 | } |
978 | if (smmu->version == ARM_SMMU_V2) | ||
979 | tlb_ops = &arm_smmu_s2_tlb_ops_v2; | ||
980 | else | ||
981 | tlb_ops = &arm_smmu_s2_tlb_ops_v1; | ||
925 | break; | 982 | break; |
926 | default: | 983 | default: |
927 | ret = -EINVAL; | 984 | ret = -EINVAL; |
928 | goto out_unlock; | 985 | goto out_unlock; |
929 | } | 986 | } |
930 | |||
931 | ret = __arm_smmu_alloc_bitmap(smmu->context_map, start, | 987 | ret = __arm_smmu_alloc_bitmap(smmu->context_map, start, |
932 | smmu->num_context_banks); | 988 | smmu->num_context_banks); |
933 | if (ret < 0) | 989 | if (ret < 0) |
@@ -941,11 +997,16 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
941 | cfg->irptndx = cfg->cbndx; | 997 | cfg->irptndx = cfg->cbndx; |
942 | } | 998 | } |
943 | 999 | ||
1000 | if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2) | ||
1001 | cfg->vmid = cfg->cbndx + 1 + smmu->cavium_id_base; | ||
1002 | else | ||
1003 | cfg->asid = cfg->cbndx + smmu->cavium_id_base; | ||
1004 | |||
944 | pgtbl_cfg = (struct io_pgtable_cfg) { | 1005 | pgtbl_cfg = (struct io_pgtable_cfg) { |
945 | .pgsize_bitmap = smmu->pgsize_bitmap, | 1006 | .pgsize_bitmap = smmu->pgsize_bitmap, |
946 | .ias = ias, | 1007 | .ias = ias, |
947 | .oas = oas, | 1008 | .oas = oas, |
948 | .tlb = &arm_smmu_gather_ops, | 1009 | .tlb = tlb_ops, |
949 | .iommu_dev = smmu->dev, | 1010 | .iommu_dev = smmu->dev, |
950 | }; | 1011 | }; |
951 | 1012 | ||
@@ -998,14 +1059,14 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) | |||
998 | void __iomem *cb_base; | 1059 | void __iomem *cb_base; |
999 | int irq; | 1060 | int irq; |
1000 | 1061 | ||
1001 | if (!smmu) | 1062 | if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) |
1002 | return; | 1063 | return; |
1003 | 1064 | ||
1004 | /* | 1065 | /* |
1005 | * Disable the context bank and free the page tables before freeing | 1066 | * Disable the context bank and free the page tables before freeing |
1006 | * it. | 1067 | * it. |
1007 | */ | 1068 | */ |
1008 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); | 1069 | cb_base = ARM_SMMU_CB(smmu, cfg->cbndx); |
1009 | writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR); | 1070 | writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR); |
1010 | 1071 | ||
1011 | if (cfg->irptndx != INVALID_IRPTNDX) { | 1072 | if (cfg->irptndx != INVALID_IRPTNDX) { |
@@ -1021,7 +1082,9 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) | |||
1021 | { | 1082 | { |
1022 | struct arm_smmu_domain *smmu_domain; | 1083 | struct arm_smmu_domain *smmu_domain; |
1023 | 1084 | ||
1024 | if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA) | 1085 | if (type != IOMMU_DOMAIN_UNMANAGED && |
1086 | type != IOMMU_DOMAIN_DMA && | ||
1087 | type != IOMMU_DOMAIN_IDENTITY) | ||
1025 | return NULL; | 1088 | return NULL; |
1026 | /* | 1089 | /* |
1027 | * Allocate the domain and initialise some of its data structures. | 1090 | * Allocate the domain and initialise some of its data structures. |
@@ -1250,10 +1313,15 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, | |||
1250 | { | 1313 | { |
1251 | struct arm_smmu_device *smmu = smmu_domain->smmu; | 1314 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
1252 | struct arm_smmu_s2cr *s2cr = smmu->s2crs; | 1315 | struct arm_smmu_s2cr *s2cr = smmu->s2crs; |
1253 | enum arm_smmu_s2cr_type type = S2CR_TYPE_TRANS; | ||
1254 | u8 cbndx = smmu_domain->cfg.cbndx; | 1316 | u8 cbndx = smmu_domain->cfg.cbndx; |
1317 | enum arm_smmu_s2cr_type type; | ||
1255 | int i, idx; | 1318 | int i, idx; |
1256 | 1319 | ||
1320 | if (smmu_domain->stage == ARM_SMMU_DOMAIN_BYPASS) | ||
1321 | type = S2CR_TYPE_BYPASS; | ||
1322 | else | ||
1323 | type = S2CR_TYPE_TRANS; | ||
1324 | |||
1257 | for_each_cfg_sme(fwspec, i, idx) { | 1325 | for_each_cfg_sme(fwspec, i, idx) { |
1258 | if (type == s2cr[idx].type && cbndx == s2cr[idx].cbndx) | 1326 | if (type == s2cr[idx].type && cbndx == s2cr[idx].cbndx) |
1259 | continue; | 1327 | continue; |
@@ -1356,7 +1424,7 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain, | |||
1356 | u64 phys; | 1424 | u64 phys; |
1357 | unsigned long va; | 1425 | unsigned long va; |
1358 | 1426 | ||
1359 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); | 1427 | cb_base = ARM_SMMU_CB(smmu, cfg->cbndx); |
1360 | 1428 | ||
1361 | /* ATS1 registers can only be written atomically */ | 1429 | /* ATS1 registers can only be written atomically */ |
1362 | va = iova & ~0xfffUL; | 1430 | va = iova & ~0xfffUL; |
@@ -1549,6 +1617,9 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, | |||
1549 | { | 1617 | { |
1550 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); | 1618 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1551 | 1619 | ||
1620 | if (domain->type != IOMMU_DOMAIN_UNMANAGED) | ||
1621 | return -EINVAL; | ||
1622 | |||
1552 | switch (attr) { | 1623 | switch (attr) { |
1553 | case DOMAIN_ATTR_NESTING: | 1624 | case DOMAIN_ATTR_NESTING: |
1554 | *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); | 1625 | *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); |
@@ -1564,6 +1635,9 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, | |||
1564 | int ret = 0; | 1635 | int ret = 0; |
1565 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); | 1636 | struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); |
1566 | 1637 | ||
1638 | if (domain->type != IOMMU_DOMAIN_UNMANAGED) | ||
1639 | return -EINVAL; | ||
1640 | |||
1567 | mutex_lock(&smmu_domain->init_mutex); | 1641 | mutex_lock(&smmu_domain->init_mutex); |
1568 | 1642 | ||
1569 | switch (attr) { | 1643 | switch (attr) { |
@@ -1590,13 +1664,15 @@ out_unlock: | |||
1590 | 1664 | ||
1591 | static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args) | 1665 | static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args) |
1592 | { | 1666 | { |
1593 | u32 fwid = 0; | 1667 | u32 mask, fwid = 0; |
1594 | 1668 | ||
1595 | if (args->args_count > 0) | 1669 | if (args->args_count > 0) |
1596 | fwid |= (u16)args->args[0]; | 1670 | fwid |= (u16)args->args[0]; |
1597 | 1671 | ||
1598 | if (args->args_count > 1) | 1672 | if (args->args_count > 1) |
1599 | fwid |= (u16)args->args[1] << SMR_MASK_SHIFT; | 1673 | fwid |= (u16)args->args[1] << SMR_MASK_SHIFT; |
1674 | else if (!of_property_read_u32(args->np, "stream-match-mask", &mask)) | ||
1675 | fwid |= (u16)mask << SMR_MASK_SHIFT; | ||
1600 | 1676 | ||
1601 | return iommu_fwspec_add_ids(dev, &fwid, 1); | 1677 | return iommu_fwspec_add_ids(dev, &fwid, 1); |
1602 | } | 1678 | } |
@@ -1683,7 +1759,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu) | |||
1683 | 1759 | ||
1684 | /* Make sure all context banks are disabled and clear CB_FSR */ | 1760 | /* Make sure all context banks are disabled and clear CB_FSR */ |
1685 | for (i = 0; i < smmu->num_context_banks; ++i) { | 1761 | for (i = 0; i < smmu->num_context_banks; ++i) { |
1686 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, i); | 1762 | cb_base = ARM_SMMU_CB(smmu, i); |
1687 | writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR); | 1763 | writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR); |
1688 | writel_relaxed(FSR_FAULT, cb_base + ARM_SMMU_CB_FSR); | 1764 | writel_relaxed(FSR_FAULT, cb_base + ARM_SMMU_CB_FSR); |
1689 | /* | 1765 | /* |
@@ -1729,7 +1805,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu) | |||
1729 | reg |= sCR0_EXIDENABLE; | 1805 | reg |= sCR0_EXIDENABLE; |
1730 | 1806 | ||
1731 | /* Push the button */ | 1807 | /* Push the button */ |
1732 | __arm_smmu_tlb_sync(smmu); | 1808 | arm_smmu_tlb_sync_global(smmu); |
1733 | writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); | 1809 | writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); |
1734 | } | 1810 | } |
1735 | 1811 | ||
@@ -1863,11 +1939,11 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) | |||
1863 | 1939 | ||
1864 | /* Check for size mismatch of SMMU address space from mapped region */ | 1940 | /* Check for size mismatch of SMMU address space from mapped region */ |
1865 | size = 1 << (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1); | 1941 | size = 1 << (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1); |
1866 | size *= 2 << smmu->pgshift; | 1942 | size <<= smmu->pgshift; |
1867 | if (smmu->size != size) | 1943 | if (smmu->cb_base != gr0_base + size) |
1868 | dev_warn(smmu->dev, | 1944 | dev_warn(smmu->dev, |
1869 | "SMMU address space size (0x%lx) differs from mapped region size (0x%lx)!\n", | 1945 | "SMMU address space size (0x%lx) differs from mapped region size (0x%tx)!\n", |
1870 | size, smmu->size); | 1946 | size * 2, (smmu->cb_base - gr0_base) * 2); |
1871 | 1947 | ||
1872 | smmu->num_s2_context_banks = (id >> ID1_NUMS2CB_SHIFT) & ID1_NUMS2CB_MASK; | 1948 | smmu->num_s2_context_banks = (id >> ID1_NUMS2CB_SHIFT) & ID1_NUMS2CB_MASK; |
1873 | smmu->num_context_banks = (id >> ID1_NUMCB_SHIFT) & ID1_NUMCB_MASK; | 1949 | smmu->num_context_banks = (id >> ID1_NUMCB_SHIFT) & ID1_NUMCB_MASK; |
@@ -1887,6 +1963,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) | |||
1887 | atomic_add_return(smmu->num_context_banks, | 1963 | atomic_add_return(smmu->num_context_banks, |
1888 | &cavium_smmu_context_count); | 1964 | &cavium_smmu_context_count); |
1889 | smmu->cavium_id_base -= smmu->num_context_banks; | 1965 | smmu->cavium_id_base -= smmu->num_context_banks; |
1966 | dev_notice(smmu->dev, "\tenabling workaround for Cavium erratum 27704\n"); | ||
1890 | } | 1967 | } |
1891 | 1968 | ||
1892 | /* ID2 */ | 1969 | /* ID2 */ |
@@ -2103,7 +2180,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev) | |||
2103 | smmu->base = devm_ioremap_resource(dev, res); | 2180 | smmu->base = devm_ioremap_resource(dev, res); |
2104 | if (IS_ERR(smmu->base)) | 2181 | if (IS_ERR(smmu->base)) |
2105 | return PTR_ERR(smmu->base); | 2182 | return PTR_ERR(smmu->base); |
2106 | smmu->size = resource_size(res); | 2183 | smmu->cb_base = smmu->base + resource_size(res) / 2; |
2107 | 2184 | ||
2108 | num_irqs = 0; | 2185 | num_irqs = 0; |
2109 | while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, num_irqs))) { | 2186 | while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, num_irqs))) { |
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index f9bc6ebb8140..6e5df5e0a3bd 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c | |||
@@ -74,7 +74,7 @@ | |||
74 | 74 | ||
75 | /* Calculate the block/page mapping size at level l for pagetable in d. */ | 75 | /* Calculate the block/page mapping size at level l for pagetable in d. */ |
76 | #define ARM_LPAE_BLOCK_SIZE(l,d) \ | 76 | #define ARM_LPAE_BLOCK_SIZE(l,d) \ |
77 | (1 << (ilog2(sizeof(arm_lpae_iopte)) + \ | 77 | (1ULL << (ilog2(sizeof(arm_lpae_iopte)) + \ |
78 | ((ARM_LPAE_MAX_LEVELS - (l)) * (d)->bits_per_level))) | 78 | ((ARM_LPAE_MAX_LEVELS - (l)) * (d)->bits_per_level))) |
79 | 79 | ||
80 | /* Page table bits */ | 80 | /* Page table bits */ |
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 3b67144dead2..770ba7e7ef4d 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c | |||
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | static struct kset *iommu_group_kset; | 37 | static struct kset *iommu_group_kset; |
38 | static DEFINE_IDA(iommu_group_ida); | 38 | static DEFINE_IDA(iommu_group_ida); |
39 | static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA; | ||
39 | 40 | ||
40 | struct iommu_callback_data { | 41 | struct iommu_callback_data { |
41 | const struct iommu_ops *ops; | 42 | const struct iommu_ops *ops; |
@@ -112,6 +113,18 @@ static int __iommu_attach_group(struct iommu_domain *domain, | |||
112 | static void __iommu_detach_group(struct iommu_domain *domain, | 113 | static void __iommu_detach_group(struct iommu_domain *domain, |
113 | struct iommu_group *group); | 114 | struct iommu_group *group); |
114 | 115 | ||
116 | static int __init iommu_set_def_domain_type(char *str) | ||
117 | { | ||
118 | bool pt; | ||
119 | |||
120 | if (!str || strtobool(str, &pt)) | ||
121 | return -EINVAL; | ||
122 | |||
123 | iommu_def_domain_type = pt ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA; | ||
124 | return 0; | ||
125 | } | ||
126 | early_param("iommu.passthrough", iommu_set_def_domain_type); | ||
127 | |||
115 | static ssize_t iommu_group_attr_show(struct kobject *kobj, | 128 | static ssize_t iommu_group_attr_show(struct kobject *kobj, |
116 | struct attribute *__attr, char *buf) | 129 | struct attribute *__attr, char *buf) |
117 | { | 130 | { |
@@ -1015,10 +1028,19 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev) | |||
1015 | * IOMMU driver. | 1028 | * IOMMU driver. |
1016 | */ | 1029 | */ |
1017 | if (!group->default_domain) { | 1030 | if (!group->default_domain) { |
1018 | group->default_domain = __iommu_domain_alloc(dev->bus, | 1031 | struct iommu_domain *dom; |
1019 | IOMMU_DOMAIN_DMA); | 1032 | |
1033 | dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type); | ||
1034 | if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) { | ||
1035 | dev_warn(dev, | ||
1036 | "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA", | ||
1037 | iommu_def_domain_type); | ||
1038 | dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA); | ||
1039 | } | ||
1040 | |||
1041 | group->default_domain = dom; | ||
1020 | if (!group->domain) | 1042 | if (!group->domain) |
1021 | group->domain = group->default_domain; | 1043 | group->domain = dom; |
1022 | } | 1044 | } |
1023 | 1045 | ||
1024 | ret = iommu_group_add_device(group, dev); | 1046 | ret = iommu_group_add_device(group, dev); |
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 2e4de0deee53..88ec8c6580d3 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h | |||
@@ -32,10 +32,13 @@ | |||
32 | #define IOMMU_NOEXEC (1 << 3) | 32 | #define IOMMU_NOEXEC (1 << 3) |
33 | #define IOMMU_MMIO (1 << 4) /* e.g. things like MSI doorbells */ | 33 | #define IOMMU_MMIO (1 << 4) /* e.g. things like MSI doorbells */ |
34 | /* | 34 | /* |
35 | * This is to make the IOMMU API setup privileged | 35 | * Where the bus hardware includes a privilege level as part of its access type |
36 | * mapppings accessible by the master only at higher | 36 | * markings, and certain devices are capable of issuing transactions marked as |
37 | * privileged execution level and inaccessible at | 37 | * either 'supervisor' or 'user', the IOMMU_PRIV flag requests that the other |
38 | * less privileged levels. | 38 | * given permission flags only apply to accesses at the higher privilege level, |
39 | * and that unprivileged transactions should have as little access as possible. | ||
40 | * This would usually imply the same permissions as kernel mappings on the CPU, | ||
41 | * if the IOMMU page table format is equivalent. | ||
39 | */ | 42 | */ |
40 | #define IOMMU_PRIV (1 << 5) | 43 | #define IOMMU_PRIV (1 << 5) |
41 | 44 | ||