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>
This commit is contained in:
parent
537f67f053
commit
a8dbf61b46
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue