Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
[platform/adaptation/renesas_rcar/renesas_kernel.git] / arch / sparc64 / mm / init.c
index 2ae143b..ded63ee 100644 (file)
@@ -283,6 +283,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
        struct mm_struct *mm;
        struct tsb *tsb;
        unsigned long tag, flags;
+       unsigned long tsb_index, tsb_hash_shift;
 
        if (tlb_type != hypervisor) {
                unsigned long pfn = pte_pfn(pte);
@@ -312,10 +313,26 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
 
        mm = vma->vm_mm;
 
+       tsb_index = MM_TSB_BASE;
+       tsb_hash_shift = PAGE_SHIFT;
+
        spin_lock_irqsave(&mm->context.lock, flags);
 
-       tsb = &mm->context.tsb[(address >> PAGE_SHIFT) &
-                              (mm->context.tsb_nentries - 1UL)];
+#ifdef CONFIG_HUGETLB_PAGE
+       if (mm->context.tsb_block[MM_TSB_HUGE].tsb != NULL) {
+               if ((tlb_type == hypervisor &&
+                    (pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
+                   (tlb_type != hypervisor &&
+                    (pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U)) {
+                       tsb_index = MM_TSB_HUGE;
+                       tsb_hash_shift = HPAGE_SHIFT;
+               }
+       }
+#endif
+
+       tsb = mm->context.tsb_block[tsb_index].tsb;
+       tsb += ((address >> tsb_hash_shift) &
+               (mm->context.tsb_block[tsb_index].tsb_nentries - 1UL));
        tag = (address >> 22UL);
        tsb_insert(tsb, tag, pte_val(pte));