diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index abe8e4b..483bad7 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -285,7 +285,7 @@ check_v8086_mode(struct pt_regs *regs, unsigned long address, tsk->thread.screen_bitmap |= 1 << bit; } -static void dump_pagetable(unsigned long address) +void dump_pagetable(unsigned long address) { __typeof__(pte_val(__pte(0))) page; @@ -603,6 +603,10 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, printk_address(regs->ip, 1); dump_pagetable(address); + printk(KERN_CRIT "Fixmap KM_PTE0 @ %#lx\n", fix_to_virt(KM_PTE0)); + dump_pagetable(fix_to_virt(KM_PTE0)); + printk(KERN_CRIT "Fixmap KM_PTE0 @ %#lx\n", fix_to_virt(KM_PTE1)); + dump_pagetable(fix_to_virt(KM_PTE1)); } static noinline void diff --git a/include/xen/swiotlb.h b/include/xen/swiotlb.h index f35183b..5db8659 100644 --- a/include/xen/swiotlb.h +++ b/include/xen/swiotlb.h @@ -5,6 +5,10 @@ extern void xen_swiotlb_fixup(void *buf, size_t size, unsigned long nslabs); extern phys_addr_t xen_bus_to_phys(dma_addr_t daddr); extern dma_addr_t xen_phys_to_bus(phys_addr_t paddr); extern int xen_range_needs_mapping(phys_addr_t phys, size_t size); +#ifdef CONFIG_XEN_PCI extern int xen_wants_swiotlb(void); +#else +static inline int xen_wants_swiotlb(void) { return 0; } +#endif #endif /* _XEN_SWIOTLB_H */ diff --git a/mm/rmap.c b/mm/rmap.c index 1652166..ae5d5a0 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -267,6 +267,7 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) pte_t *page_check_address(struct page *page, struct mm_struct *mm, unsigned long address, spinlock_t **ptlp, int sync) { + struct page *pgd_page, *pte_page; pgd_t *pgd; pud_t *pud; pmd_t *pmd; @@ -285,6 +286,22 @@ pte_t *page_check_address(struct page *page, struct mm_struct *mm, if (!pmd_present(*pmd)) return NULL; + pgd_page = virt_to_page(mm->pgd); + pte_page = pmd_page(*pmd); + + if (PagePinned(pgd_page) != PagePinned(pte_page)) { + extern void dump_pagetable(unsigned long address); + printk(KERN_CRIT "L4 at %p is %s contains L2 at %p which points at an L1 which is %s %s\n", + pgd, PagePinned(pgd_page) ? "pinned" : "unpinned", + pmd, PagePinned(pte_page) ? "pinned" : "unpinned", + PageHighMem(pte_page) ? "highmem" : "lowmem"); + printk(KERN_CRIT "address %#lx\n", address); + dump_pagetable(address); + printk(KERN_CRIT "Fixmap KM_PTE0 @ %#lx\n", fix_to_virt(KM_PTE0)); + dump_pagetable(fix_to_virt(KM_PTE0)); + printk(KERN_CRIT "Fixmap KM_PTE0 @ %#lx\n", fix_to_virt(KM_PTE1)); + dump_pagetable(fix_to_virt(KM_PTE1)); + } pte = pte_offset_map(pmd, address); /* Make a quick check before getting the lock */ if (!sync && !pte_present(*pte)) {