Index: linux-2.6.11/include/asm-xen/asm-i386/page.h =================================================================== --- linux-2.6.11.orig/include/asm-xen/asm-i386/page.h 2005-07-11 12:18:47.000000000 +0200 +++ linux-2.6.11/include/asm-xen/asm-i386/page.h 2005-07-11 12:19:48.000000000 +0200 @@ -72,6 +72,19 @@ static inline unsigned long phys_to_mach static inline unsigned long machine_to_phys(unsigned long machine) { unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT); + +#if 1 /* debug */ +# ifdef CONFIG_X86_PAE +# define MAX_PFN 0xffffffl /* 36 bit phys addr */ +# else +# define MAX_PFN 0x0fffffl /* 32 bit phys addr */ +# endif + if (unlikely(phys > MAX_PFN)) { + printk("machine_to_phys BUG: insane pfn %lx > %lx, machine addr %lx\n", + phys, MAX_PFN, machine); + dump_stack(); + } +#endif phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK); return phys; } Index: linux-2.6.11/arch/xen/i386/mm/fault.c =================================================================== --- linux-2.6.11.orig/arch/xen/i386/mm/fault.c 2005-07-11 12:18:46.000000000 +0200 +++ linux-2.6.11/arch/xen/i386/mm/fault.c 2005-07-11 12:19:48.000000000 +0200 @@ -454,10 +454,53 @@ no_context: printk(" at virtual address %08lx\n",address); printk(KERN_ALERT " printing eip:\n"); printk("%08lx\n", regs->eip); +#ifndef CONFIG_X86_PAE + /* dirty shortcut for 2-level pgtables */ page = ((unsigned long *) per_cpu(cur_pgd, smp_processor_id())) [address >> 22]; printk(KERN_ALERT "*pde = ma %08lx pa %08lx\n", page, machine_to_phys(page)); +#else + { + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + int i; + + pgd = per_cpu(cur_pgd, smp_processor_id()) + pgd_index(address); + printk(" pgd: %p %8llx\n", pgd, pgd_val(*pgd)); + if (!pgd_present(*pgd)) + goto oops_walk_done; + + pud = pud_offset(pgd, address); + printk(" pud: %p %8llx\n", pud, pud_val(*pud)); + if (!pud_present(*pud)) + goto oops_walk_done; + + pmd = pmd_offset(pud, address); + printk(" pmd: %p %8llx\n", pmd, pmd_val(*pmd)); + if (!pmd_present(*pmd)) + goto oops_walk_done; + + pte = pte_offset_kernel(pmd, address); + printk(" pte: %p %8llx (ma %8llx)\n", + pte, pte_val(*pte), pte_val_ma(*pte)); + printk(" pte: mfn %5lx\n", pte_mfn(*pte)); + printk(" pte: pfn %5lx\n", pte_pfn(*pte)); + if (!pte_present(*pte)) + goto oops_walk_done; + + for (i = -4; i < 4; i++) { + if (((unsigned long)(pte+i) & PAGE_MASK) != + ((unsigned long)(pte) & PAGE_MASK)) + continue; + printk(" pte[%2d]: %8llx\n", i, pte_val(pte[i])); + } +oops_walk_done: + page = 0; + } +#endif /* * We must not directly access the pte in the highpte * case, the page table might be allocated in highmem. @@ -517,6 +560,7 @@ do_sigbus: vmalloc_fault: { + printk("%s: vmalloc_fault @ %lx\n", __FUNCTION__, address); /* * Synchronize this task's top level page-table * with the 'reference' page table. Index: linux-2.6.11/arch/xen/i386/mm/pgtable.c =================================================================== --- linux-2.6.11.orig/arch/xen/i386/mm/pgtable.c 2005-07-11 12:19:30.000000000 +0200 +++ linux-2.6.11/arch/xen/i386/mm/pgtable.c 2005-07-11 12:19:48.000000000 +0200 @@ -437,7 +437,32 @@ void make_pages_writable(void *va, unsig LIST_HEAD(mm_unpinned); DEFINE_SPINLOCK(mm_unpinned_lock); -static inline void mm_walk_set_prot(void *pt, pgprot_t flags) +#ifdef CONFIG_X86_PAE /* debug */ +#define MAX_PFN 0xffffffl /* 36 bit phys addr */ + +int mm_check_pmd(pmd_t *pmd) +{ + unsigned long flags = pmd->pmd & 0xfff; + unsigned long mfn = pmd->pmd >> PAGE_SHIFT; + unsigned long pfn = mfn_to_pfn(mfn); + + if (!(flags & _PAGE_PRESENT)) + return 0; + if (pfn < MAX_PFN) + return 0; + + printk("\n"); + printk("%s: BUG: %p %8llx, mfn %lx, pfn %lx\n", + __FUNCTION__, pmd, pmd->pmd, mfn, pfn); + printk("%s: pmd: machine %lx\n", + __FUNCTION__, virt_to_machine(pmd)); + return 1; +} +#else +#define mm_check_pmd(pmd) +#endif + +static void mm_walk_set_prot(void *pt, pgprot_t flags) { struct page *page = virt_to_page(pt); unsigned long pfn = page_to_pfn(page); @@ -471,6 +496,8 @@ static void mm_walk(struct mm_struct *mm if (PTRS_PER_PMD > 1) /* not folded */ mm_walk_set_prot(pmd,flags); for (m = 0; m < PTRS_PER_PMD; m++, pmd++) { + if (mm_check_pmd(pmd)) + goto bug; if (pmd_none(*pmd)) continue; pte = pte_offset_kernel(pmd,0); @@ -478,12 +505,26 @@ static void mm_walk(struct mm_struct *mm } } } + return; + + bug: + printk("pgd %p %8llx\n", pgd, pgd->pgd); + printk("pmd %p %8llx\n", pmd, pmd->pmd); + + printk("--\n"); + for (; m < PTRS_PER_PMD; m++, pmd++) { + if (!pmd->pmd) + continue; + printk("pmd %p %8llx\n", pmd, pmd->pmd); + } + panic("better stop here"); } void mm_pin(struct mm_struct *mm) { spin_lock(&mm->page_table_lock); +// printk("%s\n", __FUNCTION__); mm_walk(mm, PAGE_KERNEL_RO); HYPERVISOR_update_va_mapping( (unsigned long)mm->pgd, @@ -502,6 +543,7 @@ void mm_unpin(struct mm_struct *mm) { spin_lock(&mm->page_table_lock); +// printk("%s\n", __FUNCTION__); xen_pgd_unpin(__pa(mm->pgd)); HYPERVISOR_update_va_mapping( (unsigned long)mm->pgd,