mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 22:51:35 +00:00
powerpc/powernv: Machine check handler for POWER10
Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20200702233343.1128026-1-npiggin@gmail.com
This commit is contained in:
parent
5a090f7c36
commit
201220bb0e
@ -86,6 +86,7 @@ enum MCE_TlbErrorType {
|
|||||||
enum MCE_UserErrorType {
|
enum MCE_UserErrorType {
|
||||||
MCE_USER_ERROR_INDETERMINATE = 0,
|
MCE_USER_ERROR_INDETERMINATE = 0,
|
||||||
MCE_USER_ERROR_TLBIE = 1,
|
MCE_USER_ERROR_TLBIE = 1,
|
||||||
|
MCE_USER_ERROR_SCV = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MCE_RaErrorType {
|
enum MCE_RaErrorType {
|
||||||
|
@ -66,6 +66,7 @@ struct dt_cpu_feature {
|
|||||||
|
|
||||||
extern long __machine_check_early_realmode_p8(struct pt_regs *regs);
|
extern long __machine_check_early_realmode_p8(struct pt_regs *regs);
|
||||||
extern long __machine_check_early_realmode_p9(struct pt_regs *regs);
|
extern long __machine_check_early_realmode_p9(struct pt_regs *regs);
|
||||||
|
extern long __machine_check_early_realmode_p10(struct pt_regs *regs);
|
||||||
|
|
||||||
static int hv_mode;
|
static int hv_mode;
|
||||||
|
|
||||||
@ -475,6 +476,14 @@ static int __init feat_enable_pmu_power10(struct dt_cpu_feature *f)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __init feat_enable_mce_power10(struct dt_cpu_feature *f)
|
||||||
|
{
|
||||||
|
cur_cpu_spec->platform = "power10";
|
||||||
|
cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p10;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int __init feat_enable_tm(struct dt_cpu_feature *f)
|
static int __init feat_enable_tm(struct dt_cpu_feature *f)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||||
@ -663,6 +672,7 @@ static struct dt_cpu_feature_match __initdata
|
|||||||
{"group-start-register", feat_enable, 0},
|
{"group-start-register", feat_enable, 0},
|
||||||
{"pc-relative-addressing", feat_enable, 0},
|
{"pc-relative-addressing", feat_enable, 0},
|
||||||
{"machine-check-power9", feat_enable_mce_power9, 0},
|
{"machine-check-power9", feat_enable_mce_power9, 0},
|
||||||
|
{"machine-check-power10", feat_enable_mce_power10, 0},
|
||||||
{"performance-monitor-power9", feat_enable_pmu_power9, 0},
|
{"performance-monitor-power9", feat_enable_pmu_power9, 0},
|
||||||
{"performance-monitor-power10", feat_enable_pmu_power10, 0},
|
{"performance-monitor-power10", feat_enable_pmu_power10, 0},
|
||||||
{"event-based-branch-v3", feat_enable, 0},
|
{"event-based-branch-v3", feat_enable, 0},
|
||||||
|
@ -385,6 +385,7 @@ void machine_check_print_event_info(struct machine_check_event *evt,
|
|||||||
static const char *mc_user_types[] = {
|
static const char *mc_user_types[] = {
|
||||||
"Indeterminate",
|
"Indeterminate",
|
||||||
"tlbie(l) invalid",
|
"tlbie(l) invalid",
|
||||||
|
"scv invalid",
|
||||||
};
|
};
|
||||||
static const char *mc_ra_types[] = {
|
static const char *mc_ra_types[] = {
|
||||||
"Indeterminate",
|
"Indeterminate",
|
||||||
|
@ -243,6 +243,45 @@ static const struct mce_ierror_table mce_p9_ierror_table[] = {
|
|||||||
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
{ 0, 0, 0, 0, 0, 0, 0 } };
|
{ 0, 0, 0, 0, 0, 0, 0 } };
|
||||||
|
|
||||||
|
static const struct mce_ierror_table mce_p10_ierror_table[] = {
|
||||||
|
{ 0x00000000081c0000, 0x0000000000040000, true,
|
||||||
|
MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000000081c0000, 0x0000000000080000, true,
|
||||||
|
MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000000081c0000, 0x00000000000c0000, true,
|
||||||
|
MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
|
||||||
|
{ 0x00000000081c0000, 0x0000000000100000, true,
|
||||||
|
MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
|
||||||
|
{ 0x00000000081c0000, 0x0000000000140000, true,
|
||||||
|
MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
|
||||||
|
{ 0x00000000081c0000, 0x0000000000180000, true,
|
||||||
|
MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_HARDWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000000081c0000, 0x00000000001c0000, true,
|
||||||
|
MCE_ERROR_TYPE_RA, MCE_RA_ERROR_IFETCH_FOREIGN, MCE_ECLASS_SOFTWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000000081c0000, 0x0000000008080000, true,
|
||||||
|
MCE_ERROR_TYPE_USER,MCE_USER_ERROR_SCV, MCE_ECLASS_SOFTWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
|
||||||
|
{ 0x00000000081c0000, 0x00000000080c0000, true,
|
||||||
|
MCE_ERROR_TYPE_RA, MCE_RA_ERROR_IFETCH, MCE_ECLASS_SOFTWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000000081c0000, 0x0000000008100000, true,
|
||||||
|
MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_SOFTWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000000081c0000, 0x0000000008140000, false,
|
||||||
|
MCE_ERROR_TYPE_RA, MCE_RA_ERROR_STORE, MCE_ECLASS_HARDWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_FATAL, false }, /* ASYNC is fatal */
|
||||||
|
{ 0x00000000081c0000, 0x00000000081c0000, true, MCE_ECLASS_HARDWARE,
|
||||||
|
MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH_FOREIGN,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0 } };
|
||||||
|
|
||||||
struct mce_derror_table {
|
struct mce_derror_table {
|
||||||
unsigned long dsisr_value;
|
unsigned long dsisr_value;
|
||||||
bool dar_valid; /* dar is a valid indicator of faulting address */
|
bool dar_valid; /* dar is a valid indicator of faulting address */
|
||||||
@ -361,6 +400,46 @@ static const struct mce_derror_table mce_p9_derror_table[] = {
|
|||||||
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
{ 0, false, 0, 0, 0, 0, 0 } };
|
{ 0, false, 0, 0, 0, 0, 0 } };
|
||||||
|
|
||||||
|
static const struct mce_derror_table mce_p10_derror_table[] = {
|
||||||
|
{ 0x00008000, false,
|
||||||
|
MCE_ERROR_TYPE_UE, MCE_UE_ERROR_LOAD_STORE, MCE_ECLASS_HARDWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00004000, true,
|
||||||
|
MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
|
||||||
|
MCE_ECLASS_HARDWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000800, true,
|
||||||
|
MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
|
||||||
|
{ 0x00000400, true,
|
||||||
|
MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
|
||||||
|
{ 0x00000200, false,
|
||||||
|
MCE_ERROR_TYPE_USER, MCE_USER_ERROR_TLBIE, MCE_ECLASS_SOFTWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
|
||||||
|
{ 0x00000080, true,
|
||||||
|
MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, /* Before PARITY */
|
||||||
|
MCE_ECLASS_SOFT_INDETERMINATE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
|
||||||
|
{ 0x00000100, true,
|
||||||
|
MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000040, true,
|
||||||
|
MCE_ERROR_TYPE_RA, MCE_RA_ERROR_LOAD, MCE_ECLASS_HARDWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000020, false,
|
||||||
|
MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
|
||||||
|
MCE_ECLASS_HARDWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000010, false,
|
||||||
|
MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE_FOREIGN,
|
||||||
|
MCE_ECLASS_HARDWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0x00000008, false,
|
||||||
|
MCE_ERROR_TYPE_RA, MCE_RA_ERROR_LOAD_STORE_FOREIGN, MCE_ECLASS_HARDWARE,
|
||||||
|
MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
|
||||||
|
{ 0, false, 0, 0, 0, 0, 0 } };
|
||||||
|
|
||||||
static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
|
static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
|
||||||
uint64_t *phys_addr)
|
uint64_t *phys_addr)
|
||||||
{
|
{
|
||||||
@ -657,3 +736,8 @@ long __machine_check_early_realmode_p9(struct pt_regs *regs)
|
|||||||
|
|
||||||
return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table);
|
return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long __machine_check_early_realmode_p10(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
return mce_handle_error(regs, mce_p10_derror_table, mce_p10_ierror_table);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user