diff options
author | Lionel Landwerlin <[email protected]> | 2018-04-03 11:01:56 +0100 |
---|---|---|
committer | Lionel Landwerlin <[email protected]> | 2018-04-03 16:55:53 +0100 |
commit | 2841af6238b7648b388ba806f1ad181332b6eef0 (patch) | |
tree | e4d7e37c599e5c3609563662fa8f3800e5a040de | |
parent | 81375516b273094f29d4e1c4fcb90d832273690a (diff) |
intel: gen-decoder: don't decode fields beyond a dword length
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 <[email protected]>
Reviewed-by: Scott D Phillips <[email protected]>
-rw-r--r-- | src/intel/common/gen_decoder.c | 41 |
1 files 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; } |