summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/mce.c
diff options
context:
space:
mode:
authorBalbir Singh <bsingharora@gmail.com>2017-09-29 14:26:53 +1000
committerMichael Ellerman <mpe@ellerman.id.au>2017-10-16 23:12:01 +1100
commitba41e1e1ccb9771ce41a3b8e2121f95486e76ac9 (patch)
treea6ca6c4b6e2cd1ce5eabf605b9ec2884fbf912de /arch/powerpc/kernel/mce.c
parent81b61fa7a065e639d097b09c303e3212e4264fac (diff)
downloadlinux-0-day-ba41e1e1ccb9771ce41a3b8e2121f95486e76ac9.tar.gz
linux-0-day-ba41e1e1ccb9771ce41a3b8e2121f95486e76ac9.tar.xz
powerpc/mce: Hookup derror (load/store) UE errors
Extract physical_address for UE errors by walking the page tables for the mm and address at the NIP, to extract the instruction. Then use the instruction to find the effective address via analyse_instr(). We might have page table walking races, but we expect them to be rare, the physical address extraction is best effort. The idea is to then hook up this infrastructure to memory failure eventually. Signed-off-by: Balbir Singh <bsingharora@gmail.com> Reviewed-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel/mce.c')
-rw-r--r--arch/powerpc/kernel/mce.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c
index d1775bdade72d..1af7c559edbc4 100644
--- a/arch/powerpc/kernel/mce.c
+++ b/arch/powerpc/kernel/mce.c
@@ -82,7 +82,7 @@ static void mce_set_error_info(struct machine_check_event *mce,
*/
void save_mce_event(struct pt_regs *regs, long handled,
struct mce_error_info *mce_err,
- uint64_t nip, uint64_t addr)
+ uint64_t nip, uint64_t addr, uint64_t phys_addr)
{
int index = __this_cpu_inc_return(mce_nest_count) - 1;
struct machine_check_event *mce = this_cpu_ptr(&mce_event[index]);
@@ -140,6 +140,10 @@ void save_mce_event(struct pt_regs *regs, long handled,
} else if (mce->error_type == MCE_ERROR_TYPE_UE) {
mce->u.ue_error.effective_address_provided = true;
mce->u.ue_error.effective_address = addr;
+ if (phys_addr != ULONG_MAX) {
+ mce->u.ue_error.physical_address_provided = true;
+ mce->u.ue_error.physical_address = phys_addr;
+ }
}
return;
}