summaryrefslogtreecommitdiff
path: root/src/sna/sna_io.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-09-26 23:23:47 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-09-27 10:47:18 +0100
commit6ac1ac98c28d38b539f465c5ac488d879f1c2ab6 (patch)
tree449febdd0d44dc5fffa425e8ba65ee6bad3e610b /src/sna/sna_io.c
parent7025956558cfc391b553c9adb39d2a38fe494946 (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_io.c')
-rw-r--r--src/sna/sna_io.c126
1 files changed, 81 insertions, 45 deletions
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 746b1226..d66668c4 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -113,6 +113,11 @@ read_boxes_inplace__cpu(struct kgem *kgem,
return false;
kgem_bo_sync__cpu_full(kgem, bo, 0);
+
+ sigtrap_assert();
+ if (sigtrap_get())
+ return false;
+
if (bo->tiling == I915_TILING_X) {
assert(kgem->memcpy_from_tiled_x);
do {
@@ -132,6 +137,7 @@ read_boxes_inplace__cpu(struct kgem *kgem,
} while (--n);
}
+ sigtrap_put();
return true;
}
@@ -158,6 +164,10 @@ static void read_boxes_inplace(struct kgem *kgem,
if (src == NULL)
return;
+ sigtrap_assert();
+ if (sigtrap_get())
+ return;
+
assert(src != dst);
do {
DBG(("%s: copying box (%d, %d), (%d, %d)\n",
@@ -183,6 +193,8 @@ static void read_boxes_inplace(struct kgem *kgem,
box->x2 - box->x1, box->y2 - box->y1);
box++;
} while (--n);
+
+ sigtrap_put();
}
static bool download_inplace(struct kgem *kgem,
@@ -578,6 +590,11 @@ write_boxes_inplace__tiled(struct kgem *kgem,
return false;
kgem_bo_sync__cpu(kgem, bo);
+
+ sigtrap_assert();
+ if (sigtrap_get())
+ return false;
+
do {
memcpy_to_tiled_x(kgem, src, dst, bpp, stride, bo->pitch,
box->x1 + src_dx, box->y1 + src_dy,
@@ -586,6 +603,7 @@ write_boxes_inplace__tiled(struct kgem *kgem,
box++;
} while (--n);
+ sigtrap_put();
return true;
}
@@ -615,6 +633,10 @@ static bool write_boxes_inplace(struct kgem *kgem,
assert(dst != src);
+ sigtrap_assert();
+ if (sigtrap_get())
+ return false;
+
do {
DBG(("%s: (%d, %d) -> (%d, %d) x (%d, %d) [bpp=%d, src_pitch=%d, dst_pitch=%d]\n", __FUNCTION__,
box->x1 + src_dx, box->y1 + src_dy,
@@ -641,6 +663,8 @@ static bool write_boxes_inplace(struct kgem *kgem,
box->x2 - box->x1, box->y2 - box->y1);
box++;
} while (--n);
+
+ sigtrap_put();
return true;
}
@@ -794,37 +818,41 @@ tile:
goto fallback;
}
- c = clipped;
- for (n = 0; n < nbox; n++) {
- *c = box[n];
- if (!box_intersect(c, &tile))
- continue;
-
- DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n",
- __FUNCTION__,
- c->x1, c->y1,
- c->x2, c->y2,
- src_dx, src_dy,
- c->x1 - tile.x1,
- c->y1 - tile.y1));
- memcpy_blt(src, ptr, tmp.drawable.bitsPerPixel,
- stride, src_bo->pitch,
- c->x1 + src_dx,
- c->y1 + src_dy,
- c->x1 - tile.x1,
- c->y1 - tile.y1,
- c->x2 - c->x1,
- c->y2 - c->y1);
- c++;
- }
-
- if (c != clipped)
- n = sna->render.copy_boxes(sna, GXcopy,
- &tmp, src_bo, -tile.x1, -tile.y1,
- dst, dst_bo, dst_dx, dst_dy,
- clipped, c - clipped, 0);
- else
- n = 1;
+ if (sigtrap_get() == 0) {
+ c = clipped;
+ for (n = 0; n < nbox; n++) {
+ *c = box[n];
+ if (!box_intersect(c, &tile))
+ continue;
+
+ DBG(("%s: box(%d, %d), (%d, %d), src=(%d, %d), dst=(%d, %d)\n",
+ __FUNCTION__,
+ c->x1, c->y1,
+ c->x2, c->y2,
+ src_dx, src_dy,
+ c->x1 - tile.x1,
+ c->y1 - tile.y1));
+ memcpy_blt(src, ptr, tmp.drawable.bitsPerPixel,
+ stride, src_bo->pitch,
+ c->x1 + src_dx,
+ c->y1 + src_dy,
+ c->x1 - tile.x1,
+ c->y1 - tile.y1,
+ c->x2 - c->x1,
+ c->y2 - c->y1);
+ c++;
+ }
+
+ if (c != clipped)
+ n = sna->render.copy_boxes(sna, GXcopy,
+ &tmp, src_bo, -tile.x1, -tile.y1,
+ dst, dst_bo, dst_dx, dst_dy,
+ clipped, c - clipped, 0);
+ else
+ n = 1;
+ sigtrap_put();
+ } else
+ n = 0;
kgem_bo_destroy(&sna->kgem, src_bo);
@@ -1408,21 +1436,26 @@ indirect_replace(struct sna *sna,
if (!src_bo)
return false;
- memcpy_blt(src, ptr, pixmap->drawable.bitsPerPixel,
- stride, src_bo->pitch,
- 0, 0,
- 0, 0,
- pixmap->drawable.width,
- pixmap->drawable.height);
+ sigtrap_assert();
+ if (sigtrap_get() == 0) {
+ memcpy_blt(src, ptr, pixmap->drawable.bitsPerPixel,
+ stride, src_bo->pitch,
+ 0, 0,
+ 0, 0,
+ pixmap->drawable.width,
+ pixmap->drawable.height);
- box.x1 = box.y1 = 0;
- box.x2 = pixmap->drawable.width;
- box.y2 = pixmap->drawable.height;
+ box.x1 = box.y1 = 0;
+ box.x2 = pixmap->drawable.width;
+ box.y2 = pixmap->drawable.height;
- ret = sna->render.copy_boxes(sna, GXcopy,
- pixmap, src_bo, 0, 0,
- pixmap, bo, 0, 0,
- &box, 1, 0);
+ ret = sna->render.copy_boxes(sna, GXcopy,
+ pixmap, src_bo, 0, 0,
+ pixmap, bo, 0, 0,
+ &box, 1, 0);
+ sigtrap_put();
+ } else
+ ret = false;
kgem_bo_destroy(kgem, src_bo);
@@ -1485,14 +1518,17 @@ bool sna_replace(struct sna *sna,
goto done;
}
+ sigtrap_assert();
if (kgem_bo_is_mappable(kgem, bo) &&
- (dst = kgem_bo_map(kgem, bo)) != NULL) {
+ (dst = kgem_bo_map(kgem, bo)) != NULL &&
+ sigtrap_get() == 0) {
memcpy_blt(src, dst, pixmap->drawable.bitsPerPixel,
stride, bo->pitch,
0, 0,
0, 0,
pixmap->drawable.width,
pixmap->drawable.height);
+ sigtrap_put();
} else {
BoxRec box;