Loading drivers/iommu/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST config IOMMU_IO_PGTABLE_FAST bool "Fast ARMv7/v8 Long Descriptor Format" select IOMMU_IO_PGTABLE depends on ARM64_DMA_USE_IOMMU || ARM_DMA_USE_IOMMU help Enable support for a subset of the ARM long descriptor pagetable format. This allocator achieves fast performance by Loading drivers/iommu/dma-mapping-fast.c +2 −2 Original line number Diff line number Diff line /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -927,7 +927,7 @@ static int fast_smmu_errata_init(struct dma_iommu_mapping *mapping) int fast_smmu_init_mapping(struct device *dev, struct dma_iommu_mapping *mapping) { int err; int err = 0; struct iommu_domain *domain = mapping->domain; struct iommu_pgtbl_info info; u64 size = (u64)mapping->bits << PAGE_SHIFT; Loading drivers/iommu/io-pgtable-arm.c +12 −1 Original line number Diff line number Diff line Loading @@ -213,6 +213,7 @@ struct arm_lpae_io_pgtable { unsigned long bits_per_level; void *pgd; void *pgd_ttbr1; }; typedef u64 arm_lpae_iopte; Loading Loading @@ -739,6 +740,8 @@ static void arm_lpae_free_pgtable(struct io_pgtable *iop) struct arm_lpae_io_pgtable *data = io_pgtable_to_data(iop); __arm_lpae_free_pgtable(data, ARM_LPAE_START_LVL(data), data->pgd); __arm_lpae_free_pgtable(data, ARM_LPAE_START_LVL(data), data->pgd_ttbr1); kfree(data); } Loading Loading @@ -1203,14 +1206,22 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) if (!data->pgd) goto out_free_data; data->pgd_ttbr1 = __arm_lpae_alloc_pages(data->pgd_size, GFP_KERNEL, cfg, cookie); if (!data->pgd_ttbr1) goto out_free_pgd; /* Ensure the empty pgd is visible before any actual TTBR write */ wmb(); /* TTBRs */ cfg->arm_lpae_s1_cfg.ttbr[0] = virt_to_phys(data->pgd); cfg->arm_lpae_s1_cfg.ttbr[1] = 0; cfg->arm_lpae_s1_cfg.ttbr[1] = virt_to_phys(data->pgd_ttbr1); return &data->iop; out_free_pgd: __arm_lpae_free_pages(data->pgd, data->pgd_size, cfg, cookie); out_free_data: kfree(data); return NULL; Loading drivers/iommu/iommu-debug.c +33 −1 Original line number Diff line number Diff line Loading @@ -170,6 +170,8 @@ struct iommu_debug_device { u64 phys; size_t len; struct list_head list; struct mutex clk_lock; unsigned int clk_count; }; static int iommu_debug_build_phoney_sg_table(struct device *dev, Loading Loading @@ -1278,7 +1280,7 @@ static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev, } ddev->domain->is_debug_domain = true; val = VMID_CP_CAMERA; if (is_secure && iommu_domain_set_attr(ddev->domain, DOMAIN_ATTR_SECURE_VMID, &val)) { Loading Loading @@ -1571,6 +1573,10 @@ static ssize_t iommu_debug_pte_read(struct file *file, char __user *ubuf, ssize_t retval; size_t buflen; if (kptr_restrict != 0) { pr_err("kptr_restrict needs to be disabled.\n"); return -EPERM; } if (!dev->archdata.mapping) { pr_err("No mapping. Did you already attach?\n"); return -EINVAL; Loading Loading @@ -1638,6 +1644,10 @@ static ssize_t iommu_debug_atos_read(struct file *file, char __user *ubuf, ssize_t retval; size_t buflen; if (kptr_restrict != 0) { pr_err("kptr_restrict needs to be disabled.\n"); return -EPERM; } if (!ddev->domain) { pr_err("No domain. Did you already attach?\n"); return -EINVAL; Loading Loading @@ -1686,6 +1696,10 @@ static ssize_t iommu_debug_dma_atos_read(struct file *file, char __user *ubuf, ssize_t retval; size_t buflen; if (kptr_restrict != 0) { pr_err("kptr_restrict needs to be disabled.\n"); return -EPERM; } if (!dev->archdata.mapping) { pr_err("No mapping. Did you already attach?\n"); return -EINVAL; Loading Loading @@ -2132,20 +2146,34 @@ static ssize_t iommu_debug_config_clocks_write(struct file *file, return -EFAULT; } mutex_lock(&ddev->clk_lock); switch (buf) { case '0': if (ddev->clk_count == 0) { dev_err(dev, "Config clocks already disabled\n"); break; } if (--ddev->clk_count > 0) break; dev_err(dev, "Disabling config clocks\n"); iommu_disable_config_clocks(ddev->domain); break; case '1': if (ddev->clk_count++ > 0) break; dev_err(dev, "Enabling config clocks\n"); if (iommu_enable_config_clocks(ddev->domain)) dev_err(dev, "Failed!\n"); break; default: dev_err(dev, "Invalid value. Should be 0 or 1.\n"); mutex_unlock(&ddev->clk_lock); return -EINVAL; } mutex_unlock(&ddev->clk_lock); return count; } Loading Loading @@ -2195,6 +2223,9 @@ static int snarf_iommu_devices(struct device *dev, void *ignored) if (!of_find_property(dev->of_node, "iommus", NULL)) return 0; if (!of_device_is_compatible(dev->of_node, "iommu-debug-test")) return 0; /* Hold a reference count */ if (!iommu_group_get(dev)) return 0; Loading @@ -2203,6 +2234,7 @@ static int snarf_iommu_devices(struct device *dev, void *ignored) if (!ddev) return -ENODEV; mutex_init(&ddev->clk_lock); ddev->dev = dev; dir = debugfs_create_dir(dev_name(dev), debugfs_tests_dir); if (!dir) { Loading Loading
drivers/iommu/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST config IOMMU_IO_PGTABLE_FAST bool "Fast ARMv7/v8 Long Descriptor Format" select IOMMU_IO_PGTABLE depends on ARM64_DMA_USE_IOMMU || ARM_DMA_USE_IOMMU help Enable support for a subset of the ARM long descriptor pagetable format. This allocator achieves fast performance by Loading
drivers/iommu/dma-mapping-fast.c +2 −2 Original line number Diff line number Diff line /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -927,7 +927,7 @@ static int fast_smmu_errata_init(struct dma_iommu_mapping *mapping) int fast_smmu_init_mapping(struct device *dev, struct dma_iommu_mapping *mapping) { int err; int err = 0; struct iommu_domain *domain = mapping->domain; struct iommu_pgtbl_info info; u64 size = (u64)mapping->bits << PAGE_SHIFT; Loading
drivers/iommu/io-pgtable-arm.c +12 −1 Original line number Diff line number Diff line Loading @@ -213,6 +213,7 @@ struct arm_lpae_io_pgtable { unsigned long bits_per_level; void *pgd; void *pgd_ttbr1; }; typedef u64 arm_lpae_iopte; Loading Loading @@ -739,6 +740,8 @@ static void arm_lpae_free_pgtable(struct io_pgtable *iop) struct arm_lpae_io_pgtable *data = io_pgtable_to_data(iop); __arm_lpae_free_pgtable(data, ARM_LPAE_START_LVL(data), data->pgd); __arm_lpae_free_pgtable(data, ARM_LPAE_START_LVL(data), data->pgd_ttbr1); kfree(data); } Loading Loading @@ -1203,14 +1206,22 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) if (!data->pgd) goto out_free_data; data->pgd_ttbr1 = __arm_lpae_alloc_pages(data->pgd_size, GFP_KERNEL, cfg, cookie); if (!data->pgd_ttbr1) goto out_free_pgd; /* Ensure the empty pgd is visible before any actual TTBR write */ wmb(); /* TTBRs */ cfg->arm_lpae_s1_cfg.ttbr[0] = virt_to_phys(data->pgd); cfg->arm_lpae_s1_cfg.ttbr[1] = 0; cfg->arm_lpae_s1_cfg.ttbr[1] = virt_to_phys(data->pgd_ttbr1); return &data->iop; out_free_pgd: __arm_lpae_free_pages(data->pgd, data->pgd_size, cfg, cookie); out_free_data: kfree(data); return NULL; Loading
drivers/iommu/iommu-debug.c +33 −1 Original line number Diff line number Diff line Loading @@ -170,6 +170,8 @@ struct iommu_debug_device { u64 phys; size_t len; struct list_head list; struct mutex clk_lock; unsigned int clk_count; }; static int iommu_debug_build_phoney_sg_table(struct device *dev, Loading Loading @@ -1278,7 +1280,7 @@ static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev, } ddev->domain->is_debug_domain = true; val = VMID_CP_CAMERA; if (is_secure && iommu_domain_set_attr(ddev->domain, DOMAIN_ATTR_SECURE_VMID, &val)) { Loading Loading @@ -1571,6 +1573,10 @@ static ssize_t iommu_debug_pte_read(struct file *file, char __user *ubuf, ssize_t retval; size_t buflen; if (kptr_restrict != 0) { pr_err("kptr_restrict needs to be disabled.\n"); return -EPERM; } if (!dev->archdata.mapping) { pr_err("No mapping. Did you already attach?\n"); return -EINVAL; Loading Loading @@ -1638,6 +1644,10 @@ static ssize_t iommu_debug_atos_read(struct file *file, char __user *ubuf, ssize_t retval; size_t buflen; if (kptr_restrict != 0) { pr_err("kptr_restrict needs to be disabled.\n"); return -EPERM; } if (!ddev->domain) { pr_err("No domain. Did you already attach?\n"); return -EINVAL; Loading Loading @@ -1686,6 +1696,10 @@ static ssize_t iommu_debug_dma_atos_read(struct file *file, char __user *ubuf, ssize_t retval; size_t buflen; if (kptr_restrict != 0) { pr_err("kptr_restrict needs to be disabled.\n"); return -EPERM; } if (!dev->archdata.mapping) { pr_err("No mapping. Did you already attach?\n"); return -EINVAL; Loading Loading @@ -2132,20 +2146,34 @@ static ssize_t iommu_debug_config_clocks_write(struct file *file, return -EFAULT; } mutex_lock(&ddev->clk_lock); switch (buf) { case '0': if (ddev->clk_count == 0) { dev_err(dev, "Config clocks already disabled\n"); break; } if (--ddev->clk_count > 0) break; dev_err(dev, "Disabling config clocks\n"); iommu_disable_config_clocks(ddev->domain); break; case '1': if (ddev->clk_count++ > 0) break; dev_err(dev, "Enabling config clocks\n"); if (iommu_enable_config_clocks(ddev->domain)) dev_err(dev, "Failed!\n"); break; default: dev_err(dev, "Invalid value. Should be 0 or 1.\n"); mutex_unlock(&ddev->clk_lock); return -EINVAL; } mutex_unlock(&ddev->clk_lock); return count; } Loading Loading @@ -2195,6 +2223,9 @@ static int snarf_iommu_devices(struct device *dev, void *ignored) if (!of_find_property(dev->of_node, "iommus", NULL)) return 0; if (!of_device_is_compatible(dev->of_node, "iommu-debug-test")) return 0; /* Hold a reference count */ if (!iommu_group_get(dev)) return 0; Loading @@ -2203,6 +2234,7 @@ static int snarf_iommu_devices(struct device *dev, void *ignored) if (!ddev) return -ENODEV; mutex_init(&ddev->clk_lock); ddev->dev = dev; dir = debugfs_create_dir(dev_name(dev), debugfs_tests_dir); if (!dir) { Loading