summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <mdaenzer@redhat.com>2019-09-26 15:56:59 +0200
committerMichel Dänzer <mdaenzer@redhat.com>2019-09-26 15:56:59 +0200
commita1b7263277c033e109629829c370c0e95978e061 (patch)
treee967947f2988150aeaf14c452d9e2808d497a71c
parent5b8bc9fc505c551dcd9b0ed5ab835a49fa4f9fda (diff)
Don't unreference FBs of pixmaps from different screens in LeaveVT
FindClientResourcesByType finds pixmaps from all screens, but trying to process ones from other screens here makes no sense and likely results in a crash or memory corruption. Fixes: c16ff42f927d ("Make all active CRTCs scan out an all-black framebuffer in LeaveVT") (Ported from radeon commit 2faaecc69b127248718e759c6c98c84d56dd1b6b)
-rw-r--r--src/amdgpu_kms.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 6263bd7..6a60f54 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -2240,16 +2240,25 @@ Bool AMDGPUEnterVT_KMS(ScrnInfoPtr pScrn)
}
static void
-pixmap_unref_fb(void *value, XID id, void *cdata)
+pixmap_unref_fb(PixmapPtr pixmap)
{
- PixmapPtr pixmap = value;
- AMDGPUEntPtr pAMDGPUEnt = cdata;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
struct drmmode_fb **fb_ptr = amdgpu_pixmap_get_fb_ptr(pixmap);
+ AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
if (fb_ptr)
drmmode_fb_reference(pAMDGPUEnt->fd, fb_ptr, NULL);
}
+static void
+client_pixmap_unref_fb(void *value, XID id, void *pScreen)
+{
+ PixmapPtr pixmap = value;
+
+ if (pixmap->drawable.pScreen == pScreen)
+ pixmap_unref_fb(pixmap);
+}
+
void AMDGPULeaveVT_KMS(ScrnInfoPtr pScrn)
{
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
@@ -2311,11 +2320,9 @@ void AMDGPULeaveVT_KMS(ScrnInfoPtr pScrn)
if (pScrn->is_gpu) {
if (drmmode_crtc->scanout[0].pixmap)
- pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap,
- None, pAMDGPUEnt);
+ pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap);
if (drmmode_crtc->scanout[1].pixmap)
- pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap,
- None, pAMDGPUEnt);
+ pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap);
} else {
drmmode_crtc_scanout_free(crtc);
}
@@ -2335,11 +2342,11 @@ void AMDGPULeaveVT_KMS(ScrnInfoPtr pScrn)
(!clients[i] || clients[i]->clientState != ClientStateRunning))
continue;
- FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb,
- pAMDGPUEnt);
+ FindClientResourcesByType(clients[i], RT_PIXMAP,
+ client_pixmap_unref_fb, pScreen);
}
- pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pAMDGPUEnt);
+ pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen));
} else {
memset(info->front_buffer->cpu_ptr, 0, pScrn->virtualX *
info->pixel_bytes * pScrn->virtualY);