[Mesa-dev] [PATCH 3/5] intel: gen-decoder: don't decode fields beyond a dword length
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Tue Apr 3 13:27:55 UTC 2018
For example, a PIPE_CONTROL with DWordLength = 2 should look like
this :
0xffffe374: 0x7a000002: PIPE_CONTROL
0xffffe374: 0x7a000002 : Dword 0
DWord Length: 2
0xffffe378: 0x00800000 : Dword 1
Depth Cache Flush Enable: false
Stall At Pixel Scoreboard: false
State Cache Invalidation Enable: false
Constant Cache Invalidation Enable: false
VF Cache Invalidation Enable: false
DC Flush Enable: false
Pipe Control Flush Enable: false
Notify Enable: false
Indirect State Pointers Disable: false
Texture Cache Invalidation Enable: false
Instruction Cache Invalidate Enable: false
Render Target Cache Flush Enable: false
Depth Stall Enable: false
Post Sync Operation: 0 (No Write)
Generic Media State Clear: false
TLB Invalidate: false
Global Snapshot Count Reset: false
Command Streamer Stall Enable: false
Store Data Index: 0
LRI Post Sync Operation: 1 (MMIO Write Immediate Data)
Destination Address Type: 0 (PPGTT)
Flush LLC: false
0xffffe37c: 0x00000000 : Dword 2
Address: 0x00000000
0xffffe384: 0x05000000: MI_BATCH_BUFFER_END
Prior to this change, fields beyond the length of the command would be
decoded (notice the MI_BATCH_BUFFER_END decoded as part of the
previous PIPE_CONTROL) :
0xffffe374: 0x7a000002: PIPE_CONTROL
0xffffe374: 0x7a000002 : Dword 0
DWord Length: 2
0xffffe378: 0x00800000 : Dword 1
Depth Cache Flush Enable: false
Stall At Pixel Scoreboard: false
State Cache Invalidation Enable: false
Constant Cache Invalidation Enable: false
VF Cache Invalidation Enable: false
DC Flush Enable: false
Pipe Control Flush Enable: false
Notify Enable: false
Indirect State Pointers Disable: false
Texture Cache Invalidation Enable: false
Instruction Cache Invalidate Enable: false
Render Target Cache Flush Enable: false
Depth Stall Enable: false
Post Sync Operation: 0 (No Write)
Generic Media State Clear: false
TLB Invalidate: false
Global Snapshot Count Reset: false
Command Streamer Stall Enable: false
Store Data Index: 0
LRI Post Sync Operation: 1 (MMIO Write Immediate Data)
Destination Address Type: 0 (PPGTT)
Flush LLC: false
0xffffe37c: 0x00000000 : Dword 2
Address: 0x00000000
0xffffe380: 0x00000000 : Dword 3
0xffffe384: 0x05000000 : Dword 4
Immediate Data: 83886080
0xffffe384: 0x05000000: MI_BATCH_BUFFER_END
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
src/intel/common/gen_decoder.c | 41 ++++++++++++++++++++++++++---------------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_decoder.c
index 7ca71c0d9fc..595fa29e43d 100644
--- a/src/intel/common/gen_decoder.c
+++ b/src/intel/common/gen_decoder.c
@@ -847,35 +847,38 @@ iter_advance_field(struct gen_field_iterator *iter)
return true;
}
-static uint64_t
-iter_decode_field_raw(struct gen_field_iterator *iter)
+static bool
+iter_decode_field_raw(struct gen_field_iterator *iter, uint64_t *qw)
{
- uint64_t qw = 0;
+ *qw = 0;
int field_start = iter->p_bit + iter->bit;
int field_end = field_start + (iter->field->end - iter->field->start);
const uint32_t *p = iter->p + (iter->bit / 32);
+ if (iter->p_end && p >= iter->p_end)
+ return false;
+
if ((field_end - field_start) > 32) {
- if ((p + 1) < iter->p_end)
- qw = ((uint64_t) p[1]) << 32;
- qw |= p[0];
+ if (!iter->p_end || (p + 1) < iter->p_end)
+ *qw = ((uint64_t) p[1]) << 32;
+ *qw |= p[0];
} else
- qw = p[0];
+ *qw = p[0];
- qw = field_value(qw, field_start, field_end);
+ *qw = field_value(*qw, field_start, field_end);
/* Address & offset types have to be aligned to dwords, their start bit is
* a reminder of the alignment requirement.
*/
if (iter->field->type.kind == GEN_TYPE_ADDRESS ||
iter->field->type.kind == GEN_TYPE_OFFSET)
- qw <<= field_start % 32;
+ *qw <<= field_start % 32;
- return qw;
+ return true;
}
-static void
+static bool
iter_decode_field(struct gen_field_iterator *iter)
{
union {
@@ -890,7 +893,8 @@ iter_decode_field(struct gen_field_iterator *iter)
memset(&v, 0, sizeof(v));
- iter->raw_value = iter_decode_field_raw(iter);
+ if (!iter_decode_field_raw(iter, &iter->raw_value))
+ return false;
const char *enum_name = NULL;
@@ -963,6 +967,8 @@ iter_decode_field(struct gen_field_iterator *iter)
" (%s)", fmt_name);
}
}
+
+ return true;
}
void
@@ -980,10 +986,14 @@ gen_field_iterator_init(struct gen_field_iterator *iter,
iter->field = group->next->fields;
iter->p = p;
iter->p_bit = p_bit;
- iter->p_end = &p[gen_group_get_length(iter->group, iter->p)];
+
+ int length = gen_group_get_length(iter->group, iter->p);
+ iter->p_end = length > 0 ? &p[length] : NULL;
iter->print_colors = print_colors;
- iter_decode_field(iter);
+ bool result = iter_decode_field(iter);
+ if (length >= 0)
+ assert(result);
}
bool
@@ -992,7 +1002,8 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
if (!iter_advance_field(iter))
return false;
- iter_decode_field(iter);
+ if (!iter_decode_field(iter))
+ return false;
return true;
}
--
2.16.3
More information about the mesa-dev
mailing list