Commit 9ca766f9 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman

powerpc/64s/pseries: machine check convert to use common event code

The common machine_check_event data structures and queues are mostly
platform independent, with powernv decoding SRR1/DSISR/etc., into
machine_check_event objects.

This patch converts pseries to use this infrastructure by decoding
fwnmi/rtas data into machine_check_event objects.

This allows queueing to be used by a subsequent change to delay the
virtual mode handling of machine checks that occur in kernel space
where it is unsafe to switch immediately to virtual mode, similarly
to powernv.
Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
[mpe: Fix implicit fallthrough warnings in mce_handle_error()]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190802105709.27696-10-npiggin@gmail.com
parent 7290f3b3
...@@ -30,6 +30,10 @@ enum MCE_Disposition { ...@@ -30,6 +30,10 @@ enum MCE_Disposition {
enum MCE_Initiator { enum MCE_Initiator {
MCE_INITIATOR_UNKNOWN = 0, MCE_INITIATOR_UNKNOWN = 0,
MCE_INITIATOR_CPU = 1, MCE_INITIATOR_CPU = 1,
MCE_INITIATOR_PCI = 2,
MCE_INITIATOR_ISA = 3,
MCE_INITIATOR_MEMORY= 4,
MCE_INITIATOR_POWERMGM = 5,
}; };
enum MCE_ErrorType { enum MCE_ErrorType {
...@@ -41,6 +45,8 @@ enum MCE_ErrorType { ...@@ -41,6 +45,8 @@ enum MCE_ErrorType {
MCE_ERROR_TYPE_USER = 5, MCE_ERROR_TYPE_USER = 5,
MCE_ERROR_TYPE_RA = 6, MCE_ERROR_TYPE_RA = 6,
MCE_ERROR_TYPE_LINK = 7, MCE_ERROR_TYPE_LINK = 7,
MCE_ERROR_TYPE_DCACHE = 8,
MCE_ERROR_TYPE_ICACHE = 9,
}; };
enum MCE_ErrorClass { enum MCE_ErrorClass {
......
...@@ -325,7 +325,7 @@ static void machine_check_process_queued_event(struct irq_work *work) ...@@ -325,7 +325,7 @@ static void machine_check_process_queued_event(struct irq_work *work)
void machine_check_print_event_info(struct machine_check_event *evt, void machine_check_print_event_info(struct machine_check_event *evt,
bool user_mode, bool in_guest) bool user_mode, bool in_guest)
{ {
const char *level, *sevstr, *subtype, *err_type; const char *level, *sevstr, *subtype, *err_type, *initiator;
uint64_t ea = 0, pa = 0; uint64_t ea = 0, pa = 0;
int n = 0; int n = 0;
char dar_str[50]; char dar_str[50];
...@@ -410,6 +410,28 @@ void machine_check_print_event_info(struct machine_check_event *evt, ...@@ -410,6 +410,28 @@ void machine_check_print_event_info(struct machine_check_event *evt,
break; break;
} }
switch(evt->initiator) {
case MCE_INITIATOR_CPU:
initiator = "CPU";
break;
case MCE_INITIATOR_PCI:
initiator = "PCI";
break;
case MCE_INITIATOR_ISA:
initiator = "ISA";
break;
case MCE_INITIATOR_MEMORY:
initiator = "Memory";
break;
case MCE_INITIATOR_POWERMGM:
initiator = "Power Management";
break;
case MCE_INITIATOR_UNKNOWN:
default:
initiator = "Unknown";
break;
}
switch (evt->error_type) { switch (evt->error_type) {
case MCE_ERROR_TYPE_UE: case MCE_ERROR_TYPE_UE:
err_type = "UE"; err_type = "UE";
...@@ -476,6 +498,14 @@ void machine_check_print_event_info(struct machine_check_event *evt, ...@@ -476,6 +498,14 @@ void machine_check_print_event_info(struct machine_check_event *evt,
if (evt->u.link_error.effective_address_provided) if (evt->u.link_error.effective_address_provided)
ea = evt->u.link_error.effective_address; ea = evt->u.link_error.effective_address;
break; break;
case MCE_ERROR_TYPE_DCACHE:
err_type = "D-Cache";
subtype = "Unknown";
break;
case MCE_ERROR_TYPE_ICACHE:
err_type = "I-Cache";
subtype = "Unknown";
break;
default: default:
case MCE_ERROR_TYPE_UNKNOWN: case MCE_ERROR_TYPE_UNKNOWN:
err_type = "Unknown"; err_type = "Unknown";
...@@ -508,6 +538,8 @@ void machine_check_print_event_info(struct machine_check_event *evt, ...@@ -508,6 +538,8 @@ void machine_check_print_event_info(struct machine_check_event *evt,
level, evt->cpu, evt->srr0, (void *)evt->srr0, pa_str); level, evt->cpu, evt->srr0, (void *)evt->srr0, pa_str);
} }
printk("%sMCE: CPU%d: Initiator %s\n", level, evt->cpu, initiator);
subtype = evt->error_class < ARRAY_SIZE(mc_error_class) ? subtype = evt->error_class < ARRAY_SIZE(mc_error_class) ?
mc_error_class[evt->error_class] : "Unknown"; mc_error_class[evt->error_class] : "Unknown";
printk("%sMCE: CPU%d: %s\n", level, evt->cpu, subtype); printk("%sMCE: CPU%d: %s\n", level, evt->cpu, subtype);
......
This diff is collapsed.
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