summaryrefslogtreecommitdiff
path: root/src/amdgpu_dri2.c
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2016-04-01 15:29:26 +0900
committerMichel Dänzer <michel.daenzer@amd.com>2016-04-01 15:29:26 +0900
commit5ba95c3abeb8df82aa8d33a47596eae6403ea7af (patch)
tree15c5bc7bbdb7263e893cbb061c51c083496b4d06 /src/amdgpu_dri2.c
parent8ecfa69b5a833bd4c39e773a6acfd7eef9144d13 (diff)
Identify DRM event queue entries by sequence number instead of by pointer
If the memory for an entry was allocated at the same address as that for a previously cancelled entry, the handler could theoretically be called prematurely, triggered by the DRM event which was submitted for the cancelled entry. (Ported from radeon commit 4693b1bd5b5c381e8b7b68a6f7f0c6696d6a68df) Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'src/amdgpu_dri2.c')
-rw-r--r--src/amdgpu_dri2.c47
1 files changed, 24 insertions, 23 deletions
diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c
index 4478b16..29f60ba 100644
--- a/src/amdgpu_dri2.c
+++ b/src/amdgpu_dri2.c
@@ -395,7 +395,7 @@ typedef struct _DRI2FrameEvent {
unsigned frame;
xf86CrtcPtr crtc;
OsTimerPtr timer;
- struct amdgpu_drm_queue_entry *drm_queue;
+ uintptr_t drm_queue_seq;
/* for swaps & flips only */
DRI2SwapEventPtr event_complete;
@@ -961,8 +961,8 @@ CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
*/
if (!event_info->crtc) {
ErrorF("%s no crtc\n", __func__);
- if (event_info->drm_queue)
- amdgpu_drm_abort_entry(event_info->drm_queue);
+ if (event_info->drm_queue_seq)
+ amdgpu_drm_abort_entry(event_info->drm_queue_seq);
else
amdgpu_dri2_frame_event_abort(NULL, data);
return 0;
@@ -974,9 +974,9 @@ CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"%s cannot get current time\n", __func__);
- if (event_info->drm_queue)
+ if (event_info->drm_queue_seq)
amdgpu_drm_queue_handler(pAMDGPUEnt->fd, 0, 0, 0,
- event_info->drm_queue);
+ (void*)event_info->drm_queue_seq);
else
amdgpu_dri2_frame_event_handler(crtc, 0, 0, data);
return 0;
@@ -990,9 +990,10 @@ CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
delta_seq /= 1000000;
frame = (CARD64) drmmode_crtc->dpms_last_seq + delta_seq;
- if (event_info->drm_queue)
+ if (event_info->drm_queue_seq)
amdgpu_drm_queue_handler(pAMDGPUEnt->fd, frame, drm_now / 1000000,
- drm_now % 1000000, event_info->drm_queue);
+ drm_now % 1000000,
+ (void*)event_info->drm_queue_seq);
else
amdgpu_dri2_frame_event_handler(crtc, frame, drm_now, data);
return 0;
@@ -1023,7 +1024,7 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
DRI2FrameEventPtr wait_info = NULL;
- struct amdgpu_drm_queue_entry *wait = NULL;
+ uintptr_t drm_queue_seq = 0;
xf86CrtcPtr crtc = amdgpu_dri2_drawable_crtc(draw, TRUE);
uint32_t msc_delta;
drmVBlank vbl;
@@ -1079,15 +1080,15 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
current_msc = vbl.reply.sequence + msc_delta;
current_msc &= 0xffffffff;
- wait = amdgpu_drm_queue_alloc(crtc, client, AMDGPU_DRM_QUEUE_ID_DEFAULT,
- wait_info, amdgpu_dri2_frame_event_handler,
- amdgpu_dri2_frame_event_abort);
- if (!wait) {
+ drm_queue_seq = amdgpu_drm_queue_alloc(crtc, client, AMDGPU_DRM_QUEUE_ID_DEFAULT,
+ wait_info, amdgpu_dri2_frame_event_handler,
+ amdgpu_dri2_frame_event_abort);
+ if (!drm_queue_seq) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Allocating DRM queue event entry failed.\n");
goto out_complete;
}
- wait_info->drm_queue = wait;
+ wait_info->drm_queue_seq = drm_queue_seq;
/*
* If divisor is zero, or current_msc is smaller than target_msc,
@@ -1106,7 +1107,7 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
vbl.request.type |= amdgpu_populate_vbl_request_type(crtc);
vbl.request.sequence = target_msc - msc_delta;
- vbl.request.signal = (unsigned long)wait;
+ vbl.request.signal = drm_queue_seq;
ret = drmWaitVBlank(pAMDGPUEnt->fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1138,7 +1139,7 @@ static int amdgpu_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw,
if ((current_msc % divisor) >= remainder)
vbl.request.sequence += divisor;
- vbl.request.signal = (unsigned long)wait;
+ vbl.request.signal = drm_queue_seq;
ret = drmWaitVBlank(pAMDGPUEnt->fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1190,7 +1191,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
drmVBlank vbl;
int ret, flip = 0;
DRI2FrameEventPtr swap_info = NULL;
- struct amdgpu_drm_queue_entry *swap;
+ uintptr_t drm_queue_seq;
CARD64 current_msc;
BoxRec box;
RegionRec region;
@@ -1227,15 +1228,15 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
swap_info->back = back;
swap_info->crtc = crtc;
- swap = amdgpu_drm_queue_alloc(crtc, client, AMDGPU_DRM_QUEUE_ID_DEFAULT,
- swap_info, amdgpu_dri2_frame_event_handler,
- amdgpu_dri2_frame_event_abort);
- if (!swap) {
+ drm_queue_seq = amdgpu_drm_queue_alloc(crtc, client, AMDGPU_DRM_QUEUE_ID_DEFAULT,
+ swap_info, amdgpu_dri2_frame_event_handler,
+ amdgpu_dri2_frame_event_abort);
+ if (!drm_queue_seq) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Allocating DRM queue entry failed.\n");
goto blit_fallback;
}
- swap_info->drm_queue = swap;
+ swap_info->drm_queue_seq = drm_queue_seq;
/*
* CRTC is in DPMS off state, fallback to blit, but calculate
@@ -1304,7 +1305,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
*target_msc = current_msc;
vbl.request.sequence = *target_msc - msc_delta;
- vbl.request.signal = (unsigned long)swap;
+ vbl.request.signal = drm_queue_seq;
ret = drmWaitVBlank(pAMDGPUEnt->fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
@@ -1350,7 +1351,7 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
/* Account for 1 frame extra pageflip delay if flip > 0 */
vbl.request.sequence -= flip;
- vbl.request.signal = (unsigned long)swap;
+ vbl.request.signal = drm_queue_seq;
ret = drmWaitVBlank(pAMDGPUEnt->fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,