GPF fix in atomic flipping, sun4i overflow fix.

-----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJbypLRAAoJEAx081l5xIa+mMMP/1ywMk9LSQhECJrU58f9XAts
 vOiFrtgy4HLxUw7Nj8PFV3tXTAhuNfITJ5az01ggLPpFH4KtVRtHUM9xMc7wRUJe
 5seR6AntgiwjZ5VU036+BMD1j6c1cD7OA7BY2moio3PAbXv+wmQ2P3qwGl5pxzVR
 20emwYgQSfkiThblI2MwNvV1os8Gy6bDO9vowVc1+vpYkWvCf5lEVvaZRsujZl1/
 FvLamGVIs19VlNMUzlUFKqv8c54qnv1y7CpZtNNZEGDitT+/fPC1BmyyxTMaNl7Z
 iMhfHwT4hFy9CS4EcLqFvGgKZSGrC9IzSjiCYWo/uXsqDMv8SrlH33adBlcwMM7q
 5ECALrSLF0BKWuD3dU/GipYHB0FmEm9U6nbruHpO9k3HyayJ3+mU2NjvCncxzLFb
 J/lywag+GeB3pcNUNIuvN4IIBl85ytJTUV+yU1DYlxb644cPighlLZqMcAJJg5kP
 045ixmSKiPyLv2hVUn5DsrnzMx1S7j9HUZwzsg4BXuguYu7pz6p3ui3sjgZuN+vU
 ryvpmM0YeySB6BfbVTqTNFzRtN6ozcy6KIu/TKNh1qudE46ktA0+/7NkZ+dN5HN4
 RqZQarbCTq2x4mpOFWBFwdjl0ehhtcAFL9eKJoD55PxzbV/8P205gD5loUVQI+qi
 Qwawgc3Mn3Z/PbZhrKtI
 =ZlVF
 -----END PGP SIGNATURE-----

Merge tag 'drm-fixes-2018-10-20-1' of git://anongit.freedesktop.org/drm/drm

Dave writes:
  "drm fixes for 4.19 final (part 2)

   Looked like two stragglers snuck in, one very urgent the pageflipping
   was missing a reference that could result in a GPF on non-i915
   drivers, the other is an overflow in the sun4i dotclock calcs
   resulting in a mode not getting set."

* tag 'drm-fixes-2018-10-20-1' of git://anongit.freedesktop.org/drm/drm:
  drm/sun4i: Fix an ulong overflow in the dotclock driver
  drm: Get ref on CRTC commit object when waiting for flip_done
This commit is contained in:
Greg Kroah-Hartman 2018-10-20 09:23:12 +02:00
commit 270b77a0f3
4 changed files with 35 additions and 5 deletions

View File

@ -174,6 +174,11 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
state->crtcs[i].state = NULL; state->crtcs[i].state = NULL;
state->crtcs[i].old_state = NULL; state->crtcs[i].old_state = NULL;
state->crtcs[i].new_state = NULL; state->crtcs[i].new_state = NULL;
if (state->crtcs[i].commit) {
drm_crtc_commit_put(state->crtcs[i].commit);
state->crtcs[i].commit = NULL;
}
} }
for (i = 0; i < config->num_total_plane; i++) { for (i = 0; i < config->num_total_plane; i++) {

View File

@ -1408,15 +1408,16 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev, void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
struct drm_atomic_state *old_state) struct drm_atomic_state *old_state)
{ {
struct drm_crtc_state *new_crtc_state;
struct drm_crtc *crtc; struct drm_crtc *crtc;
int i; int i;
for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { for (i = 0; i < dev->mode_config.num_crtc; i++) {
struct drm_crtc_commit *commit = new_crtc_state->commit; struct drm_crtc_commit *commit = old_state->crtcs[i].commit;
int ret; int ret;
if (!commit) crtc = old_state->crtcs[i].ptr;
if (!crtc || !commit)
continue; continue;
ret = wait_for_completion_timeout(&commit->flip_done, 10 * HZ); ret = wait_for_completion_timeout(&commit->flip_done, 10 * HZ);
@ -1934,6 +1935,9 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
drm_crtc_commit_get(commit); drm_crtc_commit_get(commit);
commit->abort_completion = true; commit->abort_completion = true;
state->crtcs[i].commit = commit;
drm_crtc_commit_get(commit);
} }
for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) { for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) {

View File

@ -81,9 +81,19 @@ static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
int i; int i;
for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) { for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) {
unsigned long ideal = rate * i; u64 ideal = (u64)rate * i;
unsigned long rounded; unsigned long rounded;
/*
* ideal has overflowed the max value that can be stored in an
* unsigned long, and every clk operation we might do on a
* truncated u64 value will give us incorrect results.
* Let's just stop there since bigger dividers will result in
* the same overflow issue.
*/
if (ideal > ULONG_MAX)
goto out;
rounded = clk_hw_round_rate(clk_hw_get_parent(hw), rounded = clk_hw_round_rate(clk_hw_get_parent(hw),
ideal); ideal);

View File

@ -153,6 +153,17 @@ struct __drm_planes_state {
struct __drm_crtcs_state { struct __drm_crtcs_state {
struct drm_crtc *ptr; struct drm_crtc *ptr;
struct drm_crtc_state *state, *old_state, *new_state; struct drm_crtc_state *state, *old_state, *new_state;
/**
* @commit:
*
* A reference to the CRTC commit object that is kept for use by
* drm_atomic_helper_wait_for_flip_done() after
* drm_atomic_helper_commit_hw_done() is called. This ensures that a
* concurrent commit won't free a commit object that is still in use.
*/
struct drm_crtc_commit *commit;
s32 __user *out_fence_ptr; s32 __user *out_fence_ptr;
u64 last_vblank_count; u64 last_vblank_count;
}; };