summaryrefslogtreecommitdiff
path: root/drivers/iommu/iommu-debug.c
diff options
context:
space:
mode:
authorMitchel Humpherys <mitchelh@codeaurora.org>2015-07-30 19:40:21 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:13:45 -0700
commit6f964907135cb60421ba48fafceb2d2c9d6cc995 (patch)
tree453c480b057268d49eb5559bc363b98d61016a9d /drivers/iommu/iommu-debug.c
parent75cd28f90d05320e7bebb1c67b8a514618898a6d (diff)
iommu/iommu-debug: Add secure_attach debugfs file
It can be useful to perform tests on secure domains. Add support for this with a "secure_attach" file that will also set the DOMAIN_ATTR_SECURE_VMID to the value written to the file. Example usage: # cd /sys/kernel/debug/iommu/tests/<device> # echo 0xA > secure_attach # echo 0x1000,0x1000,0x1000,1 > map # echo 0x1000,0x1000 > unmap # echo 0 > secure_attach Change-Id: I0181e360f3e98e0e47a3af8c6adb71c9c4a3c9b5 Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
Diffstat (limited to 'drivers/iommu/iommu-debug.c')
-rw-r--r--drivers/iommu/iommu-debug.c70
1 files changed, 50 insertions, 20 deletions
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 3aef661c3340..aaa79c028a0b 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -433,7 +433,8 @@ static const struct file_operations iommu_debug_profiling_fops = {
.release = single_release,
};
-static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev)
+static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev,
+ int val, bool is_secure)
{
int htw_disable = 1;
@@ -450,6 +451,13 @@ static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev)
goto out_domain_free;
}
+ if (is_secure && iommu_domain_set_attr(ddev->domain,
+ DOMAIN_ATTR_SECURE_VMID,
+ &val)) {
+ pr_err("Couldn't set secure vmid to %d\n", val);
+ goto out_domain_free;
+ }
+
if (iommu_attach_device(ddev->domain, ddev->dev)) {
pr_err("Couldn't attach new domain to device. Is it already attached?\n");
goto out_domain_free;
@@ -463,27 +471,22 @@ out_domain_free:
return -EIO;
}
-static ssize_t iommu_debug_attach_write(struct file *file,
- const char __user *ubuf,
- size_t count, loff_t *offset)
+static ssize_t __iommu_debug_attach_write(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *offset,
+ bool is_secure)
{
struct iommu_debug_device *ddev = file->private_data;
ssize_t retval;
- char val;
-
- if (count > 2) {
- pr_err("Invalid value. Expected 0 or 1.\n");
- retval = -EINVAL;
- goto out;
- }
+ int val;
- if (copy_from_user(&val, ubuf, 1)) {
- pr_err("Couldn't copy from user\n");
+ if (kstrtoint_from_user(ubuf, count, 0, &val)) {
+ pr_err("Invalid format. Expected a hex or decimal integer");
retval = -EFAULT;
goto out;
}
- if (val == '1') {
+ if (val) {
if (ddev->domain) {
pr_err("Already attached.\n");
retval = -EINVAL;
@@ -494,12 +497,12 @@ static ssize_t iommu_debug_attach_write(struct file *file,
retval = -EINVAL;
goto out;
}
- if (iommu_debug_attach_do_attach(ddev)) {
+ if (iommu_debug_attach_do_attach(ddev, val, is_secure)) {
retval = -EIO;
goto out;
}
pr_err("Attached\n");
- } else if (val == '0') {
+ } else {
if (!ddev->domain) {
pr_err("No domain. Did you already attach?\n");
retval = -EINVAL;
@@ -509,10 +512,6 @@ static ssize_t iommu_debug_attach_write(struct file *file,
iommu_domain_free(ddev->domain);
ddev->domain = NULL;
pr_err("Detached\n");
- } else {
- pr_err("Invalid value. Expected 0 or 1\n");
- retval = -EFAULT;
- goto out;
}
retval = count;
@@ -520,6 +519,15 @@ out:
return retval;
}
+static ssize_t iommu_debug_attach_write(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *offset)
+{
+ return __iommu_debug_attach_write(file, ubuf, count, offset,
+ false);
+
+}
+
static ssize_t iommu_debug_attach_read(struct file *file, char __user *ubuf,
size_t count, loff_t *offset)
{
@@ -546,6 +554,21 @@ static const struct file_operations iommu_debug_attach_fops = {
.read = iommu_debug_attach_read,
};
+static ssize_t iommu_debug_attach_write_secure(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *offset)
+{
+ return __iommu_debug_attach_write(file, ubuf, count, offset,
+ true);
+
+}
+
+static const struct file_operations iommu_debug_secure_attach_fops = {
+ .open = simple_open,
+ .write = iommu_debug_attach_write_secure,
+ .read = iommu_debug_attach_read,
+};
+
static ssize_t iommu_debug_atos_write(struct file *file,
const char __user *ubuf,
size_t count, loff_t *offset)
@@ -790,6 +813,13 @@ static int snarf_iommu_devices(struct device *dev, void *ignored)
goto err_rmdir;
}
+ if (!debugfs_create_file("secure_attach", S_IRUSR, dir, ddev,
+ &iommu_debug_secure_attach_fops)) {
+ pr_err("Couldn't create iommu/devices/%s/secure_attach debugfs file\n",
+ dev_name(dev));
+ goto err_rmdir;
+ }
+
if (!debugfs_create_file("atos", S_IWUSR, dir, ddev,
&iommu_debug_atos_fops)) {
pr_err("Couldn't create iommu/devices/%s/atos debugfs file\n",