powerpc/64s: split do_hash_fault

This is required for subsequent interrupt wrapper implementation.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210130130852.2952424-16-npiggin@gmail.com
This commit is contained in:
Nicholas Piggin 2021-01-30 23:08:25 +10:00 committed by Michael Ellerman
parent f4c03b0e52
commit bf0e2374aa

View file

@ -1512,7 +1512,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
}
EXPORT_SYMBOL_GPL(hash_page);
long do_hash_fault(struct pt_regs *regs)
static long __do_hash_fault(struct pt_regs *regs)
{
unsigned long ea = regs->dar;
unsigned long dsisr = regs->dsisr;
@ -1522,27 +1522,6 @@ long do_hash_fault(struct pt_regs *regs)
unsigned int region_id;
long err;
if (unlikely(dsisr & (DSISR_BAD_FAULT_64S | DSISR_KEYFAULT)))
goto page_fault;
/*
* If we are in an "NMI" (e.g., an interrupt when soft-disabled), then
* don't call hash_page, just fail the fault. This is required to
* prevent re-entrancy problems in the hash code, namely perf
* interrupts hitting while something holds H_PAGE_BUSY, and taking a
* hash fault. See the comment in hash_preload().
*
* We come here as a result of a DSI at a point where we don't want
* to call hash_page, such as when we are accessing memory (possibly
* user memory) inside a PMU interrupt that occurred while interrupts
* were soft-disabled. We want to invoke the exception handler for
* the access, or panic if there isn't a handler.
*/
if (unlikely(in_nmi())) {
bad_page_fault(regs, SIGSEGV);
return 0;
}
region_id = get_region_id(ea);
if ((region_id == VMALLOC_REGION_ID) || (region_id == IO_REGION_ID))
mm = &init_mm;
@ -1581,8 +1560,39 @@ long do_hash_fault(struct pt_regs *regs)
bad_page_fault(regs, SIGBUS);
}
err = 0;
}
} else if (err) {
return err;
}
long do_hash_fault(struct pt_regs *regs)
{
unsigned long dsisr = regs->dsisr;
long err;
if (unlikely(dsisr & (DSISR_BAD_FAULT_64S | DSISR_KEYFAULT)))
goto page_fault;
/*
* If we are in an "NMI" (e.g., an interrupt when soft-disabled), then
* don't call hash_page, just fail the fault. This is required to
* prevent re-entrancy problems in the hash code, namely perf
* interrupts hitting while something holds H_PAGE_BUSY, and taking a
* hash fault. See the comment in hash_preload().
*
* We come here as a result of a DSI at a point where we don't want
* to call hash_page, such as when we are accessing memory (possibly
* user memory) inside a PMU interrupt that occurred while interrupts
* were soft-disabled. We want to invoke the exception handler for
* the access, or panic if there isn't a handler.
*/
if (unlikely(in_nmi())) {
bad_page_fault(regs, SIGSEGV);
return 0;
}
err = __do_hash_fault(regs);
if (err) {
page_fault:
err = do_page_fault(regs);
}