aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/iommu/amd_iommu.c2
-rw-r--r--drivers/iommu/arm-smmu.c133
-rw-r--r--include/linux/iommu.h3
3 files changed, 113 insertions, 25 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 505a9adac2d5..3d78a8fb5a6a 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -3411,6 +3411,8 @@ static bool amd_iommu_capable(enum iommu_cap cap)
3411 return true; 3411 return true;
3412 case IOMMU_CAP_INTR_REMAP: 3412 case IOMMU_CAP_INTR_REMAP:
3413 return (irq_remapping_enabled == 1); 3413 return (irq_remapping_enabled == 1);
3414 case IOMMU_CAP_NOEXEC:
3415 return false;
3414 } 3416 }
3415 3417
3416 return false; 3418 return false;
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 60558f794922..7a80f710ba2d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -404,9 +404,16 @@ struct arm_smmu_cfg {
404#define ARM_SMMU_CB_ASID(cfg) ((cfg)->cbndx) 404#define ARM_SMMU_CB_ASID(cfg) ((cfg)->cbndx)
405#define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1) 405#define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1)
406 406
407enum arm_smmu_domain_stage {
408 ARM_SMMU_DOMAIN_S1 = 0,
409 ARM_SMMU_DOMAIN_S2,
410 ARM_SMMU_DOMAIN_NESTED,
411};
412
407struct arm_smmu_domain { 413struct arm_smmu_domain {
408 struct arm_smmu_device *smmu; 414 struct arm_smmu_device *smmu;
409 struct arm_smmu_cfg cfg; 415 struct arm_smmu_cfg cfg;
416 enum arm_smmu_domain_stage stage;
410 spinlock_t lock; 417 spinlock_t lock;
411}; 418};
412 419
@@ -906,19 +913,46 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
906 if (smmu_domain->smmu) 913 if (smmu_domain->smmu)
907 goto out_unlock; 914 goto out_unlock;
908 915
909 if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) { 916 /*
917 * Mapping the requested stage onto what we support is surprisingly
918 * complicated, mainly because the spec allows S1+S2 SMMUs without
919 * support for nested translation. That means we end up with the
920 * following table:
921 *
922 * Requested Supported Actual
923 * S1 N S1
924 * S1 S1+S2 S1
925 * S1 S2 S2
926 * S1 S1 S1
927 * N N N
928 * N S1+S2 S2
929 * N S2 S2
930 * N S1 S1
931 *
932 * Note that you can't actually request stage-2 mappings.
933 */
934 if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S1))
935 smmu_domain->stage = ARM_SMMU_DOMAIN_S2;
936 if (!(smmu->features & ARM_SMMU_FEAT_TRANS_S2))
937 smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
938
939 switch (smmu_domain->stage) {
940 case ARM_SMMU_DOMAIN_S1:
941 cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
942 start = smmu->num_s2_context_banks;
943 break;
944 case ARM_SMMU_DOMAIN_NESTED:
910 /* 945 /*
911 * We will likely want to change this if/when KVM gets 946 * We will likely want to change this if/when KVM gets
912 * involved. 947 * involved.
913 */ 948 */
914 cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS; 949 case ARM_SMMU_DOMAIN_S2:
915 start = smmu->num_s2_context_banks;
916 } else if (smmu->features & ARM_SMMU_FEAT_TRANS_S1) {
917 cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS;
918 start = smmu->num_s2_context_banks;
919 } else {
920 cfg->cbar = CBAR_TYPE_S2_TRANS; 950 cfg->cbar = CBAR_TYPE_S2_TRANS;
921 start = 0; 951 start = 0;
952 break;
953 default:
954 ret = -EINVAL;
955 goto out_unlock;
922 } 956 }
923 957
924 ret = __arm_smmu_alloc_bitmap(smmu->context_map, start, 958 ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
@@ -1281,7 +1315,7 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd,
1281 unsigned long pfn, int prot, int stage) 1315 unsigned long pfn, int prot, int stage)
1282{ 1316{
1283 pte_t *pte, *start; 1317 pte_t *pte, *start;
1284 pteval_t pteval = ARM_SMMU_PTE_PAGE | ARM_SMMU_PTE_AF | ARM_SMMU_PTE_XN; 1318 pteval_t pteval = ARM_SMMU_PTE_PAGE | ARM_SMMU_PTE_AF;
1285 1319
1286 if (pmd_none(*pmd)) { 1320 if (pmd_none(*pmd)) {
1287 /* Allocate a new set of tables */ 1321 /* Allocate a new set of tables */
@@ -1315,10 +1349,11 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd,
1315 pteval |= ARM_SMMU_PTE_MEMATTR_NC; 1349 pteval |= ARM_SMMU_PTE_MEMATTR_NC;
1316 } 1350 }
1317 1351
1352 if (prot & IOMMU_NOEXEC)
1353 pteval |= ARM_SMMU_PTE_XN;
1354
1318 /* If no access, create a faulting entry to avoid TLB fills */ 1355 /* If no access, create a faulting entry to avoid TLB fills */
1319 if (prot & IOMMU_EXEC) 1356 if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
1320 pteval &= ~ARM_SMMU_PTE_XN;
1321 else if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
1322 pteval &= ~ARM_SMMU_PTE_PAGE; 1357 pteval &= ~ARM_SMMU_PTE_PAGE;
1323 1358
1324 pteval |= ARM_SMMU_PTE_SH_IS; 1359 pteval |= ARM_SMMU_PTE_SH_IS;
@@ -1568,6 +1603,8 @@ static bool arm_smmu_capable(enum iommu_cap cap)
1568 return true; 1603 return true;
1569 case IOMMU_CAP_INTR_REMAP: 1604 case IOMMU_CAP_INTR_REMAP:
1570 return true; /* MSIs are just memory writes */ 1605 return true; /* MSIs are just memory writes */
1606 case IOMMU_CAP_NOEXEC:
1607 return true;
1571 default: 1608 default:
1572 return false; 1609 return false;
1573 } 1610 }
@@ -1644,20 +1681,56 @@ static void arm_smmu_remove_device(struct device *dev)
1644 iommu_group_remove_device(dev); 1681 iommu_group_remove_device(dev);
1645} 1682}
1646 1683
1684static int arm_smmu_domain_get_attr(struct iommu_domain *domain,
1685 enum iommu_attr attr, void *data)
1686{
1687 struct arm_smmu_domain *smmu_domain = domain->priv;
1688
1689 switch (attr) {
1690 case DOMAIN_ATTR_NESTING:
1691 *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED);
1692 return 0;
1693 default:
1694 return -ENODEV;
1695 }
1696}
1697
1698static int arm_smmu_domain_set_attr(struct iommu_domain *domain,
1699 enum iommu_attr attr, void *data)
1700{
1701 struct arm_smmu_domain *smmu_domain = domain->priv;
1702
1703 switch (attr) {
1704 case DOMAIN_ATTR_NESTING:
1705 if (smmu_domain->smmu)
1706 return -EPERM;
1707 if (*(int *)data)
1708 smmu_domain->stage = ARM_SMMU_DOMAIN_NESTED;
1709 else
1710 smmu_domain->stage = ARM_SMMU_DOMAIN_S1;
1711
1712 return 0;
1713 default:
1714 return -ENODEV;
1715 }
1716}
1717
1647static const struct iommu_ops arm_smmu_ops = { 1718static const struct iommu_ops arm_smmu_ops = {
1648 .capable = arm_smmu_capable, 1719 .capable = arm_smmu_capable,
1649 .domain_init = arm_smmu_domain_init, 1720 .domain_init = arm_smmu_domain_init,
1650 .domain_destroy = arm_smmu_domain_destroy, 1721 .domain_destroy = arm_smmu_domain_destroy,
1651 .attach_dev = arm_smmu_attach_dev, 1722 .attach_dev = arm_smmu_attach_dev,
1652 .detach_dev = arm_smmu_detach_dev, 1723 .detach_dev = arm_smmu_detach_dev,
1653 .map = arm_smmu_map, 1724 .map = arm_smmu_map,
1654 .unmap = arm_smmu_unmap, 1725 .unmap = arm_smmu_unmap,
1655 .iova_to_phys = arm_smmu_iova_to_phys, 1726 .iova_to_phys = arm_smmu_iova_to_phys,
1656 .add_device = arm_smmu_add_device, 1727 .add_device = arm_smmu_add_device,
1657 .remove_device = arm_smmu_remove_device, 1728 .remove_device = arm_smmu_remove_device,
1658 .pgsize_bitmap = (SECTION_SIZE | 1729 .domain_get_attr = arm_smmu_domain_get_attr,
1659 ARM_SMMU_PTE_CONT_SIZE | 1730 .domain_set_attr = arm_smmu_domain_set_attr,
1660 PAGE_SIZE), 1731 .pgsize_bitmap = (SECTION_SIZE |
1732 ARM_SMMU_PTE_CONT_SIZE |
1733 PAGE_SIZE),
1661}; 1734};
1662 1735
1663static void arm_smmu_device_reset(struct arm_smmu_device *smmu) 1736static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
@@ -2072,8 +2145,20 @@ static struct platform_driver arm_smmu_driver = {
2072 2145
2073static int __init arm_smmu_init(void) 2146static int __init arm_smmu_init(void)
2074{ 2147{
2148 struct device_node *np;
2075 int ret; 2149 int ret;
2076 2150
2151 /*
2152 * Play nice with systems that don't have an ARM SMMU by checking that
2153 * an ARM SMMU exists in the system before proceeding with the driver
2154 * and IOMMU bus operation registration.
2155 */
2156 np = of_find_matching_node(NULL, arm_smmu_of_match);
2157 if (!np)
2158 return 0;
2159
2160 of_node_put(np);
2161
2077 ret = platform_driver_register(&arm_smmu_driver); 2162 ret = platform_driver_register(&arm_smmu_driver);
2078 if (ret) 2163 if (ret)
2079 return ret; 2164 return ret;
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index e6a7c9ff72f2..e438b30f062b 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -27,7 +27,7 @@
27#define IOMMU_READ (1 << 0) 27#define IOMMU_READ (1 << 0)
28#define IOMMU_WRITE (1 << 1) 28#define IOMMU_WRITE (1 << 1)
29#define IOMMU_CACHE (1 << 2) /* DMA cache coherency */ 29#define IOMMU_CACHE (1 << 2) /* DMA cache coherency */
30#define IOMMU_EXEC (1 << 3) 30#define IOMMU_NOEXEC (1 << 3)
31 31
32struct iommu_ops; 32struct iommu_ops;
33struct iommu_group; 33struct iommu_group;
@@ -61,6 +61,7 @@ enum iommu_cap {
61 IOMMU_CAP_CACHE_COHERENCY, /* IOMMU can enforce cache coherent DMA 61 IOMMU_CAP_CACHE_COHERENCY, /* IOMMU can enforce cache coherent DMA
62 transactions */ 62 transactions */
63 IOMMU_CAP_INTR_REMAP, /* IOMMU supports interrupt isolation */ 63 IOMMU_CAP_INTR_REMAP, /* IOMMU supports interrupt isolation */
64 IOMMU_CAP_NOEXEC, /* IOMMU_NOEXEC flag */
64}; 65};
65 66
66/* 67/*