Skip to content

Commit 6456c42

Browse files
committed
Merge tag 'parisc-for-6.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc fix from Helge Deller: "On parisc we have suffered since years from random segfaults which seem to have been triggered due to cache inconsistencies. Those segfaults happened more often on machines with PA8800 and PA8900 CPUs, which have much bigger caches than the earlier machines. Dave Anglin has worked over the last few weeks to fix this bug. His patch has been successfully tested by various people on various machines and with various kernels (6.6, 6.8 and 6.9), and the debian buildd servers haven't shown a single random segfault with this patch. Since the cache handling has been reworked, the patch is slightly bigger than I would like in this stage, but the greatly improved stability IMHO justifies the inclusion now" * tag 'parisc-for-6.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: parisc: Try to fix random segmentation faults in package builds
2 parents 4301487 + 72d9592 commit 6456c42

File tree

3 files changed

+275
-180
lines changed

3 files changed

+275
-180
lines changed

arch/parisc/include/asm/cacheflush.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,17 @@ void flush_cache_all_local(void);
3131
void flush_cache_all(void);
3232
void flush_cache_mm(struct mm_struct *mm);
3333

34-
void flush_kernel_dcache_page_addr(const void *addr);
35-
3634
#define flush_kernel_dcache_range(start,size) \
3735
flush_kernel_dcache_range_asm((start), (start)+(size));
3836

37+
/* The only way to flush a vmap range is to flush whole cache */
3938
#define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1
4039
void flush_kernel_vmap_range(void *vaddr, int size);
4140
void invalidate_kernel_vmap_range(void *vaddr, int size);
4241

43-
#define flush_cache_vmap(start, end) flush_cache_all()
42+
void flush_cache_vmap(unsigned long start, unsigned long end);
4443
#define flush_cache_vmap_early(start, end) do { } while (0)
45-
#define flush_cache_vunmap(start, end) flush_cache_all()
44+
void flush_cache_vunmap(unsigned long start, unsigned long end);
4645

4746
void flush_dcache_folio(struct folio *folio);
4847
#define flush_dcache_folio flush_dcache_folio
@@ -77,17 +76,11 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
7776
void flush_cache_range(struct vm_area_struct *vma,
7877
unsigned long start, unsigned long end);
7978

80-
/* defined in pacache.S exported in cache.c used by flush_anon_page */
81-
void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
82-
8379
#define ARCH_HAS_FLUSH_ANON_PAGE
8480
void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr);
8581

8682
#define ARCH_HAS_FLUSH_ON_KUNMAP
87-
static inline void kunmap_flush_on_unmap(const void *addr)
88-
{
89-
flush_kernel_dcache_page_addr(addr);
90-
}
83+
void kunmap_flush_on_unmap(const void *addr);
9184

9285
#endif /* _PARISC_CACHEFLUSH_H */
9386

arch/parisc/include/asm/pgtable.h

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -448,32 +448,28 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
448448
return pte;
449449
}
450450

451+
static inline pte_t ptep_get(pte_t *ptep)
452+
{
453+
return READ_ONCE(*ptep);
454+
}
455+
#define ptep_get ptep_get
456+
451457
static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
452458
{
453459
pte_t pte;
454460

455-
if (!pte_young(*ptep))
456-
return 0;
457-
458-
pte = *ptep;
461+
pte = ptep_get(ptep);
459462
if (!pte_young(pte)) {
460463
return 0;
461464
}
462465
set_pte(ptep, pte_mkold(pte));
463466
return 1;
464467
}
465468

466-
struct mm_struct;
467-
static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
468-
{
469-
pte_t old_pte;
470-
471-
old_pte = *ptep;
472-
set_pte(ptep, __pte(0));
473-
474-
return old_pte;
475-
}
469+
int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
470+
pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
476471

472+
struct mm_struct;
477473
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
478474
{
479475
set_pte(ptep, pte_wrprotect(*ptep));
@@ -511,7 +507,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
511507
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
512508

513509
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
514-
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
510+
#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
511+
#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
515512
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
516513
#define __HAVE_ARCH_PTE_SAME
517514

0 commit comments

Comments
 (0)