From 311077c483200e3594a755bba3a4df0c5d561df7 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 6 Dec 2021 15:06:23 -0500 Subject: [PATCH] panfrost: Make pan_merge macro more robust Consider the following innocuous-looking code: pan_merge(packed, vtx->attributes[i], ATTRIBUTE); Under the current implementation, this code is completely broken. Why? The current implemention is a macro which hardcodes the loop index i, which shadows the i used to index attributes. Pull out a helper method so we do the right thing without resulting to further preprocessor abuse (__COUNTER__). While making things more robust, assert the crucial pan_merge invariant that the total size is a multiple of 4; if this fails, the routine risks memory corruption. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/panfrost/lib/genxml/gen_pack.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/panfrost/lib/genxml/gen_pack.py b/src/panfrost/lib/genxml/gen_pack.py index 93464525fb3..2a729f64ae0 100644 --- a/src/panfrost/lib/genxml/gen_pack.py +++ b/src/panfrost/lib/genxml/gen_pack.py @@ -176,11 +176,16 @@ __gen_unpack_padded(const uint8_t *restrict cl, uint32_t start, uint32_t end) #define pan_section_print(fp, A, S, var, indent) \\ PREFIX4(A, SECTION, S, print)(fp, &(var), indent) +static inline void pan_merge_helper(uint32_t *dst, const uint32_t *src, size_t bytes) +{ + assert((bytes & 3) == 0); + + for (unsigned i = 0; i < (bytes / 4); ++i) + dst[i] |= src[i]; +} + #define pan_merge(packed1, packed2, type) \ - do { \ - for (unsigned i = 0; i < (PREFIX2(type, LENGTH) / 4); ++i) \ - (packed1).opaque[i] |= (packed2).opaque[i]; \ - } while(0) + pan_merge_helper((packed1).opaque, (packed2).opaque, pan_size(type)) /* From presentations, 16x16 tiles externally. Use shift for fast computation * of tile numbers. */