[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-ia64-devel] Oops from loop driver on IA64



Hi,

Yamahata-san is right. After more investigation, that page is valid
but the page struct is missing.

Attached patch fixes this issue but I think this patch is messy.
Probably it's a stopgap until P2M/VP integration.

Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>

Thanks,
Kouya

Isaku Yamahata writes:
 > 
 > On Tue, Apr 18, 2006 at 07:41:55PM +0900, Kouya SHIMURA wrote:
 > Content-Description: message body text
 > 
 > > We encounter a Oops message from loop driver when vbd is used
 > > in dom0 kernel with CONFIG_VIRTUAL_MEM_MAP on ia64.
 > > 
 > > I investigated this and might find a serious bug.
 > > On x86, flush_dcache_page() does nothing and there is no problem.
 > > But on ia64 flush_dcache_page() might access a wrong page struct
 > > and destroy the kernel memory.
 > > 
 > > Attached patch fixes this problem but it seems bad idea to modify
 > > a linux driver. How should we fix it?
 > 
 > Why is a invalid page passed?
 > Should it be fixed instead of modifying loop.c?
 > 
 > -- 
 > yamahata

diff -r 7ed6c203efe9 linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c Wed Apr 19 
10:39:15 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c Thu Apr 20 
20:37:20 2006 +0900
@@ -43,7 +43,7 @@ unsigned long alloc_empty_foreign_map_pa
        struct vm_struct *vma;
 
        if ( (vma = get_vm_area(PAGE_SIZE * pages, VM_ALLOC)) == NULL )
-               return NULL;
+               return 0;
 
        return (unsigned long)vma->addr;
 }
@@ -53,4 +53,55 @@ unsigned long alloc_empty_foreign_map_pa
  * a convenient arch include */
 unsigned long mfn_to_pfn(unsigned long mfn) { return mfn; }
 #endif
+
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+#include <asm/pgalloc.h>
+#include <asm/meminit.h>
+
+static inline void *alloc_one_page(void)
+{
+       struct page *pg = alloc_page(GFP_KERNEL);
+       unsigned long pfn;
+       void *p;
+
+       if (!pg)
+               panic("Not enough memory for virtual mem map!\n");
+       pfn = page_to_pfn(pg);
+       p = (void *)(pfn << PAGE_SHIFT);
+       memset(__va(p), 0, PAGE_SIZE);
+       return p;
+}
+
+void
+extend_mem_map_page_table (u64 vaddr)
+{
+       unsigned long address;
+       struct page *map;
+       pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmd;
+       pte_t *pte;
+
+       map = vmem_map + (__pa(vaddr) >> PAGE_SHIFT);
+       address = (unsigned long) map & PAGE_MASK;
+
+       pgd = pgd_offset_k(address);
+       if (pgd_none(*pgd))
+               pgd_populate(&init_mm, pgd, alloc_one_page());
+       pud = pud_offset(pgd, address);
+
+       if (pud_none(*pud))
+               pud_populate(&init_mm, pud, alloc_one_page());
+       pmd = pmd_offset(pud, address);
+
+       if (pmd_none(*pmd))
+               pmd_populate_kernel(&init_mm, pmd, alloc_one_page());
+       pte = pte_offset_kernel(pmd, address);
+
+       if (pte_none(*pte))
+               set_pte(pte, pfn_pte(__pa(alloc_one_page()) >> PAGE_SHIFT,
+                                    PAGE_KERNEL));
+}
+#endif /* CONFIG_VIRTUAL_MEM_MAP */
+
 #endif
diff -r 7ed6c203efe9 linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Wed Apr 19 
10:39:15 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c        Thu Apr 20 
20:37:20 2006 +0900
@@ -413,6 +413,15 @@ static void dispatch_rw_block_io(blkif_t
 #ifdef __ia64__
                pending_vaddrs[vaddr_pagenr(pending_req, i)] =
                        (unsigned long)gnttab_map_vaddr(map[i]);
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+               {
+                       extern void extend_mem_map_page_table(u64);
+                       u64 vaddr = gnttab_map_vaddr(map[i]);
+
+                       if (!pfn_valid(__pa(vaddr) >> PAGE_SHIFT))
+                               extend_mem_map_page_table(vaddr);
+               }
+#endif
 #else
                set_phys_to_machine(__pa(vaddr(
                        pending_req, i)) >> PAGE_SHIFT,
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.