6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikko Perttunen mperttunen@nvidia.com
[ 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 | 2 +- drivers/gpu/host1x/context.c | 4 ++++ include/linux/host1x.h | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/tegra/uapi.c b/drivers/gpu/drm/tegra/uapi.c index a98239cb0e29a..5adab6b229164 100644 --- a/drivers/gpu/drm/tegra/uapi.c +++ b/drivers/gpu/drm/tegra/uapi.c @@ -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) { diff --git a/drivers/gpu/host1x/context.c b/drivers/gpu/host1x/context.c index 93c0c532fe5af..9c0db178fade9 100644 --- a/drivers/gpu/host1x/context.c +++ b/drivers/gpu/host1x/context.c @@ -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); diff --git a/include/linux/host1x.h b/include/linux/host1x.h index cb2100d9b0ffe..dc55d9d3b94f0 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -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;