diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index 116989cf3d4571e447291d9909743cdfa1850935..aa862b91d9a1a645ef18dd776e67c33d59f68c35 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -154,6 +154,59 @@ static const char * const proc_flag_strs[] = { "corrected", }; +static const char *const zdi_zpi_err_type_strs[] = { + "No Error", + "Training Error Status (PHY)", + "Data Link Protocol Error Status (DLL)", + "Surprise Down Error Status", + "Flow Control Protocol Error Status (TL)", + "Receiver Overflow Status (TL)", + "Receiver Error Status (PHY)", + "Bad TLP Status (DLL)", + "Bad Data Link Layer Packet (DLLP) Status (DLL)", + "REPLAY_NUM Rollover Status (DLL)", + "Replay Timer Timeout Status (DLL)", + "X16 Link Width Unreliable Status", + "ZPI X8 Link Width Unreliable Status", + "ZPI X4 Link Width Unreliable Status", + "ZPI X2 Link Width Unreliable Status", + "ZPI Gen3 Link Speed Unreliable Status", + "ZPI Gen2 Link Speed Unreliable Status", + "ZDI Gen3 Link Speed Unreliable Status", + "ZDI Gen4 Link Speed Unreliable Status", +}; + +const char *cper_zdi_zpi_err_type_str(unsigned int etype) +{ + return etype < ARRAY_SIZE(zdi_zpi_err_type_strs) ? + zdi_zpi_err_type_strs[etype] : "unknown error"; +} +EXPORT_SYMBOL_GPL(cper_zdi_zpi_err_type_str); + +static void cper_print_proc_generic_zdi_zpi(const char *pfx, + const struct cper_sec_proc_generic *zdi_zpi) +{ +#if IS_ENABLED(CONFIG_X86) + u8 etype = zdi_zpi->responder_id; + + if (boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN || + boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR) { + if ((zdi_zpi->requestor_id & 0xff) == 7) { + pr_info("%s general processor error(zpi error)\n", pfx); + } else if ((zdi_zpi->requestor_id & 0xff) == 6) { + pr_info("%s general processor error(zdi error)\n", pfx); + } else { + pr_info("%s general processor error(unknown error)\n", pfx); + return; + } + pr_info("%s bus number %llx device number %llx function number 0\n", pfx, + ((zdi_zpi->requestor_id)>>8) & 0xff, zdi_zpi->requestor_id & 0xff); + pr_info("%s apic id %lld error_type: %s\n", pfx, zdi_zpi->proc_id, + cper_zdi_zpi_err_type_str(etype)); + } +#endif +} + static void cper_print_proc_generic(const char *pfx, const struct cper_sec_proc_generic *proc) { @@ -197,6 +250,8 @@ static void cper_print_proc_generic(const char *pfx, pfx, proc->responder_id); if (proc->validation_bits & CPER_PROC_VALID_IP) printk("%s""IP: 0x%016llx\n", pfx, proc->ip); + + cper_print_proc_generic_zdi_zpi(pfx, proc); } static const char * const mem_err_type_strs[] = { diff --git a/include/linux/cper.h b/include/linux/cper.h index 9c703a0abe6edcb6d7613ffc2c2fade60f44095e..4376fa262c9fbf6dee1a37a249416cef478b82d5 100644 --- a/include/linux/cper.h +++ b/include/linux/cper.h @@ -553,5 +553,6 @@ void cper_print_proc_arm(const char *pfx, const struct cper_sec_proc_arm *proc); void cper_print_proc_ia(const char *pfx, const struct cper_sec_proc_ia *proc); +const char *cper_zdi_zpi_err_type_str(unsigned int etype); #endif