x86: unify noexec handling
[safe/jmp/linux-2.6] / arch / x86 / mm / ioremap.c
index 2ddb1e7..8a45093 100644 (file)
 #include <asm/pgalloc.h>
 #include <asm/pat.h>
 
-#ifdef CONFIG_X86_64
-
-static inline int phys_addr_valid(unsigned long addr)
+static inline int phys_addr_valid(resource_size_t addr)
 {
-       return addr < (1UL << boot_cpu_data.x86_phys_bits);
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+       return !(addr >> boot_cpu_data.x86_phys_bits);
+#else
+       return 1;
+#endif
 }
 
+#ifdef CONFIG_X86_64
+
 unsigned long __phys_addr(unsigned long x)
 {
        if (x >= __START_KERNEL_map) {
@@ -38,8 +42,7 @@ unsigned long __phys_addr(unsigned long x)
        } else {
                VIRTUAL_BUG_ON(x < PAGE_OFFSET);
                x -= PAGE_OFFSET;
-               VIRTUAL_BUG_ON(system_state == SYSTEM_BOOTING ? x > MAXMEM :
-                                       !phys_addr_valid(x));
+               VIRTUAL_BUG_ON(!phys_addr_valid(x));
        }
        return x;
 }
@@ -56,10 +59,8 @@ bool __virt_addr_valid(unsigned long x)
                if (x < PAGE_OFFSET)
                        return false;
                x -= PAGE_OFFSET;
-               if (system_state == SYSTEM_BOOTING ?
-                               x > MAXMEM : !phys_addr_valid(x)) {
+               if (!phys_addr_valid(x))
                        return false;
-               }
        }
 
        return pfn_valid(x >> PAGE_SHIFT);
@@ -68,18 +69,12 @@ EXPORT_SYMBOL(__virt_addr_valid);
 
 #else
 
-static inline int phys_addr_valid(unsigned long addr)
-{
-       return 1;
-}
-
 #ifdef CONFIG_DEBUG_VIRTUAL
 unsigned long __phys_addr(unsigned long x)
 {
-       /* VMALLOC_* aren't constants; not available at the boot time */
+       /* VMALLOC_* aren't constants  */
        VIRTUAL_BUG_ON(x < PAGE_OFFSET);
-       VIRTUAL_BUG_ON(system_state != SYSTEM_BOOTING &&
-               is_vmalloc_addr((void *) x));
+       VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
        return x - PAGE_OFFSET;
 }
 EXPORT_SYMBOL(__phys_addr);
@@ -89,7 +84,9 @@ bool __virt_addr_valid(unsigned long x)
 {
        if (x < PAGE_OFFSET)
                return false;
-       if (system_state != SYSTEM_BOOTING && is_vmalloc_addr((void *) x))
+       if (__vmalloc_start_set && is_vmalloc_addr((void *) x))
+               return false;
+       if (x >= FIXADDR_START)
                return false;
        return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
 }
@@ -134,25 +131,6 @@ int page_is_ram(unsigned long pagenr)
        return 0;
 }
 
-int pagerange_is_ram(unsigned long start, unsigned long end)
-{
-       int ram_page = 0, not_rampage = 0;
-       unsigned long page_nr;
-
-       for (page_nr = (start >> PAGE_SHIFT); page_nr < (end >> PAGE_SHIFT);
-            ++page_nr) {
-               if (page_is_ram(page_nr))
-                       ram_page = 1;
-               else
-                       not_rampage = 1;
-
-               if (ram_page == not_rampage)
-                       return -1;
-       }
-
-       return ram_page;
-}
-
 /*
  * Fix up the linear direct mapping of the kernel to avoid cache attribute
  * conflicts.
@@ -302,15 +280,16 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
                return NULL;
        area->phys_addr = phys_addr;
        vaddr = (unsigned long) area->addr;
-       if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
+
+       if (kernel_map_sync_memtype(phys_addr, size, prot_val)) {
                free_memtype(phys_addr, phys_addr + size);
                free_vm_area(area);
                return NULL;
        }
 
-       if (ioremap_change_attr(vaddr, size, prot_val) < 0) {
+       if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
                free_memtype(phys_addr, phys_addr + size);
-               vunmap(area->addr);
+               free_vm_area(area);
                return NULL;
        }
 
@@ -396,7 +375,8 @@ static void __iomem *ioremap_default(resource_size_t phys_addr,
         * - UC_MINUS for non-WB-able memory with no other conflicting mappings
         * - Inherit from confliting mappings otherwise
         */
-       err = reserve_memtype(phys_addr, phys_addr + size, -1, &flags);
+       err = reserve_memtype(phys_addr, phys_addr + size,
+                               _PAGE_CACHE_WB, &flags);
        if (err < 0)
                return NULL;
 
@@ -527,13 +507,19 @@ static inline pte_t * __init early_ioremap_pte(unsigned long addr)
        return &bm_pte[pte_index(addr)];
 }
 
