Skip to content

Commit a37102d

Browse files
committed
Merge branch 'parisc-4.9-5' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc fixes from Helge Deller: "Three important fixes for the parisc architecture. Dave provided two patches: One which purges the TLB before setting a PTE entry and a second one which drops unnecessary TLB flushes. Both patches have been tested for one week on the debian buildd servers and prevent random segmentation faults. The patch from me fixes a crash at boot inside the TLB measuring code on SMP machines with PA8000-PA8700 CPUs (specifically A500-44 and J5000 servers)" * 'parisc-4.9-5' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: parisc: Fix TLB related boot crash on SMP machines parisc: Remove unnecessary TLB purges from flush_dcache_page_asm and flush_icache_page_asm parisc: Purge TLB before setting PTE
2 parents b4aafe7 + 24d0492 commit a37102d

3 files changed

Lines changed: 16 additions & 25 deletions

File tree

arch/parisc/include/asm/pgtable.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
6565
unsigned long flags; \
6666
spin_lock_irqsave(&pa_tlb_lock, flags); \
6767
old_pte = *ptep; \
68-
set_pte(ptep, pteval); \
6968
if (pte_inserted(old_pte)) \
7069
purge_tlb_entries(mm, addr); \
70+
set_pte(ptep, pteval); \
7171
spin_unlock_irqrestore(&pa_tlb_lock, flags); \
7272
} while (0)
7373

@@ -478,8 +478,8 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned
478478
spin_unlock_irqrestore(&pa_tlb_lock, flags);
479479
return 0;
480480
}
481-
set_pte(ptep, pte_mkold(pte));
482481
purge_tlb_entries(vma->vm_mm, addr);
482+
set_pte(ptep, pte_mkold(pte));
483483
spin_unlock_irqrestore(&pa_tlb_lock, flags);
484484
return 1;
485485
}
@@ -492,9 +492,9 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
492492

493493
spin_lock_irqsave(&pa_tlb_lock, flags);
494494
old_pte = *ptep;
495-
set_pte(ptep, __pte(0));
496495
if (pte_inserted(old_pte))
497496
purge_tlb_entries(mm, addr);
497+
set_pte(ptep, __pte(0));
498498
spin_unlock_irqrestore(&pa_tlb_lock, flags);
499499

500500
return old_pte;
@@ -504,8 +504,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
504504
{
505505
unsigned long flags;
506506
spin_lock_irqsave(&pa_tlb_lock, flags);
507-
set_pte(ptep, pte_wrprotect(*ptep));
508507
purge_tlb_entries(mm, addr);
508+
set_pte(ptep, pte_wrprotect(*ptep));
509509
spin_unlock_irqrestore(&pa_tlb_lock, flags);
510510
}
511511

arch/parisc/kernel/cache.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,15 @@ void __init parisc_setup_cache_timing(void)
393393

394394
/* calculate TLB flush threshold */
395395

396+
/* On SMP machines, skip the TLB measure of kernel text which
397+
* has been mapped as huge pages. */
398+
if (num_online_cpus() > 1 && !parisc_requires_coherency()) {
399+
threshold = max(cache_info.it_size, cache_info.dt_size);
400+
threshold *= PAGE_SIZE;
401+
threshold /= num_online_cpus();
402+
goto set_tlb_threshold;
403+
}
404+
396405
alltime = mfctl(16);
397406
flush_tlb_all();
398407
alltime = mfctl(16) - alltime;
@@ -411,6 +420,8 @@ void __init parisc_setup_cache_timing(void)
411420
alltime, size, rangetime);
412421

413422
threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime);
423+
424+
set_tlb_threshold:
414425
if (threshold)
415426
parisc_tlb_flush_threshold = threshold;
416427
printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",

arch/parisc/kernel/pacache.S

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -892,19 +892,10 @@ ENTRY_CFI(flush_dcache_page_asm)
892892
fdc,m r31(%r28)
893893
fdc,m r31(%r28)
894894
fdc,m r31(%r28)
895-
cmpb,COND(<<) %r28, %r25,1b
895+
cmpb,COND(<<) %r28, %r25,1b
896896
fdc,m r31(%r28)
897897

898898
sync
899-
900-
#ifdef CONFIG_PA20
901-
pdtlb,l %r0(%r25)
902-
#else
903-
tlb_lock %r20,%r21,%r22
904-
pdtlb %r0(%r25)
905-
tlb_unlock %r20,%r21,%r22
906-
#endif
907-
908899
bv %r0(%r2)
909900
nop
910901
.exit
@@ -979,17 +970,6 @@ ENTRY_CFI(flush_icache_page_asm)
979970
fic,m %r31(%sr4,%r28)
980971

981972
sync
982-
983-
#ifdef CONFIG_PA20
984-
pdtlb,l %r0(%r28)
985-
pitlb,l %r0(%sr4,%r25)
986-
#else
987-
tlb_lock %r20,%r21,%r22
988-
pdtlb %r0(%r28)
989-
pitlb %r0(%sr4,%r25)
990-
tlb_unlock %r20,%r21,%r22
991-
#endif
992-
993973
bv %r0(%r2)
994974
nop
995975
.exit

0 commit comments

Comments
 (0)