diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-09-26 23:23:47 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-09-27 10:47:18 +0100 |
commit | 6ac1ac98c28d38b539f465c5ac488d879f1c2ab6 (patch) | |
tree | 449febdd0d44dc5fffa425e8ba65ee6bad3e610b /src/sna/sna_glyphs.c | |
parent | 7025956558cfc391b553c9adb39d2a38fe494946 (diff) |
sna: Catch SIGBUS to prevent X death
We know that when we access either a CPU or GTT mmap we are vulernable
to receiving a SIGBUS. In fact, we can catch these and abort the
operation preventing X and all of its clients from randomly dieing.
This helps for instance if you try and use a 1GiB frontbuffer on a 2GiB
machine...
For complete protection, we also need to catch signals for all GTT maps,
such as VBO and staging buffers. (TBD)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_glyphs.c')
-rw-r--r-- | src/sna/sna_glyphs.c | 176 |
1 files changed, 92 insertions, 84 deletions
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c index b56c8440..b7ccb888 100644 --- a/src/sna/sna_glyphs.c +++ b/src/sna/sna_glyphs.c @@ -1627,21 +1627,25 @@ next: if (dst_image == NULL) goto out_free_src; - if (mask_format) { - pixman_composite_glyphs(op, src_image, dst_image, - mask_format->format | (mask_format->depth << 24), - src_x + src_dx + region.extents.x1 - dst_x, - src_y + src_dy + region.extents.y1 - dst_y, - region.extents.x1, region.extents.y1, - region.extents.x1 + dst_dx, region.extents.y1 + dst_dy, - region.extents.x2 - region.extents.x1, - region.extents.y2 - region.extents.y1, - cache, count, pglyphs); - } else { - pixman_composite_glyphs_no_mask(op, src_image, dst_image, - src_x + src_dx - dst_x, src_y + src_dy - dst_y, - dst_dx, dst_dy, + sigtrap_assert(); + if (sigtrap_get() == 0) { + if (mask_format) { + pixman_composite_glyphs(op, src_image, dst_image, + mask_format->format | (mask_format->depth << 24), + src_x + src_dx + region.extents.x1 - dst_x, + src_y + src_dy + region.extents.y1 - dst_y, + region.extents.x1, region.extents.y1, + region.extents.x1 + dst_dx, region.extents.y1 + dst_dy, + region.extents.x2 - region.extents.x1, + region.extents.y2 - region.extents.y1, cache, count, pglyphs); + } else { + pixman_composite_glyphs_no_mask(op, src_image, dst_image, + src_x + src_dx - dst_x, src_y + src_dy - dst_y, + dst_dx, dst_dy, + cache, count, pglyphs); + } + sigtrap_put(); } free_pixman_pict(dst, dst_image); @@ -1706,86 +1710,90 @@ out: src_y -= y - dst->pDrawable->y; } - do { - n = list->len; - x += list->xOff; - y += list->yOff; - while (n--) { - GlyphPtr g = *glyphs++; - pixman_image_t *glyph_image; + sigtrap_assert(); + if (sigtrap_get() == 0) { + do { + n = list->len; + x += list->xOff; + y += list->yOff; + while (n--) { + GlyphPtr g = *glyphs++; + pixman_image_t *glyph_image; - if (!glyph_valid(g)) - goto next_glyph; + if (!glyph_valid(g)) + goto next_glyph; - glyph_image = sna_glyph_get_image(g, screen); - if (glyph_image == NULL) - goto next_glyph; + glyph_image = sna_glyph_get_image(g, screen); + if (glyph_image == NULL) + goto next_glyph; - if (mask_format) { - DBG(("%s: glyph to mask (%d, %d)x(%d, %d)\n", - __FUNCTION__, - x - g->info.x, - y - g->info.y, - g->info.width, - g->info.height)); - - if (list->format == mask_format) { - assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image)); - pixman_image_composite(PictOpAdd, - glyph_image, - NULL, - mask_image, - 0, 0, - 0, 0, - x - g->info.x, - y - g->info.y, - g->info.width, - g->info.height); + if (mask_format) { + DBG(("%s: glyph to mask (%d, %d)x(%d, %d)\n", + __FUNCTION__, + x - g->info.x, + y - g->info.y, + g->info.width, + g->info.height)); + + if (list->format == mask_format) { + assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image)); + pixman_image_composite(PictOpAdd, + glyph_image, + NULL, + mask_image, + 0, 0, + 0, 0, + x - g->info.x, + y - g->info.y, + g->info.width, + g->info.height); + } else { + pixman_image_composite(PictOpAdd, + sna->render.white_image, + glyph_image, + mask_image, + 0, 0, + 0, 0, + x - g->info.x, + y - g->info.y, + g->info.width, + g->info.height); + } } else { - pixman_image_composite(PictOpAdd, - sna->render.white_image, + int xi = x - g->info.x; + int yi = y - g->info.y; + + DBG(("%s: glyph to dst (%d, %d)x(%d, %d)/[(%d, %d)x(%d, %d)], src (%d, %d) [op=%d]\n", + __FUNCTION__, + xi, yi, + g->info.width, g->info.height, + dst->pDrawable->x, + dst->pDrawable->y, + dst->pDrawable->width, + dst->pDrawable->height, + src_x + xi, + src_y + yi, + op)); + + pixman_image_composite(op, + src_image, glyph_image, - mask_image, + dst_image, + src_x + xi, + src_y + yi, 0, 0, - 0, 0, - x - g->info.x, - y - g->info.y, + xi, yi, g->info.width, g->info.height); } - } else { - int xi = x - g->info.x; - int yi = y - g->info.y; - - DBG(("%s: glyph to dst (%d, %d)x(%d, %d)/[(%d, %d)x(%d, %d)], src (%d, %d) [op=%d]\n", - __FUNCTION__, - xi, yi, - g->info.width, g->info.height, - dst->pDrawable->x, - dst->pDrawable->y, - dst->pDrawable->width, - dst->pDrawable->height, - src_x + xi, - src_y + yi, - op)); - - pixman_image_composite(op, - src_image, - glyph_image, - dst_image, - src_x + xi, - src_y + yi, - 0, 0, - xi, yi, - g->info.width, - g->info.height); - } next_glyph: - x += g->info.xOff; - y += g->info.yOff; - } - list++; - } while (--nlist); + x += g->info.xOff; + y += g->info.yOff; + } + list++; + } while (--nlist); + sigtrap_put(); + } if (mask_format) { DBG(("%s: glyph mask composite src=(%d+%d,%d+%d) dst=(%d, %d)x(%d, %d)\n", |