aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-22 15:38:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-22 15:38:40 -0400
commit17238005f377888b9d4583835205c77e3d781bb8 (patch)
tree9cad40902138d08a2694f87736cfebd031dc9542 /arch/parisc
parent34ea646c9f8c18fd2e4332ff3b2b509f878c56f1 (diff)
parent7fe2ac6882f74e8bd5b3891f63c09cb10aee9d03 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6: [PARISC] wire up syncfs syscall [PARISC] wire up the fhandle syscalls [PARISC] wire up clock_adjtime syscall [PARISC] wire up fanotify syscalls [PARISC] prevent speculative re-read on cache flush [PARISC] only make executable areas executable [PARISC] fix pacache .size with new binutils
Diffstat (limited to 'arch/parisc')
-rw-r--r--arch/parisc/include/asm/cacheflush.h5
-rw-r--r--arch/parisc/include/asm/pgtable.h9
-rw-r--r--arch/parisc/include/asm/unistd.h10
-rw-r--r--arch/parisc/kernel/cache.c13
-rw-r--r--arch/parisc/kernel/entry.S3
-rw-r--r--arch/parisc/kernel/head.S5
-rw-r--r--arch/parisc/kernel/module.c10
-rw-r--r--arch/parisc/kernel/pacache.S6
-rw-r--r--arch/parisc/kernel/sys_parisc32.c8
-rw-r--r--arch/parisc/kernel/syscall_table.S6
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S1
-rw-r--r--arch/parisc/mm/init.c260
12 files changed, 206 insertions, 130 deletions
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index d18328b3f93..da601dd34c0 100644
--- a/arch/parisc/include/asm/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/mm.h> 4#include <linux/mm.h>
5#include <linux/uaccess.h> 5#include <linux/uaccess.h>
6#include <asm/tlbflush.h>
6 7
7/* The usual comment is "Caches aren't brain-dead on the <architecture>". 8/* The usual comment is "Caches aren't brain-dead on the <architecture>".
8 * Unfortunately, that doesn't apply to PA-RISC. */ 9 * Unfortunately, that doesn't apply to PA-RISC. */
@@ -112,8 +113,10 @@ void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
112static inline void 113static inline void
113flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) 114flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
114{ 115{
115 if (PageAnon(page)) 116 if (PageAnon(page)) {
117 flush_tlb_page(vma, vmaddr);
116 flush_dcache_page_asm(page_to_phys(page), vmaddr); 118 flush_dcache_page_asm(page_to_phys(page), vmaddr);
119 }
117} 120}
118 121
119#ifdef CONFIG_DEBUG_RODATA 122#ifdef CONFIG_DEBUG_RODATA
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index 5d7b8ce9fdf..22dadeb5869 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -177,7 +177,10 @@ struct vm_area_struct;
177 177
178#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED) 178#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED)
179#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) 179#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
180#define _PAGE_KERNEL (_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED) 180#define _PAGE_KERNEL_RO (_PAGE_PRESENT | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
181#define _PAGE_KERNEL_EXEC (_PAGE_KERNEL_RO | _PAGE_EXEC)
182#define _PAGE_KERNEL_RWX (_PAGE_KERNEL_EXEC | _PAGE_WRITE)
183#define _PAGE_KERNEL (_PAGE_KERNEL_RO | _PAGE_WRITE)
181 184
182/* The pgd/pmd contains a ptr (in phys addr space); since all pgds/pmds 185/* The pgd/pmd contains a ptr (in phys addr space); since all pgds/pmds
183 * are page-aligned, we don't care about the PAGE_OFFSET bits, except 186 * are page-aligned, we don't care about the PAGE_OFFSET bits, except
@@ -208,7 +211,9 @@ struct vm_area_struct;
208#define PAGE_COPY PAGE_EXECREAD 211#define PAGE_COPY PAGE_EXECREAD
209#define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) 212#define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
210#define PAGE_KERNEL __pgprot(_PAGE_KERNEL) 213#define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
211#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) 214#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC)
215#define PAGE_KERNEL_RWX __pgprot(_PAGE_KERNEL_RWX)
216#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL_RO)
212#define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) 217#define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
213#define PAGE_GATEWAY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ) 218#define PAGE_GATEWAY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ)
214 219
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index 3eb82c2a5ec..9cbc2c3bf63 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -814,8 +814,14 @@
814#define __NR_recvmmsg (__NR_Linux + 319) 814#define __NR_recvmmsg (__NR_Linux + 319)
815#define __NR_accept4 (__NR_Linux + 320) 815#define __NR_accept4 (__NR_Linux + 320)
816#define __NR_prlimit64 (__NR_Linux + 321) 816#define __NR_prlimit64 (__NR_Linux + 321)
817 817#define __NR_fanotify_init (__NR_Linux + 322)
818#define __NR_Linux_syscalls (__NR_prlimit64 + 1) 818#define __NR_fanotify_mark (__NR_Linux + 323)
819#define __NR_clock_adjtime (__NR_Linux + 324)
820#define __NR_name_to_handle_at (__NR_Linux + 325)
821#define __NR_open_by_handle_at (__NR_Linux + 326)
822#define __NR_syncfs (__NR_Linux + 327)
823
824#define __NR_Linux_syscalls (__NR_syncfs + 1)
819 825
820 826
821#define __IGNORE_select /* newselect */ 827#define __IGNORE_select /* newselect */
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 3f11331c277..83335f3da5f 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -304,10 +304,20 @@ void flush_dcache_page(struct page *page)
304 offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; 304 offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
305 addr = mpnt->vm_start + offset; 305 addr = mpnt->vm_start + offset;
306 306
307 /* The TLB is the engine of coherence on parisc: The
308 * CPU is entitled to speculate any page with a TLB
309 * mapping, so here we kill the mapping then flush the
310 * page along a special flush only alias mapping.
311 * This guarantees that the page is no-longer in the
312 * cache for any process and nor may it be
313 * speculatively read in (until the user or kernel
314 * specifically accesses it, of course) */
315
316 flush_tlb_page(mpnt, addr);
307 if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) { 317 if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
308 __flush_cache_page(mpnt, addr, page_to_phys(page)); 318 __flush_cache_page(mpnt, addr, page_to_phys(page));
309 if (old_addr) 319 if (old_addr)
310 printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? mpnt->vm_file->f_path.dentry->d_name.name : "(null)"); 320 printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? (char *)mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
311 old_addr = addr; 321 old_addr = addr;
312 } 322 }
313 } 323 }
@@ -499,6 +509,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
499{ 509{
500 BUG_ON(!vma->vm_mm->context); 510 BUG_ON(!vma->vm_mm->context);
501 511
512 flush_tlb_page(vma, vmaddr);
502 __flush_cache_page(vma, vmaddr, page_to_phys(pfn_to_page(pfn))); 513 __flush_cache_page(vma, vmaddr, page_to_phys(pfn_to_page(pfn)));
503 514
504} 515}
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index ead8d2a1034..6f059443914 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -692,6 +692,9 @@ ENTRY(fault_vector_11)
692END(fault_vector_11) 692END(fault_vector_11)
693 693
694#endif 694#endif
695 /* Fault vector is separately protected and *must* be on its own page */
696 .align PAGE_SIZE
697ENTRY(end_fault_vector)
695 698
696 .import handle_interruption,code 699 .import handle_interruption,code
697 .import do_cpu_irq_mask,code 700 .import do_cpu_irq_mask,code
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index 145c5e4caaa..37aabd772fb 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -106,8 +106,9 @@ $bss_loop:
106#endif 106#endif
107 107
108 108
109 /* Now initialize the PTEs themselves */ 109 /* Now initialize the PTEs themselves. We use RWX for
110 ldo 0+_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */ 110 * everything ... it will get remapped correctly later */
111 ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */
111 ldi (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */ 112 ldi (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */
112 load32 PA(pg0),%r1 113 load32 PA(pg0),%r1
113 114
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 6e81bb596e5..cedbbb8b18d 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -61,8 +61,10 @@
61#include <linux/string.h> 61#include <linux/string.h>
62#include <linux/kernel.h> 62#include <linux/kernel.h>
63#include <linux/bug.h> 63#include <linux/bug.h>
64#include <linux/mm.h>
64#include <linux/slab.h> 65#include <linux/slab.h>
65 66
67#include <asm/pgtable.h>
66#include <asm/unwind.h> 68#include <asm/unwind.h>
67 69
68#if 0 70#if 0
@@ -214,7 +216,13 @@ void *module_alloc(unsigned long size)
214{ 216{
215 if (size == 0) 217 if (size == 0)
216 return NULL; 218 return NULL;
217 return vmalloc(size); 219 /* using RWX means less protection for modules, but it's
220 * easier than trying to map the text, data, init_text and
221 * init_data correctly */
222 return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
223 GFP_KERNEL | __GFP_HIGHMEM,
224 PAGE_KERNEL_RWX, -1,
225 __builtin_return_address(0));
218} 226}
219 227
220#ifndef CONFIG_64BIT 228#ifndef CONFIG_64BIT
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index a85823668cb..93ff3d90edd 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -817,10 +817,7 @@ ENTRY(purge_kernel_dcache_page)
817 .procend 817 .procend
818ENDPROC(purge_kernel_dcache_page) 818ENDPROC(purge_kernel_dcache_page)
819 819
820 820ENTRY(flush_user_dcache_range_asm)
821 .export flush_user_dcache_range_asm
822
823flush_user_dcache_range_asm:
824 .proc 821 .proc
825 .callinfo NO_CALLS 822 .callinfo NO_CALLS
826 .entry 823 .entry
@@ -839,6 +836,7 @@ flush_user_dcache_range_asm:
839 .exit 836 .exit
840 837
841 .procend 838 .procend
839ENDPROC(flush_user_dcache_range_asm)
842 840
843ENTRY(flush_kernel_dcache_range_asm) 841ENTRY(flush_kernel_dcache_range_asm)
844 .proc 842 .proc
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index 88a0ad14a9c..dc9a6246232 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -228,3 +228,11 @@ asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo,
228 return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, 228 return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo,
229 ((loff_t)lenhi << 32) | lenlo); 229 ((loff_t)lenhi << 32) | lenlo);
230} 230}
231
232asmlinkage long compat_sys_fanotify_mark(int fan_fd, int flags, u32 mask_hi,
233 u32 mask_lo, int fd,
234 const char __user *pathname)
235{
236 return sys_fanotify_mark(fan_fd, flags, ((u64)mask_hi << 32) | mask_lo,
237 fd, pathname);
238}
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 4be85ee10b8..a5b02ce4d41 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -420,6 +420,12 @@
420 ENTRY_COMP(recvmmsg) 420 ENTRY_COMP(recvmmsg)
421 ENTRY_SAME(accept4) /* 320 */ 421 ENTRY_SAME(accept4) /* 320 */
422 ENTRY_SAME(prlimit64) 422 ENTRY_SAME(prlimit64)
423 ENTRY_SAME(fanotify_init)
424 ENTRY_COMP(fanotify_mark)
425 ENTRY_COMP(clock_adjtime)
426 ENTRY_SAME(name_to_handle_at) /* 325 */
427 ENTRY_COMP(open_by_handle_at)
428 ENTRY_SAME(syncfs)
423 429
424 /* Nothing yet */ 430 /* Nothing yet */
425 431
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 2d9a5c7c76f..e1a55849bfa 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -137,6 +137,7 @@ SECTIONS
137 . = ALIGN(16384); 137 . = ALIGN(16384);
138 __init_begin = .; 138 __init_begin = .;
139 INIT_TEXT_SECTION(16384) 139 INIT_TEXT_SECTION(16384)
140 . = ALIGN(PAGE_SIZE);
140 INIT_DATA_SECTION(16) 141 INIT_DATA_SECTION(16)
141 /* we have to discard exit text and such at runtime, not link time */ 142 /* we have to discard exit text and such at runtime, not link time */
142 .exit.text : 143 .exit.text :
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index b1d126258de..5fa1e273006 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -371,24 +371,158 @@ static void __init setup_bootmem(void)
371 request_resource(&sysram_resources[0], &pdcdata_resource); 371 request_resource(&sysram_resources[0], &pdcdata_resource);
372} 372}
373 373
374static void __init map_pages(unsigned long start_vaddr,
375 unsigned long start_paddr, unsigned long size,
376 pgprot_t pgprot, int force)
377{
378 pgd_t *pg_dir;
379 pmd_t *pmd;
380 pte_t *pg_table;
381 unsigned long end_paddr;
382 unsigned long start_pmd;
383 unsigned long start_pte;
384 unsigned long tmp1;
385 unsigned long tmp2;
386 unsigned long address;
387 unsigned long vaddr;
388 unsigned long ro_start;
389 unsigned long ro_end;
390 unsigned long fv_addr;
391 unsigned long gw_addr;
392 extern const unsigned long fault_vector_20;
393 extern void * const linux_gateway_page;
394
395 ro_start = __pa((unsigned long)_text);
396 ro_end = __pa((unsigned long)&data_start);
397 fv_addr = __pa((unsigned long)&fault_vector_20) & PAGE_MASK;
398 gw_addr = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK;
399
400 end_paddr = start_paddr + size;
401
402 pg_dir = pgd_offset_k(start_vaddr);
403
404#if PTRS_PER_PMD == 1
405 start_pmd = 0;
406#else
407 start_pmd = ((start_vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
408#endif
409 start_pte = ((start_vaddr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
410
411 address = start_paddr;
412 vaddr = start_vaddr;
413 while (address < end_paddr) {
414#if PTRS_PER_PMD == 1
415 pmd = (pmd_t *)__pa(pg_dir);
416#else
417 pmd = (pmd_t *)pgd_address(*pg_dir);
418
419 /*
420 * pmd is physical at this point
421 */
422
423 if (!pmd) {
424 pmd = (pmd_t *) alloc_bootmem_low_pages_node(NODE_DATA(0), PAGE_SIZE << PMD_ORDER);
425 pmd = (pmd_t *) __pa(pmd);
426 }
427
428 pgd_populate(NULL, pg_dir, __va(pmd));
429#endif
430 pg_dir++;
431
432 /* now change pmd to kernel virtual addresses */
433
434 pmd = (pmd_t *)__va(pmd) + start_pmd;
435 for (tmp1 = start_pmd; tmp1 < PTRS_PER_PMD; tmp1++, pmd++) {
436
437 /*
438 * pg_table is physical at this point
439 */
440
441 pg_table = (pte_t *)pmd_address(*pmd);
442 if (!pg_table) {
443 pg_table = (pte_t *)
444 alloc_bootmem_low_pages_node(NODE_DATA(0), PAGE_SIZE);
445 pg_table = (pte_t *) __pa(pg_table);
446 }
447
448 pmd_populate_kernel(NULL, pmd, __va(pg_table));
449
450 /* now change pg_table to kernel virtual addresses */
451
452 pg_table = (pte_t *) __va(pg_table) + start_pte;
453 for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++, pg_table++) {
454 pte_t pte;
455
456 /*
457 * Map the fault vector writable so we can
458 * write the HPMC checksum.
459 */
460 if (force)
461 pte = __mk_pte(address, pgprot);
462 else if (core_kernel_text(vaddr) &&
463 address != fv_addr)
464 pte = __mk_pte(address, PAGE_KERNEL_EXEC);
465 else
466#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
467 if (address >= ro_start && address < ro_end
468 && address != fv_addr
469 && address != gw_addr)
470 pte = __mk_pte(address, PAGE_KERNEL_RO);
471 else
472#endif
473 pte = __mk_pte(address, pgprot);
474
475 if (address >= end_paddr) {
476 if (force)
477 break;
478 else
479 pte_val(pte) = 0;
480 }
481
482 set_pte(pg_table, pte);
483
484 address += PAGE_SIZE;
485 vaddr += PAGE_SIZE;
486 }
487 start_pte = 0;
488
489 if (address >= end_paddr)
490 break;
491 }
492 start_pmd = 0;
493 }
494}
495
374void free_initmem(void) 496void free_initmem(void)
375{ 497{
376 unsigned long addr; 498 unsigned long addr;
377 unsigned long init_begin = (unsigned long)__init_begin; 499 unsigned long init_begin = (unsigned long)__init_begin;
378 unsigned long init_end = (unsigned long)__init_end; 500 unsigned long init_end = (unsigned long)__init_end;
379 501
380#ifdef CONFIG_DEBUG_KERNEL 502 /* The init text pages are marked R-X. We have to
503 * flush the icache and mark them RW-
504 *
505 * This is tricky, because map_pages is in the init section.
506 * Do a dummy remap of the data section first (the data
507 * section is already PAGE_KERNEL) to pull in the TLB entries
508 * for map_kernel */
509 map_pages(init_begin, __pa(init_begin), init_end - init_begin,
510 PAGE_KERNEL_RWX, 1);
511 /* now remap at PAGE_KERNEL since the TLB is pre-primed to execute
512 * map_pages */
513 map_pages(init_begin, __pa(init_begin), init_end - init_begin,
514 PAGE_KERNEL, 1);
515
516 /* force the kernel to see the new TLB entries */
517 __flush_tlb_range(0, init_begin, init_end);
381 /* Attempt to catch anyone trying to execute code here 518 /* Attempt to catch anyone trying to execute code here
382 * by filling the page with BRK insns. 519 * by filling the page with BRK insns.
383 */ 520 */
384 memset((void *)init_begin, 0x00, init_end - init_begin); 521 memset((void *)init_begin, 0x00, init_end - init_begin);
522 /* finally dump all the instructions which were cached, since the
523 * pages are no-longer executable */
385 flush_icache_range(init_begin, init_end); 524 flush_icache_range(init_begin, init_end);
386#endif
387 525
388 /* align __init_begin and __init_end to page size,
389 ignoring linker script where we might have tried to save RAM */
390 init_begin = PAGE_ALIGN(init_begin);
391 init_end = PAGE_ALIGN(init_end);
392 for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) { 526 for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) {
393 ClearPageReserved(virt_to_page(addr)); 527 ClearPageReserved(virt_to_page(addr));
394 init_page_count(virt_to_page(addr)); 528 init_page_count(virt_to_page(addr));
@@ -618,114 +752,6 @@ void show_mem(unsigned int filter)
618#endif 752#endif
619} 753}
620 754
621
622static void __init map_pages(unsigned long start_vaddr, unsigned long start_paddr, unsigned long size, pgprot_t pgprot)
623{
624 pgd_t *pg_dir;
625 pmd_t *pmd;
626 pte_t *pg_table;
627 unsigned long end_paddr;
628 unsigned long start_pmd;
629 unsigned long start_pte;
630 unsigned long tmp1;
631 unsigned long tmp2;
632 unsigned long address;
633 unsigned long ro_start;
634 unsigned long ro_end;
635 unsigned long fv_addr;
636 unsigned long gw_addr;
637 extern const unsigned long fault_vector_20;
638 extern void * const linux_gateway_page;
639
640 ro_start = __pa((unsigned long)_text);
641 ro_end = __pa((unsigned long)&data_start);
642 fv_addr = __pa((unsigned long)&fault_vector_20) & PAGE_MASK;
643 gw_addr = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK;
644
645 end_paddr = start_paddr + size;
646
647 pg_dir = pgd_offset_k(start_vaddr);
648
649#if PTRS_PER_PMD == 1
650 start_pmd = 0;
651#else
652 start_pmd = ((start_vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
653#endif
654 start_pte = ((start_vaddr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
655
656 address = start_paddr;
657 while (address < end_paddr) {
658#if PTRS_PER_PMD == 1
659 pmd = (pmd_t *)__pa(pg_dir);
660#else
661 pmd = (pmd_t *)pgd_address(*pg_dir);
662
663 /*
664 * pmd is physical at this point
665 */
666
667 if (!pmd) {
668 pmd = (pmd_t *) alloc_bootmem_low_pages_node(NODE_DATA(0),PAGE_SIZE << PMD_ORDER);
669 pmd = (pmd_t *) __pa(pmd);
670 }
671
672 pgd_populate(NULL, pg_dir, __va(pmd));
673#endif
674 pg_dir++;
675
676 /* now change pmd to kernel virtual addresses */
677
678 pmd = (pmd_t *)__va(pmd) + start_pmd;
679 for (tmp1 = start_pmd; tmp1 < PTRS_PER_PMD; tmp1++,pmd++) {
680
681 /*
682 * pg_table is physical at this point
683 */
684
685 pg_table = (pte_t *)pmd_address(*pmd);
686 if (!pg_table) {
687 pg_table = (pte_t *)
688 alloc_bootmem_low_pages_node(NODE_DATA(0),PAGE_SIZE);
689 pg_table = (pte_t *) __pa(pg_table);
690 }
691
692 pmd_populate_kernel(NULL, pmd, __va(pg_table));
693
694 /* now change pg_table to kernel virtual addresses */
695
696 pg_table = (pte_t *) __va(pg_table) + start_pte;
697 for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++,pg_table++) {
698 pte_t pte;
699
700 /*
701 * Map the fault vector writable so we can
702 * write the HPMC checksum.
703 */
704#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
705 if (address >= ro_start && address < ro_end
706 && address != fv_addr
707 && address != gw_addr)
708 pte = __mk_pte(address, PAGE_KERNEL_RO);
709 else
710#endif
711 pte = __mk_pte(address, pgprot);
712
713 if (address >= end_paddr)
714 pte_val(pte) = 0;
715
716 set_pte(pg_table, pte);
717
718 address += PAGE_SIZE;
719 }
720 start_pte = 0;
721
722 if (address >= end_paddr)
723 break;
724 }
725 start_pmd = 0;
726 }
727}
728
729/* 755/*
730 * pagetable_init() sets up the page tables 756 * pagetable_init() sets up the page tables
731 * 757 *
@@ -750,14 +776,14 @@ static void __init pagetable_init(void)
750 size = pmem_ranges[range].pages << PAGE_SHIFT; 776 size = pmem_ranges[range].pages << PAGE_SHIFT;
751 777
752 map_pages((unsigned long)__va(start_paddr), start_paddr, 778 map_pages((unsigned long)__va(start_paddr), start_paddr,
753 size, PAGE_KERNEL); 779 size, PAGE_KERNEL, 0);
754 } 780 }
755 781
756#ifdef CONFIG_BLK_DEV_INITRD 782#ifdef CONFIG_BLK_DEV_INITRD
757 if (initrd_end && initrd_end > mem_limit) { 783 if (initrd_end && initrd_end > mem_limit) {
758 printk(KERN_INFO "initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end); 784 printk(KERN_INFO "initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end);
759 map_pages(initrd_start, __pa(initrd_start), 785 map_pages(initrd_start, __pa(initrd_start),
760 initrd_end - initrd_start, PAGE_KERNEL); 786 initrd_end - initrd_start, PAGE_KERNEL, 0);
761 } 787 }
762#endif 788#endif
763 789
@@ -782,7 +808,7 @@ static void __init gateway_init(void)
782 */ 808 */
783 809
784 map_pages(linux_gateway_page_addr, __pa(&linux_gateway_page), 810 map_pages(linux_gateway_page_addr, __pa(&linux_gateway_page),
785 PAGE_SIZE, PAGE_GATEWAY); 811 PAGE_SIZE, PAGE_GATEWAY, 1);
786} 812}
787 813
788#ifdef CONFIG_HPUX 814#ifdef CONFIG_HPUX