4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
5 * Copyright (C) 2002 - 2005 Paul Mundt
7 * Released under the terms of the GNU GPL v2.0.
10 #include <linux/mutex.h>
11 #include <asm/mmu_context.h>
12 #include <asm/cacheflush.h>
14 extern struct mutex p3map_mutex
[];
16 #define CACHE_ALIAS (current_cpu_data.dcache.alias_mask)
21 * @address: U0 address to be mapped
22 * @page: page (virt_to_page(to))
24 void clear_user_page(void *to
, unsigned long address
, struct page
*page
)
26 __set_bit(PG_mapped
, &page
->flags
);
27 if (((address
^ (unsigned long)to
) & CACHE_ALIAS
) == 0)
30 unsigned long phys_addr
= PHYSADDR(to
);
31 unsigned long p3_addr
= P3SEG
+ (address
& CACHE_ALIAS
);
32 pgd_t
*pgd
= pgd_offset_k(p3_addr
);
33 pud_t
*pud
= pud_offset(pgd
, p3_addr
);
34 pmd_t
*pmd
= pmd_offset(pud
, p3_addr
);
35 pte_t
*pte
= pte_offset_kernel(pmd
, p3_addr
);
39 entry
= pfn_pte(phys_addr
>> PAGE_SHIFT
, PAGE_KERNEL
);
40 mutex_lock(&p3map_mutex
[(address
& CACHE_ALIAS
)>>12]);
42 local_irq_save(flags
);
43 flush_tlb_one(get_asid(), p3_addr
);
44 local_irq_restore(flags
);
45 update_mmu_cache(NULL
, p3_addr
, entry
);
46 __clear_user_page((void *)p3_addr
, to
);
47 pte_clear(&init_mm
, p3_addr
, pte
);
48 mutex_unlock(&p3map_mutex
[(address
& CACHE_ALIAS
)>>12]);
56 * @address: U0 address to be mapped
57 * @page: page (virt_to_page(to))
59 void copy_user_page(void *to
, void *from
, unsigned long address
,
62 __set_bit(PG_mapped
, &page
->flags
);
63 if (((address
^ (unsigned long)to
) & CACHE_ALIAS
) == 0)
66 unsigned long phys_addr
= PHYSADDR(to
);
67 unsigned long p3_addr
= P3SEG
+ (address
& CACHE_ALIAS
);
68 pgd_t
*pgd
= pgd_offset_k(p3_addr
);
69 pud_t
*pud
= pud_offset(pgd
, p3_addr
);
70 pmd_t
*pmd
= pmd_offset(pud
, p3_addr
);
71 pte_t
*pte
= pte_offset_kernel(pmd
, p3_addr
);
75 entry
= pfn_pte(phys_addr
>> PAGE_SHIFT
, PAGE_KERNEL
);
76 mutex_lock(&p3map_mutex
[(address
& CACHE_ALIAS
)>>12]);
78 local_irq_save(flags
);
79 flush_tlb_one(get_asid(), p3_addr
);
80 local_irq_restore(flags
);
81 update_mmu_cache(NULL
, p3_addr
, entry
);
82 __copy_user_page((void *)p3_addr
, from
, to
);
83 pte_clear(&init_mm
, p3_addr
, pte
);
84 mutex_unlock(&p3map_mutex
[(address
& CACHE_ALIAS
)>>12]);
89 * For SH-4, we have our own implementation for ptep_get_and_clear
91 inline pte_t
ptep_get_and_clear(struct mm_struct
*mm
, unsigned long addr
, pte_t
*ptep
)
95 pte_clear(mm
, addr
, ptep
);
96 if (!pte_not_present(pte
)) {
97 unsigned long pfn
= pte_pfn(pte
);
99 struct page
*page
= pfn_to_page(pfn
);
100 struct address_space
*mapping
= page_mapping(page
);
101 if (!mapping
|| !mapping_writably_mapped(mapping
))
102 __clear_bit(PG_mapped
, &page
->flags
);