fix amd64-agp aperture validation
PATCH 1/1 fix amd64-agp aperture validation
Under Xen, pfn_valid() on a machine address makes no sense. But even on native, under CONFIG_DISCONTIGMEM, assuming that a !pfn_valid() implies all subsequent pfn-s are also invalid is wrong. Thus replace this by explicitly checking against the E820 map.
Patch is in 2.6.22-rc4, but was not tested against 2.6.18.
Signed-off-by Jan Beulich <[email protected]>
Acked-by Mark Langsdorf <[email protected]>
arch/i386/kernel/setup-xen.c +29 -0
@@ -1029,6 +1029,35 @@ efi_memory_present_wrapper(unsigned longreturn 0 ; } +/* +* This function checks if any part of the range <start,end> is mapped +* with type. +*/ +int +e820_any_mapped (u64 start,u64 end,unsigned type) +{ +int i; + +#ifndef CONFIG_XEN +for (i =0 ; i < e820.nr_map; i++) { +const struct e820entry *ei = &e820.map[i]; +#else +if (!is_initial_xendomain ()) +return 0 ; +for (i =0 ; i < machine_e820.nr_map; ++i) { +const struct e820entry *ei = &machine_e820.map[i]; +#endif + +if (type && ei->type != type) +continue ; +if (ei->addr >= end || ei->addr + ei->size <= start) +continue ; +return 1 ; + } +return 0 ; +} +EXPORT_SYMBOL_GPL (e820_any_mapped); +/* * This function checks if the entire range <start,end> is mapped with type. *
arch/i386/kernel/setup.c +22 -0
@@ -1029,6 +1029,28 @@ efi_memory_present_wrapper(unsigned longreturn 0 ; } +/* +* This function checks if any part of the range <start,end> is mapped +* with type. +*/ +int +e820_any_mapped (u64 start,u64 end,unsigned type) +{ +int i; + +for (i =0 ; i < e820.nr_map; i++) { +const struct e820entry *ei = &e820.map[i]; + +if (type && ei->type != type) +continue ; +if (ei->addr >= end || ei->addr + ei->size <= start) +continue ; +return 1 ; + } +return 0 ; +} +EXPORT_SYMBOL_GPL (e820_any_mapped); +/* * This function checks if the entire range <start,end> is mapped with type. *
arch/x86_64/kernel/e820-xen.c +13 -4
@@ -88,17 +88,26 @@ static inline int bad_addr(unsigned longreturn 0 ; } -#ifndef CONFIG_XEN /* * This function checks if any part of the range <start,end> is mapped * with type. */ -int __meminit -e820_any_mapped (unsigned long start,unsigned long end,unsigned type) +int e820_any_mapped (unsigned long start,unsigned long end,unsigned type) {int i; + +#ifndef CONFIG_XEN for (i =0 ; i < e820.nr_map; i++) {struct e820entry *ei = &e820.map[i]; +#else +extern struct e820map machine_e820; + +if (!is_initial_xendomain ()) +return 0 ; +for (i =0 ; i < machine_e820.nr_map; i++) { +const struct e820entry *ei = &machine_e820.map[i]; +#endif +if (type && ei->type != type)continue ;if (ei->addr >= end || ei->addr + ei->size <= start)
@@ -107,7 +116,7 @@ int __meminit e820_any_mapped(unsigned l }return 0 ; } -#endif +EXPORT_SYMBOL_GPL (e820_any_mapped);/* * This function checks if the entire range <start,end> is mapped with type.
arch/x86_64/kernel/e820.c +2 -1
@@ -98,7 +98,7 @@ static inline int bad_addr(unsigned long* This function checks if any part of the range <start,end> is mapped * with type. */ -int __meminit +int e820_any_mapped (unsigned long start,unsigned long end,unsigned type) {int i;
@@ -112,6 +112,7 @@ e820_any_mapped(unsigned long start, uns }return 0 ; } +EXPORT_SYMBOL_GPL (e820_any_mapped);/* * This function checks if the entire range <start,end> is mapped with type.
drivers/char/agp/amd64-agp.c +4 -9
@@ -15,6 +15,7 @@#include <linux/mmzone.h> #include <asm/page.h> /* PAGE_SIZE */ #include <asm/k8.h> +#include <asm/e820.h> #include "agp.h" /* PTE bits. */
@@ -259,7 +260,6 @@ static const struct agp_bridge_driver am/* Some basic sanity checks for the aperture. */ static int __devinit aperture_valid (u64 aper,u32 size) { -u32 pfn, c;if (aper ==0 ) { printk(KERN_ERR PFX "No aperture\n");return 0 ;
@@ -272,14 +272,9 @@ static int __devinit aperture_valid(u64 printk(KERN_ERR PFX "Aperture out of bounds\n");return 0 ; } - pfn = aper >>PAGE_SHIFT ; -for (c =0 ; c < size/PAGE_SIZE ; c++) { -if (!pfn_valid (pfn + c)) -break ; -if (!PageReserved (pfn_to_page (pfn + c))) { - printk(KERN_ERR PFX "Aperture pointing to RAM\n"); -return 0 ; - } +if (e820_any_mapped (aper, aper + size,E820_RAM )) { + printk(KERN_ERR PFX "Aperture pointing to RAM\n"); +return 0 ; }/* Request the Aperture. This catches cases when someone else
include/asm-i386/e820.h +1 -0
@@ -38,6 +38,7 @@ extern struct e820map e820;extern int e820_all_mapped (unsigned long start,unsigned long end,unsigned type); +extern int e820_any_mapped (u64 start,u64 end,unsigned type);#endif /*!__ASSEMBLY__*/