* [PATCH 1/3] drm/omap: Fix possible NULL dereference
2024-08-06 13:50 [PATCH 0/3] drm/omap: Minor fixes Tomi Valkeinen
@ 2024-08-06 13:50 ` Tomi Valkeinen
2024-08-06 13:50 ` [PATCH 2/3] drm/omap: Hide sparse warnings Tomi Valkeinen
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Tomi Valkeinen @ 2024-08-06 13:50 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Daniel Vetter, Laurent Pinchart, Sebastian Reichel
Cc: dri-devel, linux-kernel, Tomi Valkeinen
smatch reports:
drivers/gpu/drm/omapdrm/dss/base.c:176 omapdss_device_disconnect() error: we previously assumed 'src' could be null (see line 169)
This code is mostly from a time when omapdrm had its own display device
model. I can't honestly remember the details, and I don't think it's
worth digging in deeply into that for a legacy driver.
However, it looks like we only call omapdss_device_disconnect() and
omapdss_device_connect() with NULL as the src parameter. We can thus
drop the src parameter from both functions, and fix the smatch warning.
I don't think omapdss_device_disconnect() ever gets NULL for the dst
parameter (if it did, we'd crash soon after returning from the
function), but I have kept the !dst check, just in case, but I added a
WARN_ON() there.
Also, if the dst parameter can be NULL, we can't always get the struct
dss_device pointer from dst->dss (which is only used for a debug print).
To make sure we can't hit that issue, do it similarly to the
omapdss_device_connect() function: add 'struct dss_device *dss' as the
first parameter, so that we always have it regardless of the dst.
Fixes: 79107f274b2f ("drm/omap: Add support for drm_bridge")
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/omapdrm/dss/base.c | 25 ++++++-------------------
drivers/gpu/drm/omapdrm/dss/omapdss.h | 3 +--
drivers/gpu/drm/omapdrm/omap_drv.c | 4 ++--
3 files changed, 9 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c
index 050ca7eafac5..556e0f9026be 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -139,21 +139,13 @@ static bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
}
int omapdss_device_connect(struct dss_device *dss,
- struct omap_dss_device *src,
struct omap_dss_device *dst)
{
- dev_dbg(&dss->pdev->dev, "connect(%s, %s)\n",
- src ? dev_name(src->dev) : "NULL",
+ dev_dbg(&dss->pdev->dev, "connect(%s)\n",
dst ? dev_name(dst->dev) : "NULL");
- if (!dst) {
- /*
- * The destination is NULL when the source is connected to a
- * bridge instead of a DSS device. Stop here, we will attach
- * the bridge later when we will have a DRM encoder.
- */
- return src && src->bridge ? 0 : -EINVAL;
- }
+ if (!dst)
+ return -EINVAL;
if (omapdss_device_is_connected(dst))
return -EBUSY;
@@ -163,19 +155,14 @@ int omapdss_device_connect(struct dss_device *dss,
return 0;
}
-void omapdss_device_disconnect(struct omap_dss_device *src,
+void omapdss_device_disconnect(struct dss_device *dss,
struct omap_dss_device *dst)
{
- struct dss_device *dss = src ? src->dss : dst->dss;
-
- dev_dbg(&dss->pdev->dev, "disconnect(%s, %s)\n",
- src ? dev_name(src->dev) : "NULL",
+ dev_dbg(&dss->pdev->dev, "disconnect(%s)\n",
dst ? dev_name(dst->dev) : "NULL");
- if (!dst) {
- WARN_ON(!src->bridge);
+ if (WARN_ON(!dst))
return;
- }
if (!dst->id && !omapdss_device_is_connected(dst)) {
WARN_ON(1);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 040d5a3e33d6..4c22c09c93d5 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -242,9 +242,8 @@ struct omap_dss_device *omapdss_device_get(struct omap_dss_device *dssdev);
void omapdss_device_put(struct omap_dss_device *dssdev);
struct omap_dss_device *omapdss_find_device_by_node(struct device_node *node);
int omapdss_device_connect(struct dss_device *dss,
- struct omap_dss_device *src,
struct omap_dss_device *dst);
-void omapdss_device_disconnect(struct omap_dss_device *src,
+void omapdss_device_disconnect(struct dss_device *dss,
struct omap_dss_device *dst);
int omap_dss_get_num_overlay_managers(void);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 6598c9c08ba1..d80d24fce79f 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -307,7 +307,7 @@ static void omap_disconnect_pipelines(struct drm_device *ddev)
for (i = 0; i < priv->num_pipes; i++) {
struct omap_drm_pipeline *pipe = &priv->pipes[i];
- omapdss_device_disconnect(NULL, pipe->output);
+ omapdss_device_disconnect(priv->dss, pipe->output);
omapdss_device_put(pipe->output);
pipe->output = NULL;
@@ -325,7 +325,7 @@ static int omap_connect_pipelines(struct drm_device *ddev)
int r;
for_each_dss_output(output) {
- r = omapdss_device_connect(priv->dss, NULL, output);
+ r = omapdss_device_connect(priv->dss, output);
if (r == -EPROBE_DEFER) {
omapdss_device_put(output);
return r;
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 2/3] drm/omap: Hide sparse warnings
2024-08-06 13:50 [PATCH 0/3] drm/omap: Minor fixes Tomi Valkeinen
2024-08-06 13:50 ` [PATCH 1/3] drm/omap: Fix possible NULL dereference Tomi Valkeinen
@ 2024-08-06 13:50 ` Tomi Valkeinen
2024-08-06 13:50 ` [PATCH 3/3] drm/omap: Fix locking in omap_gem_new_dmabuf() Tomi Valkeinen
2024-09-14 7:43 ` [PATCH 0/3] drm/omap: Minor fixes Sebastian Reichel
3 siblings, 0 replies; 6+ messages in thread
From: Tomi Valkeinen @ 2024-08-06 13:50 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Daniel Vetter, Laurent Pinchart, Sebastian Reichel
Cc: dri-devel, linux-kernel, Tomi Valkeinen, kernel test robot,
Ville Syrjälä
sparse reports:
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:122:16: warning: incorrect type in argument 1 (different address spaces)
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:122:16: expected void const volatile [noderef] __iomem *addr
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:122:16: got unsigned int [usertype] *wa_dma_data
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:130:9: warning: incorrect type in argument 2 (different address spaces)
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:130:9: expected void volatile [noderef] __iomem *addr
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:130:9: got unsigned int [usertype] *wa_dma_data
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:414:9: warning: incorrect type in argument 1 (different address spaces)
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:414:9: expected void const volatile [noderef] __iomem *addr
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c:414:9: got unsigned int *
These come from pieces of code which do essentially:
p = dma_alloc_coherent()
dma_transfer_to_p()
readl(p)
writel(x, p)
dma_transfer_from_p()
I think we would do just fine without readl() and writel(), accessing
the memory without any extras, but ensuring that the necessary barriers
are in place. But this code is for a legacy platform, has been working
for ages, and it's doing work-arounds for hardware issues, and those
hardware issues are very difficult to trigger... So I would just rather
leave the code be as it is now.
However, the warnings are not nice. Hide the warnings by a (__iomem void
*) typecast.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202407311737.VsJ0Sr1w-lkp@intel.com/
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index 1aca3060333e..fcd600024136 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -119,7 +119,7 @@ static u32 dmm_read_wa(struct dmm *dmm, u32 reg)
* earlier than the DMA finished writing the value to memory.
*/
rmb();
- return readl(dmm->wa_dma_data);
+ return readl((__iomem void *)dmm->wa_dma_data);
}
static void dmm_write_wa(struct dmm *dmm, u32 val, u32 reg)
@@ -127,7 +127,7 @@ static void dmm_write_wa(struct dmm *dmm, u32 val, u32 reg)
dma_addr_t src, dst;
int r;
- writel(val, dmm->wa_dma_data);
+ writel(val, (__iomem void *)dmm->wa_dma_data);
/*
* As per i878 workaround, the DMA is used to access the DMM registers.
* Make sure that the writel is not moved by the compiler or the CPU, so
@@ -411,7 +411,7 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
*/
/* read back to ensure the data is in RAM */
- readl(&txn->last_pat->next_pa);
+ readl((__iomem void *)&txn->last_pat->next_pa);
/* write to PAT_DESCR to clear out any pending transaction */
dmm_write(dmm, 0x0, reg[PAT_DESCR][engine->id]);
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/3] drm/omap: Fix locking in omap_gem_new_dmabuf()
2024-08-06 13:50 [PATCH 0/3] drm/omap: Minor fixes Tomi Valkeinen
2024-08-06 13:50 ` [PATCH 1/3] drm/omap: Fix possible NULL dereference Tomi Valkeinen
2024-08-06 13:50 ` [PATCH 2/3] drm/omap: Hide sparse warnings Tomi Valkeinen
@ 2024-08-06 13:50 ` Tomi Valkeinen
2024-08-06 15:20 ` Markus Elfring
2024-09-14 7:43 ` [PATCH 0/3] drm/omap: Minor fixes Sebastian Reichel
3 siblings, 1 reply; 6+ messages in thread
From: Tomi Valkeinen @ 2024-08-06 13:50 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Daniel Vetter, Laurent Pinchart, Sebastian Reichel
Cc: dri-devel, linux-kernel, Tomi Valkeinen, Dan Carpenter
omap_gem_new_dmabuf() creates the new gem object, and then takes and
holds the omap_obj->lock for the rest of the function. This has two
issues:
- omap_gem_free_object(), which is called in the error paths, also takes
the same lock, leading to deadlock
- Even if the above wouldn't happen, in the error cases
omap_gem_new_dmabuf() still unlocks omap_obj->lock, even after the
omap_obj has already been freed.
Furthermore, I don't think there's any reason to take the lock at all,
as the object was just created and not yet shared with anyone else.
To fix all this, drop taking the lock.
Fixes: 3cbd0c587b12 ("drm/omap: gem: Replace struct_mutex usage with omap_obj private lock")
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/all/511b99d7-aade-4f92-bd3e-63163a13d617@stanley.mountain/
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
---
drivers/gpu/drm/omapdrm/omap_gem.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index 9ea0c64c26b5..ebbe80c1c0ef 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -1402,8 +1402,6 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
omap_obj = to_omap_bo(obj);
- mutex_lock(&omap_obj->lock);
-
omap_obj->sgt = sgt;
if (omap_gem_sgt_is_contiguous(sgt, size)) {
@@ -1418,21 +1416,17 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
if (!pages) {
omap_gem_free_object(obj);
- obj = ERR_PTR(-ENOMEM);
- goto done;
+ return ERR_PTR(-ENOMEM);
}
omap_obj->pages = pages;
ret = drm_prime_sg_to_page_array(sgt, pages, npages);
if (ret) {
omap_gem_free_object(obj);
- obj = ERR_PTR(-ENOMEM);
- goto done;
+ return ERR_PTR(-ENOMEM);
}
}
-done:
- mutex_unlock(&omap_obj->lock);
return obj;
}
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH 3/3] drm/omap: Fix locking in omap_gem_new_dmabuf()
2024-08-06 13:50 ` [PATCH 3/3] drm/omap: Fix locking in omap_gem_new_dmabuf() Tomi Valkeinen
@ 2024-08-06 15:20 ` Markus Elfring
0 siblings, 0 replies; 6+ messages in thread
From: Markus Elfring @ 2024-08-06 15:20 UTC (permalink / raw)
To: Tomi Valkeinen, dri-devel, Daniel Vetter, David Airlie,
Laurent Pinchart, Maarten Lankhorst, Maxime Ripard,
Sebastian Reichel, Thomas Zimmermann
Cc: LKML, Dan Carpenter
…
> +++ b/drivers/gpu/drm/omapdrm/omap_gem.c
…
> @@ -1418,21 +1416,17 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
> pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
> if (!pages) {
> omap_gem_free_object(obj);
> - obj = ERR_PTR(-ENOMEM);
> - goto done;
> + return ERR_PTR(-ENOMEM);
> }
>
> omap_obj->pages = pages;
> ret = drm_prime_sg_to_page_array(sgt, pages, npages);
> if (ret) {
> omap_gem_free_object(obj);
> - obj = ERR_PTR(-ENOMEM);
> - goto done;
> + return ERR_PTR(-ENOMEM);
> }
…
I suggest to use another goto chain instead so that a bit of exception handling
can be better reused at the end of this function implementation.
Regards,
Markus
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/3] drm/omap: Minor fixes
2024-08-06 13:50 [PATCH 0/3] drm/omap: Minor fixes Tomi Valkeinen
` (2 preceding siblings ...)
2024-08-06 13:50 ` [PATCH 3/3] drm/omap: Fix locking in omap_gem_new_dmabuf() Tomi Valkeinen
@ 2024-09-14 7:43 ` Sebastian Reichel
3 siblings, 0 replies; 6+ messages in thread
From: Sebastian Reichel @ 2024-09-14 7:43 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Daniel Vetter, Laurent Pinchart, dri-devel,
linux-kernel, kernel test robot, Ville Syrjälä,
Dan Carpenter
[-- Attachment #1: Type: text/plain, Size: 1100 bytes --]
Hi,
On Tue, Aug 06, 2024 at 04:50:26PM GMT, Tomi Valkeinen wrote:
> A few minor fixes to omapdrm, mostly to remove sparse or other checker
> warnings.
>
> Tomi
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
For the series:
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Greetings,
-- Sebastian
> ---
> Tomi Valkeinen (3):
> drm/omap: Fix possible NULL dereference
> drm/omap: Hide sparse warnings
> drm/omap: Fix locking in omap_gem_new_dmabuf()
>
> drivers/gpu/drm/omapdrm/dss/base.c | 25 ++++++-------------------
> drivers/gpu/drm/omapdrm/dss/omapdss.h | 3 +--
> drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 6 +++---
> drivers/gpu/drm/omapdrm/omap_drv.c | 4 ++--
> drivers/gpu/drm/omapdrm/omap_gem.c | 10 ++--------
> 5 files changed, 14 insertions(+), 34 deletions(-)
> ---
> base-commit: 0c3836482481200ead7b416ca80c68a29cfdaabd
> change-id: 20240806-omapdrm-misc-fixes-2ea920193dde
>
> Best regards,
> --
> Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread