hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/mips/include/asm/pgtable.h
....@@ -17,8 +17,10 @@
1717 #include <asm/pgtable-64.h>
1818 #endif
1919
20
+#include <asm/cmpxchg.h>
2021 #include <asm/io.h>
2122 #include <asm/pgtable-bits.h>
23
+#include <asm/cpu-features.h>
2224
2325 struct mm_struct;
2426 struct vm_area_struct;
....@@ -35,8 +37,6 @@
3537 _PAGE_GLOBAL | _page_cachable_default)
3638 #define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
3739 _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
38
-#define PAGE_USERIO __pgprot(_PAGE_PRESENT | _PAGE_WRITE | \
39
- _page_cachable_default)
4040 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
4141 __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
4242
....@@ -197,58 +197,18 @@
197197 static inline void set_pte(pte_t *ptep, pte_t pteval)
198198 {
199199 *ptep = pteval;
200
-#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
200
+#if !defined(CONFIG_CPU_R3K_TLB)
201201 if (pte_val(pteval) & _PAGE_GLOBAL) {
202202 pte_t *buddy = ptep_buddy(ptep);
203203 /*
204204 * Make sure the buddy is global too (if it's !none,
205205 * it better already be global)
206206 */
207
-#ifdef CONFIG_SMP
208
- /*
209
- * For SMP, multiple CPUs can race, so we need to do
210
- * this atomically.
211
- */
212
- unsigned long page_global = _PAGE_GLOBAL;
213
- unsigned long tmp;
214
-
215
- if (kernel_uses_llsc && R10000_LLSC_WAR) {
216
- __asm__ __volatile__ (
217
- " .set arch=r4000 \n"
218
- " .set push \n"
219
- " .set noreorder \n"
220
- "1:" __LL "%[tmp], %[buddy] \n"
221
- " bnez %[tmp], 2f \n"
222
- " or %[tmp], %[tmp], %[global] \n"
223
- __SC "%[tmp], %[buddy] \n"
224
- " beqzl %[tmp], 1b \n"
225
- " nop \n"
226
- "2: \n"
227
- " .set pop \n"
228
- " .set mips0 \n"
229
- : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
230
- : [global] "r" (page_global));
231
- } else if (kernel_uses_llsc) {
232
- __asm__ __volatile__ (
233
- " .set "MIPS_ISA_ARCH_LEVEL" \n"
234
- " .set push \n"
235
- " .set noreorder \n"
236
- "1:" __LL "%[tmp], %[buddy] \n"
237
- " bnez %[tmp], 2f \n"
238
- " or %[tmp], %[tmp], %[global] \n"
239
- __SC "%[tmp], %[buddy] \n"
240
- " beqz %[tmp], 1b \n"
241
- " nop \n"
242
- "2: \n"
243
- " .set pop \n"
244
- " .set mips0 \n"
245
- : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
246
- : [global] "r" (page_global));
247
- }
248
-#else /* !CONFIG_SMP */
249
- if (pte_none(*buddy))
250
- pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
251
-#endif /* CONFIG_SMP */
207
+# if defined(CONFIG_PHYS_ADDR_T_64BIT) && !defined(CONFIG_CPU_MIPS32)
208
+ cmpxchg64(&buddy->pte, 0, _PAGE_GLOBAL);
209
+# else
210
+ cmpxchg(&buddy->pte, 0, _PAGE_GLOBAL);
211
+# endif
252212 }
253213 #endif
254214 }
....@@ -256,7 +216,7 @@
256216 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
257217 {
258218 htw_stop();
259
-#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
219
+#if !defined(CONFIG_CPU_R3K_TLB)
260220 /* Preserve global status for the pair */
261221 if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
262222 set_pte_at(mm, addr, ptep, __pte(_PAGE_GLOBAL));
....@@ -306,6 +266,36 @@
306266 * to find that this expression is a constant, so the size is dropped.
307267 */
308268 extern pgd_t swapper_pg_dir[];
269
+
270
+/*
271
+ * Platform specific pte_special() and pte_mkspecial() definitions
272
+ * are required only when ARCH_HAS_PTE_SPECIAL is enabled.
273
+ */
274
+#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
275
+#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
276
+static inline int pte_special(pte_t pte)
277
+{
278
+ return pte.pte_low & _PAGE_SPECIAL;
279
+}
280
+
281
+static inline pte_t pte_mkspecial(pte_t pte)
282
+{
283
+ pte.pte_low |= _PAGE_SPECIAL;
284
+ return pte;
285
+}
286
+#else
287
+static inline int pte_special(pte_t pte)
288
+{
289
+ return pte_val(pte) & _PAGE_SPECIAL;
290
+}
291
+
292
+static inline pte_t pte_mkspecial(pte_t pte)
293
+{
294
+ pte_val(pte) |= _PAGE_SPECIAL;
295
+ return pte;
296
+}
297
+#endif
298
+#endif /* CONFIG_ARCH_HAS_PTE_SPECIAL */
309299
310300 /*
311301 * The following only work if pte_present() is true.
....@@ -408,7 +398,7 @@
408398
409399 static inline pte_t pte_mkdirty(pte_t pte)
410400 {
411
- pte_val(pte) |= _PAGE_MODIFIED;
401
+ pte_val(pte) |= _PAGE_MODIFIED | _PAGE_SOFT_DIRTY;
412402 if (pte_val(pte) & _PAGE_WRITE)
413403 pte_val(pte) |= _PAGE_SILENT_WRITE;
414404 return pte;
....@@ -422,6 +412,8 @@
422412 return pte;
423413 }
424414
415
+#define pte_sw_mkyoung pte_mkyoung
416
+
425417 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
426418 static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_HUGE; }
427419
....@@ -431,9 +423,31 @@
431423 return pte;
432424 }
433425 #endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
426
+
427
+#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
428
+static inline bool pte_soft_dirty(pte_t pte)
429
+{
430
+ return pte_val(pte) & _PAGE_SOFT_DIRTY;
431
+}
432
+#define pte_swp_soft_dirty pte_soft_dirty
433
+
434
+static inline pte_t pte_mksoft_dirty(pte_t pte)
435
+{
436
+ pte_val(pte) |= _PAGE_SOFT_DIRTY;
437
+ return pte;
438
+}
439
+#define pte_swp_mksoft_dirty pte_mksoft_dirty
440
+
441
+static inline pte_t pte_clear_soft_dirty(pte_t pte)
442
+{
443
+ pte_val(pte) &= ~(_PAGE_SOFT_DIRTY);
444
+ return pte;
445
+}
446
+#define pte_swp_clear_soft_dirty pte_clear_soft_dirty
447
+
448
+#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
449
+
434450 #endif
435
-static inline int pte_special(pte_t pte) { return 0; }
436
-static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
437451
438452 /*
439453 * Macro to make mark a page protection value as "uncacheable". Note
....@@ -464,6 +478,31 @@
464478 return __pgprot(prot);
465479 }
466480
481
+static inline void flush_tlb_fix_spurious_fault(struct vm_area_struct *vma,
482
+ unsigned long address)
483
+{
484
+}
485
+
486
+#define __HAVE_ARCH_PTE_SAME
487
+static inline int pte_same(pte_t pte_a, pte_t pte_b)
488
+{
489
+ return pte_val(pte_a) == pte_val(pte_b);
490
+}
491
+
492
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
493
+static inline int ptep_set_access_flags(struct vm_area_struct *vma,
494
+ unsigned long address, pte_t *ptep,
495
+ pte_t entry, int dirty)
496
+{
497
+ if (!pte_same(*ptep, entry))
498
+ set_pte_at(vma->vm_mm, address, ptep, entry);
499
+ /*
500
+ * update_mmu_cache will unconditionally execute, handling both
501
+ * the case that the PTE changed and the spurious fault case.
502
+ */
503
+ return true;
504
+}
505
+
467506 /*
468507 * Conversion functions: convert a page and protection to a page entry,
469508 * and a page entry and page directory to the page they refer to.
....@@ -491,8 +530,11 @@
491530 #else
492531 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
493532 {
494
- return __pte((pte_val(pte) & _PAGE_CHG_MASK) |
495
- (pgprot_val(newprot) & ~_PAGE_CHG_MASK));
533
+ pte_val(pte) &= _PAGE_CHG_MASK;
534
+ pte_val(pte) |= pgprot_val(newprot) & ~_PAGE_CHG_MASK;
535
+ if ((pte_val(pte) & _PAGE_ACCESSED) && !(pte_val(pte) & _PAGE_NO_READ))
536
+ pte_val(pte) |= _PAGE_SILENT_READ;
537
+ return pte;
496538 }
497539 #endif
498540
....@@ -507,6 +549,9 @@
507549 __update_tlb(vma, address, pte);
508550 }
509551
552
+#define __HAVE_ARCH_UPDATE_MMU_TLB
553
+#define update_mmu_tlb update_mmu_cache
554
+
510555 static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
511556 unsigned long address, pmd_t *pmdp)
512557 {
....@@ -517,20 +562,17 @@
517562
518563 #define kern_addr_valid(addr) (1)
519564
520
-#ifdef CONFIG_PHYS_ADDR_T_64BIT
521
-extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
522
-
523
-static inline int io_remap_pfn_range(struct vm_area_struct *vma,
524
- unsigned long vaddr,
525
- unsigned long pfn,
526
- unsigned long size,
527
- pgprot_t prot)
528
-{
529
- phys_addr_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
530
- return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
531
-}
565
+/*
566
+ * Allow physical addresses to be fixed up to help 36-bit peripherals.
567
+ */
568
+#ifdef CONFIG_MIPS_FIXUP_BIGPHYS_ADDR
569
+phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size);
570
+int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long vaddr,
571
+ unsigned long pfn, unsigned long size, pgprot_t prot);
532572 #define io_remap_pfn_range io_remap_pfn_range
533
-#endif
573
+#else
574
+#define fixup_bigphys_addr(addr, size) (addr)
575
+#endif /* CONFIG_MIPS_FIXUP_BIGPHYS_ADDR */
534576
535577 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
536578
....@@ -589,7 +631,7 @@
589631
590632 static inline pmd_t pmd_mkdirty(pmd_t pmd)
591633 {
592
- pmd_val(pmd) |= _PAGE_MODIFIED;
634
+ pmd_val(pmd) |= _PAGE_MODIFIED | _PAGE_SOFT_DIRTY;
593635 if (pmd_val(pmd) & _PAGE_WRITE)
594636 pmd_val(pmd) |= _PAGE_SILENT_WRITE;
595637
....@@ -618,6 +660,26 @@
618660 return pmd;
619661 }
620662
663
+#ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY
664
+static inline int pmd_soft_dirty(pmd_t pmd)
665
+{
666
+ return !!(pmd_val(pmd) & _PAGE_SOFT_DIRTY);
667
+}
668
+
669
+static inline pmd_t pmd_mksoft_dirty(pmd_t pmd)
670
+{
671
+ pmd_val(pmd) |= _PAGE_SOFT_DIRTY;
672
+ return pmd;
673
+}
674
+
675
+static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
676
+{
677
+ pmd_val(pmd) &= ~(_PAGE_SOFT_DIRTY);
678
+ return pmd;
679
+}
680
+
681
+#endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */
682
+
621683 /* Extern to avoid header file madness */
622684 extern pmd_t mk_pmd(struct page *page, pgprot_t prot);
623685
....@@ -641,7 +703,7 @@
641703 return pmd;
642704 }
643705
644
-static inline pmd_t pmd_mknotpresent(pmd_t pmd)
706
+static inline pmd_t pmd_mkinvalid(pmd_t pmd)
645707 {
646708 pmd_val(pmd) &= ~(_PAGE_PRESENT | _PAGE_VALID | _PAGE_DIRTY);
647709
....@@ -665,18 +727,12 @@
665727
666728 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
667729
668
-#include <asm-generic/pgtable.h>
669
-
670
-/*
671
- * uncached accelerated TLB map for video memory access
672
- */
673
-#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
674
-#define __HAVE_PHYS_MEM_ACCESS_PROT
675
-
676
-struct file;
677
-pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
678
- unsigned long size, pgprot_t vma_prot);
730
+#ifdef _PAGE_HUGE
731
+#define pmd_leaf(pmd) ((pmd_val(pmd) & _PAGE_HUGE) != 0)
732
+#define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0)
679733 #endif
734
+
735
+#define gup_fast_permitted(start, end) (!cpu_has_dc_aliases)
680736
681737 /*
682738 * We provide our own get_unmapped area to cope with the virtual aliasing
....@@ -684,10 +740,5 @@
684740 */
685741 #define HAVE_ARCH_UNMAPPED_AREA
686742 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
687
-
688
-/*
689
- * No page table caches to initialise
690
- */
691
-#define pgtable_cache_init() do { } while (0)
692743
693744 #endif /* _ASM_PGTABLE_H */