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:
parent
f4c03b0e52
commit
bf0e2374aa
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user