]> err.no Git - linux-2.6/blobdiff - arch/sh/mm/pg-sh4.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[linux-2.6] / arch / sh / mm / pg-sh4.c
index 969efeceb9282ae1b434dfc025a9728923e696c2..df69da9ca69c7685e48a709924e58c175836ebe3 100644 (file)
@@ -23,6 +23,7 @@ extern struct mutex p3map_mutex[];
  */
 void clear_user_page(void *to, unsigned long address, struct page *page)
 {
+       __set_bit(PG_mapped, &page->flags);
        if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
                clear_page(to);
        else {
@@ -58,6 +59,7 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
 void copy_user_page(void *to, void *from, unsigned long address,
                    struct page *page)
 {
+       __set_bit(PG_mapped, &page->flags);
        if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
                copy_page(to, from);
        else {
@@ -82,3 +84,23 @@ void copy_user_page(void *to, void *from, unsigned long address,
                mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
        }
 }
+
+/*
+ * For SH-4, we have our own implementation for ptep_get_and_clear
+ */
+inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+       pte_t pte = *ptep;
+
+       pte_clear(mm, addr, ptep);
+       if (!pte_not_present(pte)) {
+               unsigned long pfn = pte_pfn(pte);
+               if (pfn_valid(pfn)) {
+                       struct page *page = pfn_to_page(pfn);
+                       struct address_space *mapping = page_mapping(page);
+                       if (!mapping || !mapping_writably_mapped(mapping))
+                               __clear_bit(PG_mapped, &page->flags);
+               }
+       }
+       return pte;
+}