diff options
-rw-r--r-- | arch/mips/include/asm/pgtable.h | 8 | ||||
-rw-r--r-- | arch/mips/mm/cache.c | 27 |
2 files changed, 22 insertions, 13 deletions
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 027c74db13f9..df49a308085c 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
@@ -122,6 +122,9 @@ do { \ | |||
122 | } \ | 122 | } \ |
123 | } while(0) | 123 | } while(0) |
124 | 124 | ||
125 | extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, | ||
126 | pte_t pteval); | ||
127 | |||
125 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 128 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) |
126 | 129 | ||
127 | #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) | 130 | #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) |
@@ -145,7 +148,6 @@ static inline void set_pte(pte_t *ptep, pte_t pte) | |||
145 | } | 148 | } |
146 | } | 149 | } |
147 | } | 150 | } |
148 | #define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) | ||
149 | 151 | ||
150 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 152 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
151 | { | 153 | { |
@@ -183,7 +185,6 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) | |||
183 | } | 185 | } |
184 | #endif | 186 | #endif |
185 | } | 187 | } |
186 | #define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) | ||
187 | 188 | ||
188 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 189 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
189 | { | 190 | { |
@@ -390,15 +391,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
390 | 391 | ||
391 | extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, | 392 | extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, |
392 | pte_t pte); | 393 | pte_t pte); |
393 | extern void __update_cache(struct vm_area_struct *vma, unsigned long address, | ||
394 | pte_t pte); | ||
395 | 394 | ||
396 | static inline void update_mmu_cache(struct vm_area_struct *vma, | 395 | static inline void update_mmu_cache(struct vm_area_struct *vma, |
397 | unsigned long address, pte_t *ptep) | 396 | unsigned long address, pte_t *ptep) |
398 | { | 397 | { |
399 | pte_t pte = *ptep; | 398 | pte_t pte = *ptep; |
400 | __update_tlb(vma, address, pte); | 399 | __update_tlb(vma, address, pte); |
401 | __update_cache(vma, address, pte); | ||
402 | } | 400 | } |
403 | 401 | ||
404 | static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, | 402 | static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, |
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index f7b91d3a371d..7e3ea7766822 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
@@ -119,25 +119,36 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr) | |||
119 | 119 | ||
120 | EXPORT_SYMBOL(__flush_anon_page); | 120 | EXPORT_SYMBOL(__flush_anon_page); |
121 | 121 | ||
122 | void __update_cache(struct vm_area_struct *vma, unsigned long address, | 122 | static void mips_flush_dcache_from_pte(pte_t pteval, unsigned long address) |
123 | pte_t pte) | ||
124 | { | 123 | { |
125 | struct page *page; | 124 | struct page *page; |
126 | unsigned long pfn, addr; | 125 | unsigned long pfn = pte_pfn(pteval); |
127 | int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc; | ||
128 | 126 | ||
129 | pfn = pte_pfn(pte); | ||
130 | if (unlikely(!pfn_valid(pfn))) | 127 | if (unlikely(!pfn_valid(pfn))) |
131 | return; | 128 | return; |
129 | |||
132 | page = pfn_to_page(pfn); | 130 | page = pfn_to_page(pfn); |
133 | if (page_mapping(page) && Page_dcache_dirty(page)) { | 131 | if (page_mapping(page) && Page_dcache_dirty(page)) { |
134 | addr = (unsigned long) page_address(page); | 132 | unsigned long page_addr = (unsigned long) page_address(page); |
135 | if (exec || pages_do_alias(addr, address & PAGE_MASK)) | 133 | |
136 | flush_data_cache_page(addr); | 134 | if (!cpu_has_ic_fills_f_dc || |
135 | pages_do_alias(page_addr, address & PAGE_MASK)) | ||
136 | flush_data_cache_page(page_addr); | ||
137 | ClearPageDcacheDirty(page); | 137 | ClearPageDcacheDirty(page); |
138 | } | 138 | } |
139 | } | 139 | } |
140 | 140 | ||
141 | void set_pte_at(struct mm_struct *mm, unsigned long addr, | ||
142 | pte_t *ptep, pte_t pteval) | ||
143 | { | ||
144 | if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc) { | ||
145 | if (pte_present(pteval)) | ||
146 | mips_flush_dcache_from_pte(pteval, addr); | ||
147 | } | ||
148 | |||
149 | set_pte(ptep, pteval); | ||
150 | } | ||
151 | |||
141 | unsigned long _page_cachable_default; | 152 | unsigned long _page_cachable_default; |
142 | EXPORT_SYMBOL(_page_cachable_default); | 153 | EXPORT_SYMBOL(_page_cachable_default); |
143 | 154 | ||