Mesa (main): panfrost: Add a debug option for checking overflows on pool uploads

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Jul 23 01:13:20 UTC 2022


Module: Mesa
Branch: main
Commit: a8dbf61b461a3cf0fc2e8fd92d4e669e785ad60b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a8dbf61b461a3cf0fc2e8fd92d4e669e785ad60b

Author: Icecream95 <ixn at disroot.org>
Date:   Sun Jul 10 21:10:19 2022 +1200

panfrost: Add a debug option for checking overflows on pool uploads

PAN_MESA_DEBUG=overflow will place objects as close as possible to a
protected region at the end of the buffer, so that overflows segfault.

Caught the bugs in all four of the preceding commits.

v2: memset the BO to 0xbb to catch code expecting zeroed allocations.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17447>

---

 src/gallium/drivers/panfrost/pan_mempool.c | 26 ++++++++++++++++++++++++++
 src/gallium/drivers/panfrost/pan_screen.c  |  3 +++
 src/panfrost/lib/pan_util.h                |  4 ++++
 3 files changed, 33 insertions(+)

diff --git a/src/gallium/drivers/panfrost/pan_mempool.c b/src/gallium/drivers/panfrost/pan_mempool.c
index a0ec486450a..1757e99b87c 100644
--- a/src/gallium/drivers/panfrost/pan_mempool.c
+++ b/src/gallium/drivers/panfrost/pan_mempool.c
@@ -23,6 +23,9 @@
  *
  */
 
+#include <unistd.h>
+#include <sys/mman.h>
+
 #include "pan_device.h"
 #include "pan_mempool.h"
 
@@ -115,6 +118,8 @@ panfrost_pool_get_bo_handles(struct panfrost_pool *pool, uint32_t *handles)
         }
 }
 
+#define PAN_GUARD_SIZE 4096
+
 static struct panfrost_ptr
 panfrost_pool_alloc_aligned(struct panfrost_pool *pool, size_t sz, unsigned alignment)
 {
@@ -124,6 +129,27 @@ panfrost_pool_alloc_aligned(struct panfrost_pool *pool, size_t sz, unsigned alig
         struct panfrost_bo *bo = pool->transient_bo;
         unsigned offset = ALIGN_POT(pool->transient_offset, alignment);
 
+#ifdef PAN_DBG_OVERFLOW
+        if (unlikely(pool->base.dev->debug & PAN_DBG_OVERFLOW) &&
+            !(pool->base.create_flags & PAN_BO_INVISIBLE)) {
+                unsigned aligned = ALIGN_POT(sz, sysconf(_SC_PAGESIZE));
+                unsigned bo_size = aligned + PAN_GUARD_SIZE;
+
+                bo = panfrost_pool_alloc_backing(pool, bo_size);
+                memset(bo->ptr.cpu, 0xbb, bo_size);
+
+                /* Place the object as close as possible to the protected
+                 * region at the end of the buffer while keeping alignment. */
+                offset = ROUND_DOWN_TO(aligned - sz, alignment);
+
+                if (mprotect(bo->ptr.cpu + aligned,
+                             PAN_GUARD_SIZE, PROT_NONE) == -1)
+                        perror("mprotect");
+
+                pool->transient_bo = NULL;
+        }
+#endif
+
         /* If we don't fit, allocate a new backing */
         if (unlikely(bo == NULL || (offset + sz) >= pool->base.slab_size)) {
                 bo = panfrost_pool_alloc_backing(pool,
diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c
index a023d129c2f..516131640cc 100644
--- a/src/gallium/drivers/panfrost/pan_screen.c
+++ b/src/gallium/drivers/panfrost/pan_screen.c
@@ -69,6 +69,9 @@ static const struct debug_named_value panfrost_debug_options[] = {
         {"linear",    PAN_DBG_LINEAR,   "Force linear textures"},
         {"nocache",   PAN_DBG_NO_CACHE, "Disable BO cache"},
         {"dump",      PAN_DBG_DUMP,     "Dump all graphics memory"},
+#ifdef PAN_DBG_OVERFLOW
+        {"overflow",  PAN_DBG_OVERFLOW, "Check for buffer overflows in pool uploads"},
+#endif
         DEBUG_NAMED_VALUE_END
 };
 
diff --git a/src/panfrost/lib/pan_util.h b/src/panfrost/lib/pan_util.h
index 8d8a2e20b88..39628904faa 100644
--- a/src/panfrost/lib/pan_util.h
+++ b/src/panfrost/lib/pan_util.h
@@ -48,6 +48,10 @@
 #define PAN_DBG_NO_CACHE        0x2000
 #define PAN_DBG_DUMP            0x4000
 
+#ifndef NDEBUG
+#define PAN_DBG_OVERFLOW        0x8000
+#endif
+
 struct panfrost_device;
 
 unsigned



More information about the mesa-commit mailing list