Commit bf0e2374 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

powerpc/64s: split do_hash_fault



This is required for subsequent interrupt wrapper implementation.

Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210130130852.2952424-16-npiggin@gmail.com
parent f4c03b0e
Loading
Loading
Loading
Loading
+33 −23
Original line number Diff line number Diff line
@@ -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;
	}

	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;
	}

	} else if (err) {
	err = __do_hash_fault(regs);
	if (err) {
page_fault:
		err = do_page_fault(regs);
	}