aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/parisc/include/asm/cache.h3
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S3
-rw-r--r--arch/parisc/mm/init.c67
3 files changed, 35 insertions, 38 deletions
diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
index 4016fe1c65a9..73ca89a47f49 100644
--- a/arch/parisc/include/asm/cache.h
+++ b/arch/parisc/include/asm/cache.h
@@ -24,9 +24,6 @@
24 24
25#define __read_mostly __attribute__((__section__(".data..read_mostly"))) 25#define __read_mostly __attribute__((__section__(".data..read_mostly")))
26 26
27/* Read-only memory is marked before mark_rodata_ro() is called. */
28#define __ro_after_init __read_mostly
29
30void parisc_cache_init(void); /* initializes cache-flushing */ 27void parisc_cache_init(void); /* initializes cache-flushing */
31void disable_sr_hashing_asm(int); /* low level support for above */ 28void disable_sr_hashing_asm(int); /* low level support for above */
32void disable_sr_hashing(void); /* turns off space register hashing */ 29void disable_sr_hashing(void); /* turns off space register hashing */
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index a8be7a47fcc0..c3b1b9c24ede 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -18,9 +18,6 @@
18 *(.data..vm0.pgd) \ 18 *(.data..vm0.pgd) \
19 *(.data..vm0.pte) 19 *(.data..vm0.pte)
20 20
21/* No __ro_after_init data in the .rodata section - which will always be ro */
22#define RO_AFTER_INIT_DATA
23
24#include <asm-generic/vmlinux.lds.h> 21#include <asm-generic/vmlinux.lds.h>
25 22
26/* needed for the processor specific cache alignment size */ 23/* needed for the processor specific cache alignment size */
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 3b0f9eab7f2c..b99bcbf1ecdb 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -345,16 +345,7 @@ static void __init setup_bootmem(void)
345 memblock_dump_all(); 345 memblock_dump_all();
346} 346}
347 347
348static int __init parisc_text_address(unsigned long vaddr) 348static bool kernel_set_to_readonly;
349{
350 static unsigned long head_ptr __initdata;
351
352 if (!head_ptr)
353 head_ptr = PAGE_MASK & (unsigned long)
354 dereference_function_descriptor(&parisc_kernel_start);
355
356 return core_kernel_text(vaddr) || vaddr == head_ptr;
357}
358 349
359static void __init map_pages(unsigned long start_vaddr, 350static void __init map_pages(unsigned long start_vaddr,
360 unsigned long start_paddr, unsigned long size, 351 unsigned long start_paddr, unsigned long size,
@@ -372,10 +363,11 @@ static void __init map_pages(unsigned long start_vaddr,
372 unsigned long vaddr; 363 unsigned long vaddr;
373 unsigned long ro_start; 364 unsigned long ro_start;
374 unsigned long ro_end; 365 unsigned long ro_end;
375 unsigned long kernel_end; 366 unsigned long kernel_start, kernel_end;
376 367
377 ro_start = __pa((unsigned long)_text); 368 ro_start = __pa((unsigned long)_text);
378 ro_end = __pa((unsigned long)&data_start); 369 ro_end = __pa((unsigned long)&data_start);
370 kernel_start = __pa((unsigned long)&__init_begin);
379 kernel_end = __pa((unsigned long)&_end); 371 kernel_end = __pa((unsigned long)&_end);
380 372
381 end_paddr = start_paddr + size; 373 end_paddr = start_paddr + size;
@@ -438,26 +430,30 @@ static void __init map_pages(unsigned long start_vaddr,
438 pg_table = (pte_t *) __va(pg_table) + start_pte; 430 pg_table = (pte_t *) __va(pg_table) + start_pte;
439 for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++, pg_table++) { 431 for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++, pg_table++) {
440 pte_t pte; 432 pte_t pte;
441 433 pgprot_t prot;
442 if (force) 434 bool huge = false;
443 pte = __mk_pte(address, pgprot); 435
444 else if (parisc_text_address(vaddr)) { 436 if (force) {
445 pte = __mk_pte(address, PAGE_KERNEL_EXEC); 437 prot = pgprot;
446 if (address >= ro_start && address < kernel_end) 438 } else if (address < kernel_start || address >= kernel_end) {
447 pte = pte_mkhuge(pte); 439 /* outside kernel memory */
440 prot = PAGE_KERNEL;
441 } else if (!kernel_set_to_readonly) {
442 /* still initializing, allow writing to RO memory */
443 prot = PAGE_KERNEL_RWX;
444 huge = true;
445 } else if (address >= ro_start) {
446 /* Code (ro) and Data areas */
447 prot = (address < ro_end) ?
448 PAGE_KERNEL_EXEC : PAGE_KERNEL;
449 huge = true;
450 } else {
451 prot = PAGE_KERNEL;
448 } 452 }
449 else 453
450#if defined(CONFIG_PARISC_PAGE_SIZE_4KB) 454 pte = __mk_pte(address, prot);
451 if (address >= ro_start && address < ro_end) { 455 if (huge)
452 pte = __mk_pte(address, PAGE_KERNEL_EXEC);
453 pte = pte_mkhuge(pte); 456 pte = pte_mkhuge(pte);
454 } else
455#endif
456 {
457 pte = __mk_pte(address, pgprot);
458 if (address >= ro_start && address < kernel_end)
459 pte = pte_mkhuge(pte);
460 }
461 457
462 if (address >= end_paddr) 458 if (address >= end_paddr)
463 break; 459 break;
@@ -493,6 +489,12 @@ void __ref free_initmem(void)
493{ 489{
494 unsigned long init_begin = (unsigned long)__init_begin; 490 unsigned long init_begin = (unsigned long)__init_begin;
495 unsigned long init_end = (unsigned long)__init_end; 491 unsigned long init_end = (unsigned long)__init_end;
492 unsigned long kernel_end = (unsigned long)&_end;
493
494 /* Remap kernel text and data, but do not touch init section yet. */
495 kernel_set_to_readonly = true;
496 map_pages(init_end, __pa(init_end), kernel_end - init_end,
497 PAGE_KERNEL, 0);
496 498
497 /* The init text pages are marked R-X. We have to 499 /* The init text pages are marked R-X. We have to
498 * flush the icache and mark them RW- 500 * flush the icache and mark them RW-
@@ -509,7 +511,7 @@ void __ref free_initmem(void)
509 PAGE_KERNEL, 1); 511 PAGE_KERNEL, 1);
510 512
511 /* force the kernel to see the new TLB entries */ 513 /* force the kernel to see the new TLB entries */
512 __flush_tlb_range(0, init_begin, init_end); 514 __flush_tlb_range(0, init_begin, kernel_end);
513 515
514 /* finally dump all the instructions which were cached, since the 516 /* finally dump all the instructions which were cached, since the
515 * pages are no-longer executable */ 517 * pages are no-longer executable */
@@ -527,8 +529,9 @@ void mark_rodata_ro(void)
527{ 529{
528 /* rodata memory was already mapped with KERNEL_RO access rights by 530 /* rodata memory was already mapped with KERNEL_RO access rights by
529 pagetable_init() and map_pages(). No need to do additional stuff here */ 531 pagetable_init() and map_pages(). No need to do additional stuff here */
530 printk (KERN_INFO "Write protecting the kernel read-only data: %luk\n", 532 unsigned long roai_size = __end_ro_after_init - __start_ro_after_init;
531 (unsigned long)(__end_rodata - __start_rodata) >> 10); 533
534 pr_info("Write protected read-only-after-init data: %luk\n", roai_size >> 10);
532} 535}
533#endif 536#endif
534 537