|
@@ -596,3 +596,67 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
|
|
|
__flush_cache_page(vma, vmaddr, page_to_phys(pfn_to_page(pfn)));
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+#ifdef CONFIG_PARISC_TMPALIAS
|
|
|
+
|
|
|
+void clear_user_highpage(struct page *page, unsigned long vaddr)
|
|
|
+{
|
|
|
+ void *vto;
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ /* Clear using TMPALIAS region. The page doesn't need to
|
|
|
+ be flushed but the kernel mapping needs to be purged. */
|
|
|
+
|
|
|
+ vto = kmap_atomic(page, KM_USER0);
|
|
|
+
|
|
|
+ /* The PA-RISC 2.0 Architecture book states on page F-6:
|
|
|
+ "Before a write-capable translation is enabled, *all*
|
|
|
+ non-equivalently-aliased translations must be removed
|
|
|
+ from the page table and purged from the TLB. (Note
|
|
|
+ that the caches are not required to be flushed at this
|
|
|
+ time.) Before any non-equivalent aliased translation
|
|
|
+ is re-enabled, the virtual address range for the writeable
|
|
|
+ page (the entire page) must be flushed from the cache,
|
|
|
+ and the write-capable translation removed from the page
|
|
|
+ table and purged from the TLB." */
|
|
|
+
|
|
|
+ purge_kernel_dcache_page_asm((unsigned long)vto);
|
|
|
+ purge_tlb_start(flags);
|
|
|
+ pdtlb_kernel(vto);
|
|
|
+ purge_tlb_end(flags);
|
|
|
+ preempt_disable();
|
|
|
+ clear_user_page_asm(vto, vaddr);
|
|
|
+ preempt_enable();
|
|
|
+
|
|
|
+ pagefault_enable(); /* kunmap_atomic(addr, KM_USER0); */
|
|
|
+}
|
|
|
+
|
|
|
+void copy_user_highpage(struct page *to, struct page *from,
|
|
|
+ unsigned long vaddr, struct vm_area_struct *vma)
|
|
|
+{
|
|
|
+ void *vfrom, *vto;
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ /* Copy using TMPALIAS region. This has the advantage
|
|
|
+ that the `from' page doesn't need to be flushed. However,
|
|
|
+ the `to' page must be flushed in copy_user_page_asm since
|
|
|
+ it can be used to bring in executable code. */
|
|
|
+
|
|
|
+ vfrom = kmap_atomic(from, KM_USER0);
|
|
|
+ vto = kmap_atomic(to, KM_USER1);
|
|
|
+
|
|
|
+ purge_kernel_dcache_page_asm((unsigned long)vto);
|
|
|
+ purge_tlb_start(flags);
|
|
|
+ pdtlb_kernel(vto);
|
|
|
+ pdtlb_kernel(vfrom);
|
|
|
+ purge_tlb_end(flags);
|
|
|
+ preempt_disable();
|
|
|
+ copy_user_page_asm(vto, vfrom, vaddr);
|
|
|
+ flush_dcache_page_asm(__pa(vto), vaddr);
|
|
|
+ preempt_enable();
|
|
|
+
|
|
|
+ pagefault_enable(); /* kunmap_atomic(addr, KM_USER1); */
|
|
|
+ pagefault_enable(); /* kunmap_atomic(addr, KM_USER0); */
|
|
|
+}
|
|
|
+
|
|
|
+#endif /* CONFIG_PARISC_TMPALIAS */
|