4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
5 * Copyright (C) 2002 - 2007 Paul Mundt
7 * Released under the terms of the GNU GPL v2.0.
10 #include <linux/init.h>
11 #include <linux/mutex.h>
13 #include <linux/highmem.h>
14 #include <linux/module.h>
15 #include <asm/mmu_context.h>
16 #include <asm/cacheflush.h>
18 #define CACHE_ALIAS (current_cpu_data.dcache.alias_mask)
20 #define kmap_get_fixmap_pte(vaddr) \
21 pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
23 static pte_t
*kmap_coherent_pte
;
25 void __init
kmap_coherent_init(void)
29 /* cache the first coherent kmap pte */
30 vaddr
= __fix_to_virt(FIX_CMAP_BEGIN
);
31 kmap_coherent_pte
= kmap_get_fixmap_pte(vaddr
);
34 static inline void *kmap_coherent(struct page
*page
, unsigned long addr
)
36 enum fixed_addresses idx
;
37 unsigned long vaddr
, flags
;
42 idx
= (addr
& current_cpu_data
.dcache
.alias_mask
) >> PAGE_SHIFT
;
43 vaddr
= __fix_to_virt(FIX_CMAP_END
- idx
);
44 pte
= mk_pte(page
, PAGE_KERNEL
);
46 local_irq_save(flags
);
47 flush_tlb_one(get_asid(), vaddr
);
48 local_irq_restore(flags
);
50 update_mmu_cache(NULL
, vaddr
, pte
);
52 set_pte(kmap_coherent_pte
- (FIX_CMAP_END
- idx
), pte
);
57 static inline void kunmap_coherent(struct page
*page
)
60 preempt_check_resched();
66 * @address: U0 address to be mapped
67 * @page: page (virt_to_page(to))
69 void clear_user_page(void *to
, unsigned long address
, struct page
*page
)
71 __set_bit(PG_mapped
, &page
->flags
);
74 if ((((address
& PAGE_MASK
) ^ (unsigned long)to
) & CACHE_ALIAS
))
75 __flush_wback_region(to
, PAGE_SIZE
);
78 void copy_to_user_page(struct vm_area_struct
*vma
, struct page
*page
,
79 unsigned long vaddr
, void *dst
, const void *src
,
84 __set_bit(PG_mapped
, &page
->flags
);
86 vto
= kmap_coherent(page
, vaddr
) + (vaddr
& ~PAGE_MASK
);
87 memcpy(vto
, src
, len
);
90 if (vma
->vm_flags
& VM_EXEC
)
91 flush_cache_page(vma
, vaddr
, page_to_pfn(page
));
94 void copy_from_user_page(struct vm_area_struct
*vma
, struct page
*page
,
95 unsigned long vaddr
, void *dst
, const void *src
,
100 __set_bit(PG_mapped
, &page
->flags
);
102 vfrom
= kmap_coherent(page
, vaddr
) + (vaddr
& ~PAGE_MASK
);
103 memcpy(dst
, vfrom
, len
);
104 kunmap_coherent(vfrom
);
107 void copy_user_highpage(struct page
*to
, struct page
*from
,
108 unsigned long vaddr
, struct vm_area_struct
*vma
)
112 __set_bit(PG_mapped
, &to
->flags
);
114 vto
= kmap_atomic(to
, KM_USER1
);
115 vfrom
= kmap_coherent(from
, vaddr
);
116 copy_page(vto
, vfrom
);
117 kunmap_coherent(vfrom
);
119 if (((vaddr
^ (unsigned long)vto
) & CACHE_ALIAS
))
120 __flush_wback_region(vto
, PAGE_SIZE
);
122 kunmap_atomic(vto
, KM_USER1
);
123 /* Make sure this page is cleared on other CPU's too before using it */
126 EXPORT_SYMBOL(copy_user_highpage
);
129 * For SH-4, we have our own implementation for ptep_get_and_clear
131 pte_t
ptep_get_and_clear(struct mm_struct
*mm
, unsigned long addr
, pte_t
*ptep
)
135 pte_clear(mm
, addr
, ptep
);
136 if (!pte_not_present(pte
)) {
137 unsigned long pfn
= pte_pfn(pte
);
138 if (pfn_valid(pfn
)) {
139 struct page
*page
= pfn_to_page(pfn
);
140 struct address_space
*mapping
= page_mapping(page
);
141 if (!mapping
|| !mapping_writably_mapped(mapping
))
142 __clear_bit(PG_mapped
, &page
->flags
);