diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2007-07-21 11:11:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-21 21:37:14 -0400 |
commit | 9585116ba09f1d8c52d0a1346e20bb9d443e9c02 (patch) | |
tree | c3380b477754d3d2d77fa8dbd08f0b0d08fdcadf /include/linux/vmalloc.h | |
parent | a2900975ef3f1df33c83e750cc1e490de3374ca8 (diff) |
i386: fix iounmap's use of vm_struct's size field
get_vm_area always returns an area with an adjacent guard page. That guard
page is included in vm_struct.size. iounmap uses vm_struct.size to
determine how much address space needs to have change_page_attr applied to
it, which will BUG if applied to the guard page.
This patch adds a helper function - get_vm_area_size() in linux/vmalloc.h -
to return the actual size of a vm area, and uses it to make iounmap do the
right thing. There are probably other places which should be using
get_vm_area_size().
Thanks to Dave Young <hidave.darkstar@gmail.com> for debugging the
problem.
[ Andi, it wasn't clear to me whether x86_64 needs the same fix. ]
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Cc: Dave Young <hidave.darkstar@gmail.com>
Cc: Chuck Ebbert <cebbert@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/vmalloc.h')
-rw-r--r-- | include/linux/vmalloc.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index c2b10cae5da5..89338b468d0d 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h | |||
@@ -58,6 +58,13 @@ void vmalloc_sync_all(void); | |||
58 | /* | 58 | /* |
59 | * Lowlevel-APIs (not for driver use!) | 59 | * Lowlevel-APIs (not for driver use!) |
60 | */ | 60 | */ |
61 | |||
62 | static inline size_t get_vm_area_size(const struct vm_struct *area) | ||
63 | { | ||
64 | /* return actual size without guard page */ | ||
65 | return area->size - PAGE_SIZE; | ||
66 | } | ||
67 | |||
61 | extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags); | 68 | extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags); |
62 | extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, | 69 | extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, |
63 | unsigned long start, unsigned long end); | 70 | unsigned long start, unsigned long end); |