sna: Add a few more checks for a hosted Xserver before walking CRTC lists

If we are hosted, we do not own the CRTC configuration, and deferencing
the private data structures believing them to be ours, only leads to
disaster.

Based on patches by Christopher James Halse Rogers.

Reported-by: Christopher James Halse Rogers <raof@ubuntu.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2013-08-25 10:49:57 +01:00
parent d7e6e9b83c
commit 097c256793
8 changed files with 33 additions and 28 deletions

View File

@ -389,7 +389,7 @@ to_sna_from_kgem(struct kgem *kgem)
#define MAX(a,b) ((a) >= (b) ? (a) : (b))
#endif
extern xf86CrtcPtr sna_covering_crtc(ScrnInfoPtr scrn,
extern xf86CrtcPtr sna_covering_crtc(struct sna *sna,
const BoxRec *box,
xf86CrtcPtr desired);

View File

@ -1004,6 +1004,7 @@ void sna_copy_fbcon(struct sna *sna)
return;
DBG(("%s\n", __FUNCTION__));
assert((sna->flags & SNA_IS_HOSTED) == 0);
priv = sna_pixmap(sna->front);
assert(priv && priv->gpu_bo);
@ -2736,6 +2737,7 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
DBG(("%s (%d, %d) -> (%d, %d)\n", __FUNCTION__,
scrn->virtualX, scrn->virtualY,
width, height));
assert((sna->flags & SNA_IS_HOSTED) == 0);
if (scrn->virtualX == width && scrn->virtualY == height)
return TRUE;
@ -2873,6 +2875,7 @@ sna_page_flip(struct sna *sna,
DBG(("%s: handle %d attached\n", __FUNCTION__, bo->handle));
assert(bo->refcnt);
assert((sna->flags & SNA_IS_HOSTED) == 0);
kgem_bo_submit(&sna->kgem, bo);
@ -2979,6 +2982,8 @@ static bool sna_probe_initial_configuration(struct sna *sna)
int width, height;
int i, j;
assert((sna->flags & SNA_IS_HOSTED) == 0);
if (xf86ReturnOptValBool(sna->Options, OPTION_REPROBE, FALSE))
return false;
@ -3278,16 +3283,17 @@ static int sna_box_area(const BoxRec *box)
* with greater coverage
*/
xf86CrtcPtr
sna_covering_crtc(ScrnInfoPtr scrn,
const BoxRec *box,
xf86CrtcPtr desired)
sna_covering_crtc(struct sna *sna, const BoxRec *box, xf86CrtcPtr desired)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn);
xf86CrtcPtr best_crtc;
int best_coverage, c;
if (sna->flags & SNA_IS_HOSTED)
return NULL;
/* If we do not own the VT, we do not own the CRTC either */
if (!scrn->vtSema)
if (!sna->scrn->vtSema)
return NULL;
DBG(("%s for box=(%d, %d), (%d, %d)\n",
@ -3616,6 +3622,9 @@ void sna_mode_update(struct sna *sna)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn);
int i;
if (sna->flags & SNA_IS_HOSTED)
return;
/* Validate CRTC attachments and force consistency upon the kernel */
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
@ -3906,6 +3915,7 @@ void sna_mode_redisplay(struct sna *sna)
return;
DBG(("%s: posting shadow damage\n", __FUNCTION__));
assert((sna->flags & SNA_IS_HOSTED) == 0);
assert(sna->mode.shadow_active);
region = DamageRegion(sna->mode.shadow_damage);

View File

@ -781,7 +781,7 @@ __sna_dri_copy_region(struct sna *sna, DrawablePtr draw, RegionPtr region,
crtc = NULL;
if (sync && sna_pixmap_is_scanout(sna, pixmap))
crtc = sna_covering_crtc(sna->scrn, &clip.extents, NULL);
crtc = sna_covering_crtc(sna, &clip.extents, NULL);
sna_dri_select_mode(sna, dst_bo, src_bo, crtc != NULL);
sync = (crtc != NULL&&
@ -885,22 +885,22 @@ static inline int sna_wait_vblank(struct sna *sna, drmVBlank *vbl)
#if DRI2INFOREC_VERSION >= 4
static int
sna_dri_get_pipe(DrawablePtr pDraw)
sna_dri_get_pipe(DrawablePtr draw)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pDraw->pScreen);
struct sna *sna = to_sna_from_drawable(draw);
xf86CrtcPtr crtc;
BoxRec box;
int pipe;
if (pDraw->type == DRAWABLE_PIXMAP)
if (draw->type == DRAWABLE_PIXMAP)
return -1;
box.x1 = pDraw->x;
box.y1 = pDraw->y;
box.x2 = box.x1 + pDraw->width;
box.y2 = box.y1 + pDraw->height;
box.x1 = draw->x;
box.y1 = draw->y;
box.x2 = box.x1 + draw->width;
box.y2 = box.y1 + draw->height;
crtc = sna_covering_crtc(pScrn, &box, NULL);
crtc = sna_covering_crtc(sna, &box, NULL);
/* Make sure the CRTC is valid and this is the real front buffer */
pipe = -1;

View File

@ -121,10 +121,9 @@ void sna_video_buffer_fini(struct sna_video *video)
}
bool
sna_video_clip_helper(ScrnInfoPtr scrn,
struct sna_video *video,
sna_video_clip_helper(struct sna_video *video,
struct sna_video_frame *frame,
xf86CrtcPtr * crtc_ret,
xf86CrtcPtr *crtc_ret,
BoxPtr dst,
short src_x, short src_y,
short drw_x, short drw_y,
@ -152,7 +151,7 @@ sna_video_clip_helper(ScrnInfoPtr scrn,
* For overlay video, compute the relevant CRTC and
* clip video to that
*/
crtc = sna_covering_crtc(scrn, dst, video->desired_crtc);
crtc = sna_covering_crtc(video->sna, dst, video->desired_crtc);
/* For textured video, we don't actually want to clip at all. */
if (crtc && !video->textured) {

View File

@ -162,10 +162,9 @@ static inline int is_planar_fourcc(int id)
}
bool
sna_video_clip_helper(ScrnInfoPtr scrn,
struct sna_video *adaptor_priv,
sna_video_clip_helper(struct sna_video *video,
struct sna_video_frame *frame,
xf86CrtcPtr * crtc_ret,
xf86CrtcPtr *crtc_ret,
BoxPtr dst,
short src_x, short src_y,
short drw_x, short drw_y,

View File

@ -524,8 +524,7 @@ sna_video_overlay_put_image(ClientPtr client,
sna_video_frame_init(video, format->id, width, height, &frame);
if (!sna_video_clip_helper(sna->scrn, video, &frame,
&crtc, &dstBox,
if (!sna_video_clip_helper(video, &frame, &crtc, &dstBox,
src_x, src_y, draw->x + drw_x, draw->y + drw_y,
src_w, src_h, drw_w, drw_h,
&clip))

View File

@ -366,8 +366,7 @@ static int sna_video_sprite_put_image(ClientPtr client,
sna_video_frame_init(video, format->id, width, height, &frame);
if (!sna_video_clip_helper(sna->scrn, video, &frame,
&crtc, &dst_box,
if (!sna_video_clip_helper(video, &frame, &crtc, &dst_box,
src_x, src_y, draw->x + drw_x, draw->y + drw_y,
src_w, src_h, drw_w, drw_h,
&clip))

View File

@ -205,8 +205,7 @@ sna_video_textured_put_image(ClientPtr client,
sna_video_frame_init(video, format->id, width, height, &frame);
if (!sna_video_clip_helper(sna->scrn, video, &frame,
&crtc, &dstBox,
if (!sna_video_clip_helper(video, &frame, &crtc, &dstBox,
src_x, src_y, drw_x + draw->x, drw_y + draw->y,
src_w, src_h, drw_w, drw_h,
&clip))