Index: linux-2.6.18-mm3/mm/memory.c =================================================================== --- linux-2.6.18-mm3.orig/mm/memory.c 2006-10-04 22:10:28.583239844 -0500 +++ linux-2.6.18-mm3/mm/memory.c 2006-10-04 22:12:35.816735087 -0500 @@ -79,14 +79,14 @@ EXPORT_SYMBOL(mem_map); #ifdef CONFIG_VIRTUAL_MEM_MAP int __pfn_valid (unsigned long pfn) { - char byte; - struct page *page = pfn_to_page(pfn); + u8 byte; + u8 *start = (u8 *)pfn_to_page(pfn); /* * A pfn is valid if we can read the first byte of the * page struct it points to. */ - int result = __get_user(byte, (char __user *)page) == 0; + int result = probe_kernel_address(start, byte) != -EFAULT; /* & If the struct page may cross a page boundary then we also @@ -96,15 +96,15 @@ int __pfn_valid (unsigned long pfn) * additional checks. */ if (result && VMEMMAP_PAGE_SIZE % sizeof(struct page)) { - char *end = ((char *)page) + sizeof(struct page) - 1; + u8 *end = start + sizeof(struct page) - 1; /* * A check is only necessary if the end of the page struct * is on a different page of the virtual memory map. */ if ((unsigned long)end / VMEMMAP_PAGE_SIZE != - (unsigned long)page / VMEMMAP_PAGE_SIZE) - result = __get_user(byte, (char __user *)end) == 0; + (unsigned long)start / VMEMMAP_PAGE_SIZE) + result = probe_kernel_address(end, byte) != -EFAULT; } return result; }