|
@@ -10,6 +10,7 @@
|
|
|
#define VALID_LAPIC_ID BIT_ULL(0)
|
|
|
#define VALID_CPUID_INFO BIT_ULL(1)
|
|
|
#define VALID_PROC_ERR_INFO_NUM(bits) (((bits) & GENMASK_ULL(7, 2)) >> 2)
|
|
|
+#define VALID_PROC_CXT_INFO_NUM(bits) (((bits) & GENMASK_ULL(13, 8)) >> 8)
|
|
|
|
|
|
#define INFO_ERR_STRUCT_TYPE_CACHE \
|
|
|
GUID_INIT(0xA55701F5, 0xE3EF, 0x43DE, 0xAC, 0x72, 0x24, 0x9B, \
|
|
@@ -71,6 +72,9 @@
|
|
|
#define CHECK_MS_RESTARTABLE_IP BIT_ULL(22)
|
|
|
#define CHECK_MS_OVERFLOW BIT_ULL(23)
|
|
|
|
|
|
+#define CTX_TYPE_MSR 1
|
|
|
+#define CTX_TYPE_MMREG 7
|
|
|
+
|
|
|
enum err_types {
|
|
|
ERR_TYPE_CACHE = 0,
|
|
|
ERR_TYPE_TLB,
|
|
@@ -134,6 +138,17 @@ static const char * const ia_check_ms_error_type_strs[] = {
|
|
|
"Internal Unclassified",
|
|
|
};
|
|
|
|
|
|
+static const char * const ia_reg_ctx_strs[] = {
|
|
|
+ "Unclassified Data",
|
|
|
+ "MSR Registers (Machine Check and other MSRs)",
|
|
|
+ "32-bit Mode Execution Context",
|
|
|
+ "64-bit Mode Execution Context",
|
|
|
+ "FXSAVE Context",
|
|
|
+ "32-bit Mode Debug Registers (DR0-DR7)",
|
|
|
+ "64-bit Mode Debug Registers (DR0-DR7)",
|
|
|
+ "Memory Mapped Registers",
|
|
|
+};
|
|
|
+
|
|
|
static inline void print_bool(char *str, const char *pfx, u64 check, u64 bit)
|
|
|
{
|
|
|
printk("%s%s: %s\n", pfx, str, (check & bit) ? "true" : "false");
|
|
@@ -242,6 +257,7 @@ void cper_print_proc_ia(const char *pfx, const struct cper_sec_proc_ia *proc)
|
|
|
{
|
|
|
int i;
|
|
|
struct cper_ia_err_info *err_info;
|
|
|
+ struct cper_ia_proc_ctx *ctx_info;
|
|
|
char newpfx[64], infopfx[64];
|
|
|
u8 err_type;
|
|
|
|
|
@@ -305,4 +321,36 @@ void cper_print_proc_ia(const char *pfx, const struct cper_sec_proc_ia *proc)
|
|
|
|
|
|
err_info++;
|
|
|
}
|
|
|
+
|
|
|
+ ctx_info = (struct cper_ia_proc_ctx *)err_info;
|
|
|
+ for (i = 0; i < VALID_PROC_CXT_INFO_NUM(proc->validation_bits); i++) {
|
|
|
+ int size = sizeof(*ctx_info) + ctx_info->reg_arr_size;
|
|
|
+ int groupsize = 4;
|
|
|
+
|
|
|
+ printk("%sContext Information Structure %d:\n", pfx, i);
|
|
|
+
|
|
|
+ printk("%sRegister Context Type: %s\n", newpfx,
|
|
|
+ ctx_info->reg_ctx_type < ARRAY_SIZE(ia_reg_ctx_strs) ?
|
|
|
+ ia_reg_ctx_strs[ctx_info->reg_ctx_type] : "unknown");
|
|
|
+
|
|
|
+ printk("%sRegister Array Size: 0x%04x\n", newpfx,
|
|
|
+ ctx_info->reg_arr_size);
|
|
|
+
|
|
|
+ if (ctx_info->reg_ctx_type == CTX_TYPE_MSR) {
|
|
|
+ groupsize = 8; /* MSRs are 8 bytes wide. */
|
|
|
+ printk("%sMSR Address: 0x%08x\n", newpfx,
|
|
|
+ ctx_info->msr_addr);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ctx_info->reg_ctx_type == CTX_TYPE_MMREG) {
|
|
|
+ printk("%sMM Register Address: 0x%016llx\n", newpfx,
|
|
|
+ ctx_info->mm_reg_addr);
|
|
|
+ }
|
|
|
+
|
|
|
+ printk("%sRegister Array:\n", newpfx);
|
|
|
+ print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, groupsize,
|
|
|
+ (ctx_info + 1), ctx_info->reg_arr_size, 0);
|
|
|
+
|
|
|
+ ctx_info = (struct cper_ia_proc_ctx *)((long)ctx_info + size);
|
|
|
+ }
|
|
|
}
|