Commit c4335fdd authored by gengdongjiu's avatar gengdongjiu Committed by Rafael J. Wysocki

ACPI: APEI: fix the wrong iteration of generic error status block

The revision 0x300 generic error data entry is different
from the old version, but currently iterating through the
GHES estatus blocks does not take into account this difference.
This will lead to failure to get the right data entry if GHES
has revision 0x300 error data entry.

Update the GHES estatus iteration macro to properly increment using
acpi_hest_get_next(), and correct the iteration termination condition
because the status block data length only includes error data
length.

Convert the CPER estatus checking and printing iteration logic
to use same macro.
Signed-off-by: default avatarDongjiu Geng <gengdongjiu@huawei.com>
Tested-by: default avatarTyler Baicar <tbaicar@codeaurora.org>
Reviewed-by: default avatarBorislav Petkov <bp@suse.de>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent bdb9458a
...@@ -120,11 +120,6 @@ int apei_exec_collect_resources(struct apei_exec_context *ctx, ...@@ -120,11 +120,6 @@ int apei_exec_collect_resources(struct apei_exec_context *ctx,
struct dentry; struct dentry;
struct dentry *apei_get_debugfs_dir(void); struct dentry *apei_get_debugfs_dir(void);
#define apei_estatus_for_each_section(estatus, section) \
for (section = (struct acpi_hest_generic_data *)(estatus + 1); \
(void *)section - (void *)estatus < estatus->data_length; \
section = (void *)(section+1) + section->error_data_length)
static inline u32 cper_estatus_len(struct acpi_hest_generic_status *estatus) static inline u32 cper_estatus_len(struct acpi_hest_generic_status *estatus)
{ {
if (estatus->raw_data_length) if (estatus->raw_data_length)
......
...@@ -606,7 +606,6 @@ void cper_estatus_print(const char *pfx, ...@@ -606,7 +606,6 @@ void cper_estatus_print(const char *pfx,
const struct acpi_hest_generic_status *estatus) const struct acpi_hest_generic_status *estatus)
{ {
struct acpi_hest_generic_data *gdata; struct acpi_hest_generic_data *gdata;
unsigned int data_len;
int sec_no = 0; int sec_no = 0;
char newpfx[64]; char newpfx[64];
__u16 severity; __u16 severity;
...@@ -617,14 +616,10 @@ void cper_estatus_print(const char *pfx, ...@@ -617,14 +616,10 @@ void cper_estatus_print(const char *pfx,
"It has been corrected by h/w " "It has been corrected by h/w "
"and requires no further action"); "and requires no further action");
printk("%s""event severity: %s\n", pfx, cper_severity_str(severity)); printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));
data_len = estatus->data_length;
gdata = (struct acpi_hest_generic_data *)(estatus + 1);
snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP); snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
while (data_len >= acpi_hest_get_size(gdata)) { apei_estatus_for_each_section(estatus, gdata) {
cper_estatus_print_section(newpfx, gdata, sec_no); cper_estatus_print_section(newpfx, gdata, sec_no);
data_len -= acpi_hest_get_record_size(gdata);
gdata = acpi_hest_get_next(gdata);
sec_no++; sec_no++;
} }
} }
...@@ -653,15 +648,12 @@ int cper_estatus_check(const struct acpi_hest_generic_status *estatus) ...@@ -653,15 +648,12 @@ int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
if (rc) if (rc)
return rc; return rc;
data_len = estatus->data_length; data_len = estatus->data_length;
gdata = (struct acpi_hest_generic_data *)(estatus + 1);
while (data_len >= acpi_hest_get_size(gdata)) { apei_estatus_for_each_section(estatus, gdata) {
gedata_len = acpi_hest_get_error_length(gdata); gedata_len = acpi_hest_get_error_length(gdata);
if (gedata_len > data_len - acpi_hest_get_size(gdata)) if (gedata_len > data_len - acpi_hest_get_size(gdata))
return -EINVAL; return -EINVAL;
data_len -= acpi_hest_get_record_size(gdata); data_len -= acpi_hest_get_record_size(gdata);
gdata = acpi_hest_get_next(gdata);
} }
if (data_len) if (data_len)
return -EINVAL; return -EINVAL;
......
...@@ -113,6 +113,11 @@ static inline void *acpi_hest_get_next(struct acpi_hest_generic_data *gdata) ...@@ -113,6 +113,11 @@ static inline void *acpi_hest_get_next(struct acpi_hest_generic_data *gdata)
return (void *)(gdata) + acpi_hest_get_record_size(gdata); return (void *)(gdata) + acpi_hest_get_record_size(gdata);
} }
#define apei_estatus_for_each_section(estatus, section) \
for (section = (struct acpi_hest_generic_data *)(estatus + 1); \
(void *)section - (void *)(estatus + 1) < estatus->data_length; \
section = acpi_hest_get_next(section))
int ghes_notify_sea(void); int ghes_notify_sea(void);
#endif /* GHES_H */ #endif /* GHES_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment