[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |