diff options
author | Jes Sorensen <jes@sgi.com> | 2006-09-27 04:50:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-27 11:26:13 -0400 |
commit | f4b81804a2d1ab341a4613089dc31ecce0800ed8 (patch) | |
tree | fdad77a7c40790908546a74a9b5918400d01333d /include/linux | |
parent | 5d2923436217ba8bd05c5ee157712a391891c382 (diff) |
[PATCH] do_no_pfn()
Implement do_no_pfn() for handling mapping of memory without a struct page
backing it. This avoids creating fake page table entries for regions which
are not backed by real memory.
This feature is used by the MSPEC driver and other users, where it is
highly undesirable to have a struct page sitting behind the page (for
instance if the page is accessed in cached mode via the struct page in
parallel to the the driver accessing it uncached, which can result in data
corruption on some architectures, such as ia64).
This version uses specific NOPFN_{SIGBUS,OOM} return values, rather than
expect all negative pfn values would be an error. It also bugs on cow
mappings as this would not work with the VM.
[akpm@osdl.org: micro-optimise]
Signed-off-by: Jes Sorensen <jes@sgi.com>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/mm.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 8e433bbc6e7e..22165cb18906 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -199,6 +199,7 @@ struct vm_operations_struct { | |||
199 | void (*open)(struct vm_area_struct * area); | 199 | void (*open)(struct vm_area_struct * area); |
200 | void (*close)(struct vm_area_struct * area); | 200 | void (*close)(struct vm_area_struct * area); |
201 | struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int *type); | 201 | struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int *type); |
202 | unsigned long (*nopfn)(struct vm_area_struct * area, unsigned long address); | ||
202 | int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock); | 203 | int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock); |
203 | 204 | ||
204 | /* notification that a previously read-only page is about to become | 205 | /* notification that a previously read-only page is about to become |
@@ -594,6 +595,12 @@ static inline int page_mapped(struct page *page) | |||
594 | #define NOPAGE_OOM ((struct page *) (-1)) | 595 | #define NOPAGE_OOM ((struct page *) (-1)) |
595 | 596 | ||
596 | /* | 597 | /* |
598 | * Error return values for the *_nopfn functions | ||
599 | */ | ||
600 | #define NOPFN_SIGBUS ((unsigned long) -1) | ||
601 | #define NOPFN_OOM ((unsigned long) -2) | ||
602 | |||
603 | /* | ||
597 | * Different kinds of faults, as returned by handle_mm_fault(). | 604 | * Different kinds of faults, as returned by handle_mm_fault(). |
598 | * Used to decide whether a process gets delivered SIGBUS or | 605 | * Used to decide whether a process gets delivered SIGBUS or |
599 | * just gets major/minor fault counters bumped up. | 606 | * just gets major/minor fault counters bumped up. |