|
@@ -539,6 +539,10 @@ void flush_cache_mm(struct mm_struct *mm)
|
|
struct vm_area_struct *vma;
|
|
struct vm_area_struct *vma;
|
|
pgd_t *pgd;
|
|
pgd_t *pgd;
|
|
|
|
|
|
|
|
+ /* Flush the TLB to avoid speculation if coherency is required. */
|
|
|
|
+ if (parisc_requires_coherency())
|
|
|
|
+ flush_tlb_all();
|
|
|
|
+
|
|
/* Flushing the whole cache on each cpu takes forever on
|
|
/* Flushing the whole cache on each cpu takes forever on
|
|
rp3440, etc. So, avoid it if the mm isn't too big. */
|
|
rp3440, etc. So, avoid it if the mm isn't too big. */
|
|
if (mm_total_size(mm) >= parisc_cache_flush_threshold) {
|
|
if (mm_total_size(mm) >= parisc_cache_flush_threshold) {
|
|
@@ -577,33 +581,22 @@ void flush_cache_mm(struct mm_struct *mm)
|
|
void flush_cache_range(struct vm_area_struct *vma,
|
|
void flush_cache_range(struct vm_area_struct *vma,
|
|
unsigned long start, unsigned long end)
|
|
unsigned long start, unsigned long end)
|
|
{
|
|
{
|
|
- unsigned long addr;
|
|
|
|
- pgd_t *pgd;
|
|
|
|
-
|
|
|
|
BUG_ON(!vma->vm_mm->context);
|
|
BUG_ON(!vma->vm_mm->context);
|
|
|
|
|
|
|
|
+ /* Flush the TLB to avoid speculation if coherency is required. */
|
|
|
|
+ if (parisc_requires_coherency())
|
|
|
|
+ flush_tlb_range(vma, start, end);
|
|
|
|
+
|
|
if ((end - start) >= parisc_cache_flush_threshold) {
|
|
if ((end - start) >= parisc_cache_flush_threshold) {
|
|
flush_cache_all();
|
|
flush_cache_all();
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- if (vma->vm_mm->context == mfsp(3)) {
|
|
|
|
- flush_user_dcache_range_asm(start, end);
|
|
|
|
- if (vma->vm_flags & VM_EXEC)
|
|
|
|
- flush_user_icache_range_asm(start, end);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ BUG_ON(vma->vm_mm->context != mfsp(3));
|
|
|
|
|
|
- pgd = vma->vm_mm->pgd;
|
|
|
|
- for (addr = start & PAGE_MASK; addr < end; addr += PAGE_SIZE) {
|
|
|
|
- unsigned long pfn;
|
|
|
|
- pte_t *ptep = get_ptep(pgd, addr);
|
|
|
|
- if (!ptep)
|
|
|
|
- continue;
|
|
|
|
- pfn = pte_pfn(*ptep);
|
|
|
|
- if (pfn_valid(pfn))
|
|
|
|
- __flush_cache_page(vma, addr, PFN_PHYS(pfn));
|
|
|
|
- }
|
|
|
|
|
|
+ flush_user_dcache_range_asm(start, end);
|
|
|
|
+ if (vma->vm_flags & VM_EXEC)
|
|
|
|
+ flush_user_icache_range_asm(start, end);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
void
|
|
@@ -612,7 +605,8 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
|
|
BUG_ON(!vma->vm_mm->context);
|
|
BUG_ON(!vma->vm_mm->context);
|
|
|
|
|
|
if (pfn_valid(pfn)) {
|
|
if (pfn_valid(pfn)) {
|
|
- flush_tlb_page(vma, vmaddr);
|
|
|
|
|
|
+ if (parisc_requires_coherency())
|
|
|
|
+ flush_tlb_page(vma, vmaddr);
|
|
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
|
|
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
|
|
}
|
|
}
|
|
}
|
|
}
|