unsigned long vaddr;
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
- inc_preempt_count();
+ pagefault_disable();
if (!PageHighMem(page))
return page_address(page);
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-#ifdef CONFIG_DEBUG_HIGHMEM
if (!pte_none(*(kmap_pte-idx)))
BUG();
-#endif
- set_pte_at_sync(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
+ set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
return (void*) vaddr;
}
void kunmap_atomic(void *kvaddr, enum km_type type)
{
-#if defined(CONFIG_DEBUG_HIGHMEM) || defined(CONFIG_XEN)
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
- if (vaddr < FIXADDR_START) { // FIXME
- dec_preempt_count();
- preempt_check_resched();
- return;
- }
-#endif
-
-#if defined(CONFIG_DEBUG_HIGHMEM)
- if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
- BUG();
-
- /*
- * force other mappings to Oops if they'll try to access
- * this pte without first remap it
- */
- 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.
+ * Force other mappings to Oops if they'll try to access this pte
+ * without first remap it. Keeping stale mappings around is a bad idea
+ * also, in case the page changes cacheability attributes or becomes
+ * a protected page in a hypervisor.
*/
- pte_clear(&init_mm, vaddr, kmap_pte-idx);
+ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
+ kpte_clear_flush(kmap_pte-idx, vaddr);
+ __flush_tlb_one(vaddr);
+ } else {
+#ifdef CONFIG_DEBUG_HIGHMEM
+ BUG_ON(vaddr < PAGE_OFFSET);
+ BUG_ON(vaddr >= (unsigned long)high_memory);
#endif
+ }
- dec_preempt_count();
- preempt_check_resched();
+ pagefault_enable();
}
/* This is the same as kmap_atomic() but can map memory that doesn't
enum fixed_addresses idx;
unsigned long vaddr;
- inc_preempt_count();
+ pagefault_disable();
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
- __flush_tlb_one(vaddr);
return (void*) vaddr;
}