summaryrefslogtreecommitdiff
path: root/drivers/firmware
diff options
context:
space:
mode:
authorYazen Ghannam <yazen.ghannam@amd.com>2018-05-04 07:59:56 +0200
committerIngo Molnar <mingo@kernel.org>2018-05-14 08:57:48 +0200
commit9c178663cbf2e754be322505078306b4a380a697 (patch)
tree94ce5c646e9b6ff050d03922d0969f14357f19b7 /drivers/firmware
parenta32bc29ed19776ef6827d6336847de9a0b7a8dc5 (diff)
efi: Decode IA32/X64 Context Info structure
Print the fields of the IA32/X64 Context Information structure. Print the "Register Array" as raw values. Some context types are defined in the UEFI spec, so more detailed decoded may be added in the future. Based on UEFI 2.7 section N.2.4.2.2 IA32/X64 Processor Context Information Structure. Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Matt Fleming <matt@codeblueprint.co.uk> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/20180504060003.19618-11-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efi/cper-x86.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/firmware/efi/cper-x86.c b/drivers/firmware/efi/cper-x86.c
index 356b8d326219..2531de49f56c 100644
--- a/drivers/firmware/efi/cper-x86.c
+++ b/drivers/firmware/efi/cper-x86.c
@@ -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);
+ }
}