aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-08 18:40:15 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-08 18:40:15 -0500
commita37102dcd7ec71f6f6a00b1ad770c3bde3af3c18 (patch)
treedc3f896f1180a70c2c138dcd292066e06a6a8f73
parentb4aafe77ec65ab2846a5780bb1ba4eff7ccf82d1 (diff)
parent24d0492b7d5d321a9c5846c8c974eba9823ffaa0 (diff)
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
-rw-r--r--arch/parisc/include/asm/pgtable.h8
-rw-r--r--arch/parisc/kernel/cache.c11
-rw-r--r--arch/parisc/kernel/pacache.S22
3 files changed, 16 insertions, 25 deletions
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index c2c43f714684..3a4ed9f91d57 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -65,9 +65,9 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
65 unsigned long flags; \ 65 unsigned long flags; \
66 spin_lock_irqsave(&pa_tlb_lock, flags); \ 66 spin_lock_irqsave(&pa_tlb_lock, flags); \
67 old_pte = *ptep; \ 67 old_pte = *ptep; \
68 set_pte(ptep, pteval); \
69 if (pte_inserted(old_pte)) \ 68 if (pte_inserted(old_pte)) \
70 purge_tlb_entries(mm, addr); \ 69 purge_tlb_entries(mm, addr); \
70 set_pte(ptep, pteval); \
71 spin_unlock_irqrestore(&pa_tlb_lock, flags); \ 71 spin_unlock_irqrestore(&pa_tlb_lock, flags); \
72 } while (0) 72 } while (0)
73 73
@@ -478,8 +478,8 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned
478 spin_unlock_irqrestore(&pa_tlb_lock, flags); 478 spin_unlock_irqrestore(&pa_tlb_lock, flags);
479 return 0; 479 return 0;
480 } 480 }
481 set_pte(ptep, pte_mkold(pte));
482 purge_tlb_entries(vma->vm_mm, addr); 481 purge_tlb_entries(vma->vm_mm, addr);
482 set_pte(ptep, pte_mkold(pte));
483 spin_unlock_irqrestore(&pa_tlb_lock, flags); 483 spin_unlock_irqrestore(&pa_tlb_lock, flags);
484 return 1; 484 return 1;
485} 485}
@@ -492,9 +492,9 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
492 492
493 spin_lock_irqsave(&pa_tlb_lock, flags); 493 spin_lock_irqsave(&pa_tlb_lock, flags);
494 old_pte = *ptep; 494 old_pte = *ptep;
495 set_pte(ptep, __pte(0));
496 if (pte_inserted(old_pte)) 495 if (pte_inserted(old_pte))
497 purge_tlb_entries(mm, addr); 496 purge_tlb_entries(mm, addr);
497 set_pte(ptep, __pte(0));
498 spin_unlock_irqrestore(&pa_tlb_lock, flags); 498 spin_unlock_irqrestore(&pa_tlb_lock, flags);
499 499
500 return old_pte; 500 return old_pte;
@@ -504,8 +504,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
504{ 504{
505 unsigned long flags; 505 unsigned long flags;
506 spin_lock_irqsave(&pa_tlb_lock, flags); 506 spin_lock_irqsave(&pa_tlb_lock, flags);
507 set_pte(ptep, pte_wrprotect(*ptep));
508 purge_tlb_entries(mm, addr); 507 purge_tlb_entries(mm, addr);
508 set_pte(ptep, pte_wrprotect(*ptep));
509 spin_unlock_irqrestore(&pa_tlb_lock, flags); 509 spin_unlock_irqrestore(&pa_tlb_lock, flags);
510} 510}
511 511
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index c263301648f3..977f0a4f5ecf 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -393,6 +393,15 @@ void __init parisc_setup_cache_timing(void)
393 393
394 /* calculate TLB flush threshold */ 394 /* calculate TLB flush threshold */
395 395
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
396 alltime = mfctl(16); 405 alltime = mfctl(16);
397 flush_tlb_all(); 406 flush_tlb_all();
398 alltime = mfctl(16) - alltime; 407 alltime = mfctl(16) - alltime;
@@ -411,6 +420,8 @@ void __init parisc_setup_cache_timing(void)
411 alltime, size, rangetime); 420 alltime, size, rangetime);
412 421
413 threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime); 422 threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime);
423
424set_tlb_threshold:
414 if (threshold) 425 if (threshold)
415 parisc_tlb_flush_threshold = threshold; 426 parisc_tlb_flush_threshold = threshold;
416 printk(KERN_INFO "TLB flush threshold set to %lu KiB\n", 427 printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 1b39a2acaadf..adf7187f8951 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -892,19 +892,10 @@ ENTRY_CFI(flush_dcache_page_asm)
892 fdc,m r31(%r28) 892 fdc,m r31(%r28)
893 fdc,m r31(%r28) 893 fdc,m r31(%r28)
894 fdc,m r31(%r28) 894 fdc,m r31(%r28)
895 cmpb,COND(<<) %r28, %r25,1b 895 cmpb,COND(<<) %r28, %r25,1b
896 fdc,m r31(%r28) 896 fdc,m r31(%r28)
897 897
898 sync 898 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
908 bv %r0(%r2) 899 bv %r0(%r2)
909 nop 900 nop
910 .exit 901 .exit
@@ -979,17 +970,6 @@ ENTRY_CFI(flush_icache_page_asm)
979 fic,m %r31(%sr4,%r28) 970 fic,m %r31(%sr4,%r28)
980 971
981 sync 972 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
993 bv %r0(%r2) 973 bv %r0(%r2)
994 nop 974 nop
995 .exit 975 .exit