drm/tgm: tdm_pp: msc: check and adjust src/dest size parameter 50/220750/1 accepted/tizen/unified/20191223.060227 submit/tizen/20191223.042319
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 23 Dec 2019 01:21:38 +0000 (10:21 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 23 Dec 2019 01:25:23 +0000 (10:25 +0900)
In msc hw, for both src and dest, image x plus image w should be
equal or less than buffer size vsize and image y plus image shou.d
be equal or less than buffer size hsize. Otherwise, hw tries to
access out of buffer boundary and it causes msc sysmmu page fault.
Fix to check and to adjust src/dest size parameter as the hw
constraint.

Change-Id: Ie6e9d431955e0c369164f2b1f46cf9f17e0b1d8b
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
drivers/gpu/drm/tgm/tdm_pp_msc.c

index b2d59c278c1c861dce740cbe12b8696b6be9695a..92d14fbafbcb327902a01e71f693b8aaac4c9a4d 100755 (executable)
@@ -710,6 +710,22 @@ static int sc_src_set_size(struct device *dev, int swap,
        DRM_DEBUG("%s:x[%d]y[%d]w[%d]h[%d]\n",
                __func__, pos->x, pos->y, pos->w, pos->h);
 
+       if (pos->x + pos->w > sz->hsize) {
+               dev_warn(dev, "wrong src size: pos->x[%d] + pos->w[%d] "
+                             "should be equal or less than sz->hsize[%d], "
+                             "try to adjust pos->w as [%d]\n",
+                       pos->x, pos->w, sz->hsize, sz->hsize - pos->x);
+               pos->w = sz->hsize - pos->x;
+       }
+
+       if (pos->y + pos->h > sz->vsize) {
+               dev_warn(dev, "wrong src size: pos->y[%d] + pos->h[%d] "
+                             "should be equal or less than sz->vsize[%d], "
+                             "try to adjust pos->h as [%d]\n",
+                       pos->y, pos->h, sz->vsize, sz->vsize - pos->y);
+               pos->h = sz->vsize - pos->y;
+       }
+
        /* pixel offset */
        cfg = (SCALER_SRC_YX(pos->x) |
                SCALER_SRC_YY(pos->y));
@@ -1157,6 +1173,22 @@ static int sc_dst_set_size(struct device *dev, int swap,
                img_pos.h = pos->w;
        }
 
+       if (pos->x + pos->w > sz->hsize) {
+               dev_warn(dev, "wrong dst size: pos->x[%d] + pos->w[%d] "
+                             "should be equal or less than sz->hsize[%d], "
+                             "try to adjust pos->w as [%d]\n",
+                       pos->x, pos->w, sz->hsize, sz->hsize - pos->x);
+               pos->w = sz->hsize - pos->x;
+       }
+
+       if (pos->y + pos->h > sz->vsize) {
+               dev_warn(dev, "wrong dst size: pos->y[%d] + pos->h[%d] "
+                             "should be equal or less than sz->vsize[%d], "
+                             "try to adjust pos->h as [%d]\n",
+                       pos->y, pos->h, sz->vsize, sz->vsize - pos->y);
+               pos->h = sz->vsize - pos->y;
+       }
+
        /* pixel offset */
        cfg = (SCALER_DST_X(pos->x) |
                SCALER_DST_Y(pos->y));