|
@@ -39,6 +39,7 @@
|
|
|
static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
|
|
static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
|
|
|
{
|
|
{
|
|
|
pte_t *ptep;
|
|
pte_t *ptep;
|
|
|
|
|
+ unsigned int shift;
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
struct mm_struct *mm;
|
|
struct mm_struct *mm;
|
|
|
|
|
|
|
@@ -48,13 +49,18 @@ static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
|
|
|
mm = &init_mm;
|
|
mm = &init_mm;
|
|
|
|
|
|
|
|
local_irq_save(flags);
|
|
local_irq_save(flags);
|
|
|
- if (mm == current->mm)
|
|
|
|
|
- ptep = find_current_mm_pte(mm->pgd, addr, NULL, NULL);
|
|
|
|
|
- else
|
|
|
|
|
- ptep = find_init_mm_pte(addr, NULL);
|
|
|
|
|
|
|
+ ptep = __find_linux_pte(mm->pgd, addr, NULL, &shift);
|
|
|
local_irq_restore(flags);
|
|
local_irq_restore(flags);
|
|
|
|
|
+
|
|
|
if (!ptep || pte_special(*ptep))
|
|
if (!ptep || pte_special(*ptep))
|
|
|
return ULONG_MAX;
|
|
return ULONG_MAX;
|
|
|
|
|
+
|
|
|
|
|
+ if (shift > PAGE_SHIFT) {
|
|
|
|
|
+ unsigned long rpnmask = (1ul << shift) - PAGE_SIZE;
|
|
|
|
|
+
|
|
|
|
|
+ return pte_pfn(__pte(pte_val(*ptep) | (addr & rpnmask)));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return pte_pfn(*ptep);
|
|
return pte_pfn(*ptep);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -339,7 +345,7 @@ static const struct mce_derror_table mce_p9_derror_table[] = {
|
|
|
MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
|
|
MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
|
|
|
{ 0, false, 0, 0, 0, 0 } };
|
|
{ 0, false, 0, 0, 0, 0 } };
|
|
|
|
|
|
|
|
-static int mce_find_instr_ea_and_pfn(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)
|
|
|
{
|
|
{
|
|
|
/*
|
|
/*
|
|
@@ -530,7 +536,8 @@ static int mce_handle_derror(struct pt_regs *regs,
|
|
|
* kernel/exception-64s.h
|
|
* kernel/exception-64s.h
|
|
|
*/
|
|
*/
|
|
|
if (get_paca()->in_mce < MAX_MCE_DEPTH)
|
|
if (get_paca()->in_mce < MAX_MCE_DEPTH)
|
|
|
- mce_find_instr_ea_and_pfn(regs, addr, phys_addr);
|
|
|
|
|
|
|
+ mce_find_instr_ea_and_phys(regs, addr,
|
|
|
|
|
+ phys_addr);
|
|
|
}
|
|
}
|
|
|
found = 1;
|
|
found = 1;
|
|
|
}
|
|
}
|