diff --git a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c index 2a9ce1c4f8..566219167d 100644 --- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c @@ -79,6 +79,16 @@ void kunmap_atomic(void *kvaddr, enum km_type type) */ pte_clear(&init_mm, vaddr, kmap_pte-idx); __flush_tlb_one(vaddr); +#elif defined(CONFIG_XEN) + /* + * We must ensure there are no dangling pagetable references when + * returning memory to Xen (decrease_reservation). + * XXX TODO: We could make this faster by only zapping when + * kmap_flush_unused is called but that is trickier and more invasive. + */ + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); + pte_clear(&init_mm, vaddr, kmap_pte-idx); #endif dec_preempt_count(); diff --git a/xen/common/memory.c b/xen/common/memory.c index 1fd8466a4d..cd041e8585 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -170,6 +170,15 @@ guest_remove_page( if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) put_page(page); + if ( unlikely((page->count_info & PGC_count_mask) != 1) ) + { + /* We'll make this a guest-visible error in future, so take heed! */ + DPRINTK("Dom%d freeing in-use page %lx (pseudophys %lx):" + " count=%x type=%lx\n", + d->domain_id, mfn, get_gpfn_from_mfn(mfn), + page->count_info, page->u.inuse.type_info); + } + guest_physmap_remove_page(d, gmfn, mfn); put_page(page);