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 +#include + #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