Skip to content

Commit bcd896b

Browse files
committed
sparc64: Handle hugepage TSB being NULL.
Accomodate the possibility that the TSB might be NULL at the point that update_mmu_cache() is invoked. This is necessary because we will sometimes need to defer the TSB allocation to the first fault that happens in the 'mm'. Seperate out the hugepage PTE test into a seperate function so that the logic is clearer. Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent a55ee1f commit bcd896b

1 file changed

Lines changed: 22 additions & 16 deletions

File tree

arch/sparc/mm/init_64.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -314,16 +314,31 @@ static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_inde
314314
struct tsb *tsb = mm->context.tsb_block[tsb_index].tsb;
315315
unsigned long tag;
316316

317+
if (unlikely(!tsb))
318+
return;
319+
317320
tsb += ((address >> tsb_hash_shift) &
318321
(mm->context.tsb_block[tsb_index].tsb_nentries - 1UL));
319322
tag = (address >> 22UL);
320323
tsb_insert(tsb, tag, tte);
321324
}
322325

326+
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
327+
static inline bool is_hugetlb_pte(pte_t pte)
328+
{
329+
if ((tlb_type == hypervisor &&
330+
(pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
331+
(tlb_type != hypervisor &&
332+
(pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U))
333+
return true;
334+
return false;
335+
}
336+
#endif
337+
323338
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
324339
{
325-
unsigned long tsb_index, tsb_hash_shift, flags;
326340
struct mm_struct *mm;
341+
unsigned long flags;
327342
pte_t pte = *ptep;
328343

329344
if (tlb_type != hypervisor) {
@@ -335,25 +350,16 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *
335350

336351
mm = vma->vm_mm;
337352

338-
tsb_index = MM_TSB_BASE;
339-
tsb_hash_shift = PAGE_SHIFT;
340-
341353
spin_lock_irqsave(&mm->context.lock, flags);
342354

343355
#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
344-
if (mm->context.tsb_block[MM_TSB_HUGE].tsb != NULL) {
345-
if ((tlb_type == hypervisor &&
346-
(pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
347-
(tlb_type != hypervisor &&
348-
(pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U)) {
349-
tsb_index = MM_TSB_HUGE;
350-
tsb_hash_shift = HPAGE_SHIFT;
351-
}
352-
}
356+
if (mm->context.huge_pte_count && is_hugetlb_pte(pte))
357+
__update_mmu_tsb_insert(mm, MM_TSB_HUGE, HPAGE_SHIFT,
358+
address, pte_val(pte));
359+
else
353360
#endif
354-
355-
__update_mmu_tsb_insert(mm, tsb_index, tsb_hash_shift,
356-
address, pte_val(pte));
361+
__update_mmu_tsb_insert(mm, MM_TSB_BASE, PAGE_SHIFT,
362+
address, pte_val(pte));
357363

358364
spin_unlock_irqrestore(&mm->context.lock, flags);
359365
}

0 commit comments

Comments
 (0)