From: Joerg Roedel jroedel@suse.de
mainline inclusion from mainline-v4.20-rc1 commit 6954cf9bfda153f9544c63761aabf0199710aec3 category:bugfix bugzilla:NA CVE:NA
-------------------
Remove the iommu_ prefix from the function and a few other static data structures so that the iommu_release_device name can be re-used in iommu core code.
Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Chen Jun chenjun102@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/iommu/iommu-sysfs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/iommu/iommu-sysfs.c b/drivers/iommu/iommu-sysfs.c index 36d1a7ce7fc4..71c2249d3260 100644 --- a/drivers/iommu/iommu-sysfs.c +++ b/drivers/iommu/iommu-sysfs.c @@ -22,25 +22,25 @@ static struct attribute *devices_attr[] = { NULL, };
-static const struct attribute_group iommu_devices_attr_group = { +static const struct attribute_group devices_attr_group = { .name = "devices", .attrs = devices_attr, };
-static const struct attribute_group *iommu_dev_groups[] = { - &iommu_devices_attr_group, +static const struct attribute_group *dev_groups[] = { + &devices_attr_group, NULL, };
-static void iommu_release_device(struct device *dev) +static void release_device(struct device *dev) { kfree(dev); }
static struct class iommu_class = { .name = "iommu", - .dev_release = iommu_release_device, - .dev_groups = iommu_dev_groups, + .dev_release = release_device, + .dev_groups = dev_groups, };
static int __init iommu_dev_init(void)
From: Joerg Roedel jroedel@suse.de
mainline inclusion from mainline-v4.20-rc1 commit cc5aed44a3a8e4fca721636cf881a52f8d68a098 category:feature bugzilla:NA CVE:NA
-------------------
Put them into separate functions and call those where the plain ops have been called before.
Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Chen Jun chenjun102@huawei.com
Conflicts: include/linux/iommu.h Reviewed-by: Hanjun Guo guohanjun@huawei.com
Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/iommu/iommu.c | 51 +++++++++++++++++++++---------------------- include/linux/iommu.h | 3 +++ 2 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index cde37ab00760..0f420fc6fc29 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -112,6 +112,23 @@ void iommu_device_unregister(struct iommu_device *iommu) spin_unlock(&iommu_device_lock); }
+int iommu_probe_device(struct device *dev) +{ + const struct iommu_ops *ops = dev->bus->iommu_ops; + + WARN_ON(dev->iommu_group); + + return ops->add_device(dev); +} + +void iommu_release_device(struct device *dev) +{ + const struct iommu_ops *ops = dev->bus->iommu_ops; + + if (dev->iommu_group) + ops->remove_device(dev); +} + static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, unsigned type); static int __iommu_attach_device(struct iommu_domain *domain, @@ -1341,16 +1358,7 @@ struct iommu_domain *iommu_group_default_domain(struct iommu_group *group)
static int add_iommu_group(struct device *dev, void *data) { - struct iommu_callback_data *cb = data; - const struct iommu_ops *ops = cb->ops; - int ret; - - if (!ops->add_device) - return 0; - - WARN_ON(dev->iommu_group); - - ret = ops->add_device(dev); + int ret = iommu_probe_device(dev);
/* * We ignore -ENODEV errors for now, as they just mean that the @@ -1365,11 +1373,7 @@ static int add_iommu_group(struct device *dev, void *data)
static int remove_iommu_group(struct device *dev, void *data) { - struct iommu_callback_data *cb = data; - const struct iommu_ops *ops = cb->ops; - - if (ops->remove_device && dev->iommu_group) - ops->remove_device(dev); + iommu_release_device(dev);
return 0; } @@ -1377,27 +1381,22 @@ static int remove_iommu_group(struct device *dev, void *data) static int iommu_bus_notifier(struct notifier_block *nb, unsigned long action, void *data) { + unsigned long group_action = 0; struct device *dev = data; - const struct iommu_ops *ops = dev->bus->iommu_ops; struct iommu_group *group; - unsigned long group_action = 0;
/* * ADD/DEL call into iommu driver ops if provided, which may * result in ADD/DEL notifiers to group->notifier */ if (action == BUS_NOTIFY_ADD_DEVICE) { - if (ops->add_device) { - int ret; + int ret;
- ret = ops->add_device(dev); - return (ret) ? NOTIFY_DONE : NOTIFY_OK; - } + ret = iommu_probe_device(dev); + return (ret) ? NOTIFY_DONE : NOTIFY_OK; } else if (action == BUS_NOTIFY_REMOVED_DEVICE) { - if (ops->remove_device && dev->iommu_group) { - ops->remove_device(dev); - return 0; - } + iommu_release_device(dev); + return NOTIFY_OK; }
/* diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 916d95fd0344..4907aae83b84 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -682,6 +682,9 @@ static inline void dev_iommu_fwspec_set(struct device *dev, dev->iommu_fwspec = fwspec; }
+int iommu_probe_device(struct device *dev); +void iommu_release_device(struct device *dev); + extern int iommu_sva_bind_device(struct device *dev, struct mm_struct *mm, int *pasid, unsigned long flags, void *drvdata); extern int iommu_sva_unbind_device(struct device *dev, int pasid);
From: Joerg Roedel jroedel@suse.de
mainline inclusion from mainline-v4.20-rc1 commit 641fb0efbff063ed57f108c2eb4a4d26dbd5badd category:bugfix bugzilla:NA CVE:NA
-------------------
Make sure to invoke this call-back through the proper function of the IOMMU-API.
Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Chen Jun chenjun102@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/iommu/of_iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 8ca2f0ed2525..0d55a9594db1 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -216,10 +216,10 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, } /* * If we have reason to believe the IOMMU driver missed the initial - * add_device callback for dev, replay it to get things in order. + * probe for dev, replay it to get things in order. */ - if (ops && ops->add_device && dev->bus && !device_iommu_mapped(dev)) - err = ops->add_device(dev); + if (dev->bus && !device_iommu_mapped(dev)) + err = iommu_probe_device(dev);
/* Ignore all other errors apart from EPROBE_DEFER */ if (err == -EPROBE_DEFER) {
From: Robin Murphy robin.murphy@arm.com
mainline inclusion from mainline-v4.20-rc1 commit e8e683ae9a736407a20135df7809090a446db707 category:bugfix bugzilla:NA CVE:NA
-------------------
Whilst iommu_probe_device() does check for non-NULL ops as the previous code did, it does not do so in the same order relative to the other checks, and as a result means that -EPROBE_DEFER returned by of_xlate() (plus any real error condition too) gets overwritten with -EINVAL and leads to various misbehaviour.
Reinstate the original logic, but without implicitly relying on ops being set to infer !err as the initial condition (now that the validity of ops for its own sake is checked elsewhere).
Fixes: 641fb0efbff0 ("iommu/of: Don't call iommu_ops->add_device directly") Signed-off-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Chen Jun chenjun102@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/iommu/of_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 0d55a9594db1..dc0c69776863 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -218,7 +218,7 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, * If we have reason to believe the IOMMU driver missed the initial * probe for dev, replay it to get things in order. */ - if (dev->bus && !device_iommu_mapped(dev)) + if (!err && dev->bus && !device_iommu_mapped(dev)) err = iommu_probe_device(dev);
/* Ignore all other errors apart from EPROBE_DEFER */
From: Joerg Roedel jroedel@suse.de
mainline inclusion from mainline-v4.20-rc1 commit dc9de8a2b20f495696330d60a289935f36407995 category:bugfix bugzilla:NA CVE:NA
-------------------
This check needs to be there and got lost at some point during development. Add it again.
Fixes: 641fb0efbff0 ('iommu/of: Don't call iommu_ops->add_device directly') Reported-by: Marek Szyprowski m.szyprowski@samsung.com Reported-by: kernelci.org bot bot@kernelci.org Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Chen Jun chenjun102@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/iommu/iommu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 0f420fc6fc29..a5a27ba0048b 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -115,10 +115,14 @@ void iommu_device_unregister(struct iommu_device *iommu) int iommu_probe_device(struct device *dev) { const struct iommu_ops *ops = dev->bus->iommu_ops; + int ret = -EINVAL;
WARN_ON(dev->iommu_group);
- return ops->add_device(dev); + if (ops) + ret = ops->add_device(dev); + + return ret; }
void iommu_release_device(struct device *dev)
From: Joerg Roedel jroedel@suse.de
mainline inclusion from mainline-v4.20-rc1 commit d2e1a003af569e912d5f115a3c20b89a19f5caa0 category:bugfix bugzilla:NA CVE:NA
-------------------
Make sure to invoke this call-back through the proper function of the IOMMU-API.
Acked-by: Hanjun Guo hanjun.guo@linaro.org Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Chen Jun chenjun102@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/acpi/arm64/iort.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 9abb86c7044a..cd9becf65a8f 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -810,8 +810,8 @@ static inline int iort_add_device_replay(const struct iommu_ops *ops, { int err = 0;
- if (ops->add_device && dev->bus && !device_iommu_mapped(dev)) - err = ops->add_device(dev); + if (dev->bus && !device_iommu_mapped(dev)) + err = iommu_probe_device(dev);
return err; }
From: Zenghui Yu yuzenghui@huawei.com
mainline inclusion from mainline-v5.10-rc1 commit 1ab64cf81489e871bcb94fb2dea35c7fac561fff category:bugfix bugzilla:NA CVE:NA
-------------------
Since commit d2e1a003af56 ("ACPI/IORT: Don't call iommu_ops->add_device directly"), we use the IOMMU core API to replace a direct invoke of the specified callback. The parameter @ops has therefore became unused. Let's drop it.
Signed-off-by: Zenghui Yu yuzenghui@huawei.com Acked-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Acked-by: Hanjun Guo guohanjun@huawei.com Link: https://lore.kernel.org/r/20200818063625.980-2-yuzenghui@huawei.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Chen Jun chenjun102@huawei.com
Conflicts: drivers/acpi/arm64/iort.c Reviewed-by: Hanjun Guo guohanjun@huawei.com
Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/acpi/arm64/iort.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index cd9becf65a8f..ed9be22a6913 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -805,8 +805,7 @@ static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev) return (fwspec && fwspec->ops) ? fwspec->ops : NULL; }
-static inline int iort_add_device_replay(const struct iommu_ops *ops, - struct device *dev) +static inline int iort_add_device_replay(struct device *dev) { int err = 0;
@@ -882,8 +881,7 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) #else static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev) { return NULL; } -static inline int iort_add_device_replay(const struct iommu_ops *ops, - struct device *dev) +static inline int iort_add_device_replay(struct device *dev) { return 0; } int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) { return 0; } @@ -1120,7 +1118,7 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev) */ if (!err) { ops = iort_fwspec_iommu_ops(dev); - err = iort_add_device_replay(ops, dev); + err = iort_add_device_replay(dev); }
/* Ignore all other errors apart from EPROBE_DEFER */