+static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata;
+
 void __init early_ioremap_init(void)
 {
        pmd_t *pmd;
+       int i;
 
        if (early_ioremap_debug)
                printk(KERN_INFO "early_ioremap_init()\n");
 
+       for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
+               slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
+
        pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
        memset(bm_pte, 0, sizeof(bm_pte));
        pmd_populate_kernel(&init_mm, pmd, bm_pte);
@@ -557,38 +543,13 @@ void __init early_ioremap_init(void)
        }
 }
 
-void __init early_ioremap_clear(void)
-{
-       pmd_t *pmd;
-
-       if (early_ioremap_debug)
-               printk(KERN_INFO "early_ioremap_clear()\n");
-
-       pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
-       pmd_clear(pmd);
-       paravirt_release_pte(__pa(bm_pte) >> PAGE_SHIFT);
-       __flush_tlb_all();
-}
-
 void __init early_ioremap_reset(void)
 {
-       enum fixed_addresses idx;
-       unsigned long addr, phys;
-       pte_t *pte;
-
        after_paging_init = 1;
-       for (idx = FIX_BTMAP_BEGIN; idx >= FIX_BTMAP_END; idx--) {
-               addr = fix_to_virt(idx);
-               pte = early_ioremap_pte(addr);
-               if (pte_present(*pte)) {
-                       phys = pte_val(*pte) & PAGE_MASK;
-                       set_fixmap(idx, phys);
-               }
-       }
 }
 
 static void __init __early_set_fixmap(enum fixed_addresses idx,
-                                  unsigned long phys, pgprot_t flags)
+                                     phys_addr_t phys, pgprot_t flags)
 {
        unsigned long addr = __fix_to_virt(idx);
        pte_t *pte;
@@ -607,7 +568,7 @@ static void __init __early_set_fixmap(enum fixed_addresses idx,
 }
 
 static inline void __init early_set_fixmap(enum fixed_addresses idx,
-                                          unsigned long phys, pgprot_t prot)
+                                          phys_addr_t phys, pgprot_t prot)
 {
        if (after_paging_init)
                __set_fixmap(idx, phys, prot);
@@ -625,6 +586,7 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx)
 
 static void __iomem *prev_map[FIX_BTMAPS_SLOTS] __initdata;
 static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata;
+
 static int __init check_early_ioremap_leak(void)
 {
        int count = 0;
@@ -646,9 +608,11 @@ static int __init check_early_ioremap_leak(void)
 }
 late_initcall(check_early_ioremap_leak);
 
-static void __init __iomem *__early_ioremap(unsigned long phys_addr, unsigned long size, pgprot_t prot)
+static void __init __iomem *
+__early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot)
 {
-       unsigned long offset, last_addr;
+       unsigned long offset;
+       resource_size_t last_addr;
        unsigned int nrpages;
        enum fixed_addresses idx0, idx;
        int i, slot;
@@ -664,15 +628,15 @@ static void __init __iomem *__early_ioremap(unsigned long phys_addr, unsigned lo
        }
 
        if (slot < 0) {
-               printk(KERN_INFO "early_iomap(%08lx, %08lx) not found slot\n",
-                        phys_addr, size);
+               printk(KERN_INFO "early_iomap(%08llx, %08lx) not found slot\n",
+                        (u64)phys_addr, size);
                WARN_ON(1);
                return NULL;
        }
 
        if (early_ioremap_debug) {
-               printk(KERN_INFO "early_ioremap(%08lx, %08lx) [%d] => ",
-                      phys_addr, size, slot);
+               printk(KERN_INFO "early_ioremap(%08llx, %08lx) [%d] => ",
+                      (u64)phys_addr, size, slot);
                dump_stack();
        }
 
@@ -712,20 +676,22 @@ static void __init __iomem *__early_ioremap(unsigned long phys_addr, unsigned lo
                --nrpages;
        }
        if (early_ioremap_debug)
-               printk(KERN_CONT "%08lx + %08lx\n", offset, fix_to_virt(idx0));
+               printk(KERN_CONT "%08lx + %08lx\n", offset, slot_virt[slot]);
 
-       prev_map[slot] = (void __iomem *)(offset + fix_to_virt(idx0));
+       prev_map[slot] = (void __iomem *)(offset + slot_virt[slot]);
        return prev_map[slot];
 }
 
 /* Remap an IO device */
-void __init __iomem *early_ioremap(unsigned long phys_addr, unsigned long size)
+void __init __iomem *
+early_ioremap(resource_size_t phys_addr, unsigned long size)
 {
        return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO);
 }
 
 /* Remap memory */
-void __init __iomem *early_memremap(unsigned long phys_addr, unsigned long size)
+void __init __iomem *
+early_memremap(resource_size_t phys_addr, unsigned long size)
 {
        return __early_ioremap(phys_addr, size, PAGE_KERNEL);
 }
@@ -782,8 +748,3 @@ void __init early_iounmap(void __iomem *addr, unsigned long size)
        }
        prev_map[slot] = NULL;
 }
-
-void __this_fixmap_does_not_exist(void)
-{
-       WARN_ON(1);
-}