lkml.org 
[lkml]   [2019]   [Oct]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.3 022/148] powerpc/mce: Fix MCE handling for huge pages
    Date
    From: Balbir Singh <bsingharora@gmail.com>

    commit 99ead78afd1128bfcebe7f88f3b102fb2da09aee upstream.

    The current code would fail on huge pages addresses, since the shift would
    be incorrect. Use the correct page shift value returned by
    __find_linux_pte() to get the correct physical address. The code is more
    generic and can handle both regular and compound pages.

    Fixes: ba41e1e1ccb9 ("powerpc/mce: Hookup derror (load/store) UE errors")
    Signed-off-by: Balbir Singh <bsingharora@gmail.com>
    [arbab@linux.ibm.com: Fixup pseries_do_memory_failure()]
    Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
    Tested-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
    Signed-off-by: Santosh Sivaraj <santosh@fossix.org>
    Cc: stable@vger.kernel.org # v4.15+
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20190820081352.8641-3-santosh@fossix.org
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/powerpc/kernel/mce_power.c | 19 +++++++++++++------
    1 file changed, 13 insertions(+), 6 deletions(-)

    --- a/arch/powerpc/kernel/mce_power.c
    +++ b/arch/powerpc/kernel/mce_power.c
    @@ -26,6 +26,7 @@
    unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
    {
    pte_t *ptep;
    + unsigned int shift;
    unsigned long flags;
    struct mm_struct *mm;

    @@ -35,13 +36,18 @@ unsigned long addr_to_pfn(struct pt_regs
    mm = &init_mm;

    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);
    +
    if (!ptep || pte_special(*ptep))
    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);
    }

    @@ -344,7 +350,7 @@ static const struct mce_derror_table mce
    MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
    { 0, false, 0, 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)
    {
    /*
    @@ -541,7 +547,8 @@ static int mce_handle_derror(struct pt_r
    * kernel/exception-64s.h
    */
    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;
    }

    \
     
     \ /
      Last update: 2019-10-10 10:39    [W:9.589 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site