* [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes
@ 2020-11-11 22:21 Nicolin Chen
2020-11-11 22:21 ` [PATCH RESEND 1/5] iommu/tegra-smmu: Unwrap tegra_smmu_group_get Nicolin Chen
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: Nicolin Chen @ 2020-11-11 22:21 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-kernel, iommu, linux-tegra, jonathanh, vdumpa
This is a merged set of resend for previously two series of patches
that were reviewed/acked a month ago yet have not got applied.
Series-1: https://lkml.org/lkml/2020/9/29/73
"[PATCH v4 0/2] iommu/tegra-smmu: Two followup changes"
Series-2: https://lkml.org/lkml/2020/10/9/808
"[PATCH v7 0/3] iommu/tegra-smmu: Add PCI support"
Nicolin Chen (5):
iommu/tegra-smmu: Unwrap tegra_smmu_group_get
iommu/tegra-smmu: Expand mutex protection range
iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
iommu/tegra-smmu: Rework tegra_smmu_probe_device()
iommu/tegra-smmu: Add PCI support
drivers/iommu/tegra-smmu.c | 240 ++++++++++++++-----------------------
1 file changed, 88 insertions(+), 152 deletions(-)
--
2.17.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH RESEND 1/5] iommu/tegra-smmu: Unwrap tegra_smmu_group_get
2020-11-11 22:21 [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
@ 2020-11-11 22:21 ` Nicolin Chen
2020-11-11 22:21 ` [PATCH RESEND 2/5] iommu/tegra-smmu: Expand mutex protection range Nicolin Chen
` (4 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Nicolin Chen @ 2020-11-11 22:21 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-kernel, iommu, linux-tegra, jonathanh, vdumpa
The tegra_smmu_group_get was added to group devices in different
SWGROUPs and it'd return a NULL group pointer upon a mismatch at
tegra_smmu_find_group(), so for most of clients/devices, it very
likely would mismatch and need a fallback generic_device_group().
But now tegra_smmu_group_get handles devices in same SWGROUP too,
which means that it would allocate a group for every new SWGROUP
or would directly return an existing one upon matching a SWGROUP,
i.e. any device will go through this function.
So possibility of having a NULL group pointer in device_group()
is upon failure of either devm_kzalloc() or iommu_group_alloc().
In either case, calling generic_device_group() no longer makes a
sense. Especially for devm_kzalloc() failing case, it'd cause a
problem if it fails at devm_kzalloc() yet succeeds at a fallback
generic_device_group(), because it does not create a group->list
for other devices to match.
This patch simply unwraps the function to clean it up.
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
drivers/iommu/tegra-smmu.c | 19 ++++---------------
1 file changed, 4 insertions(+), 15 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 0becdbfea306..ec4c9dafff95 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -903,10 +903,12 @@ static void tegra_smmu_group_release(void *iommu_data)
mutex_unlock(&smmu->lock);
}
-static struct iommu_group *tegra_smmu_group_get(struct tegra_smmu *smmu,
- unsigned int swgroup)
+static struct iommu_group *tegra_smmu_device_group(struct device *dev)
{
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+ struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
const struct tegra_smmu_group_soc *soc;
+ unsigned int swgroup = fwspec->ids[0];
struct tegra_smmu_group *group;
struct iommu_group *grp;
@@ -950,19 +952,6 @@ static struct iommu_group *tegra_smmu_group_get(struct tegra_smmu *smmu,
return group->group;
}
-static struct iommu_group *tegra_smmu_device_group(struct device *dev)
-{
- struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
- struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
- struct iommu_group *group;
-
- group = tegra_smmu_group_get(smmu, fwspec->ids[0]);
- if (!group)
- group = generic_device_group(dev);
-
- return group;
-}
-
static int tegra_smmu_of_xlate(struct device *dev,
struct of_phandle_args *args)
{
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH RESEND 2/5] iommu/tegra-smmu: Expand mutex protection range
2020-11-11 22:21 [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
2020-11-11 22:21 ` [PATCH RESEND 1/5] iommu/tegra-smmu: Unwrap tegra_smmu_group_get Nicolin Chen
@ 2020-11-11 22:21 ` Nicolin Chen
2020-11-11 22:21 ` [PATCH RESEND 3/5] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev Nicolin Chen
` (3 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Nicolin Chen @ 2020-11-11 22:21 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-kernel, iommu, linux-tegra, jonathanh, vdumpa
This is used to protect potential race condition at use_count.
since probes of client drivers, calling attach_dev(), may run
concurrently.
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
drivers/iommu/tegra-smmu.c | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index ec4c9dafff95..6a3ecc334481 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -256,26 +256,19 @@ static int tegra_smmu_alloc_asid(struct tegra_smmu *smmu, unsigned int *idp)
{
unsigned long id;
- mutex_lock(&smmu->lock);
-
id = find_first_zero_bit(smmu->asids, smmu->soc->num_asids);
- if (id >= smmu->soc->num_asids) {
- mutex_unlock(&smmu->lock);
+ if (id >= smmu->soc->num_asids)
return -ENOSPC;
- }
set_bit(id, smmu->asids);
*idp = id;
- mutex_unlock(&smmu->lock);
return 0;
}
static void tegra_smmu_free_asid(struct tegra_smmu *smmu, unsigned int id)
{
- mutex_lock(&smmu->lock);
clear_bit(id, smmu->asids);
- mutex_unlock(&smmu->lock);
}
static bool tegra_smmu_capable(enum iommu_cap cap)
@@ -420,17 +413,21 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
struct tegra_smmu_as *as)
{
u32 value;
- int err;
+ int err = 0;
+
+ mutex_lock(&smmu->lock);
if (as->use_count > 0) {
as->use_count++;
- return 0;
+ goto unlock;
}
as->pd_dma = dma_map_page(smmu->dev, as->pd, 0, SMMU_SIZE_PD,
DMA_TO_DEVICE);
- if (dma_mapping_error(smmu->dev, as->pd_dma))
- return -ENOMEM;
+ if (dma_mapping_error(smmu->dev, as->pd_dma)) {
+ err = -ENOMEM;
+ goto unlock;
+ }
/* We can't handle 64-bit DMA addresses */
if (!smmu_dma_addr_valid(smmu, as->pd_dma)) {
@@ -453,24 +450,35 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu,
as->smmu = smmu;
as->use_count++;
+ mutex_unlock(&smmu->lock);
+
return 0;
err_unmap:
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
+unlock:
+ mutex_unlock(&smmu->lock);
+
return err;
}
static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu,
struct tegra_smmu_as *as)
{
- if (--as->use_count > 0)
+ mutex_lock(&smmu->lock);
+
+ if (--as->use_count > 0) {
+ mutex_unlock(&smmu->lock);
return;
+ }
tegra_smmu_free_asid(smmu, as->id);
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
as->smmu = NULL;
+
+ mutex_unlock(&smmu->lock);
}
static int tegra_smmu_attach_dev(struct iommu_domain *domain,
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH RESEND 3/5] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
2020-11-11 22:21 [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
2020-11-11 22:21 ` [PATCH RESEND 1/5] iommu/tegra-smmu: Unwrap tegra_smmu_group_get Nicolin Chen
2020-11-11 22:21 ` [PATCH RESEND 2/5] iommu/tegra-smmu: Expand mutex protection range Nicolin Chen
@ 2020-11-11 22:21 ` Nicolin Chen
2020-11-20 16:23 ` Thierry Reding
2020-11-11 22:21 ` [PATCH RESEND 4/5] iommu/tegra-smmu: Rework tegra_smmu_probe_device() Nicolin Chen
` (2 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2020-11-11 22:21 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-kernel, iommu, linux-tegra, jonathanh, vdumpa
In tegra_smmu_(de)attach_dev() functions, we poll DTB for each
client's iommus property to get swgroup ID in order to prepare
"as" and enable smmu. Actually tegra_smmu_configure() prepared
an fwspec for each client, and added to the fwspec all swgroup
IDs of client DT node in DTB.
So this patch uses fwspec in tegra_smmu_(de)attach_dev() so as
to replace the redundant DT polling code.
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
drivers/iommu/tegra-smmu.c | 56 ++++++++++++++++----------------------
1 file changed, 23 insertions(+), 33 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 6a3ecc334481..297d49f3f80e 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -484,60 +484,50 @@ static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu,
static int tegra_smmu_attach_dev(struct iommu_domain *domain,
struct device *dev)
{
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
struct tegra_smmu_as *as = to_smmu_as(domain);
- struct device_node *np = dev->of_node;
- struct of_phandle_args args;
- unsigned int index = 0;
- int err = 0;
-
- while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index,
- &args)) {
- unsigned int swgroup = args.args[0];
-
- if (args.np != smmu->dev->of_node) {
- of_node_put(args.np);
- continue;
- }
+ unsigned int index;
+ int err;
- of_node_put(args.np);
+ if (!fwspec)
+ return -ENOENT;
+ for (index = 0; index < fwspec->num_ids; index++) {
err = tegra_smmu_as_prepare(smmu, as);
- if (err < 0)
- return err;
+ if (err)
+ goto disable;
- tegra_smmu_enable(smmu, swgroup, as->id);
- index++;
+ tegra_smmu_enable(smmu, fwspec->ids[index], as->id);
}
if (index == 0)
return -ENODEV;
return 0;
+
+disable:
+ while (index--) {
+ tegra_smmu_disable(smmu, fwspec->ids[index], as->id);
+ tegra_smmu_as_unprepare(smmu, as);
+ }
+
+ return err;
}
static void tegra_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)
{
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
struct tegra_smmu_as *as = to_smmu_as(domain);
- struct device_node *np = dev->of_node;
struct tegra_smmu *smmu = as->smmu;
- struct of_phandle_args args;
- unsigned int index = 0;
-
- while (!of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index,
- &args)) {
- unsigned int swgroup = args.args[0];
+ unsigned int index;
- if (args.np != smmu->dev->of_node) {
- of_node_put(args.np);
- continue;
- }
-
- of_node_put(args.np);
+ if (!fwspec)
+ return;
- tegra_smmu_disable(smmu, swgroup, as->id);
+ for (index = 0; index < fwspec->num_ids; index++) {
+ tegra_smmu_disable(smmu, fwspec->ids[index], as->id);
tegra_smmu_as_unprepare(smmu, as);
- index++;
}
}
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH RESEND 4/5] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
2020-11-11 22:21 [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
` (2 preceding siblings ...)
2020-11-11 22:21 ` [PATCH RESEND 3/5] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev Nicolin Chen
@ 2020-11-11 22:21 ` Nicolin Chen
2020-11-20 16:25 ` Thierry Reding
2020-11-11 22:21 ` [PATCH RESEND 5/5] iommu/tegra-smmu: Add PCI support Nicolin Chen
2020-11-24 21:21 ` [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
5 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2020-11-11 22:21 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-kernel, iommu, linux-tegra, jonathanh, vdumpa
The bus_set_iommu() in tegra_smmu_probe() enumerates all clients
to call in tegra_smmu_probe_device() where each client searches
its DT node for smmu pointer and swgroup ID, so as to configure
an fwspec. But this requires a valid smmu pointer even before mc
and smmu drivers are probed. So in tegra_smmu_probe() we added a
line of code to fill mc->smmu, marking "a bit of a hack".
This works for most of clients in the DTB, however, doesn't work
for a client that doesn't exist in DTB, a PCI device for example.
Actually, if we return ERR_PTR(-ENODEV) in ->probe_device() when
it's called from bus_set_iommu(), iommu core will let everything
carry on. Then when a client gets probed, of_iommu_configure() in
iommu core will search DTB for swgroup ID and call ->of_xlate()
to prepare an fwspec, similar to tegra_smmu_probe_device() and
tegra_smmu_configure(). Then it'll call tegra_smmu_probe_device()
again, and this time we shall return smmu->iommu pointer properly.
So we can get rid of tegra_smmu_find() and tegra_smmu_configure()
along with DT polling code by letting the iommu core handle every
thing, except a problem that we search iommus property in DTB not
only for swgroup ID but also for mc node to get mc->smmu pointer
to call dev_iommu_priv_set() and return the smmu->iommu pointer.
So we'll need to find another way to get smmu pointer.
Referencing the implementation of sun50i-iommu driver, of_xlate()
has client's dev pointer, mc node and swgroup ID. This means that
we can call dev_iommu_priv_set() in of_xlate() instead, so we can
simply get smmu pointer in ->probe_device().
This patch reworks tegra_smmu_probe_device() by:
1) Removing mc->smmu hack in tegra_smmu_probe() so as to return
ERR_PTR(-ENODEV) in tegra_smmu_probe_device() during stage of
tegra_smmu_probe/tegra_mc_probe().
2) Moving dev_iommu_priv_set() to of_xlate() so we can get smmu
pointer in tegra_smmu_probe_device() to replace DTB polling.
3) Removing tegra_smmu_configure() accordingly since iommu core
takes care of it.
This also fixes a problem that previously we could add clients to
iommu groups before iommu core initializes its default domain:
ubuntu@jetson:~$ dmesg | grep iommu
platform 50000000.host1x: Adding to iommu group 1
platform 57000000.gpu: Adding to iommu group 2
iommu: Default domain type: Translated
platform 54200000.dc: Adding to iommu group 3
platform 54240000.dc: Adding to iommu group 3
platform 54340000.vic: Adding to iommu group 4
Though it works fine with IOMMU_DOMAIN_UNMANAGED, but will have
warnings if switching to IOMMU_DOMAIN_DMA:
iommu: Failed to allocate default IOMMU domain of type 0 for
group (null) - Falling back to IOMMU_DOMAIN_DMA
iommu: Failed to allocate default IOMMU domain of type 0 for
group (null) - Falling back to IOMMU_DOMAIN_DMA
Now, bypassing the first probe_device() call from bus_set_iommu()
fixes the sequence:
ubuntu@jetson:~$ dmesg | grep iommu
iommu: Default domain type: Translated
tegra-host1x 50000000.host1x: Adding to iommu group 0
tegra-dc 54200000.dc: Adding to iommu group 1
tegra-dc 54240000.dc: Adding to iommu group 1
tegra-vic 54340000.vic: Adding to iommu group 2
nouveau 57000000.gpu: Adding to iommu group 3
Note that dmesg log above is testing with IOMMU_DOMAIN_UNMANAGED.
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
drivers/iommu/tegra-smmu.c | 96 ++++++--------------------------------
1 file changed, 15 insertions(+), 81 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 297d49f3f80e..f45ed43cf8db 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -797,75 +797,9 @@ static phys_addr_t tegra_smmu_iova_to_phys(struct iommu_domain *domain,
return SMMU_PFN_PHYS(pfn) + SMMU_OFFSET_IN_PAGE(iova);
}
-static struct tegra_smmu *tegra_smmu_find(struct device_node *np)
-{
- struct platform_device *pdev;
- struct tegra_mc *mc;
-
- pdev = of_find_device_by_node(np);
- if (!pdev)
- return NULL;
-
- mc = platform_get_drvdata(pdev);
- if (!mc)
- return NULL;
-
- return mc->smmu;
-}
-
-static int tegra_smmu_configure(struct tegra_smmu *smmu, struct device *dev,
- struct of_phandle_args *args)
-{
- const struct iommu_ops *ops = smmu->iommu.ops;
- int err;
-
- err = iommu_fwspec_init(dev, &dev->of_node->fwnode, ops);
- if (err < 0) {
- dev_err(dev, "failed to initialize fwspec: %d\n", err);
- return err;
- }
-
- err = ops->of_xlate(dev, args);
- if (err < 0) {
- dev_err(dev, "failed to parse SW group ID: %d\n", err);
- iommu_fwspec_free(dev);
- return err;
- }
-
- return 0;
-}
-
static struct iommu_device *tegra_smmu_probe_device(struct device *dev)
{
- struct device_node *np = dev->of_node;
- struct tegra_smmu *smmu = NULL;
- struct of_phandle_args args;
- unsigned int index = 0;
- int err;
-
- while (of_parse_phandle_with_args(np, "iommus", "#iommu-cells", index,
- &args) == 0) {
- smmu = tegra_smmu_find(args.np);
- if (smmu) {
- err = tegra_smmu_configure(smmu, dev, &args);
- of_node_put(args.np);
-
- if (err < 0)
- return ERR_PTR(err);
-
- /*
- * Only a single IOMMU master interface is currently
- * supported by the Linux kernel, so abort after the
- * first match.
- */
- dev_iommu_priv_set(dev, smmu);
-
- break;
- }
-
- of_node_put(args.np);
- index++;
- }
+ struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
if (!smmu)
return ERR_PTR(-ENODEV);
@@ -873,10 +807,7 @@ static struct iommu_device *tegra_smmu_probe_device(struct device *dev)
return &smmu->iommu;
}
-static void tegra_smmu_release_device(struct device *dev)
-{
- dev_iommu_priv_set(dev, NULL);
-}
+static void tegra_smmu_release_device(struct device *dev) {}
static const struct tegra_smmu_group_soc *
tegra_smmu_find_group(struct tegra_smmu *smmu, unsigned int swgroup)
@@ -953,8 +884,21 @@ static struct iommu_group *tegra_smmu_device_group(struct device *dev)
static int tegra_smmu_of_xlate(struct device *dev,
struct of_phandle_args *args)
{
+ struct platform_device *iommu_pdev = of_find_device_by_node(args->np);
+ struct tegra_mc *mc = platform_get_drvdata(iommu_pdev);
u32 id = args->args[0];
+ /*
+ * Note: we are here releasing the reference of &iommu_pdev->dev, which
+ * is mc->dev. Although some functions in tegra_smmu_ops may keep using
+ * its private data beyond this point, it's still safe to do so because
+ * the SMMU parent device is the same as the MC, so the reference count
+ * isn't strictly necessary.
+ */
+ put_device(&iommu_pdev->dev);
+
+ dev_iommu_priv_set(dev, mc->smmu);
+
return iommu_fwspec_add_ids(dev, &id, 1);
}
@@ -1079,16 +1023,6 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
if (!smmu)
return ERR_PTR(-ENOMEM);
- /*
- * This is a bit of a hack. Ideally we'd want to simply return this
- * value. However the IOMMU registration process will attempt to add
- * all devices to the IOMMU when bus_set_iommu() is called. In order
- * not to rely on global variables to track the IOMMU instance, we
- * set it here so that it can be looked up from the .probe_device()
- * callback via the IOMMU device's .drvdata field.
- */
- mc->smmu = smmu;
-
size = BITS_TO_LONGS(soc->num_asids) * sizeof(long);
smmu->asids = devm_kzalloc(dev, size, GFP_KERNEL);
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH RESEND 5/5] iommu/tegra-smmu: Add PCI support
2020-11-11 22:21 [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
` (3 preceding siblings ...)
2020-11-11 22:21 ` [PATCH RESEND 4/5] iommu/tegra-smmu: Rework tegra_smmu_probe_device() Nicolin Chen
@ 2020-11-11 22:21 ` Nicolin Chen
2020-11-20 16:26 ` Thierry Reding
2020-11-24 21:21 ` [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
5 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2020-11-11 22:21 UTC (permalink / raw)
To: thierry.reding, joro; +Cc: linux-kernel, iommu, linux-tegra, jonathanh, vdumpa
This patch simply adds support for PCI devices.
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Tested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
drivers/iommu/tegra-smmu.c | 35 +++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index f45ed43cf8db..4a3f095a1c26 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
@@ -865,7 +866,11 @@ static struct iommu_group *tegra_smmu_device_group(struct device *dev)
group->smmu = smmu;
group->soc = soc;
- group->group = iommu_group_alloc();
+ if (dev_is_pci(dev))
+ group->group = pci_device_group(dev);
+ else
+ group->group = generic_device_group(dev);
+
if (IS_ERR(group->group)) {
devm_kfree(smmu->dev, group);
mutex_unlock(&smmu->lock);
@@ -1075,22 +1080,32 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
iommu_device_set_fwnode(&smmu->iommu, dev->fwnode);
err = iommu_device_register(&smmu->iommu);
- if (err) {
- iommu_device_sysfs_remove(&smmu->iommu);
- return ERR_PTR(err);
- }
+ if (err)
+ goto remove_sysfs;
err = bus_set_iommu(&platform_bus_type, &tegra_smmu_ops);
- if (err < 0) {
- iommu_device_unregister(&smmu->iommu);
- iommu_device_sysfs_remove(&smmu->iommu);
- return ERR_PTR(err);
- }
+ if (err < 0)
+ goto unregister;
+
+#ifdef CONFIG_PCI
+ err = bus_set_iommu(&pci_bus_type, &tegra_smmu_ops);
+ if (err < 0)
+ goto unset_platform_bus;
+#endif
if (IS_ENABLED(CONFIG_DEBUG_FS))
tegra_smmu_debugfs_init(smmu);
return smmu;
+
+unset_platform_bus: __maybe_unused;
+ bus_set_iommu(&platform_bus_type, NULL);
+unregister:
+ iommu_device_unregister(&smmu->iommu);
+remove_sysfs:
+ iommu_device_sysfs_remove(&smmu->iommu);
+
+ return ERR_PTR(err);
}
void tegra_smmu_remove(struct tegra_smmu *smmu)
--
2.17.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH RESEND 3/5] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
2020-11-11 22:21 ` [PATCH RESEND 3/5] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev Nicolin Chen
@ 2020-11-20 16:23 ` Thierry Reding
0 siblings, 0 replies; 14+ messages in thread
From: Thierry Reding @ 2020-11-20 16:23 UTC (permalink / raw)
To: Nicolin Chen; +Cc: joro, linux-kernel, iommu, linux-tegra, jonathanh, vdumpa
[-- Attachment #1: Type: text/plain, Size: 820 bytes --]
On Wed, Nov 11, 2020 at 02:21:27PM -0800, Nicolin Chen wrote:
> In tegra_smmu_(de)attach_dev() functions, we poll DTB for each
> client's iommus property to get swgroup ID in order to prepare
> "as" and enable smmu. Actually tegra_smmu_configure() prepared
> an fwspec for each client, and added to the fwspec all swgroup
> IDs of client DT node in DTB.
>
> So this patch uses fwspec in tegra_smmu_(de)attach_dev() so as
> to replace the redundant DT polling code.
>
> Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
> Tested-by: Dmitry Osipenko <digetx@gmail.com>
> Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
> ---
> drivers/iommu/tegra-smmu.c | 56 ++++++++++++++++----------------------
> 1 file changed, 23 insertions(+), 33 deletions(-)
Acked-by: Thierry Reding <treding@nvidia.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH RESEND 4/5] iommu/tegra-smmu: Rework tegra_smmu_probe_device()
2020-11-11 22:21 ` [PATCH RESEND 4/5] iommu/tegra-smmu: Rework tegra_smmu_probe_device() Nicolin Chen
@ 2020-11-20 16:25 ` Thierry Reding
0 siblings, 0 replies; 14+ messages in thread
From: Thierry Reding @ 2020-11-20 16:25 UTC (permalink / raw)
To: Nicolin Chen; +Cc: joro, linux-kernel, iommu, linux-tegra, jonathanh, vdumpa
[-- Attachment #1: Type: text/plain, Size: 3959 bytes --]
On Wed, Nov 11, 2020 at 02:21:28PM -0800, Nicolin Chen wrote:
> The bus_set_iommu() in tegra_smmu_probe() enumerates all clients
> to call in tegra_smmu_probe_device() where each client searches
> its DT node for smmu pointer and swgroup ID, so as to configure
> an fwspec. But this requires a valid smmu pointer even before mc
> and smmu drivers are probed. So in tegra_smmu_probe() we added a
> line of code to fill mc->smmu, marking "a bit of a hack".
>
> This works for most of clients in the DTB, however, doesn't work
> for a client that doesn't exist in DTB, a PCI device for example.
>
> Actually, if we return ERR_PTR(-ENODEV) in ->probe_device() when
> it's called from bus_set_iommu(), iommu core will let everything
> carry on. Then when a client gets probed, of_iommu_configure() in
> iommu core will search DTB for swgroup ID and call ->of_xlate()
> to prepare an fwspec, similar to tegra_smmu_probe_device() and
> tegra_smmu_configure(). Then it'll call tegra_smmu_probe_device()
> again, and this time we shall return smmu->iommu pointer properly.
>
> So we can get rid of tegra_smmu_find() and tegra_smmu_configure()
> along with DT polling code by letting the iommu core handle every
> thing, except a problem that we search iommus property in DTB not
> only for swgroup ID but also for mc node to get mc->smmu pointer
> to call dev_iommu_priv_set() and return the smmu->iommu pointer.
> So we'll need to find another way to get smmu pointer.
>
> Referencing the implementation of sun50i-iommu driver, of_xlate()
> has client's dev pointer, mc node and swgroup ID. This means that
> we can call dev_iommu_priv_set() in of_xlate() instead, so we can
> simply get smmu pointer in ->probe_device().
>
> This patch reworks tegra_smmu_probe_device() by:
> 1) Removing mc->smmu hack in tegra_smmu_probe() so as to return
> ERR_PTR(-ENODEV) in tegra_smmu_probe_device() during stage of
> tegra_smmu_probe/tegra_mc_probe().
> 2) Moving dev_iommu_priv_set() to of_xlate() so we can get smmu
> pointer in tegra_smmu_probe_device() to replace DTB polling.
> 3) Removing tegra_smmu_configure() accordingly since iommu core
> takes care of it.
>
> This also fixes a problem that previously we could add clients to
> iommu groups before iommu core initializes its default domain:
> ubuntu@jetson:~$ dmesg | grep iommu
> platform 50000000.host1x: Adding to iommu group 1
> platform 57000000.gpu: Adding to iommu group 2
> iommu: Default domain type: Translated
> platform 54200000.dc: Adding to iommu group 3
> platform 54240000.dc: Adding to iommu group 3
> platform 54340000.vic: Adding to iommu group 4
>
> Though it works fine with IOMMU_DOMAIN_UNMANAGED, but will have
> warnings if switching to IOMMU_DOMAIN_DMA:
> iommu: Failed to allocate default IOMMU domain of type 0 for
> group (null) - Falling back to IOMMU_DOMAIN_DMA
> iommu: Failed to allocate default IOMMU domain of type 0 for
> group (null) - Falling back to IOMMU_DOMAIN_DMA
>
> Now, bypassing the first probe_device() call from bus_set_iommu()
> fixes the sequence:
> ubuntu@jetson:~$ dmesg | grep iommu
> iommu: Default domain type: Translated
> tegra-host1x 50000000.host1x: Adding to iommu group 0
> tegra-dc 54200000.dc: Adding to iommu group 1
> tegra-dc 54240000.dc: Adding to iommu group 1
> tegra-vic 54340000.vic: Adding to iommu group 2
> nouveau 57000000.gpu: Adding to iommu group 3
>
> Note that dmesg log above is testing with IOMMU_DOMAIN_UNMANAGED.
>
> Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
> Tested-by: Dmitry Osipenko <digetx@gmail.com>
> Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
> ---
> drivers/iommu/tegra-smmu.c | 96 ++++++--------------------------------
> 1 file changed, 15 insertions(+), 81 deletions(-)
Acked-by: Thierry Reding <treding@nvidia.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH RESEND 5/5] iommu/tegra-smmu: Add PCI support
2020-11-11 22:21 ` [PATCH RESEND 5/5] iommu/tegra-smmu: Add PCI support Nicolin Chen
@ 2020-11-20 16:26 ` Thierry Reding
0 siblings, 0 replies; 14+ messages in thread
From: Thierry Reding @ 2020-11-20 16:26 UTC (permalink / raw)
To: Nicolin Chen; +Cc: joro, linux-kernel, iommu, linux-tegra, jonathanh, vdumpa
[-- Attachment #1: Type: text/plain, Size: 456 bytes --]
On Wed, Nov 11, 2020 at 02:21:29PM -0800, Nicolin Chen wrote:
> This patch simply adds support for PCI devices.
>
> Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
> Tested-by: Dmitry Osipenko <digetx@gmail.com>
> Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
> ---
> drivers/iommu/tegra-smmu.c | 35 +++++++++++++++++++++++++----------
> 1 file changed, 25 insertions(+), 10 deletions(-)
Acked-by: Thierry Reding <treding@nvidia.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes
2020-11-11 22:21 [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
` (4 preceding siblings ...)
2020-11-11 22:21 ` [PATCH RESEND 5/5] iommu/tegra-smmu: Add PCI support Nicolin Chen
@ 2020-11-24 21:21 ` Nicolin Chen
2020-11-24 23:05 ` Dmitry Osipenko
5 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2020-11-24 21:21 UTC (permalink / raw)
To: joro; +Cc: thierry.reding, linux-kernel, iommu, linux-tegra, jonathanh, vdumpa
Hi Joerg,
These five patches were acked by Thierry and acked-n-tested by
Dmitry a while ago. Would it be possible for you to apply them?
Thanks!
On Wed, Nov 11, 2020 at 02:21:24PM -0800, Nicolin Chen wrote:
> This is a merged set of resend for previously two series of patches
> that were reviewed/acked a month ago yet have not got applied.
>
> Series-1: https://lkml.org/lkml/2020/9/29/73
> "[PATCH v4 0/2] iommu/tegra-smmu: Two followup changes"
>
> Series-2: https://lkml.org/lkml/2020/10/9/808
> "[PATCH v7 0/3] iommu/tegra-smmu: Add PCI support"
>
> Nicolin Chen (5):
> iommu/tegra-smmu: Unwrap tegra_smmu_group_get
> iommu/tegra-smmu: Expand mutex protection range
> iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev
> iommu/tegra-smmu: Rework tegra_smmu_probe_device()
> iommu/tegra-smmu: Add PCI support
>
> drivers/iommu/tegra-smmu.c | 240 ++++++++++++++-----------------------
> 1 file changed, 88 insertions(+), 152 deletions(-)
>
> --
> 2.17.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes
2020-11-24 21:21 ` [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
@ 2020-11-24 23:05 ` Dmitry Osipenko
2020-11-24 23:12 ` Nicolin Chen
0 siblings, 1 reply; 14+ messages in thread
From: Dmitry Osipenko @ 2020-11-24 23:05 UTC (permalink / raw)
To: Nicolin Chen, joro
Cc: linux-kernel, iommu, thierry.reding, linux-tegra, jonathanh, Will Deacon
25.11.2020 00:21, Nicolin Chen пишет:
> Hi Joerg,
>
> These five patches were acked by Thierry and acked-n-tested by
> Dmitry a while ago. Would it be possible for you to apply them?
>
> Thanks!
Hi,
You probably should try to ping Will Deacon.
https://lkml.org/lkml/2020/11/17/243
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes
2020-11-24 23:05 ` Dmitry Osipenko
@ 2020-11-24 23:12 ` Nicolin Chen
2020-11-25 9:55 ` Will Deacon
0 siblings, 1 reply; 14+ messages in thread
From: Nicolin Chen @ 2020-11-24 23:12 UTC (permalink / raw)
To: Dmitry Osipenko, Will Deacon
Cc: joro, linux-kernel, iommu, thierry.reding, linux-tegra, jonathanh
On Wed, Nov 25, 2020 at 02:05:14AM +0300, Dmitry Osipenko wrote:
> 25.11.2020 00:21, Nicolin Chen пишет:
> > Hi Joerg,
> >
> > These five patches were acked by Thierry and acked-n-tested by
> > Dmitry a while ago. Would it be possible for you to apply them?
> >
> > Thanks!
>
> Hi,
>
> You probably should try to ping Will Deacon.
>
> https://lkml.org/lkml/2020/11/17/243
Thank you, Dmitry.
--
Will, would it be possible for you to take these changes?
I sent them on Nov 11 to the following lists:
linux-kernel@vger.kernel.org
iommu@lists.linux-foundation.org
If you need me to resend it again by adding you in To line,
please kindly let me know.
Thanks
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes
2020-11-24 23:12 ` Nicolin Chen
@ 2020-11-25 9:55 ` Will Deacon
2020-11-25 10:08 ` Nicolin Chen
0 siblings, 1 reply; 14+ messages in thread
From: Will Deacon @ 2020-11-25 9:55 UTC (permalink / raw)
To: Nicolin Chen
Cc: Dmitry Osipenko, joro, linux-kernel, iommu, thierry.reding,
linux-tegra, jonathanh
On Tue, Nov 24, 2020 at 03:12:16PM -0800, Nicolin Chen wrote:
> On Wed, Nov 25, 2020 at 02:05:14AM +0300, Dmitry Osipenko wrote:
> > 25.11.2020 00:21, Nicolin Chen пишет:
> > > These five patches were acked by Thierry and acked-n-tested by
> > > Dmitry a while ago. Would it be possible for you to apply them?
> > >
> > > Thanks!
> >
> > You probably should try to ping Will Deacon.
> >
> > https://lkml.org/lkml/2020/11/17/243
>
> Thank you, Dmitry.
> --
>
> Will, would it be possible for you to take these changes?
>
> I sent them on Nov 11 to the following lists:
> linux-kernel@vger.kernel.org
> iommu@lists.linux-foundation.org
>
> If you need me to resend it again by adding you in To line,
> please kindly let me know.
Weird, this ended up in my spam. If you wouldn't mind resending with me
on To: then please do that. Then I know I'm looking at the correct version.
Thanks,
Will
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes
2020-11-25 9:55 ` Will Deacon
@ 2020-11-25 10:08 ` Nicolin Chen
0 siblings, 0 replies; 14+ messages in thread
From: Nicolin Chen @ 2020-11-25 10:08 UTC (permalink / raw)
To: Will Deacon
Cc: Dmitry Osipenko, joro, linux-kernel, iommu, thierry.reding,
linux-tegra, jonathanh
On Wed, Nov 25, 2020 at 09:55:10AM +0000, Will Deacon wrote:
> On Tue, Nov 24, 2020 at 03:12:16PM -0800, Nicolin Chen wrote:
> > On Wed, Nov 25, 2020 at 02:05:14AM +0300, Dmitry Osipenko wrote:
> > > 25.11.2020 00:21, Nicolin Chen пишет:
> > > > These five patches were acked by Thierry and acked-n-tested by
> > > > Dmitry a while ago. Would it be possible for you to apply them?
> > > >
> > > > Thanks!
> > >
> > > You probably should try to ping Will Deacon.
> > >
> > > https://lkml.org/lkml/2020/11/17/243
> >
> > Thank you, Dmitry.
> > --
> >
> > Will, would it be possible for you to take these changes?
> >
> > I sent them on Nov 11 to the following lists:
> > linux-kernel@vger.kernel.org
> > iommu@lists.linux-foundation.org
> >
> > If you need me to resend it again by adding you in To line,
> > please kindly let me know.
>
> Weird, this ended up in my spam. If you wouldn't mind resending with me
> on To: then please do that. Then I know I'm looking at the correct version.
Resending.
Thanks!
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2020-11-25 10:09 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-11 22:21 [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
2020-11-11 22:21 ` [PATCH RESEND 1/5] iommu/tegra-smmu: Unwrap tegra_smmu_group_get Nicolin Chen
2020-11-11 22:21 ` [PATCH RESEND 2/5] iommu/tegra-smmu: Expand mutex protection range Nicolin Chen
2020-11-11 22:21 ` [PATCH RESEND 3/5] iommu/tegra-smmu: Use fwspec in tegra_smmu_(de)attach_dev Nicolin Chen
2020-11-20 16:23 ` Thierry Reding
2020-11-11 22:21 ` [PATCH RESEND 4/5] iommu/tegra-smmu: Rework tegra_smmu_probe_device() Nicolin Chen
2020-11-20 16:25 ` Thierry Reding
2020-11-11 22:21 ` [PATCH RESEND 5/5] iommu/tegra-smmu: Add PCI support Nicolin Chen
2020-11-20 16:26 ` Thierry Reding
2020-11-24 21:21 ` [PATCH RESEND 0/5] iommu/tegra-smmu: Some pending reviewed changes Nicolin Chen
2020-11-24 23:05 ` Dmitry Osipenko
2020-11-24 23:12 ` Nicolin Chen
2020-11-25 9:55 ` Will Deacon
2020-11-25 10:08 ` Nicolin Chen
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).