Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48292738 authored by Chris Metcalf's avatar Chris Metcalf
Browse files

arch/tile: don't wait for migrating PTEs in an NMI handler



Doing so raises the possibility of self-deadlock if we are waiting
for a backtrace for an oprofile or perf interrupt while we are
in the middle of migrating our own stack page.

Signed-off-by: default avatarChris Metcalf <cmetcalf@tilera.com>
parent 6731aa9e
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -203,9 +203,14 @@ static pgd_t *get_current_pgd(void)
 * interrupt or a critical region, and must do as little as possible.
 * Similarly, we can't use atomic ops here, since we may be handling a
 * fault caused by an atomic op access.
 *
 * If we find a migrating PTE while we're in an NMI context, and we're
 * at a PC that has a registered exception handler, we don't wait,
 * since this thread may (e.g.) have been interrupted while migrating
 * its own stack, which would then cause us to self-deadlock.
 */
static int handle_migrating_pte(pgd_t *pgd, int fault_num,
				unsigned long address,
				unsigned long address, unsigned long pc,
				int is_kernel_mode, int write)
{
	pud_t *pud;
@@ -227,6 +232,8 @@ static int handle_migrating_pte(pgd_t *pgd, int fault_num,
		pte_offset_kernel(pmd, address);
	pteval = *pte;
	if (pte_migrating(pteval)) {
		if (in_nmi() && search_exception_tables(pc))
			return 0;
		wait_for_migration(pte);
		return 1;
	}
@@ -300,7 +307,7 @@ static int handle_page_fault(struct pt_regs *regs,
	 * rather than trying to patch up the existing PTE.
	 */
	pgd = get_current_pgd();
	if (handle_migrating_pte(pgd, fault_num, address,
	if (handle_migrating_pte(pgd, fault_num, address, regs->pc,
				 is_kernel_mode, write))
		return 1;

@@ -665,7 +672,7 @@ struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num,
	 */
	if (fault_num == INT_DTLB_ACCESS)
		write = 1;
	if (handle_migrating_pte(pgd, fault_num, address, 1, write))
	if (handle_migrating_pte(pgd, fault_num, address, pc, 1, write))
		return state;

	/* Return zero so that we continue on with normal fault handling. */