[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |