]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
gpu: host1x: Select context device based on attached IOMMU
authorMikko Perttunen <mperttunen@nvidia.com>
Wed, 7 Sep 2022 08:38:42 +0000 (11:38 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 6 Dec 2025 21:12:38 +0000 (06:12 +0900)
[ Upstream commit 8935002fc37fce1ad211d98a70f2fd42083c0594 ]

On Tegra234, engines that are programmed through Host1x channels can
be attached to either the NISO0 or NISO1 SMMU. Because of that, when
selecting a context device to use with an engine, we need to select
one that is also attached to the same SMMU.

Add a parameter to host1x_memory_context_alloc to specify which device
we are allocating a context for, and use it to pick an appropriate
context device.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
[treding@nvidia.com: update !IOMMU_API stub signature]
Signed-off-by: Thierry Reding <treding@nvidia.com>
Stable-dep-of: 6cbab9f0da72 ("drm/tegra: Add call to put_pid()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/tegra/uapi.c
drivers/gpu/host1x/context.c
include/linux/host1x.h

index a98239cb0e29a599e28ee58a7293a0754c9ae3b8..5adab6b229164eed6ec1830243ad9f9e5b5147f6 100644 (file)
@@ -116,7 +116,7 @@ int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_
 
                if (supported)
                        context->memory_context = host1x_memory_context_alloc(
-                               host, get_task_pid(current, PIDTYPE_TGID));
+                               host, client->base.dev, get_task_pid(current, PIDTYPE_TGID));
 
                if (IS_ERR(context->memory_context)) {
                        if (PTR_ERR(context->memory_context) != -EOPNOTSUPP) {
index 93c0c532fe5afd3a79ab16d4bae4b28c9a3545ff..9c0db178fade9f301ce15dbba11a3b9b207123b6 100644 (file)
@@ -112,6 +112,7 @@ void host1x_memory_context_list_free(struct host1x_memory_context_list *cdl)
 }
 
 struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
+                                                         struct device *dev,
                                                          struct pid *pid)
 {
        struct host1x_memory_context_list *cdl = &host1x->context_list;
@@ -126,6 +127,9 @@ struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
        for (i = 0; i < cdl->len; i++) {
                struct host1x_memory_context *cd = &cdl->devs[i];
 
+               if (cd->dev.iommu->iommu_dev != dev->iommu->iommu_dev)
+                       continue;
+
                if (cd->owner == pid) {
                        refcount_inc(&cd->ref);
                        mutex_unlock(&cdl->lock);
index cb2100d9b0ffe481d661bfcf1a051e0cba7c0507..dc55d9d3b94f00501bed188cd5cd57c952a19343 100644 (file)
@@ -469,11 +469,13 @@ struct host1x_memory_context {
 
 #ifdef CONFIG_IOMMU_API
 struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
+                                                         struct device *dev,
                                                          struct pid *pid);
 void host1x_memory_context_get(struct host1x_memory_context *cd);
 void host1x_memory_context_put(struct host1x_memory_context *cd);
 #else
 static inline struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
+                                                                       struct device *dev,
                                                                        struct pid *pid)
 {
        return NULL;