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

Commit 2749539b authored by Scott Wood's avatar Scott Wood
Browse files

powerpc/e6500: add locking to hugetlb



e6500 has threads but does not have TLB write conditional.  Thus,
the hugetlb code needs to take the same lock that the normal TLB miss
handlers take, to ensure that the tlbsx and tlbwe are atomic.

Signed-off-by: default avatarScott Wood <scottwood@freescale.com>
parent 9d68e7ac
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -51,6 +51,48 @@ static inline int mmu_get_tsize(int psize)
	return mmu_psize_defs[psize].enc;
}

#if defined(CONFIG_PPC_FSL_BOOK3E) && defined(CONFIG_PPC64)
#include <asm/paca.h>

static inline void book3e_tlb_lock(void)
{
	struct paca_struct *paca = get_paca();
	unsigned long tmp;
	int token = smp_processor_id() + 1;

	asm volatile("1: lbarx %0, 0, %1;"
		     "cmpwi %0, 0;"
		     "bne 2f;"
		     "stbcx. %2, 0, %1;"
		     "bne 1b;"
		     "b 3f;"
		     "2: lbzx %0, 0, %1;"
		     "cmpwi %0, 0;"
		     "bne 2b;"
		     "b 1b;"
		     "3:"
		     : "=&r" (tmp)
		     : "r" (&paca->tcd_ptr->lock), "r" (token)
		     : "memory");
}

static inline void book3e_tlb_unlock(void)
{
	struct paca_struct *paca = get_paca();

	isync();
	paca->tcd_ptr->lock = 0;
}
#else
static inline void book3e_tlb_lock(void)
{
}

static inline void book3e_tlb_unlock(void)
{
}
#endif

static inline int book3e_tlb_exists(unsigned long ea, unsigned long pid)
{
	int found = 0;
@@ -109,7 +151,10 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
	 */
	local_irq_save(flags);

	book3e_tlb_lock();

	if (unlikely(book3e_tlb_exists(ea, mm->context.id))) {
		book3e_tlb_unlock();
		local_irq_restore(flags);
		return;
	}
@@ -141,6 +186,7 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,

	asm volatile ("tlbwe");

	book3e_tlb_unlock();
	local_irq_restore(flags);
}