diff options
Diffstat (limited to 'arch/microblaze/mm')
| -rw-r--r-- | arch/microblaze/mm/consistent.c | 16 | ||||
| -rw-r--r-- | arch/microblaze/mm/fault.c | 18 | ||||
| -rw-r--r-- | arch/microblaze/mm/highmem.c | 2 | ||||
| -rw-r--r-- | arch/microblaze/mm/init.c | 117 | ||||
| -rw-r--r-- | arch/microblaze/mm/pgtable.c | 22 |
5 files changed, 54 insertions, 121 deletions
diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c index a1e2e18e096..e10ad930895 100644 --- a/arch/microblaze/mm/consistent.c +++ b/arch/microblaze/mm/consistent.c @@ -13,7 +13,7 @@ * published by the Free Software Foundation. */ -#include <linux/module.h> +#include <linux/export.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -37,7 +37,7 @@ #include <asm/pgalloc.h> #include <linux/io.h> #include <linux/hardirq.h> -#include <asm/mmu_context.h> +#include <linux/mmu_context.h> #include <asm/mmu.h> #include <linux/uaccess.h> #include <asm/pgtable.h> @@ -102,8 +102,7 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle) # endif if ((unsigned int)ret > cpuinfo.dcache_base && (unsigned int)ret < cpuinfo.dcache_high) - printk(KERN_WARNING - "ERROR: Your cache coherent area is CACHED!!!\n"); + pr_warn("ERROR: Your cache coherent area is CACHED!!!\n"); /* dma_handle is same as physical (shadowed) address */ *dma_handle = (dma_addr_t)ret; @@ -118,7 +117,7 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle) ret = (void *)va; /* This gives us the real physical address of the first page. */ - *dma_handle = pa = virt_to_bus((void *)vaddr); + *dma_handle = pa = __virt_to_phys(vaddr); #endif /* @@ -177,8 +176,7 @@ void consistent_free(size_t size, void *vaddr) page = virt_to_page(vaddr); do { - ClearPageReserved(page); - __free_page(page); + __free_reserved_page(page); page++; } while (size -= PAGE_SIZE); #else @@ -195,9 +193,7 @@ void consistent_free(size_t size, void *vaddr) pte_clear(&init_mm, (unsigned int)vaddr, ptep); if (pfn_valid(pfn)) { page = pfn_to_page(pfn); - - ClearPageReserved(page); - __free_page(page); + __free_reserved_page(page); } } vaddr += PAGE_SIZE; diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c index eb365d6795f..fa4cf52aa7a 100644 --- a/arch/microblaze/mm/fault.c +++ b/arch/microblaze/mm/fault.c @@ -32,7 +32,7 @@ #include <asm/page.h> #include <asm/pgtable.h> #include <asm/mmu.h> -#include <asm/mmu_context.h> +#include <linux/mmu_context.h> #include <linux/uaccess.h> #include <asm/exceptions.h> @@ -92,15 +92,14 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, int code = SEGV_MAPERR; int is_write = error_code & ESR_S; int fault; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | - (is_write ? FAULT_FLAG_WRITE : 0); + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; regs->ear = address; regs->esr = error_code; /* On a kernel SLB miss we can only check for a valid exception entry */ if (unlikely(kernel_mode(regs) && (address >= TASK_SIZE))) { - printk(KERN_WARNING "kernel task_size exceed"); + pr_warn("kernel task_size exceed"); _exception(SIGSEGV, regs, code, address); } @@ -114,13 +113,16 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, /* in_atomic() in user mode is really bad, as is current->mm == NULL. */ - printk(KERN_EMERG "Page fault in user mode with " - "in_atomic(), mm = %p\n", mm); - printk(KERN_EMERG "r15 = %lx MSR = %lx\n", + pr_emerg("Page fault in user mode with in_atomic(), mm = %p\n", + mm); + pr_emerg("r15 = %lx MSR = %lx\n", regs->r15, regs->msr); die("Weird page fault", regs, SIGSEGV); } + if (user_mode(regs)) + flags |= FAULT_FLAG_USER; + /* When running in the kernel we expect faults to occur only to * addresses in user space. All other faults represent errors in the * kernel and should generate an OOPS. Unfortunately, in the case of an @@ -199,6 +201,7 @@ good_area: if (unlikely(is_write)) { if (unlikely(!(vma->vm_flags & VM_WRITE))) goto bad_area; + flags |= FAULT_FLAG_WRITE; /* a read */ } else { /* protection fault */ @@ -233,6 +236,7 @@ good_area: current->min_flt++; if (fault & VM_FAULT_RETRY) { flags &= ~FAULT_FLAG_ALLOW_RETRY; + flags |= FAULT_FLAG_TRIED; /* * No need to up_read(&mm->mmap_sem) as we would diff --git a/arch/microblaze/mm/highmem.c b/arch/microblaze/mm/highmem.c index 7d78838e8bf..5a92576fad9 100644 --- a/arch/microblaze/mm/highmem.c +++ b/arch/microblaze/mm/highmem.c @@ -20,8 +20,8 @@ * highmem.h by Benjamin Herrenschmidt (c) 2009 IBM Corp. */ +#include <linux/export.h> #include <linux/highmem.h> -#include <linux/module.h> /* * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c index ce80823051b..77bc7c7e652 100644 --- a/arch/microblaze/mm/init.c +++ b/arch/microblaze/mm/init.c @@ -71,28 +71,17 @@ static void __init highmem_init(void) kmap_prot = PAGE_KERNEL; } -static unsigned long highmem_setup(void) +static void highmem_setup(void) { unsigned long pfn; - unsigned long reservedpages = 0; for (pfn = max_low_pfn; pfn < max_pfn; ++pfn) { struct page *page = pfn_to_page(pfn); /* FIXME not sure about */ - if (memblock_is_reserved(pfn << PAGE_SHIFT)) - continue; - ClearPageReserved(page); - init_page_count(page); - __free_page(page); - totalhigh_pages++; - reservedpages++; + if (!memblock_is_reserved(pfn << PAGE_SHIFT)) + free_highmem_page(page); } - totalram_pages += totalhigh_pages; - printk(KERN_INFO "High memory: %luk\n", - totalhigh_pages << (PAGE_SHIFT-10)); - - return reservedpages; } #endif /* CONFIG_HIGHMEM */ @@ -142,8 +131,8 @@ void __init setup_memory(void) ((u32)_text <= (memory_start + lowmem_size - 1))) { memory_size = lowmem_size; PAGE_OFFSET = memory_start; - printk(KERN_INFO "%s: Main mem: 0x%x, " - "size 0x%08x\n", __func__, (u32) memory_start, + pr_info("%s: Main mem: 0x%x, size 0x%08x\n", + __func__, (u32) memory_start, (u32) memory_size); break; } @@ -158,7 +147,7 @@ void __init setup_memory(void) kernel_align_start = PAGE_DOWN((u32)_text); /* ALIGN can be remove because _end in vmlinux.lds.S is align */ kernel_align_size = PAGE_UP((u32)klimit) - kernel_align_start; - printk(KERN_INFO "%s: kernel addr:0x%08x-0x%08x size=0x%08x\n", + pr_info("%s: kernel addr:0x%08x-0x%08x size=0x%08x\n", __func__, kernel_align_start, kernel_align_start + kernel_align_size, kernel_align_size); memblock_reserve(kernel_align_start, kernel_align_size); @@ -171,20 +160,19 @@ void __init setup_memory(void) * min_low_pfn - the first page (mm/bootmem.c - node_boot_start) * max_low_pfn * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn) - * num_physpages - number of all pages */ /* memory start is from the kernel end (aligned) to higher addr */ min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */ /* RAM is assumed contiguous */ - num_physpages = max_mapnr = memory_size >> PAGE_SHIFT; + max_mapnr = memory_size >> PAGE_SHIFT; max_low_pfn = ((u64)memory_start + (u64)lowmem_size) >> PAGE_SHIFT; max_pfn = ((u64)memory_start + (u64)memory_size) >> PAGE_SHIFT; - printk(KERN_INFO "%s: max_mapnr: %#lx\n", __func__, max_mapnr); - printk(KERN_INFO "%s: min_low_pfn: %#lx\n", __func__, min_low_pfn); - printk(KERN_INFO "%s: max_low_pfn: %#lx\n", __func__, max_low_pfn); - printk(KERN_INFO "%s: max_pfn: %#lx\n", __func__, max_pfn); + pr_info("%s: max_mapnr: %#lx\n", __func__, max_mapnr); + pr_info("%s: min_low_pfn: %#lx\n", __func__, min_low_pfn); + pr_info("%s: max_low_pfn: %#lx\n", __func__, max_low_pfn); + pr_info("%s: max_pfn: %#lx\n", __func__, max_pfn); /* * Find an area to use for the bootmem bitmap. @@ -204,7 +192,8 @@ void __init setup_memory(void) start_pfn = memblock_region_memory_base_pfn(reg); end_pfn = memblock_region_memory_end_pfn(reg); memblock_set_node(start_pfn << PAGE_SHIFT, - (end_pfn - start_pfn) << PAGE_SHIFT, 0); + (end_pfn - start_pfn) << PAGE_SHIFT, + &memblock.memory, 0); } /* free bootmem is whole main memory */ @@ -236,84 +225,29 @@ void __init setup_memory(void) paging_init(); } -void free_init_pages(char *what, unsigned long begin, unsigned long end) -{ - unsigned long addr; - - for (addr = begin; addr < end; addr += PAGE_SIZE) { - ClearPageReserved(virt_to_page(addr)); - init_page_count(virt_to_page(addr)); - free_page(addr); - totalram_pages++; - } - printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); -} - #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - int pages = 0; - for (; start < end; start += PAGE_SIZE) { - ClearPageReserved(virt_to_page(start)); - init_page_count(virt_to_page(start)); - free_page(start); - totalram_pages++; - pages++; - } - printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", - (int)(pages * (PAGE_SIZE / 1024))); + free_reserved_area((void *)start, (void *)end, -1, "initrd"); } #endif void free_initmem(void) { - free_init_pages("unused kernel memory", - (unsigned long)(&__init_begin), - (unsigned long)(&__init_end)); + free_initmem_default(-1); } void __init mem_init(void) { - pg_data_t *pgdat; - unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; - high_memory = (void *)__va(memory_start + lowmem_size - 1); /* this will put all memory onto the freelists */ - totalram_pages += free_all_bootmem(); - - for_each_online_pgdat(pgdat) { - unsigned long i; - struct page *page; - - for (i = 0; i < pgdat->node_spanned_pages; i++) { - if (!pfn_valid(pgdat->node_start_pfn + i)) - continue; - page = pgdat_page_nr(pgdat, i); - if (PageReserved(page)) - reservedpages++; - } - } - + free_all_bootmem(); #ifdef CONFIG_HIGHMEM - reservedpages -= highmem_setup(); + highmem_setup(); #endif - codesize = (unsigned long)&_sdata - (unsigned long)&_stext; - datasize = (unsigned long)&_edata - (unsigned long)&_sdata; - initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin; - bsssize = (unsigned long)&__bss_stop - (unsigned long)&__bss_start; - - pr_info("Memory: %luk/%luk available (%luk kernel code, " - "%luk reserved, %luk data, %luk bss, %luk init)\n", - nr_free_pages() << (PAGE_SHIFT-10), - num_physpages << (PAGE_SHIFT-10), - codesize >> 10, - reservedpages << (PAGE_SHIFT-10), - datasize >> 10, - bsssize >> 10, - initsize >> 10); - + mem_init_print_info(NULL); #ifdef CONFIG_MMU pr_info("Kernel virtual memory layout:\n"); pr_info(" * 0x%08lx..0x%08lx : fixmap\n", FIXADDR_START, FIXADDR_TOP); @@ -394,17 +328,17 @@ asmlinkage void __init mmu_init(void) unsigned int kstart, ksize; if (!memblock.reserved.cnt) { - printk(KERN_EMERG "Error memory count\n"); + pr_emerg("Error memory count\n"); machine_restart(NULL); } if ((u32) memblock.memory.regions[0].size < 0x400000) { - printk(KERN_EMERG "Memory must be greater than 4MB\n"); + pr_emerg("Memory must be greater than 4MB\n"); machine_restart(NULL); } if ((u32) memblock.memory.regions[0].size < kernel_tlb) { - printk(KERN_EMERG "Kernel size is greater than memory node\n"); + pr_emerg("Kernel size is greater than memory node\n"); machine_restart(NULL); } @@ -432,10 +366,11 @@ asmlinkage void __init mmu_init(void) #if defined(CONFIG_BLK_DEV_INITRD) /* Remove the init RAM disk from the available memory. */ -/* if (initrd_start) { - mem_pieces_remove(&phys_avail, __pa(initrd_start), - initrd_end - initrd_start, 1); - }*/ + if (initrd_start) { + unsigned long size; + size = initrd_end - initrd_start; + memblock_reserve(__virt_to_phys(initrd_start), size); + } #endif /* CONFIG_BLK_DEV_INITRD */ /* Initialize the MMU hardware */ diff --git a/arch/microblaze/mm/pgtable.c b/arch/microblaze/mm/pgtable.c index d1c06d07fed..4f4520e779a 100644 --- a/arch/microblaze/mm/pgtable.c +++ b/arch/microblaze/mm/pgtable.c @@ -26,8 +26,8 @@ * */ +#include <linux/export.h> #include <linux/kernel.h> -#include <linux/module.h> #include <linux/types.h> #include <linux/vmalloc.h> #include <linux/init.h> @@ -39,8 +39,6 @@ #include <asm/sections.h> #include <asm/fixmap.h> -#define flush_HPTE(X, va, pg) _tlbie(va) - unsigned long ioremap_base; unsigned long ioremap_bot; EXPORT_SYMBOL(ioremap_bot); @@ -71,13 +69,13 @@ static void __iomem *__ioremap(phys_addr_t addr, unsigned long size, * * However, allow remap of rootfs: TBD */ + if (mem_init_done && p >= memory_start && p < virt_to_phys(high_memory) && - !(p >= virt_to_phys((unsigned long)&__bss_stop) && - p < virt_to_phys((unsigned long)__bss_stop))) { - printk(KERN_WARNING "__ioremap(): phys addr "PTE_FMT - " is RAM lr %pf\n", (unsigned long)p, - __builtin_return_address(0)); + !(p >= __virt_to_phys((phys_addr_t)__bss_stop) && + p < __virt_to_phys((phys_addr_t)__bss_stop))) { + pr_warn("__ioremap(): phys addr "PTE_FMT" is RAM lr %pf\n", + (unsigned long)p, __builtin_return_address(0)); return NULL; } @@ -128,9 +126,10 @@ void __iomem *ioremap(phys_addr_t addr, unsigned long size) } EXPORT_SYMBOL(ioremap); -void iounmap(void *addr) +void iounmap(void __iomem *addr) { - if (addr > high_memory && (unsigned long) addr < ioremap_bot) + if ((__force void *)addr > high_memory && + (unsigned long) addr < ioremap_bot) vfree((void *) (PAGE_MASK & (unsigned long) addr)); } EXPORT_SYMBOL(iounmap); @@ -152,8 +151,7 @@ int map_page(unsigned long va, phys_addr_t pa, int flags) set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags))); if (unlikely(mem_init_done)) - flush_HPTE(0, va, pmd_val(*pd)); - /* flush_HPTE(0, va, pg); */ + _tlbie(va); } return err; } |
