|
@@ -51,6 +51,48 @@ static inline int mmu_get_tsize(int psize)
|
|
return mmu_psize_defs[psize].enc;
|
|
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)
|
|
static inline int book3e_tlb_exists(unsigned long ea, unsigned long pid)
|
|
{
|
|
{
|
|
int found = 0;
|
|
int found = 0;
|
|
@@ -109,7 +151,10 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
|
|
*/
|
|
*/
|
|
local_irq_save(flags);
|
|
local_irq_save(flags);
|
|
|
|
|
|
|
|
+ book3e_tlb_lock();
|
|
|
|
+
|
|
if (unlikely(book3e_tlb_exists(ea, mm->context.id))) {
|
|
if (unlikely(book3e_tlb_exists(ea, mm->context.id))) {
|
|
|
|
+ book3e_tlb_unlock();
|
|
local_irq_restore(flags);
|
|
local_irq_restore(flags);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -141,6 +186,7 @@ void book3e_hugetlb_preload(struct vm_area_struct *vma, unsigned long ea,
|
|
|
|
|
|
asm volatile ("tlbwe");
|
|
asm volatile ("tlbwe");
|
|
|
|
|
|
|
|
+ book3e_tlb_unlock();
|
|
local_irq_restore(flags);
|
|
local_irq_restore(flags);
|
|
}
|
|
}
|
|
|
|
|