aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/mm
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2007-07-21 11:11:35 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-21 21:37:14 -0400
commit9585116ba09f1d8c52d0a1346e20bb9d443e9c02 (patch)
treec3380b477754d3d2d77fa8dbd08f0b0d08fdcadf /arch/i386/mm
parenta2900975ef3f1df33c83e750cc1e490de3374ca8 (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 'arch/i386/mm')
-rw-r--r--arch/i386/mm/ioremap.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index fff08ae7b5ed..0b278315d737 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -196,7 +196,7 @@ void iounmap(volatile void __iomem *addr)
196 /* Reset the direct mapping. Can block */ 196 /* Reset the direct mapping. Can block */
197 if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) { 197 if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
198 change_page_attr(virt_to_page(__va(p->phys_addr)), 198 change_page_attr(virt_to_page(__va(p->phys_addr)),
199 p->size >> PAGE_SHIFT, 199 get_vm_area_size(p) >> PAGE_SHIFT,
200 PAGE_KERNEL); 200 PAGE_KERNEL);
201 global_flush_tlb(); 201 global_flush_tlb();
202 } 202 }