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: Nicholas Piggin <npiggin@gmail.com>
[mpe: Fix implicit fallthrough warnings in mce_handle_error()]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190802105709.27696-10-npiggin@gmail.com
This commit is contained in:
Nicholas Piggin
2019-08-02 20:56:34 +10:00
committed by Michael Ellerman
parent 7290f3b3d3
commit 9ca766f989
3 changed files with 242 additions and 276 deletions

View File

@@ -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,
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;
int n = 0;
char dar_str[50];
@@ -410,6 +410,28 @@ void machine_check_print_event_info(struct machine_check_event *evt,
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) {
case MCE_ERROR_TYPE_UE:
err_type = "UE";
@@ -476,6 +498,14 @@ void machine_check_print_event_info(struct machine_check_event *evt,
if (evt->u.link_error.effective_address_provided)
ea = evt->u.link_error.effective_address;
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:
case MCE_ERROR_TYPE_UNKNOWN:
err_type = "Unknown";
@@ -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);
}
printk("%sMCE: CPU%d: Initiator %s\n", level, evt->cpu, initiator);
subtype = evt->error_class < ARRAY_SIZE(mc_error_class) ?
mc_error_class[evt->error_class] : "Unknown";
printk("%sMCE: CPU%d: %s\n", level, evt->cpu, subtype);