Commit 6a8dff6a authored by Markos Chandras's avatar Markos Chandras Committed by Ralf Baechle
Browse files

MIPS: tlb-r4k: Add missing HTW stop/start sequences



HTW needs to stop and start again whenever the EntryHI register
changes otherwise an inflight HTW operation might use the new
EntryHI register for updating an old entry and that could lead
to crashes or even a machine check exception. We fix this by
ensuring the HTW has stop whenever the EntryHI register is about
to change

Signed-off-by: default avatarMarkos Chandras <markos.chandras@imgtec.com>
Cc: <stable@vger.kernel.org> # v3.17+
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/8511/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 58563817
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -299,6 +299,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)

	local_irq_save(flags);

	htw_stop();
	pid = read_c0_entryhi() & ASID_MASK;
	address &= (PAGE_MASK << 1);
	write_c0_entryhi(address | pid);
@@ -346,6 +347,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
			tlb_write_indexed();
	}
	tlbw_use_hazard();
	htw_start();
	flush_itlb_vm(vma);
	local_irq_restore(flags);
}
@@ -422,6 +424,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,

	local_irq_save(flags);
	/* Save old context and create impossible VPN2 value */
	htw_stop();
	old_ctx = read_c0_entryhi();
	old_pagemask = read_c0_pagemask();
	wired = read_c0_wired();
@@ -443,6 +446,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,

	write_c0_entryhi(old_ctx);
	write_c0_pagemask(old_pagemask);
	htw_start();
out:
	local_irq_restore(flags);
	return ret;