> -----Original Message----- > From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf > Of Michel Dänzer > Sent: Wednesday, May 10, 2017 5:11 AM > To: amd-gfx at lists.freedesktop.org > Subject: [PATCH xf86-video-ati] Simplify tracking of PRIME scanout pixmap > > From: Michel Dänzer <michel.daenzer at amd.com> > > Remember the shared pixmap passed to drmmode_set_scanout_pixmap for > each > CRTC, and just compare against that. > > Fixes leaving stale entries in ScreenRec::pixmap_dirty_list under some > circumstances, which would usually result in use-after-free and a crash > down the line. > > Signed-off-by: Michel Dänzer <michel.daenzer at amd.com> Reviewed-by: Alex Deucher <alexander.deucher at amd.com> > --- > src/drmmode_display.c | 21 +++++++++++---------- > src/drmmode_display.h | 3 +++ > src/radeon_kms.c | 7 ++----- > 3 files changed, 16 insertions(+), 15 deletions(-) > > diff --git a/src/drmmode_display.c b/src/drmmode_display.c > index ec3072621..e2899cf50 100644 > --- a/src/drmmode_display.c > +++ b/src/drmmode_display.c > @@ -732,9 +732,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr > crtc, DisplayModePtr mode, > > xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, > ent) { > - if (dirty->src == crtc->randr_crtc->scanout_pixmap > && > - dirty->slave_dst == > - drmmode_crtc->scanout[drmmode_crtc- > >scanout_id].pixmap) { > + if (dirty->src == drmmode_crtc- > >prime_scanout_pixmap) { > dirty->slave_dst = > drmmode_crtc- > >scanout[scanout_id].pixmap; > break; > @@ -887,7 +885,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, > DisplayModePtr mode, > drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); > > #ifdef RADEON_PIXMAP_SHARING > - if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) { > + if (drmmode_crtc->prime_scanout_pixmap) { > drmmode_crtc_prime_scanout_update(crtc, mode, > scanout_id, > &fb, &x, &y); > } else > @@ -1278,14 +1276,15 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, > PixmapPtr ppix) > PixmapDirtyUpdatePtr dirty; > > xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { > - if (dirty->slave_dst != drmmode_crtc- > >scanout[scanout_id].pixmap) > - continue; > - > - PixmapStopDirtyTracking(dirty->src, dirty->slave_dst); > - drmmode_crtc_scanout_free(drmmode_crtc); > - break; > + if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { > + PixmapStopDirtyTracking(dirty->src, dirty- > >slave_dst); > + break; > + } > } > > + drmmode_crtc_scanout_free(drmmode_crtc); > + drmmode_crtc->prime_scanout_pixmap = NULL; > + > if (!ppix) > return TRUE; > > @@ -1302,6 +1301,8 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, > PixmapPtr ppix) > return FALSE; > } > > + drmmode_crtc->prime_scanout_pixmap = ppix; > + > #ifdef HAS_DIRTYTRACKING_ROTATION > PixmapStartDirtyTracking(ppix, drmmode_crtc- > >scanout[scanout_id].pixmap, > 0, 0, 0, 0, RR_Rotate_0); > diff --git a/src/drmmode_display.h b/src/drmmode_display.h > index 14d1cb034..df2c4b7bb 100644 > --- a/src/drmmode_display.h > +++ b/src/drmmode_display.h > @@ -92,6 +92,9 @@ typedef struct { > unsigned scanout_id; > Bool scanout_update_pending; > Bool tear_free; > + > + PixmapPtr prime_scanout_pixmap; > + > int dpms_mode; > /* For when a flip is pending when DPMS off requested */ > int pending_dpms_mode; > diff --git a/src/radeon_kms.c b/src/radeon_kms.c > index 2b410eb3d..c4bdfcfac 100644 > --- a/src/radeon_kms.c > +++ b/src/radeon_kms.c > @@ -657,8 +657,7 @@ radeon_prime_dirty_to_crtc(PixmapDirtyUpdatePtr > dirty) > xf86CrtcPtr xf86_crtc = xf86_config->crtc[c]; > drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc- > >driver_private; > > - if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst || > - drmmode_crtc->scanout[1].pixmap == dirty->slave_dst) > + if (drmmode_crtc->prime_scanout_pixmap == dirty->src) > return xf86_crtc; > } > > @@ -671,13 +670,11 @@ radeon_prime_scanout_do_update(xf86CrtcPtr > crtc, unsigned scanout_id) > ScrnInfoPtr scrn = crtc->scrn; > ScreenPtr screen = scrn->pScreen; > drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; > - PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap; > PixmapDirtyUpdatePtr dirty; > Bool ret = FALSE; > > xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) { > - if (dirty->src == scanoutpix && dirty->slave_dst == > - drmmode_crtc->scanout[scanout_id ^ drmmode_crtc- > >tear_free].pixmap) { > + if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { > RegionPtr region; > > if (master_has_sync_shared_pixmap(scrn, dirty)) > -- > 2.11.0 > > _______________________________________________ > amd-gfx mailing list > amd-gfx at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx