From: Scott Parish Subject: [patch] more correct pfn_valid() Date: Wed, 18 May 2005 21:47:53 +0000 Message-ID: <20050518214753.GA4450@us.ibm.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="4Ckj6UjgE2iN1+kY" Return-path: Content-Disposition: inline List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org --4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Context: x86_64, 6gig ram. (XEN) Physical RAM map: (XEN) 0000000000000000 - 000000000009dc00 (usable) (XEN) 000000000009dc00 - 00000000000a0000 (reserved) (XEN) 00000000000d0000 - 0000000000100000 (reserved) (XEN) 0000000000100000 - 00000000dff60000 (usable) (XEN) 00000000dff60000 - 00000000dff72000 (ACPI data) (XEN) 00000000dff72000 - 00000000dff80000 (ACPI NVS) (XEN) 00000000dff80000 - 00000000e0000000 (reserved) (XEN) 00000000fec00000 - 00000000fec00400 (reserved) (XEN) 00000000fee00000 - 00000000fee01000 (reserved) (XEN) 00000000fff80000 - 0000000100000000 (reserved) (XEN) 0000000100000000 - 0000000180000000 (usable) <---- above hole Notice there is now memory above the pci hole. get_page_from_l1e() has the following code: /* No reference counting for out-of-range I/O pages. */ if ( !pfn_valid(mfn) ) return 1; where: #define pfn_valid(_pfn) ((_pfn) < max_page) Since max_page is now above the out-of-range io, the pfn_valid() returns "valid". And hence get_page() is called, but returns an error given that the page count is zero ("not allocated") which ultimately ends up that the ioremap() for several device drivers fails with ENOMEM. While attached patch fixes this problem (from empirical evidence), there may be a better solution. sRp -- Scott Parish Signed-off-by: srparish@us.ibm.com --4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="pfn_valid.diff" diff -rN -u -p old-xen-64/xen/include/asm-x86/e820.h new-xen-64/xen/include/asm-x86/e820.h --- old-xen-64/xen/include/asm-x86/e820.h 2005-05-17 19:24:08.000000000 +0000 +++ new-xen-64/xen/include/asm-x86/e820.h 2005-05-18 21:09:40.000000000 +0000 @@ -36,4 +36,17 @@ extern void print_e820_memory_map(struct #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +static inline int pfn_valid(unsigned long pfn) { + int i; + + for (i = 0; i < e820.nr_map; i++) { + if (pfn >= (e820.map[i].addr >> PAGE_SHIFT) && + pfn < ((e820.map[i].addr & ~PAGE_MASK) + + e820.map[i].size) >> PAGE_SHIFT) + return 1; + } + + return 0; +} + #endif /*__E820_HEADER*/ diff -rN -u -p old-xen-64/xen/include/asm-x86/page.h new-xen-64/xen/include/asm-x86/page.h --- old-xen-64/xen/include/asm-x86/page.h 2005-05-13 11:28:10.000000000 +0000 +++ new-xen-64/xen/include/asm-x86/page.h 2005-05-18 21:09:30.000000000 +0000 @@ -36,7 +36,6 @@ typedef struct { unsigned long pt_lo; } #define pfn_to_page(_pfn) (frame_table + (_pfn)) #define phys_to_page(kaddr) (frame_table + ((kaddr) >> PAGE_SHIFT)) #define virt_to_page(kaddr) (frame_table + (__pa(kaddr) >> PAGE_SHIFT)) -#define pfn_valid(_pfn) ((_pfn) < max_page) /* High table entries are reserved by the hypervisor. */ #define DOMAIN_ENTRIES_PER_L2_PAGETABLE \ --4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --4Ckj6UjgE2iN1+kY--