|
|
|
|
@@ -289,20 +289,20 @@ static int iommu_debug_dma_reconfigure(struct iommu_debug_device *ddev,
|
|
|
|
|
bool coherent;
|
|
|
|
|
|
|
|
|
|
if (ddev->domain) {
|
|
|
|
|
dev_err(dev, "Already attached.\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Already attached.\n");
|
|
|
|
|
return -EBUSY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iommu = of_iommu_configure(dev, dev->of_node);
|
|
|
|
|
if (!iommu) {
|
|
|
|
|
dev_err(dev, "Is not associated with an iommu\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Is not associated with an iommu\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
coherent = of_dma_is_coherent(dev->of_node);
|
|
|
|
|
|
|
|
|
|
if (!dev->iommu_group) {
|
|
|
|
|
dev_err(dev, "Does not have an iommu group\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Does not have an iommu group\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -310,7 +310,7 @@ static int iommu_debug_dma_reconfigure(struct iommu_debug_device *ddev,
|
|
|
|
|
domain = iommu_get_domain_for_dev(dev);
|
|
|
|
|
if (domain) {
|
|
|
|
|
if (domain->type != IOMMU_DOMAIN_DMA) {
|
|
|
|
|
dev_err(dev, "Attached, but its not a default domain?\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Attached, but its not a default domain?\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
iommu_detach_group(domain, dev->iommu_group);
|
|
|
|
|
@@ -318,19 +318,19 @@ static int iommu_debug_dma_reconfigure(struct iommu_debug_device *ddev,
|
|
|
|
|
|
|
|
|
|
domain = iommu_domain_alloc(dev->bus);
|
|
|
|
|
if (!domain) {
|
|
|
|
|
dev_err(dev, "Allocating iommu domain failed\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Allocating iommu domain failed\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
domain->is_debug_domain = true;
|
|
|
|
|
|
|
|
|
|
if (iommu_debug_set_attrs(ddev, domain, attrs)) {
|
|
|
|
|
dev_err(dev, "Setting attrs failed\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Setting attrs failed\n");
|
|
|
|
|
goto out_free_domain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (iommu_attach_group(domain, dev->iommu_group)) {
|
|
|
|
|
dev_err(dev, "attach group failed\n");
|
|
|
|
|
dev_err_ratelimited(dev, "attach group failed\n");
|
|
|
|
|
goto out_free_domain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -341,7 +341,7 @@ static int iommu_debug_dma_reconfigure(struct iommu_debug_device *ddev,
|
|
|
|
|
set_dma_ops(dev, NULL);
|
|
|
|
|
arch_setup_dma_ops(dev, dma_base, size, iommu, coherent);
|
|
|
|
|
if (!get_dma_ops(dev)) {
|
|
|
|
|
dev_err(dev, "arch_setup_dma_ops failed, dma ops are null.\n");
|
|
|
|
|
dev_err_ratelimited(dev, "arch_setup_dma_ops failed, dma ops are null.\n");
|
|
|
|
|
goto out_detach_group;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -362,13 +362,13 @@ static void iommu_debug_dma_deconfigure(struct iommu_debug_device *ddev)
|
|
|
|
|
struct device *dev = ddev->dev;
|
|
|
|
|
|
|
|
|
|
if (!dev->iommu_group) {
|
|
|
|
|
dev_err(dev, "Does not have an iommu group\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Does not have an iommu group\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
domain = ddev->domain;
|
|
|
|
|
if (!domain) {
|
|
|
|
|
dev_err(dev, "Is not attached\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Is not attached\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -770,14 +770,14 @@ static int __tlb_stress_sweep(struct device *dev, struct seq_file *s)
|
|
|
|
|
for (iova = 0, i = 0; iova < max; iova += SZ_8K, ++i) {
|
|
|
|
|
dma_addr = dma_map_single(dev, virt, SZ_8K, DMA_TO_DEVICE);
|
|
|
|
|
if (dma_addr == DMA_ERROR_CODE) {
|
|
|
|
|
dev_err(dev, "Failed map on iter %d\n", i);
|
|
|
|
|
dev_err_ratelimited(dev, "Failed map on iter %d\n", i);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dma_map_single(dev, virt, SZ_4K, DMA_TO_DEVICE) != DMA_ERROR_CODE) {
|
|
|
|
|
dev_err(dev,
|
|
|
|
|
dev_err_ratelimited(dev,
|
|
|
|
|
"dma_map_single unexpectedly (VA should have been exhausted)\n");
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto out;
|
|
|
|
|
@@ -797,7 +797,7 @@ static int __tlb_stress_sweep(struct device *dev, struct seq_file *s)
|
|
|
|
|
if (dma_addr != SZ_8K) {
|
|
|
|
|
dma_addr_t expected = SZ_8K;
|
|
|
|
|
|
|
|
|
|
dev_err(dev, "Unexpected dma_addr. got: %pa expected: %pa\n",
|
|
|
|
|
dev_err_ratelimited(dev, "Unexpected dma_addr. got: %pa expected: %pa\n",
|
|
|
|
|
&dma_addr, &expected);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto out;
|
|
|
|
|
@@ -812,14 +812,14 @@ static int __tlb_stress_sweep(struct device *dev, struct seq_file *s)
|
|
|
|
|
if (dma_addr != 0) {
|
|
|
|
|
dma_addr_t expected = 0;
|
|
|
|
|
|
|
|
|
|
dev_err(dev, "Unexpected dma_addr. got: %pa expected: %pa\n",
|
|
|
|
|
dev_err_ratelimited(dev, "Unexpected dma_addr. got: %pa expected: %pa\n",
|
|
|
|
|
&dma_addr, &expected);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dma_map_single(dev, virt, SZ_4K, DMA_TO_DEVICE) != DMA_ERROR_CODE) {
|
|
|
|
|
dev_err(dev,
|
|
|
|
|
dev_err_ratelimited(dev,
|
|
|
|
|
"dma_map_single unexpectedly after remaps (VA should have been exhausted)\n");
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto out;
|
|
|
|
|
@@ -869,7 +869,7 @@ static int __rand_va_sweep(struct device *dev, struct seq_file *s,
|
|
|
|
|
virt = (void *)__get_free_pages(GFP_KERNEL, get_order(size));
|
|
|
|
|
if (!virt) {
|
|
|
|
|
if (size > SZ_8K) {
|
|
|
|
|
dev_err(dev,
|
|
|
|
|
dev_err_ratelimited(dev,
|
|
|
|
|
"Failed to allocate %s of memory, which is a lot. Skipping test for this size\n",
|
|
|
|
|
_size_to_string(size));
|
|
|
|
|
return 0;
|
|
|
|
|
@@ -881,7 +881,7 @@ static int __rand_va_sweep(struct device *dev, struct seq_file *s,
|
|
|
|
|
for (iova = 0, i = 0; iova < max; iova += size, ++i) {
|
|
|
|
|
dma_addr = dma_map_single(dev, virt, size, DMA_TO_DEVICE);
|
|
|
|
|
if (dma_addr == DMA_ERROR_CODE) {
|
|
|
|
|
dev_err(dev, "Failed map on iter %d\n", i);
|
|
|
|
|
dev_err_ratelimited(dev, "Failed map on iter %d\n", i);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
@@ -914,7 +914,7 @@ static int __rand_va_sweep(struct device *dev, struct seq_file *s,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (unmapped != remapped) {
|
|
|
|
|
dev_err(dev,
|
|
|
|
|
dev_err_ratelimited(dev,
|
|
|
|
|
"Unexpected random remap count! Unmapped %d but remapped %d\n",
|
|
|
|
|
unmapped, remapped);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
@@ -959,7 +959,7 @@ static int __full_va_sweep(struct device *dev, struct seq_file *s,
|
|
|
|
|
virt = (void *)__get_free_pages(GFP_KERNEL, get_order(size));
|
|
|
|
|
if (!virt) {
|
|
|
|
|
if (size > SZ_8K) {
|
|
|
|
|
dev_err(dev,
|
|
|
|
|
dev_err_ratelimited(dev,
|
|
|
|
|
"Failed to allocate %s of memory, which is a lot. Skipping test for this size\n",
|
|
|
|
|
_size_to_string(size));
|
|
|
|
|
return 0;
|
|
|
|
|
@@ -988,7 +988,7 @@ static int __full_va_sweep(struct device *dev, struct seq_file *s,
|
|
|
|
|
phys_addr_t expected = phys;
|
|
|
|
|
|
|
|
|
|
if (__check_mapping(dev, domain, iova, expected)) {
|
|
|
|
|
dev_err(dev, "iter: %d\n", i);
|
|
|
|
|
dev_err_ratelimited(dev, "iter: %d\n", i);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
@@ -999,7 +999,7 @@ static int __full_va_sweep(struct device *dev, struct seq_file *s,
|
|
|
|
|
unsigned long theiova = ((SZ_1G * 4ULL) - size) - iova;
|
|
|
|
|
|
|
|
|
|
if (__check_mapping(dev, domain, theiova, expected)) {
|
|
|
|
|
dev_err(dev, "iter: %d\n", i);
|
|
|
|
|
dev_err_ratelimited(dev, "iter: %d\n", i);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
@@ -1158,7 +1158,7 @@ static int __functional_dma_api_basic_test(struct device *dev,
|
|
|
|
|
pa = iommu_iova_to_phys(domain, iova);
|
|
|
|
|
pa2 = iommu_iova_to_phys_hard(domain, iova);
|
|
|
|
|
if (pa != pa2) {
|
|
|
|
|
dev_err(dev,
|
|
|
|
|
dev_err_ratelimited(dev,
|
|
|
|
|
"iova_to_phys doesn't match iova_to_phys_hard: %pa != %pa\n",
|
|
|
|
|
&pa, &pa2);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
@@ -1166,7 +1166,7 @@ static int __functional_dma_api_basic_test(struct device *dev,
|
|
|
|
|
}
|
|
|
|
|
pa2 = virt_to_phys(data);
|
|
|
|
|
if (pa != pa2) {
|
|
|
|
|
dev_err(dev,
|
|
|
|
|
dev_err_ratelimited(dev,
|
|
|
|
|
"iova_to_phys doesn't match virt_to_phys: %pa != %pa\n",
|
|
|
|
|
&pa, &pa2);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
@@ -1175,7 +1175,8 @@ static int __functional_dma_api_basic_test(struct device *dev,
|
|
|
|
|
dma_unmap_single(dev, iova, size, DMA_TO_DEVICE);
|
|
|
|
|
for (j = 0; j < size; ++j) {
|
|
|
|
|
if (data[j] != 0xa5) {
|
|
|
|
|
dev_err(dev, "data[%d] != 0xa5\n", data[j]);
|
|
|
|
|
dev_err_ratelimited(dev,
|
|
|
|
|
"data[%d] != 0xa5\n", data[j]);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
@@ -1230,7 +1231,7 @@ static int __functional_dma_api_map_sg_test(struct device *dev,
|
|
|
|
|
pa = iommu_iova_to_phys(domain, iova);
|
|
|
|
|
pa2 = iommu_iova_to_phys_hard(domain, iova);
|
|
|
|
|
if (pa != pa2) {
|
|
|
|
|
dev_err(dev,
|
|
|
|
|
dev_err_ratelimited(dev,
|
|
|
|
|
"iova_to_phys doesn't match iova_to_phys_hard: %pa != %pa\n",
|
|
|
|
|
&pa, &pa2);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
@@ -1241,7 +1242,7 @@ static int __functional_dma_api_map_sg_test(struct device *dev,
|
|
|
|
|
pa = iommu_iova_to_phys(domain, iova);
|
|
|
|
|
pa2 = iommu_iova_to_phys_hard(domain, iova);
|
|
|
|
|
if (pa != pa2) {
|
|
|
|
|
dev_err(dev,
|
|
|
|
|
dev_err_ratelimited(dev,
|
|
|
|
|
"iova_to_phys doesn't match iova_to_phys_hard: %pa != %pa\n",
|
|
|
|
|
&pa, &pa2);
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
@@ -1289,7 +1290,7 @@ static int __apply_to_new_mapping(struct seq_file *s,
|
|
|
|
|
goto out_release_mapping;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dev_err(dev, "testing with pgtables at %pa\n", &pt_phys);
|
|
|
|
|
dev_err_ratelimited(dev, "testing with pgtables at %pa\n", &pt_phys);
|
|
|
|
|
if (iommu_enable_config_clocks(domain)) {
|
|
|
|
|
ds_printf(dev, s, "Couldn't enable clocks\n");
|
|
|
|
|
goto out_release_mapping;
|
|
|
|
|
@@ -1378,7 +1379,7 @@ static ssize_t __iommu_debug_attach_write(struct file *file,
|
|
|
|
|
int val, ret;
|
|
|
|
|
|
|
|
|
|
if (kstrtoint_from_user(ubuf, count, 0, &val)) {
|
|
|
|
|
pr_err("Invalid format. Expected a hex or decimal integer");
|
|
|
|
|
pr_err_ratelimited("Invalid format. Expected a hex or decimal integer");
|
|
|
|
|
return -EFAULT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1386,10 +1387,10 @@ static ssize_t __iommu_debug_attach_write(struct file *file,
|
|
|
|
|
if (val) {
|
|
|
|
|
ret = iommu_debug_dma_reconfigure(ddev, attrs, 0, SZ_1G * 4ULL);
|
|
|
|
|
if (!ret)
|
|
|
|
|
pr_err("Attached\n");
|
|
|
|
|
pr_err_ratelimited("Attached\n");
|
|
|
|
|
} else {
|
|
|
|
|
iommu_debug_dma_deconfigure(ddev);
|
|
|
|
|
pr_err("Detached\n");
|
|
|
|
|
pr_err_ratelimited("Detached\n");
|
|
|
|
|
}
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
retval = count;
|
|
|
|
|
@@ -1424,7 +1425,7 @@ static ssize_t iommu_debug_attach_read(struct file *file, char __user *ubuf,
|
|
|
|
|
c[0] = ddev->domain ? '1' : '0';
|
|
|
|
|
c[1] = '\n';
|
|
|
|
|
if (copy_to_user(ubuf, &c, 2)) {
|
|
|
|
|
pr_err("copy_to_user failed\n");
|
|
|
|
|
pr_err_ratelimited("copy_to_user failed\n");
|
|
|
|
|
return -EFAULT;
|
|
|
|
|
}
|
|
|
|
|
*offset = 1; /* non-zero means we're done */
|
|
|
|
|
@@ -1459,7 +1460,7 @@ static ssize_t iommu_debug_test_virt_addr_read(struct file *file,
|
|
|
|
|
|
|
|
|
|
buflen = strlen(buf);
|
|
|
|
|
if (copy_to_user(ubuf, buf, buflen)) {
|
|
|
|
|
pr_err("Couldn't copy_to_user\n");
|
|
|
|
|
pr_err_ratelimited("Couldn't copy_to_user\n");
|
|
|
|
|
retval = -EFAULT;
|
|
|
|
|
} else {
|
|
|
|
|
*offset = 1; /* non-zero means we're done */
|
|
|
|
|
@@ -1494,13 +1495,13 @@ static ssize_t iommu_debug_pte_write(struct file *file,
|
|
|
|
|
dma_addr_t iova;
|
|
|
|
|
|
|
|
|
|
if (kstrtox_from_user(ubuf, count, 0, &iova)) {
|
|
|
|
|
pr_err("Invalid format for iova\n");
|
|
|
|
|
pr_err_ratelimited("Invalid format for iova\n");
|
|
|
|
|
ddev->iova = 0;
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ddev->iova = iova;
|
|
|
|
|
pr_err("Saved iova=%pa for future PTE commands\n", &iova);
|
|
|
|
|
pr_err_ratelimited("Saved iova=%pa for future PTE commands\n", &iova);
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1515,7 +1516,7 @@ static ssize_t iommu_debug_pte_read(struct file *file, char __user *ubuf,
|
|
|
|
|
size_t buflen;
|
|
|
|
|
|
|
|
|
|
if (kptr_restrict != 0) {
|
|
|
|
|
pr_err("kptr_restrict needs to be disabled.\n");
|
|
|
|
|
pr_err_ratelimited("kptr_restrict needs to be disabled.\n");
|
|
|
|
|
return -EPERM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1524,7 +1525,7 @@ static ssize_t iommu_debug_pte_read(struct file *file, char __user *ubuf,
|
|
|
|
|
|
|
|
|
|
mutex_lock(&ddev->state_lock);
|
|
|
|
|
if (!ddev->domain) {
|
|
|
|
|
pr_err("No domain. Did you already attach?\n");
|
|
|
|
|
pr_err_ratelimited("No domain. Did you already attach?\n");
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
@@ -1540,7 +1541,7 @@ static ssize_t iommu_debug_pte_read(struct file *file, char __user *ubuf,
|
|
|
|
|
|
|
|
|
|
buflen = strlen(buf);
|
|
|
|
|
if (copy_to_user(ubuf, buf, buflen)) {
|
|
|
|
|
pr_err("Couldn't copy_to_user\n");
|
|
|
|
|
pr_err_ratelimited("Couldn't copy_to_user\n");
|
|
|
|
|
retval = -EFAULT;
|
|
|
|
|
} else {
|
|
|
|
|
*offset = 1; /* non-zero means we're done */
|
|
|
|
|
@@ -1565,13 +1566,13 @@ static ssize_t iommu_debug_atos_write(struct file *file,
|
|
|
|
|
dma_addr_t iova;
|
|
|
|
|
|
|
|
|
|
if (kstrtox_from_user(ubuf, count, 0, &iova)) {
|
|
|
|
|
pr_err("Invalid format for iova\n");
|
|
|
|
|
pr_err_ratelimited("Invalid format for iova\n");
|
|
|
|
|
ddev->iova = 0;
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ddev->iova = iova;
|
|
|
|
|
pr_err("Saved iova=%pa for future ATOS commands\n", &iova);
|
|
|
|
|
pr_err_ratelimited("Saved iova=%pa for future ATOS commands\n", &iova);
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1585,7 +1586,7 @@ static ssize_t iommu_debug_atos_read(struct file *file, char __user *ubuf,
|
|
|
|
|
size_t buflen;
|
|
|
|
|
|
|
|
|
|
if (kptr_restrict != 0) {
|
|
|
|
|
pr_err("kptr_restrict needs to be disabled.\n");
|
|
|
|
|
pr_err_ratelimited("kptr_restrict needs to be disabled.\n");
|
|
|
|
|
return -EPERM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1594,7 +1595,7 @@ static ssize_t iommu_debug_atos_read(struct file *file, char __user *ubuf,
|
|
|
|
|
|
|
|
|
|
mutex_lock(&ddev->state_lock);
|
|
|
|
|
if (!ddev->domain) {
|
|
|
|
|
pr_err("No domain. Did you already attach?\n");
|
|
|
|
|
pr_err_ratelimited("No domain. Did you already attach?\n");
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
@@ -1605,7 +1606,7 @@ static ssize_t iommu_debug_atos_read(struct file *file, char __user *ubuf,
|
|
|
|
|
if (!phys) {
|
|
|
|
|
strlcpy(buf, "FAIL\n", 100);
|
|
|
|
|
phys = iommu_iova_to_phys(ddev->domain, ddev->iova);
|
|
|
|
|
dev_err(ddev->dev, "ATOS for %pa failed. Software walk returned: %pa\n",
|
|
|
|
|
dev_err_ratelimited(ddev->dev, "ATOS for %pa failed. Software walk returned: %pa\n",
|
|
|
|
|
&ddev->iova, &phys);
|
|
|
|
|
} else {
|
|
|
|
|
snprintf(buf, 100, "%pa\n", &phys);
|
|
|
|
|
@@ -1613,7 +1614,7 @@ static ssize_t iommu_debug_atos_read(struct file *file, char __user *ubuf,
|
|
|
|
|
|
|
|
|
|
buflen = strlen(buf);
|
|
|
|
|
if (copy_to_user(ubuf, buf, buflen)) {
|
|
|
|
|
pr_err("Couldn't copy_to_user\n");
|
|
|
|
|
pr_err_ratelimited("Couldn't copy_to_user\n");
|
|
|
|
|
retval = -EFAULT;
|
|
|
|
|
} else {
|
|
|
|
|
*offset = 1; /* non-zero means we're done */
|
|
|
|
|
@@ -1640,7 +1641,7 @@ static ssize_t iommu_debug_dma_atos_read(struct file *file, char __user *ubuf,
|
|
|
|
|
size_t buflen;
|
|
|
|
|
|
|
|
|
|
if (kptr_restrict != 0) {
|
|
|
|
|
pr_err("kptr_restrict needs to be disabled.\n");
|
|
|
|
|
pr_err_ratelimited("kptr_restrict needs to be disabled.\n");
|
|
|
|
|
return -EPERM;
|
|
|
|
|
}
|
|
|
|
|
if (*offset)
|
|
|
|
|
@@ -1648,7 +1649,7 @@ static ssize_t iommu_debug_dma_atos_read(struct file *file, char __user *ubuf,
|
|
|
|
|
|
|
|
|
|
mutex_lock(&ddev->state_lock);
|
|
|
|
|
if (!ddev->domain) {
|
|
|
|
|
pr_err("No domain. Did you already attach?\n");
|
|
|
|
|
pr_err_ratelimited("No domain. Did you already attach?\n");
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
@@ -1664,7 +1665,7 @@ static ssize_t iommu_debug_dma_atos_read(struct file *file, char __user *ubuf,
|
|
|
|
|
|
|
|
|
|
buflen = strlen(buf);
|
|
|
|
|
if (copy_to_user(ubuf, buf, buflen)) {
|
|
|
|
|
pr_err("Couldn't copy_to_user\n");
|
|
|
|
|
pr_err_ratelimited("Couldn't copy_to_user\n");
|
|
|
|
|
retval = -EFAULT;
|
|
|
|
|
} else {
|
|
|
|
|
*offset = 1; /* non-zero means we're done */
|
|
|
|
|
@@ -1695,14 +1696,14 @@ static ssize_t iommu_debug_map_write(struct file *file, const char __user *ubuf,
|
|
|
|
|
struct iommu_debug_device *ddev = file->private_data;
|
|
|
|
|
|
|
|
|
|
if (count >= 100) {
|
|
|
|
|
pr_err("Value too large\n");
|
|
|
|
|
pr_err_ratelimited("Value too large\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(buf, 0, 100);
|
|
|
|
|
|
|
|
|
|
if (copy_from_user(buf, ubuf, count)) {
|
|
|
|
|
pr_err("Couldn't copy from user\n");
|
|
|
|
|
pr_err_ratelimited("Couldn't copy from user\n");
|
|
|
|
|
retval = -EFAULT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1735,27 +1736,27 @@ static ssize_t iommu_debug_map_write(struct file *file, const char __user *ubuf,
|
|
|
|
|
|
|
|
|
|
mutex_lock(&ddev->state_lock);
|
|
|
|
|
if (!ddev->domain) {
|
|
|
|
|
pr_err("No domain. Did you already attach?\n");
|
|
|
|
|
pr_err_ratelimited("No domain. Did you already attach?\n");
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = iommu_map(ddev->domain, iova, phys, size, prot);
|
|
|
|
|
if (ret) {
|
|
|
|
|
pr_err("iommu_map failed with %d\n", ret);
|
|
|
|
|
pr_err_ratelimited("iommu_map failed with %d\n", ret);
|
|
|
|
|
retval = -EIO;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
retval = count;
|
|
|
|
|
pr_err("Mapped %pa to %pa (len=0x%zx, prot=0x%x)\n",
|
|
|
|
|
pr_err_ratelimited("Mapped %pa to %pa (len=0x%zx, prot=0x%x)\n",
|
|
|
|
|
&iova, &phys, size, prot);
|
|
|
|
|
out:
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
|
|
invalid_format:
|
|
|
|
|
pr_err("Invalid format. Expected: iova,phys,len,prot where `prot' is the bitwise OR of IOMMU_READ, IOMMU_WRITE, etc.\n");
|
|
|
|
|
pr_err_ratelimited("Invalid format. Expected: iova,phys,len,prot where `prot' is the bitwise OR of IOMMU_READ, IOMMU_WRITE, etc.\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1789,14 +1790,14 @@ static ssize_t iommu_debug_dma_map_write(struct file *file,
|
|
|
|
|
struct device *dev = ddev->dev;
|
|
|
|
|
|
|
|
|
|
if (count >= sizeof(buf)) {
|
|
|
|
|
pr_err("Value too large\n");
|
|
|
|
|
pr_err_ratelimited("Value too large\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
|
|
|
|
|
|
if (copy_from_user(buf, ubuf, count)) {
|
|
|
|
|
pr_err("Couldn't copy from user\n");
|
|
|
|
|
pr_err_ratelimited("Couldn't copy from user\n");
|
|
|
|
|
return -EFAULT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1836,7 +1837,7 @@ static ssize_t iommu_debug_dma_map_write(struct file *file,
|
|
|
|
|
|
|
|
|
|
mutex_lock(&ddev->state_lock);
|
|
|
|
|
if (!ddev->domain) {
|
|
|
|
|
pr_err("No domain. Did you already attach?\n");
|
|
|
|
|
pr_err_ratelimited("No domain. Did you already attach?\n");
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
@@ -1845,26 +1846,27 @@ static ssize_t iommu_debug_dma_map_write(struct file *file,
|
|
|
|
|
DMA_TO_DEVICE, dma_attrs);
|
|
|
|
|
|
|
|
|
|
if (dma_mapping_error(dev, iova)) {
|
|
|
|
|
pr_err("Failed to perform dma_map_single\n");
|
|
|
|
|
pr_err_ratelimited("Failed to perform dma_map_single\n");
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
retval = count;
|
|
|
|
|
pr_err("Mapped 0x%p to %pa (len=0x%zx)\n",
|
|
|
|
|
pr_err_ratelimited("Mapped 0x%p to %pa (len=0x%zx)\n",
|
|
|
|
|
v_addr, &iova, size);
|
|
|
|
|
ddev->iova = iova;
|
|
|
|
|
pr_err("Saved iova=%pa for future PTE commands\n", &iova);
|
|
|
|
|
pr_err_ratelimited("Saved iova=%pa for future PTE commands\n",
|
|
|
|
|
&iova);
|
|
|
|
|
out:
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
|
|
invalid_format:
|
|
|
|
|
pr_err("Invalid format. Expected: addr,len,dma attr where 'dma attr' is\n0: normal mapping\n1: force coherent\n2: force non-cohernet\n3: use system cache\n");
|
|
|
|
|
pr_err_ratelimited("Invalid format. Expected: addr,len,dma attr where 'dma attr' is\n0: normal mapping\n1: force coherent\n2: force non-cohernet\n3: use system cache\n");
|
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
|
|
invalid_addr:
|
|
|
|
|
pr_err("Invalid addr given! Address should be within 1MB size from start addr returned by doing 'cat test_virt_addr'.\n");
|
|
|
|
|
pr_err_ratelimited("Invalid addr given! Address should be within 1MB size from start addr returned by doing 'cat test_virt_addr'.\n");
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1887,7 +1889,7 @@ static ssize_t iommu_debug_dma_map_read(struct file *file, char __user *ubuf,
|
|
|
|
|
|
|
|
|
|
buflen = strlen(buf);
|
|
|
|
|
if (copy_to_user(ubuf, buf, buflen)) {
|
|
|
|
|
pr_err("Couldn't copy_to_user\n");
|
|
|
|
|
pr_err_ratelimited("Couldn't copy_to_user\n");
|
|
|
|
|
retval = -EFAULT;
|
|
|
|
|
} else {
|
|
|
|
|
*offset = 1; /* non-zero means we're done */
|
|
|
|
|
@@ -1916,19 +1918,19 @@ static ssize_t iommu_debug_unmap_write(struct file *file,
|
|
|
|
|
struct iommu_debug_device *ddev = file->private_data;
|
|
|
|
|
|
|
|
|
|
if (count >= 100) {
|
|
|
|
|
pr_err("Value too large\n");
|
|
|
|
|
pr_err_ratelimited("Value too large\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ddev->domain) {
|
|
|
|
|
pr_err("No domain. Did you already attach?\n");
|
|
|
|
|
pr_err_ratelimited("No domain. Did you already attach?\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(buf, 0, 100);
|
|
|
|
|
|
|
|
|
|
if (copy_from_user(buf, ubuf, count)) {
|
|
|
|
|
pr_err("Couldn't copy from user\n");
|
|
|
|
|
pr_err_ratelimited("Couldn't copy from user\n");
|
|
|
|
|
retval = -EFAULT;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
@@ -1948,27 +1950,27 @@ static ssize_t iommu_debug_unmap_write(struct file *file,
|
|
|
|
|
|
|
|
|
|
mutex_lock(&ddev->state_lock);
|
|
|
|
|
if (!ddev->domain) {
|
|
|
|
|
pr_err("No domain. Did you already attach?\n");
|
|
|
|
|
pr_err_ratelimited("No domain. Did you already attach?\n");
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unmapped = iommu_unmap(ddev->domain, iova, size);
|
|
|
|
|
if (unmapped != size) {
|
|
|
|
|
pr_err("iommu_unmap failed. Expected to unmap: 0x%zx, unmapped: 0x%zx",
|
|
|
|
|
pr_err_ratelimited("iommu_unmap failed. Expected to unmap: 0x%zx, unmapped: 0x%zx",
|
|
|
|
|
size, unmapped);
|
|
|
|
|
retval = -EIO;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
retval = count;
|
|
|
|
|
pr_err("Unmapped %pa (len=0x%zx)\n", &iova, size);
|
|
|
|
|
pr_err_ratelimited("Unmapped %pa (len=0x%zx)\n", &iova, size);
|
|
|
|
|
out:
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
|
|
invalid_format:
|
|
|
|
|
pr_err("Invalid format. Expected: iova,len\n");
|
|
|
|
|
pr_err_ratelimited("Invalid format. Expected: iova,len\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1992,14 +1994,14 @@ static ssize_t iommu_debug_dma_unmap_write(struct file *file,
|
|
|
|
|
struct device *dev = ddev->dev;
|
|
|
|
|
|
|
|
|
|
if (count >= sizeof(buf)) {
|
|
|
|
|
pr_err("Value too large\n");
|
|
|
|
|
pr_err_ratelimited("Value too large\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
|
|
|
|
|
|
if (copy_from_user(buf, ubuf, count)) {
|
|
|
|
|
pr_err("Couldn't copy from user\n");
|
|
|
|
|
pr_err_ratelimited("Couldn't copy from user\n");
|
|
|
|
|
retval = -EFAULT;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
@@ -2036,20 +2038,20 @@ static ssize_t iommu_debug_dma_unmap_write(struct file *file,
|
|
|
|
|
|
|
|
|
|
mutex_lock(&ddev->state_lock);
|
|
|
|
|
if (!ddev->domain) {
|
|
|
|
|
pr_err("No domain. Did you already attach?\n");
|
|
|
|
|
pr_err_ratelimited("No domain. Did you already attach?\n");
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
dma_unmap_single_attrs(dev, iova, size, DMA_TO_DEVICE, dma_attrs);
|
|
|
|
|
|
|
|
|
|
retval = count;
|
|
|
|
|
pr_err("Unmapped %pa (len=0x%zx)\n", &iova, size);
|
|
|
|
|
pr_err_ratelimited("Unmapped %pa (len=0x%zx)\n", &iova, size);
|
|
|
|
|
out:
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
|
|
invalid_format:
|
|
|
|
|
pr_err("Invalid format. Expected: iova,len, dma attr\n");
|
|
|
|
|
pr_err_ratelimited("Invalid format. Expected: iova,len, dma attr\n");
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2068,17 +2070,17 @@ static ssize_t iommu_debug_config_clocks_write(struct file *file,
|
|
|
|
|
|
|
|
|
|
/* we're expecting a single character plus (optionally) a newline */
|
|
|
|
|
if (count > 2) {
|
|
|
|
|
dev_err(dev, "Invalid value\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Invalid value\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ddev->domain) {
|
|
|
|
|
dev_err(dev, "No domain. Did you already attach?\n");
|
|
|
|
|
dev_err_ratelimited(dev, "No domain. Did you already attach?\n");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (copy_from_user(&buf, ubuf, 1)) {
|
|
|
|
|
dev_err(dev, "Couldn't copy from user\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Couldn't copy from user\n");
|
|
|
|
|
return -EFAULT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2086,26 +2088,26 @@ static ssize_t iommu_debug_config_clocks_write(struct file *file,
|
|
|
|
|
switch (buf) {
|
|
|
|
|
case '0':
|
|
|
|
|
if (ddev->clk_count == 0) {
|
|
|
|
|
dev_err(dev, "Config clocks already disabled\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Config clocks already disabled\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (--ddev->clk_count > 0)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
dev_err(dev, "Disabling config clocks\n");
|
|
|
|
|
dev_err_ratelimited(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");
|
|
|
|
|
dev_err_ratelimited(dev, "Enabling config clocks\n");
|
|
|
|
|
if (iommu_enable_config_clocks(ddev->domain))
|
|
|
|
|
dev_err(dev, "Failed!\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Failed!\n");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
dev_err(dev, "Invalid value. Should be 0 or 1.\n");
|
|
|
|
|
dev_err_ratelimited(dev, "Invalid value. Should be 0 or 1.\n");
|
|
|
|
|
mutex_unlock(&ddev->clk_lock);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
@@ -2127,13 +2129,13 @@ static ssize_t iommu_debug_trigger_fault_write(
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
|
|
if (kstrtoul_from_user(ubuf, count, 0, &flags)) {
|
|
|
|
|
pr_err("Invalid flags format\n");
|
|
|
|
|
pr_err_ratelimited("Invalid flags format\n");
|
|
|
|
|
return -EFAULT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mutex_lock(&ddev->state_lock);
|
|
|
|
|
if (!ddev->domain) {
|
|
|
|
|
pr_err("No domain. Did you already attach?\n");
|
|
|
|
|
pr_err_ratelimited("No domain. Did you already attach?\n");
|
|
|
|
|
mutex_unlock(&ddev->state_lock);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
@@ -2177,147 +2179,147 @@ static int snarf_iommu_devices(struct device *dev, void *ignored)
|
|
|
|
|
ddev->dev = dev;
|
|
|
|
|
dir = debugfs_create_dir(dev_name(dev), debugfs_tests_dir);
|
|
|
|
|
if (!dir) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s debugfs dir\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s debugfs dir\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("nr_iters", 0400, dir, &iters_per_op,
|
|
|
|
|
&iommu_debug_nr_iters_ops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/nr_iters debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/nr_iters debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("test_virt_addr", 0400, dir, ddev,
|
|
|
|
|
&iommu_debug_test_virt_addr_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/test_virt_addr debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/test_virt_addr debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("profiling", 0400, dir, ddev,
|
|
|
|
|
&iommu_debug_profiling_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/profiling debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/profiling debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("secure_profiling", 0400, dir, ddev,
|
|
|
|
|
&iommu_debug_secure_profiling_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/secure_profiling debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/secure_profiling debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("profiling_fast", 0400, dir, ddev,
|
|
|
|
|
&iommu_debug_profiling_fast_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/profiling_fast debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/profiling_fast debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("profiling_fast_dma_api", 0400, dir, ddev,
|
|
|
|
|
&iommu_debug_profiling_fast_dma_api_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/profiling_fast_dma_api debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/profiling_fast_dma_api debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("functional_fast_dma_api", 0400, dir, ddev,
|
|
|
|
|
&iommu_debug_functional_fast_dma_api_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/functional_fast_dma_api debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/functional_fast_dma_api debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("functional_arm_dma_api", 0400, dir, ddev,
|
|
|
|
|
&iommu_debug_functional_arm_dma_api_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/functional_arm_dma_api debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/functional_arm_dma_api debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("dma_attach", 0600, dir, ddev,
|
|
|
|
|
&iommu_debug_dma_attach_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/dma_attach debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/dma_attach debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("attach", 0400, dir, ddev,
|
|
|
|
|
&iommu_debug_attach_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/attach debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/attach debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("secure_attach", 0400, dir, ddev,
|
|
|
|
|
&iommu_debug_secure_attach_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/secure_attach debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/secure_attach debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("atos", 0200, dir, ddev,
|
|
|
|
|
&iommu_debug_atos_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/atos debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/atos debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("dma_atos", 0600, dir, ddev,
|
|
|
|
|
&iommu_debug_dma_atos_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/dma_atos debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/dma_atos debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("map", 0200, dir, ddev,
|
|
|
|
|
&iommu_debug_map_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/map debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/map debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("dma_map", 0600, dir, ddev,
|
|
|
|
|
&iommu_debug_dma_map_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/dma_map debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/dma_map debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("unmap", 0200, dir, ddev,
|
|
|
|
|
&iommu_debug_unmap_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/unmap debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/unmap debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("dma_unmap", 0200, dir, ddev,
|
|
|
|
|
&iommu_debug_dma_unmap_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/dma_unmap debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/dma_unmap debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("pte", 0600, dir, ddev,
|
|
|
|
|
&iommu_debug_pte_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/pte debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/pte debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("config_clocks", 0200, dir, ddev,
|
|
|
|
|
&iommu_debug_config_clocks_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/config_clocks debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/config_clocks debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!debugfs_create_file("trigger-fault", 0200, dir, ddev,
|
|
|
|
|
&iommu_debug_trigger_fault_fops)) {
|
|
|
|
|
pr_err("Couldn't create iommu/devices/%s/trigger-fault debugfs file\n",
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/devices/%s/trigger-fault debugfs file\n",
|
|
|
|
|
dev_name(dev));
|
|
|
|
|
goto err_rmdir;
|
|
|
|
|
}
|
|
|
|
|
@@ -2337,7 +2339,7 @@ static int iommu_debug_init_tests(void)
|
|
|
|
|
debugfs_tests_dir = debugfs_create_dir("tests",
|
|
|
|
|
iommu_debugfs_top);
|
|
|
|
|
if (!debugfs_tests_dir) {
|
|
|
|
|
pr_err("Couldn't create iommu/tests debugfs directory\n");
|
|
|
|
|
pr_err_ratelimited("Couldn't create iommu/tests debugfs directory\n");
|
|
|
|
|
return -ENODEV;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|