[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] linux/i386: utilize hypervisor highmem handling helpers



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1225114489 0
# Node ID 03a4b2b9d85d37e7851b2020dcff692e6801d5fd
# Parent  61eafcbeaeb4c37bd7f2fa8b1ca790ab5326c3bd
linux/i386: utilize hypervisor highmem handling helpers

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
 arch/i386/mm/highmem-xen.c              |   47 ++++++++++++++++++++++++++++++++
 include/asm-i386/mach-xen/asm/highmem.h |   17 +++++++++++
 include/linux/highmem.h                 |    8 +++++
 3 files changed, 72 insertions(+)

diff -r 61eafcbeaeb4 -r 03a4b2b9d85d arch/i386/mm/highmem-xen.c
--- a/arch/i386/mm/highmem-xen.c        Mon Oct 27 13:34:34 2008 +0000
+++ b/arch/i386/mm/highmem-xen.c        Mon Oct 27 13:34:49 2008 +0000
@@ -128,9 +128,56 @@ struct page *kmap_atomic_to_page(void *p
        return pte_page(*pte);
 }
 
+void clear_highpage(struct page *page)
+{
+       void *kaddr;
+
+       if (likely(xen_feature(XENFEAT_highmem_assist))
+           && PageHighMem(page)) {
+               struct mmuext_op meo;
+
+               meo.cmd = MMUEXT_CLEAR_PAGE;
+               meo.arg1.mfn = pfn_to_mfn(page_to_pfn(page));
+               if (HYPERVISOR_mmuext_op(&meo, 1, NULL, DOMID_SELF) == 0)
+                       return;
+       }
+
+       kaddr = kmap_atomic(page, KM_USER0);
+       clear_page(kaddr);
+       kunmap_atomic(kaddr, KM_USER0);
+}
+
+void copy_highpage(struct page *to, struct page *from)
+{
+       void *vfrom, *vto;
+
+       if (likely(xen_feature(XENFEAT_highmem_assist))
+           && (PageHighMem(from) || PageHighMem(to))) {
+               unsigned long from_pfn = page_to_pfn(from);
+               unsigned long to_pfn = page_to_pfn(to);
+               struct mmuext_op meo;
+
+               meo.cmd = MMUEXT_COPY_PAGE;
+               meo.arg1.mfn = pfn_to_mfn(to_pfn);
+               meo.arg2.src_mfn = pfn_to_mfn(from_pfn);
+               if (mfn_to_pfn(meo.arg2.src_mfn) == from_pfn
+                   && mfn_to_pfn(meo.arg1.mfn) == to_pfn
+                   && HYPERVISOR_mmuext_op(&meo, 1, NULL, DOMID_SELF) == 0)
+                       return;
+       }
+
+       vfrom = kmap_atomic(from, KM_USER0);
+       vto = kmap_atomic(to, KM_USER1);
+       copy_page(vto, vfrom);
+       kunmap_atomic(vfrom, KM_USER0);
+       kunmap_atomic(vto, KM_USER1);
+}
+
 EXPORT_SYMBOL(kmap);
 EXPORT_SYMBOL(kunmap);
 EXPORT_SYMBOL(kmap_atomic);
 EXPORT_SYMBOL(kmap_atomic_pte);
 EXPORT_SYMBOL(kunmap_atomic);
 EXPORT_SYMBOL(kmap_atomic_to_page);
+EXPORT_SYMBOL(clear_highpage);
+EXPORT_SYMBOL(copy_highpage);
diff -r 61eafcbeaeb4 -r 03a4b2b9d85d include/asm-i386/mach-xen/asm/highmem.h
--- a/include/asm-i386/mach-xen/asm/highmem.h   Mon Oct 27 13:34:34 2008 +0000
+++ b/include/asm-i386/mach-xen/asm/highmem.h   Mon Oct 27 13:34:49 2008 +0000
@@ -75,6 +75,23 @@ struct page *kmap_atomic_to_page(void *p
 
 #define flush_cache_kmaps()    do { } while (0)
 
+void clear_highpage(struct page *);
+static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+       clear_highpage(page);
+}
+#define __HAVE_ARCH_CLEAR_HIGHPAGE
+#define __HAVE_ARCH_CLEAR_USER_HIGHPAGE
+
+void copy_highpage(struct page *to, struct page *from);
+static inline void copy_user_highpage(struct page *to, struct page *from,
+       unsigned long vaddr, struct vm_area_struct *vma)
+{
+       copy_highpage(to, from);
+}
+#define __HAVE_ARCH_COPY_HIGHPAGE
+#define __HAVE_ARCH_COPY_USER_HIGHPAGE
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_HIGHMEM_H */
diff -r 61eafcbeaeb4 -r 03a4b2b9d85d include/linux/highmem.h
--- a/include/linux/highmem.h   Mon Oct 27 13:34:34 2008 +0000
+++ b/include/linux/highmem.h   Mon Oct 27 13:34:49 2008 +0000
@@ -50,6 +50,7 @@ static inline void *kmap(struct page *pa
 
 #endif /* CONFIG_HIGHMEM */
 
+#ifndef __HAVE_ARCH_CLEAR_USER_HIGHPAGE
 /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
 static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
 {
@@ -59,6 +60,7 @@ static inline void clear_user_highpage(s
        /* Make sure this page is cleared on other CPU's too before using it */
        smp_wmb();
 }
+#endif
 
 #ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
 static inline struct page *
@@ -73,12 +75,14 @@ alloc_zeroed_user_highpage(struct vm_are
 }
 #endif
 
+#ifndef __HAVE_ARCH_CLEAR_HIGHPAGE
 static inline void clear_highpage(struct page *page)
 {
        void *kaddr = kmap_atomic(page, KM_USER0);
        clear_page(kaddr);
        kunmap_atomic(kaddr, KM_USER0);
 }
+#endif
 
 /*
  * Same but also flushes aliased cache contents to RAM.
@@ -95,6 +99,7 @@ static inline void memclear_highpage_flu
        kunmap_atomic(kaddr, KM_USER0);
 }
 
+#ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE
 static inline void copy_user_highpage(struct page *to, struct page *from, 
unsigned long vaddr)
 {
        char *vfrom, *vto;
@@ -107,7 +112,9 @@ static inline void copy_user_highpage(st
        /* Make sure this page is cleared on other CPU's too before using it */
        smp_wmb();
 }
+#endif
 
+#ifndef __HAVE_ARCH_COPY_HIGHPAGE
 static inline void copy_highpage(struct page *to, struct page *from)
 {
        char *vfrom, *vto;
@@ -118,5 +125,6 @@ static inline void copy_highpage(struct 
        kunmap_atomic(vfrom, KM_USER0);
        kunmap_atomic(vto, KM_USER1);
 }
+#endif
 
 #endif /* _LINUX_HIGHMEM_H */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.