According with UEFI 6.4 spec Table 18.11 Generic Error Status Block:
Raw Data Offset: Offset in bytes from the beginning of the
Error Status Block to raw error data.
The raw data must follow any Generic Error
Data Entries.
Data Length: Length in bytes of the generic error data.
So, basically, we have:
+----------+ /
| GEBS | |
+----------+ / |
| GEDE | | |
| header | | +--> raw data
+----------+ +--> data | offset
| GEDE | | length |
| payload | | |
+----------+ / /
| Raw data |
+----------+
where:
- raw data offset is relative to the beginning of GEBS;
- data length is only for GEDE header and payload.
The previous code was not calculating it right, as it was
filling it with the size of GEBS and placing raw data before
payload.
This is not a problem with default values, as they set raw data
length to zero, but, at the moment raw data is filled, the
generated CPERs becomes invalid.
Fix the code to calculate the offset according with the specs.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
---
scripts/qmp_helper.py | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/scripts/qmp_helper.py b/scripts/qmp_helper.py
index ac3abc794c69..1587492807fe 100755
--- a/scripts/qmp_helper.py
+++ b/scripts/qmp_helper.py
@@ -411,6 +411,7 @@ def _connect(self):
"simulated": util.bit(2),
}
+ GENERIC_ERROR_STATUS_SIZE = 20
GENERIC_DATA_SIZE = 72
def argparse(parser):
@@ -551,7 +552,7 @@ def send_cper_raw(self, cper_data):
return False
- def get_gede(self, notif_type, cper_length):
+ def get_gede(self, notif_type, payload_length):
"""
Return a Generic Error Data Entry bytearray
"""
@@ -563,22 +564,27 @@ def get_gede(self, notif_type, cper_length):
util.data_add(gede, 0x300, 2)
util.data_add(gede, self.validation_bits, 1)
util.data_add(gede, self.flags, 1)
- util.data_add(gede, cper_length, 4)
+ util.data_add(gede, payload_length, 4)
gede.extend(self.fru_id)
gede.extend(self.fru_text)
gede.extend(self.timestamp)
return gede
- def get_gebs(self, data_length):
+ def get_gebs(self, payload_length):
"""
Return a Generic Error Status Block bytearray
"""
+ data_length = payload_length
+ data_length += self.GENERIC_DATA_SIZE
+
gebs = bytearray()
if self.raw_data:
- raw_data_offset = len(gebs)
+ raw_data_offset = payload_length
+ raw_data_offset += self.GENERIC_ERROR_STATUS_SIZE
+ raw_data_offset += self.GENERIC_DATA_SIZE
else:
raw_data_offset = 0
@@ -617,8 +623,7 @@ def send_cper(self, notif_type, payload,
if raw_data:
self.raw_data = raw_data
- cper_length = len(payload)
- data_length = cper_length + len(self.raw_data) + self.GENERIC_DATA_SIZE
+ payload_length = len(payload)
if gede and len(gede) != 72:
print(f"Invalid Generic Error Data Entry length: {len(gede)}. Ignoring it")
@@ -629,16 +634,16 @@ def send_cper(self, notif_type, payload,
gebs = None
if not gede:
- gede = self.get_gede(notif_type, cper_length)
+ gede = self.get_gede(notif_type, payload_length)
if not gebs:
- gebs = self.get_gebs(data_length)
+ gebs = self.get_gebs(payload_length)
cper_data = bytearray()
cper_data.extend(gebs)
cper_data.extend(gede)
- cper_data.extend(bytearray(self.raw_data))
cper_data.extend(bytearray(payload))
+ cper_data.extend(bytearray(self.raw_data))
if self.debug:
print(f"GUID: {notif_type}")
--
2.52.0