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>
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 0827a49..4ecfb79 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -475,7 +475,8 @@
.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)
{
ddev->domain = iommu_domain_alloc(&platform_bus_type);
if (!ddev->domain) {
@@ -483,6 +484,13 @@
return -ENOMEM;
}
+ 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;
@@ -496,27 +504,22 @@
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;
+ int val;
- if (count > 2) {
- pr_err("Invalid value. Expected 0 or 1.\n");
- retval = -EINVAL;
- goto out;
- }
-
- 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;
@@ -527,12 +530,12 @@
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;
@@ -542,10 +545,6 @@
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;
@@ -553,6 +552,15 @@
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)
{
@@ -579,6 +587,21 @@
.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)
@@ -823,6 +846,13 @@
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",