Skip to content

Commit 86af6b9

Browse files
vsyrjalarodrigovivi
authored andcommitted
drm/i915/fb: Fix the set_tiling vs. addfb race, again
intel_frontbuffer_get() is what locks out subsequent set_tiling changes to the bo. Thus the fence vs. modifier check must be done after intel_frontbuffer_get(), or else a concurrent set_tiling ioctl might sneak in and change the fence after the check has been done. Close the race again. See commit dd68928 ("drm/i915: Prevent concurrent tiling/framebuffer modifications") for the previous instance. v2: Reorder intel_user_framebuffer_destroy() to match the unwind (Jani) Cc: Jouni Högander <jouni.hogander@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Fixes: 10690b8 ("drm/i915/display: Add intel_fb_bo_framebuffer_fini") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20251003145734.7634-3-ville.syrjala@linux.intel.com (cherry picked from commit 1d1e4ded216017f8febd91332ee337f0e0e79285) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent 760039c commit 86af6b9

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

drivers/gpu/drm/i915/display/intel_fb.c

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2113,10 +2113,10 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
21132113
if (intel_fb_uses_dpt(fb))
21142114
intel_dpt_destroy(intel_fb->dpt_vm);
21152115

2116-
intel_frontbuffer_put(intel_fb->frontbuffer);
2117-
21182116
intel_fb_bo_framebuffer_fini(intel_fb_bo(fb));
21192117

2118+
intel_frontbuffer_put(intel_fb->frontbuffer);
2119+
21202120
kfree(intel_fb);
21212121
}
21222122

@@ -2218,15 +2218,17 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
22182218
int ret = -EINVAL;
22192219
int i;
22202220

2221+
/*
2222+
* intel_frontbuffer_get() must be done before
2223+
* intel_fb_bo_framebuffer_init() to avoid set_tiling vs. addfb race.
2224+
*/
2225+
intel_fb->frontbuffer = intel_frontbuffer_get(obj);
2226+
if (!intel_fb->frontbuffer)
2227+
return -ENOMEM;
2228+
22212229
ret = intel_fb_bo_framebuffer_init(fb, obj, mode_cmd);
22222230
if (ret)
2223-
return ret;
2224-
2225-
intel_fb->frontbuffer = intel_frontbuffer_get(obj);
2226-
if (!intel_fb->frontbuffer) {
2227-
ret = -ENOMEM;
2228-
goto err;
2229-
}
2231+
goto err_frontbuffer_put;
22302232

22312233
ret = -EINVAL;
22322234
if (!drm_any_plane_has_format(display->drm,
@@ -2235,7 +2237,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
22352237
drm_dbg_kms(display->drm,
22362238
"unsupported pixel format %p4cc / modifier 0x%llx\n",
22372239
&mode_cmd->pixel_format, mode_cmd->modifier[0]);
2238-
goto err_frontbuffer_put;
2240+
goto err_bo_framebuffer_fini;
22392241
}
22402242

22412243
max_stride = intel_fb_max_stride(display, mode_cmd->pixel_format,
@@ -2246,15 +2248,15 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
22462248
mode_cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR ?
22472249
"tiled" : "linear",
22482250
mode_cmd->pitches[0], max_stride);
2249-
goto err_frontbuffer_put;
2251+
goto err_bo_framebuffer_fini;
22502252
}
22512253

22522254
/* FIXME need to adjust LINOFF/TILEOFF accordingly. */
22532255
if (mode_cmd->offsets[0] != 0) {
22542256
drm_dbg_kms(display->drm,
22552257
"plane 0 offset (0x%08x) must be 0\n",
22562258
mode_cmd->offsets[0]);
2257-
goto err_frontbuffer_put;
2259+
goto err_bo_framebuffer_fini;
22582260
}
22592261

22602262
drm_helper_mode_fill_fb_struct(display->drm, fb, info, mode_cmd);
@@ -2264,15 +2266,15 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
22642266

22652267
if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
22662268
drm_dbg_kms(display->drm, "bad plane %d handle\n", i);
2267-
goto err_frontbuffer_put;
2269+
goto err_bo_framebuffer_fini;
22682270
}
22692271

22702272
stride_alignment = intel_fb_stride_alignment(fb, i);
22712273
if (fb->pitches[i] & (stride_alignment - 1)) {
22722274
drm_dbg_kms(display->drm,
22732275
"plane %d pitch (%d) must be at least %u byte aligned\n",
22742276
i, fb->pitches[i], stride_alignment);
2275-
goto err_frontbuffer_put;
2277+
goto err_bo_framebuffer_fini;
22762278
}
22772279

22782280
if (intel_fb_is_gen12_ccs_aux_plane(fb, i)) {
@@ -2282,7 +2284,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
22822284
drm_dbg_kms(display->drm,
22832285
"ccs aux plane %d pitch (%d) must be %d\n",
22842286
i, fb->pitches[i], ccs_aux_stride);
2285-
goto err_frontbuffer_put;
2287+
goto err_bo_framebuffer_fini;
22862288
}
22872289
}
22882290

@@ -2291,7 +2293,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
22912293

22922294
ret = intel_fill_fb_info(display, intel_fb);
22932295
if (ret)
2294-
goto err_frontbuffer_put;
2296+
goto err_bo_framebuffer_fini;
22952297

22962298
if (intel_fb_uses_dpt(fb)) {
22972299
struct i915_address_space *vm;
@@ -2317,10 +2319,10 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
23172319
err_free_dpt:
23182320
if (intel_fb_uses_dpt(fb))
23192321
intel_dpt_destroy(intel_fb->dpt_vm);
2322+
err_bo_framebuffer_fini:
2323+
intel_fb_bo_framebuffer_fini(obj);
23202324
err_frontbuffer_put:
23212325
intel_frontbuffer_put(intel_fb->frontbuffer);
2322-
err:
2323-
intel_fb_bo_framebuffer_fini(obj);
23242326
return ret;
23252327
}
23262328

0 commit comments

Comments
 (0)