X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Flinux%2Fhighmem.h;h=8941f1283df88634f4218543fcd1ba9617e621a4;hb=refs%2Fheads%2Fvserver;hp=232d8fdb557c85723bc9fa41ad5e3b68f3b46230;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 232d8fdb5..8941f1283 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -1,25 +1,45 @@ #ifndef _LINUX_HIGHMEM_H #define _LINUX_HIGHMEM_H -#include #include #include +#include #include -#ifdef CONFIG_HIGHMEM +#ifndef ARCH_HAS_FLUSH_ANON_PAGE +static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) +{ +} +#endif + +#ifndef ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE +static inline void flush_kernel_dcache_page(struct page *page) +{ +} +#endif -extern struct page *highmem_start_page; +#ifdef CONFIG_HIGHMEM #include /* declarations for linux/mm/highmem.c */ unsigned int nr_free_highpages(void); +extern unsigned long totalhigh_pages; +#ifdef CONFIG_XEN +void kmap_flush_unused(void); +#endif #else /* CONFIG_HIGHMEM */ static inline unsigned int nr_free_highpages(void) { return 0; } +#ifdef CONFIG_XEN +static inline void kmap_flush_unused(void) { } +#endif + +#define totalhigh_pages 0 +#ifndef ARCH_HAS_KMAP static inline void *kmap(struct page *page) { might_sleep(); @@ -28,9 +48,12 @@ static inline void *kmap(struct page *page) #define kunmap(page) do { (void) (page); } while (0) -#define kmap_atomic(page, idx) page_address(page) -#define kunmap_atomic(addr, idx) do { } while (0) +#define kmap_atomic(page, idx) \ + ({ pagefault_disable(); page_address(page); }) +#define kunmap_atomic(addr, idx) do { pagefault_enable(); } while (0) +#define kmap_atomic_pfn(pfn, idx) kmap_atomic(pfn_to_page(pfn), (idx)) #define kmap_atomic_to_page(ptr) virt_to_page(ptr) +#endif #endif /* CONFIG_HIGHMEM */ @@ -40,8 +63,23 @@ static inline void clear_user_highpage(struct page *page, unsigned long vaddr) void *addr = kmap_atomic(page, KM_USER0); clear_user_page(addr, vaddr, page); kunmap_atomic(addr, KM_USER0); + /* Make sure this page is cleared on other CPU's too before using it */ + smp_wmb(); } +#ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE +static inline struct page * +alloc_zeroed_user_highpage(struct vm_area_struct *vma, unsigned long vaddr) +{ + struct page *page = alloc_page_vma(GFP_HIGHUSER, vma, vaddr); + + if (page) + clear_user_highpage(page, vaddr); + + return page; +} +#endif + static inline void clear_highpage(struct page *page) { void *kaddr = kmap_atomic(page, KM_USER0); @@ -64,7 +102,10 @@ static inline void memclear_highpage_flush(struct page *page, unsigned int offse kunmap_atomic(kaddr, KM_USER0); } -static inline void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr) +#ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE + +static inline void copy_user_highpage(struct page *to, struct page *from, + unsigned long vaddr, struct vm_area_struct *vma) { char *vfrom, *vto; @@ -73,8 +114,12 @@ static inline void copy_user_highpage(struct page *to, struct page *from, unsign copy_user_page(vto, vfrom, vaddr, to); kunmap_atomic(vfrom, KM_USER0); kunmap_atomic(vto, KM_USER1); + /* Make sure this page is cleared on other CPU's too before using it */ + smp_wmb(); } +#endif + static inline void copy_highpage(struct page *to, struct page *from) { char *vfrom, *vto;