diff options
| -rw-r--r-- | arch/s390/kernel/entry.S | 9 | ||||
| -rw-r--r-- | arch/s390/kernel/entry64.S | 1 | ||||
| -rw-r--r-- | arch/s390/mm/init.c | 35 |
3 files changed, 28 insertions, 17 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 1a434a7004ee..d8948c342caf 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
| @@ -228,8 +228,9 @@ sysc_do_svc: | |||
| 228 | sysc_nr_ok: | 228 | sysc_nr_ok: |
| 229 | mvc SP_ARGS(4,%r15),SP_R7(%r15) | 229 | mvc SP_ARGS(4,%r15),SP_R7(%r15) |
| 230 | sysc_do_restart: | 230 | sysc_do_restart: |
| 231 | l %r8,BASED(.Lsysc_table) | ||
| 231 | tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) | 232 | tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) |
| 232 | l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr. | 233 | l %r8,0(%r7,%r8) # get system call addr. |
| 233 | bnz BASED(sysc_tracesys) | 234 | bnz BASED(sysc_tracesys) |
| 234 | basr %r14,%r8 # call sys_xxxx | 235 | basr %r14,%r8 # call sys_xxxx |
| 235 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) | 236 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) |
| @@ -330,9 +331,10 @@ sysc_tracesys: | |||
| 330 | basr %r14,%r1 | 331 | basr %r14,%r1 |
| 331 | clc SP_R2(4,%r15),BASED(.Lnr_syscalls) | 332 | clc SP_R2(4,%r15),BASED(.Lnr_syscalls) |
| 332 | bnl BASED(sysc_tracenogo) | 333 | bnl BASED(sysc_tracenogo) |
| 334 | l %r8,BASED(.Lsysc_table) | ||
| 333 | l %r7,SP_R2(%r15) # strace might have changed the | 335 | l %r7,SP_R2(%r15) # strace might have changed the |
| 334 | sll %r7,2 # system call | 336 | sll %r7,2 # system call |
| 335 | l %r8,sys_call_table-system_call(%r7,%r13) | 337 | l %r8,0(%r7,%r8) |
| 336 | sysc_tracego: | 338 | sysc_tracego: |
| 337 | lm %r3,%r6,SP_R3(%r15) | 339 | lm %r3,%r6,SP_R3(%r15) |
| 338 | l %r2,SP_ORIG_R2(%r15) | 340 | l %r2,SP_ORIG_R2(%r15) |
| @@ -1009,6 +1011,7 @@ cleanup_io_leave_insn: | |||
| 1009 | .Ltrace: .long syscall_trace | 1011 | .Ltrace: .long syscall_trace |
| 1010 | .Lvfork: .long sys_vfork | 1012 | .Lvfork: .long sys_vfork |
| 1011 | .Lschedtail: .long schedule_tail | 1013 | .Lschedtail: .long schedule_tail |
| 1014 | .Lsysc_table: .long sys_call_table | ||
| 1012 | 1015 | ||
| 1013 | .Lcritical_start: | 1016 | .Lcritical_start: |
| 1014 | .long __critical_start + 0x80000000 | 1017 | .long __critical_start + 0x80000000 |
| @@ -1017,8 +1020,8 @@ cleanup_io_leave_insn: | |||
| 1017 | .Lcleanup_critical: | 1020 | .Lcleanup_critical: |
| 1018 | .long cleanup_critical | 1021 | .long cleanup_critical |
| 1019 | 1022 | ||
| 1023 | .section .rodata, "a" | ||
| 1020 | #define SYSCALL(esa,esame,emu) .long esa | 1024 | #define SYSCALL(esa,esame,emu) .long esa |
| 1021 | sys_call_table: | 1025 | sys_call_table: |
| 1022 | #include "syscalls.S" | 1026 | #include "syscalls.S" |
| 1023 | #undef SYSCALL | 1027 | #undef SYSCALL |
| 1024 | |||
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index edad60771673..1ca499fa54b4 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
| @@ -991,6 +991,7 @@ cleanup_io_leave_insn: | |||
| 991 | .Lcritical_end: | 991 | .Lcritical_end: |
| 992 | .quad __critical_end | 992 | .quad __critical_end |
| 993 | 993 | ||
| 994 | .section .rodata, "a" | ||
| 994 | #define SYSCALL(esa,esame,emu) .long esame | 995 | #define SYSCALL(esa,esame,emu) .long esame |
| 995 | sys_call_table: | 996 | sys_call_table: |
| 996 | #include "syscalls.S" | 997 | #include "syscalls.S" |
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 81dce185f836..eb6ebfef134a 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 24 | #include <linux/pagemap.h> | 24 | #include <linux/pagemap.h> |
| 25 | #include <linux/bootmem.h> | 25 | #include <linux/bootmem.h> |
| 26 | #include <linux/pfn.h> | ||
| 26 | 27 | ||
| 27 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
| 28 | #include <asm/system.h> | 29 | #include <asm/system.h> |
| @@ -33,6 +34,7 @@ | |||
| 33 | #include <asm/lowcore.h> | 34 | #include <asm/lowcore.h> |
| 34 | #include <asm/tlb.h> | 35 | #include <asm/tlb.h> |
| 35 | #include <asm/tlbflush.h> | 36 | #include <asm/tlbflush.h> |
| 37 | #include <asm/sections.h> | ||
| 36 | 38 | ||
| 37 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 39 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
| 38 | 40 | ||
| @@ -89,17 +91,6 @@ void show_mem(void) | |||
| 89 | printk("%d pages swap cached\n",cached); | 91 | printk("%d pages swap cached\n",cached); |
| 90 | } | 92 | } |
| 91 | 93 | ||
| 92 | /* References to section boundaries */ | ||
| 93 | |||
| 94 | extern unsigned long _text; | ||
| 95 | extern unsigned long _etext; | ||
| 96 | extern unsigned long _edata; | ||
| 97 | extern unsigned long __bss_start; | ||
| 98 | extern unsigned long _end; | ||
| 99 | |||
| 100 | extern unsigned long __init_begin; | ||
| 101 | extern unsigned long __init_end; | ||
| 102 | |||
| 103 | extern unsigned long __initdata zholes_size[]; | 94 | extern unsigned long __initdata zholes_size[]; |
| 104 | /* | 95 | /* |
| 105 | * paging_init() sets up the page tables | 96 | * paging_init() sets up the page tables |
| @@ -116,6 +107,10 @@ void __init paging_init(void) | |||
| 116 | unsigned long pfn = 0; | 107 | unsigned long pfn = 0; |
| 117 | unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; | 108 | unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; |
| 118 | static const int ssm_mask = 0x04000000L; | 109 | static const int ssm_mask = 0x04000000L; |
| 110 | unsigned long ro_start_pfn, ro_end_pfn; | ||
| 111 | |||
| 112 | ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); | ||
| 113 | ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); | ||
| 119 | 114 | ||
| 120 | /* unmap whole virtual address space */ | 115 | /* unmap whole virtual address space */ |
| 121 | 116 | ||
| @@ -143,7 +138,10 @@ void __init paging_init(void) | |||
| 143 | pg_dir++; | 138 | pg_dir++; |
| 144 | 139 | ||
| 145 | for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { | 140 | for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { |
| 146 | pte = pfn_pte(pfn, PAGE_KERNEL); | 141 | if (pfn >= ro_start_pfn && pfn < ro_end_pfn) |
| 142 | pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); | ||
| 143 | else | ||
| 144 | pte = pfn_pte(pfn, PAGE_KERNEL); | ||
| 147 | if (pfn >= max_low_pfn) | 145 | if (pfn >= max_low_pfn) |
| 148 | pte_clear(&init_mm, 0, &pte); | 146 | pte_clear(&init_mm, 0, &pte); |
| 149 | set_pte(pg_table, pte); | 147 | set_pte(pg_table, pte); |
| @@ -175,6 +173,7 @@ void __init paging_init(void) | |||
| 175 | } | 173 | } |
| 176 | 174 | ||
| 177 | #else /* CONFIG_64BIT */ | 175 | #else /* CONFIG_64BIT */ |
| 176 | |||
| 178 | void __init paging_init(void) | 177 | void __init paging_init(void) |
| 179 | { | 178 | { |
| 180 | pgd_t * pg_dir; | 179 | pgd_t * pg_dir; |
| @@ -186,13 +185,15 @@ void __init paging_init(void) | |||
| 186 | unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | | 185 | unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | |
| 187 | _KERN_REGION_TABLE; | 186 | _KERN_REGION_TABLE; |
| 188 | static const int ssm_mask = 0x04000000L; | 187 | static const int ssm_mask = 0x04000000L; |
| 189 | |||
| 190 | unsigned long zones_size[MAX_NR_ZONES]; | 188 | unsigned long zones_size[MAX_NR_ZONES]; |
| 191 | unsigned long dma_pfn, high_pfn; | 189 | unsigned long dma_pfn, high_pfn; |
| 190 | unsigned long ro_start_pfn, ro_end_pfn; | ||
| 192 | 191 | ||
| 193 | memset(zones_size, 0, sizeof(zones_size)); | 192 | memset(zones_size, 0, sizeof(zones_size)); |
| 194 | dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; | 193 | dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; |
| 195 | high_pfn = max_low_pfn; | 194 | high_pfn = max_low_pfn; |
| 195 | ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); | ||
| 196 | ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); | ||
| 196 | 197 | ||
| 197 | if (dma_pfn > high_pfn) | 198 | if (dma_pfn > high_pfn) |
| 198 | zones_size[ZONE_DMA] = high_pfn; | 199 | zones_size[ZONE_DMA] = high_pfn; |
| @@ -231,7 +232,10 @@ void __init paging_init(void) | |||
| 231 | pmd_populate_kernel(&init_mm, pm_dir, pt_dir); | 232 | pmd_populate_kernel(&init_mm, pm_dir, pt_dir); |
| 232 | 233 | ||
| 233 | for (k = 0 ; k < PTRS_PER_PTE ; k++,pt_dir++) { | 234 | for (k = 0 ; k < PTRS_PER_PTE ; k++,pt_dir++) { |
| 234 | pte = pfn_pte(pfn, PAGE_KERNEL); | 235 | if (pfn >= ro_start_pfn && pfn < ro_end_pfn) |
| 236 | pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); | ||
| 237 | else | ||
| 238 | pte = pfn_pte(pfn, PAGE_KERNEL); | ||
| 235 | if (pfn >= max_low_pfn) { | 239 | if (pfn >= max_low_pfn) { |
| 236 | pte_clear(&init_mm, 0, &pte); | 240 | pte_clear(&init_mm, 0, &pte); |
| 237 | continue; | 241 | continue; |
| @@ -282,6 +286,9 @@ void __init mem_init(void) | |||
| 282 | reservedpages << (PAGE_SHIFT-10), | 286 | reservedpages << (PAGE_SHIFT-10), |
| 283 | datasize >>10, | 287 | datasize >>10, |
| 284 | initsize >> 10); | 288 | initsize >> 10); |
| 289 | printk("Write protected kernel read-only data: %#lx - %#lx\n", | ||
| 290 | (unsigned long)&__start_rodata, | ||
| 291 | PFN_ALIGN((unsigned long)&__end_rodata) - 1); | ||
| 285 | } | 292 | } |
| 286 | 293 | ||
| 287 | void free_initmem(void) | 294 | void free_initmem(void) |
