From d7da6bdc322bb79c4326dff7c2727236a48c4be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Wed, 29 Oct 2014 01:22:56 +0100 Subject: [PATCH] iommu: Improve error handling when setting bus iommu When some part of bus_set_iommu fails it should undo any made changes and not simply leave everything as is. This includes unregistering the bus notifier in iommu_bus_init when add_iommu_group fails and also setting the bus->iommu_ops back to NULL. Signed-off-by: Heiko Stuebner Signed-off-by: Joerg Roedel --- drivers/iommu/iommu.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 08c53c5a046f..02e4313e937c 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -818,7 +818,15 @@ static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops) kfree(nb); return err; } - return bus_for_each_dev(bus, NULL, &cb, add_iommu_group); + + err = bus_for_each_dev(bus, NULL, &cb, add_iommu_group); + if (err) { + bus_unregister_notifier(bus, nb); + kfree(nb); + return err; + } + + return 0; } /** @@ -836,13 +844,19 @@ static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops) */ int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops) { + int err; + if (bus->iommu_ops != NULL) return -EBUSY; bus->iommu_ops = ops; /* Do IOMMU specific setup for this bus-type */ - return iommu_bus_init(bus, ops); + err = iommu_bus_init(bus, ops); + if (err) + bus->iommu_ops = NULL; + + return err; } EXPORT_SYMBOL_GPL(bus_set_iommu);