* [PATCH] iommu/core: fix bus notifier breakage
@ 2014-09-21 17:58 Mark Salter
2014-09-25 14:47 ` Joerg Roedel
0 siblings, 1 reply; 3+ messages in thread
From: Mark Salter @ 2014-09-21 17:58 UTC (permalink / raw)
To: Joerg Roedel; +Cc: iommu, linux-kernel, Suravee Suthikulpanit, Mark Salter
iommu_bus_init() registers a bus notifier on the given bus by using
a statically defined notifier block:
static struct notifier_block iommu_bus_nb = {
.notifier_call = iommu_bus_notifier,
};
This same notifier block is used for all busses. This causes a
problem for notifiers registered after iommu has registered this
callback on multiple busses. The problem is that a subsequent
notifier being registered on a bus which has this iommu notifier
will also get linked in to the notifier list of all other busses
which have this iommu notifier.
This patch fixes this by allocating the notifier_block at runtime.
Some error checking is also added to catch any allocation failure
or notifier registration error.
Signed-off-by: Mark Salter <msalter@redhat.com>
---
drivers/iommu/iommu.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 0639b92..f00697a 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -770,18 +770,26 @@ static int iommu_bus_notifier(struct notifier_block *nb,
return 0;
}
-static struct notifier_block iommu_bus_nb = {
- .notifier_call = iommu_bus_notifier,
-};
-
-static void iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
+static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
{
+ int err;
+ struct notifier_block *nb;
struct iommu_callback_data cb = {
.ops = ops,
};
- bus_register_notifier(bus, &iommu_bus_nb);
- bus_for_each_dev(bus, NULL, &cb, add_iommu_group);
+ nb = kzalloc(sizeof(struct notifier_block), GFP_KERNEL);
+ if (!nb)
+ return -ENOMEM;
+
+ nb->notifier_call = iommu_bus_notifier;
+
+ err = bus_register_notifier(bus, nb);
+ if (err) {
+ kfree(nb);
+ return err;
+ }
+ return bus_for_each_dev(bus, NULL, &cb, add_iommu_group);
}
/**
@@ -805,9 +813,7 @@ int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops)
bus->iommu_ops = ops;
/* Do IOMMU specific setup for this bus-type */
- iommu_bus_init(bus, ops);
-
- return 0;
+ return iommu_bus_init(bus, ops);
}
EXPORT_SYMBOL_GPL(bus_set_iommu);
--
1.9.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] iommu/core: fix bus notifier breakage
2014-09-21 17:58 [PATCH] iommu/core: fix bus notifier breakage Mark Salter
@ 2014-09-25 14:47 ` Joerg Roedel
2014-09-25 15:15 ` Mark Salter
0 siblings, 1 reply; 3+ messages in thread
From: Joerg Roedel @ 2014-09-25 14:47 UTC (permalink / raw)
To: Mark Salter; +Cc: iommu, linux-kernel, Suravee Suthikulpanit
On Sun, Sep 21, 2014 at 01:58:24PM -0400, Mark Salter wrote:
> iommu_bus_init() registers a bus notifier on the given bus by using
> a statically defined notifier block:
>
> static struct notifier_block iommu_bus_nb = {
> .notifier_call = iommu_bus_notifier,
> };
>
> This same notifier block is used for all busses. This causes a
> problem for notifiers registered after iommu has registered this
> callback on multiple busses. The problem is that a subsequent
> notifier being registered on a bus which has this iommu notifier
> will also get linked in to the notifier list of all other busses
> which have this iommu notifier.
>
> This patch fixes this by allocating the notifier_block at runtime.
> Some error checking is also added to catch any allocation failure
> or notifier registration error.
>
> Signed-off-by: Mark Salter <msalter@redhat.com>
> ---
> drivers/iommu/iommu.c | 26 ++++++++++++++++----------
> 1 file changed, 16 insertions(+), 10 deletions(-)
Makes sense, applied. Where have you hit this condition where IOMMUs for
different buses are registered?
Joerg
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] iommu/core: fix bus notifier breakage
2014-09-25 14:47 ` Joerg Roedel
@ 2014-09-25 15:15 ` Mark Salter
0 siblings, 0 replies; 3+ messages in thread
From: Mark Salter @ 2014-09-25 15:15 UTC (permalink / raw)
To: Joerg Roedel; +Cc: iommu, linux-kernel, Suravee Suthikulpanit
On Thu, 2014-09-25 at 16:47 +0200, Joerg Roedel wrote:
> On Sun, Sep 21, 2014 at 01:58:24PM -0400, Mark Salter wrote:
> > iommu_bus_init() registers a bus notifier on the given bus by using
> > a statically defined notifier block:
> >
> > static struct notifier_block iommu_bus_nb = {
> > .notifier_call = iommu_bus_notifier,
> > };
> >
> > This same notifier block is used for all busses. This causes a
> > problem for notifiers registered after iommu has registered this
> > callback on multiple busses. The problem is that a subsequent
> > notifier being registered on a bus which has this iommu notifier
> > will also get linked in to the notifier list of all other busses
> > which have this iommu notifier.
> >
> > This patch fixes this by allocating the notifier_block at runtime.
> > Some error checking is also added to catch any allocation failure
> > or notifier registration error.
> >
> > Signed-off-by: Mark Salter <msalter@redhat.com>
> > ---
> > drivers/iommu/iommu.c | 26 ++++++++++++++++----------
> > 1 file changed, 16 insertions(+), 10 deletions(-)
>
> Makes sense, applied. Where have you hit this condition where IOMMUs for
> different buses are registered?
arm_smmu_init()
/* Oh, for a proper bus abstraction */
if (!iommu_present(&platform_bus_type))
bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
#ifdef CONFIG_ARM_AMBA
if (!iommu_present(&amba_bustype))
bus_set_iommu(&amba_bustype, &arm_smmu_ops);
#endif
#ifdef CONFIG_PCI
if (!iommu_present(&pci_bus_type))
bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
#endif
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-09-25 15:15 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-21 17:58 [PATCH] iommu/core: fix bus notifier breakage Mark Salter
2014-09-25 14:47 ` Joerg Roedel
2014-09-25 15:15 ` Mark Salter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).