X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fmm%2Fhighmem-xen.c;h=4b5d9e3dbf091b0161c94093b3a4148af6ff580f;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=23f0e1b2e926fbeb4bd1c7ed7fe62595badcf245;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/arch/i386/mm/highmem-xen.c b/arch/i386/mm/highmem-xen.c index 23f0e1b2e..4b5d9e3db 100644 --- a/arch/i386/mm/highmem-xen.c +++ b/arch/i386/mm/highmem-xen.c @@ -32,17 +32,15 @@ static void *__kmap_atomic(struct page *page, enum km_type type, pgprot_t prot) 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; } @@ -60,39 +58,26 @@ void *kmap_atomic_pte(struct page *page, enum km_type type) 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 @@ -103,12 +88,11 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) 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; }