WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ia64-devel

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
<Prev in Thread] Current Thread [Next in Thread>