diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-11 12:16:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-11 12:16:39 -0400 |
commit | 89af571ca633ada14d17746519a179553a732d31 (patch) | |
tree | 7d5486cc43b4ce4c258cb2fcfc449e6a94cdc33d /arch/s390/kernel | |
parent | 1b195b170da6d75abafa290deeb8863dc8a4d79b (diff) | |
parent | 59e36927ee08f3bf06d8d14597e57389bf1b41dc (diff) |
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (54 commits)
[S390] tape: Use pr_xxx instead of dev_xxx in shared driver code
[S390] Wire up page fault events for software perf counters.
[S390] Remove smp_cpu_not_running.
[S390] Get rid of cpuid.h header file.
[S390] Limit cpu detection to 256 physical cpus.
[S390] tape: Fix device online messages
[S390] Enable guest page hinting by default.
[S390] use generic scatterlist.h
[S390] s390dbf: Add description for usage of "%s" in sprintf events
[S390] Initialize __LC_THREAD_INFO early.
[S390] fix recursive locking on page_table_lock
[S390] kvm: use console_initcall() to initialize s390 virtio console
[S390] tape: reversed order of labels
[S390] hypfs: Use "%u" instead of "%d" for unsigned ints in snprintf
[S390] kernel: Print an error message if kernel NSS cannot be defined
[S390] zcrypt: Free ap_device if dev_set_name fails.
[S390] zcrypt: Use spin_lock_bh in suspend callback
[S390] xpram: Remove checksum validation for suspend/resume
[S390] vmur: Invalid allocation sequence for vmur class
[S390] hypfs: remove useless variable qname
...
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 74 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 16 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 4 | ||||
-rw-r--r-- | arch/s390/kernel/head.S | 1 | ||||
-rw-r--r-- | arch/s390/kernel/head31.S | 1 | ||||
-rw-r--r-- | arch/s390/kernel/head64.S | 9 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 166 | ||||
-rw-r--r-- | arch/s390/kernel/mcount.S | 147 | ||||
-rw-r--r-- | arch/s390/kernel/mcount64.S | 78 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 10 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 39 | ||||
-rw-r--r-- | arch/s390/kernel/suspend.c | 73 | ||||
-rw-r--r-- | arch/s390/kernel/swsusp_asm64.S | 184 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 3 | ||||
-rw-r--r-- | arch/s390/kernel/vmlinux.lds.S | 87 |
16 files changed, 602 insertions, 294 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index c75ed43b1a18..c7be8e10b87e 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -32,7 +32,7 @@ extra-y += head.o init_task.o vmlinux.lds | |||
32 | 32 | ||
33 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o | 33 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o |
34 | obj-$(CONFIG_SMP) += smp.o topology.o | 34 | obj-$(CONFIG_SMP) += smp.o topology.o |
35 | 35 | obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o | |
36 | obj-$(CONFIG_AUDIT) += audit.o | 36 | obj-$(CONFIG_AUDIT) += audit.o |
37 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o | 37 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o |
38 | obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ | 38 | obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ |
@@ -41,7 +41,7 @@ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ | |||
41 | 41 | ||
42 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 42 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
43 | obj-$(CONFIG_KPROBES) += kprobes.o | 43 | obj-$(CONFIG_KPROBES) += kprobes.o |
44 | obj-$(CONFIG_FUNCTION_TRACER) += mcount.o | 44 | obj-$(CONFIG_FUNCTION_TRACER) += $(if $(CONFIG_64BIT),mcount64.o,mcount.o) |
45 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 45 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
46 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | 46 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
47 | 47 | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index cae14c499511..bf8b4ae7ff2d 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -6,6 +6,9 @@ | |||
6 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 6 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #define KMSG_COMPONENT "setup" | ||
10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
11 | |||
9 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
10 | #include <linux/init.h> | 13 | #include <linux/init.h> |
11 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
@@ -16,6 +19,7 @@ | |||
16 | #include <linux/module.h> | 19 | #include <linux/module.h> |
17 | #include <linux/pfn.h> | 20 | #include <linux/pfn.h> |
18 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/kernel.h> | ||
19 | #include <asm/ebcdic.h> | 23 | #include <asm/ebcdic.h> |
20 | #include <asm/ipl.h> | 24 | #include <asm/ipl.h> |
21 | #include <asm/lowcore.h> | 25 | #include <asm/lowcore.h> |
@@ -35,8 +39,6 @@ | |||
35 | 39 | ||
36 | char kernel_nss_name[NSS_NAME_SIZE + 1]; | 40 | char kernel_nss_name[NSS_NAME_SIZE + 1]; |
37 | 41 | ||
38 | static unsigned long machine_flags; | ||
39 | |||
40 | static void __init setup_boot_command_line(void); | 42 | static void __init setup_boot_command_line(void); |
41 | 43 | ||
42 | /* | 44 | /* |
@@ -81,6 +83,8 @@ asm( | |||
81 | " br 14\n" | 83 | " br 14\n" |
82 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); | 84 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); |
83 | 85 | ||
86 | static __initdata char upper_command_line[COMMAND_LINE_SIZE]; | ||
87 | |||
84 | static noinline __init void create_kernel_nss(void) | 88 | static noinline __init void create_kernel_nss(void) |
85 | { | 89 | { |
86 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; | 90 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; |
@@ -90,7 +94,6 @@ static noinline __init void create_kernel_nss(void) | |||
90 | int response; | 94 | int response; |
91 | size_t len; | 95 | size_t len; |
92 | char *savesys_ptr; | 96 | char *savesys_ptr; |
93 | char upper_command_line[COMMAND_LINE_SIZE]; | ||
94 | char defsys_cmd[DEFSYS_CMD_SIZE]; | 97 | char defsys_cmd[DEFSYS_CMD_SIZE]; |
95 | char savesys_cmd[SAVESYS_CMD_SIZE]; | 98 | char savesys_cmd[SAVESYS_CMD_SIZE]; |
96 | 99 | ||
@@ -141,6 +144,8 @@ static noinline __init void create_kernel_nss(void) | |||
141 | __cpcmd(defsys_cmd, NULL, 0, &response); | 144 | __cpcmd(defsys_cmd, NULL, 0, &response); |
142 | 145 | ||
143 | if (response != 0) { | 146 | if (response != 0) { |
147 | pr_err("Defining the Linux kernel NSS failed with rc=%d\n", | ||
148 | response); | ||
144 | kernel_nss_name[0] = '\0'; | 149 | kernel_nss_name[0] = '\0'; |
145 | return; | 150 | return; |
146 | } | 151 | } |
@@ -153,8 +158,11 @@ static noinline __init void create_kernel_nss(void) | |||
153 | * max SAVESYS_CMD_SIZE | 158 | * max SAVESYS_CMD_SIZE |
154 | * On error: response contains the numeric portion of cp error message. | 159 | * On error: response contains the numeric portion of cp error message. |
155 | * for SAVESYS it will be >= 263 | 160 | * for SAVESYS it will be >= 263 |
161 | * for missing privilege class, it will be 1 | ||
156 | */ | 162 | */ |
157 | if (response > SAVESYS_CMD_SIZE) { | 163 | if (response > SAVESYS_CMD_SIZE || response == 1) { |
164 | pr_err("Saving the Linux kernel NSS failed with rc=%d\n", | ||
165 | response); | ||
158 | kernel_nss_name[0] = '\0'; | 166 | kernel_nss_name[0] = '\0'; |
159 | return; | 167 | return; |
160 | } | 168 | } |
@@ -205,12 +213,9 @@ static noinline __init void detect_machine_type(void) | |||
205 | 213 | ||
206 | /* Running under KVM? If not we assume z/VM */ | 214 | /* Running under KVM? If not we assume z/VM */ |
207 | if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) | 215 | if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) |
208 | machine_flags |= MACHINE_FLAG_KVM; | 216 | S390_lowcore.machine_flags |= MACHINE_FLAG_KVM; |
209 | else | 217 | else |
210 | machine_flags |= MACHINE_FLAG_VM; | 218 | S390_lowcore.machine_flags |= MACHINE_FLAG_VM; |
211 | |||
212 | /* Store machine flags for setting up lowcore early */ | ||
213 | S390_lowcore.machine_flags = machine_flags; | ||
214 | } | 219 | } |
215 | 220 | ||
216 | static __init void early_pgm_check_handler(void) | 221 | static __init void early_pgm_check_handler(void) |
@@ -245,7 +250,7 @@ static noinline __init void setup_hpage(void) | |||
245 | facilities = stfl(); | 250 | facilities = stfl(); |
246 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) | 251 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) |
247 | return; | 252 | return; |
248 | machine_flags |= MACHINE_FLAG_HPAGE; | 253 | S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE; |
249 | __ctl_set_bit(0, 23); | 254 | __ctl_set_bit(0, 23); |
250 | #endif | 255 | #endif |
251 | } | 256 | } |
@@ -263,7 +268,7 @@ static __init void detect_mvpg(void) | |||
263 | EX_TABLE(0b,1b) | 268 | EX_TABLE(0b,1b) |
264 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); | 269 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); |
265 | if (!rc) | 270 | if (!rc) |
266 | machine_flags |= MACHINE_FLAG_MVPG; | 271 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVPG; |
267 | #endif | 272 | #endif |
268 | } | 273 | } |
269 | 274 | ||
@@ -279,7 +284,7 @@ static __init void detect_ieee(void) | |||
279 | EX_TABLE(0b,1b) | 284 | EX_TABLE(0b,1b) |
280 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); | 285 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); |
281 | if (!rc) | 286 | if (!rc) |
282 | machine_flags |= MACHINE_FLAG_IEEE; | 287 | S390_lowcore.machine_flags |= MACHINE_FLAG_IEEE; |
283 | #endif | 288 | #endif |
284 | } | 289 | } |
285 | 290 | ||
@@ -298,7 +303,7 @@ static __init void detect_csp(void) | |||
298 | EX_TABLE(0b,1b) | 303 | EX_TABLE(0b,1b) |
299 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); | 304 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); |
300 | if (!rc) | 305 | if (!rc) |
301 | machine_flags |= MACHINE_FLAG_CSP; | 306 | S390_lowcore.machine_flags |= MACHINE_FLAG_CSP; |
302 | #endif | 307 | #endif |
303 | } | 308 | } |
304 | 309 | ||
@@ -315,7 +320,7 @@ static __init void detect_diag9c(void) | |||
315 | EX_TABLE(0b,1b) | 320 | EX_TABLE(0b,1b) |
316 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); | 321 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); |
317 | if (!rc) | 322 | if (!rc) |
318 | machine_flags |= MACHINE_FLAG_DIAG9C; | 323 | S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG9C; |
319 | } | 324 | } |
320 | 325 | ||
321 | static __init void detect_diag44(void) | 326 | static __init void detect_diag44(void) |
@@ -330,7 +335,7 @@ static __init void detect_diag44(void) | |||
330 | EX_TABLE(0b,1b) | 335 | EX_TABLE(0b,1b) |
331 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); | 336 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); |
332 | if (!rc) | 337 | if (!rc) |
333 | machine_flags |= MACHINE_FLAG_DIAG44; | 338 | S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG44; |
334 | #endif | 339 | #endif |
335 | } | 340 | } |
336 | 341 | ||
@@ -341,11 +346,11 @@ static __init void detect_machine_facilities(void) | |||
341 | 346 | ||
342 | facilities = stfl(); | 347 | facilities = stfl(); |
343 | if (facilities & (1 << 28)) | 348 | if (facilities & (1 << 28)) |
344 | machine_flags |= MACHINE_FLAG_IDTE; | 349 | S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; |
345 | if (facilities & (1 << 23)) | 350 | if (facilities & (1 << 23)) |
346 | machine_flags |= MACHINE_FLAG_PFMF; | 351 | S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; |
347 | if (facilities & (1 << 4)) | 352 | if (facilities & (1 << 4)) |
348 | machine_flags |= MACHINE_FLAG_MVCOS; | 353 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; |
349 | #endif | 354 | #endif |
350 | } | 355 | } |
351 | 356 | ||
@@ -367,21 +372,35 @@ static __init void rescue_initrd(void) | |||
367 | } | 372 | } |
368 | 373 | ||
369 | /* Set up boot command line */ | 374 | /* Set up boot command line */ |
370 | static void __init setup_boot_command_line(void) | 375 | static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t)) |
371 | { | 376 | { |
372 | char *parm = NULL; | 377 | char *parm, *delim; |
378 | size_t rc, len; | ||
379 | |||
380 | len = strlen(boot_command_line); | ||
381 | |||
382 | delim = boot_command_line + len; /* '\0' character position */ | ||
383 | parm = boot_command_line + len + 1; /* append right after '\0' */ | ||
373 | 384 | ||
385 | rc = ipl_data(parm, COMMAND_LINE_SIZE - len - 1); | ||
386 | if (rc) { | ||
387 | if (*parm == '=') | ||
388 | memmove(boot_command_line, parm + 1, rc); | ||
389 | else | ||
390 | *delim = ' '; /* replace '\0' with space */ | ||
391 | } | ||
392 | } | ||
393 | |||
394 | static void __init setup_boot_command_line(void) | ||
395 | { | ||
374 | /* copy arch command line */ | 396 | /* copy arch command line */ |
375 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); | 397 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); |
376 | 398 | ||
377 | /* append IPL PARM data to the boot command line */ | 399 | /* append IPL PARM data to the boot command line */ |
378 | if (MACHINE_IS_VM) { | 400 | if (MACHINE_IS_VM) |
379 | parm = boot_command_line + strlen(boot_command_line); | 401 | append_to_cmdline(append_ipl_vmparm); |
380 | *parm++ = ' '; | 402 | |
381 | get_ipl_vmparm(parm); | 403 | append_to_cmdline(append_ipl_scpdata); |
382 | if (parm[0] == '=') | ||
383 | memmove(boot_command_line, parm + 1, strlen(parm)); | ||
384 | } | ||
385 | } | 404 | } |
386 | 405 | ||
387 | 406 | ||
@@ -413,7 +432,6 @@ void __init startup_init(void) | |||
413 | setup_hpage(); | 432 | setup_hpage(); |
414 | sclp_facilities_detect(); | 433 | sclp_facilities_detect(); |
415 | detect_memory_layout(memory_chunk); | 434 | detect_memory_layout(memory_chunk); |
416 | S390_lowcore.machine_flags = machine_flags; | ||
417 | #ifdef CONFIG_DYNAMIC_FTRACE | 435 | #ifdef CONFIG_DYNAMIC_FTRACE |
418 | S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; | 436 | S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; |
419 | #endif | 437 | #endif |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index c4c80a22bc1f..f78580a74039 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -278,7 +278,8 @@ sysc_return: | |||
278 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 278 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
279 | sysc_restore: | 279 | sysc_restore: |
280 | #ifdef CONFIG_TRACE_IRQFLAGS | 280 | #ifdef CONFIG_TRACE_IRQFLAGS |
281 | la %r1,BASED(sysc_restore_trace_psw) | 281 | la %r1,BASED(sysc_restore_trace_psw_addr) |
282 | l %r1,0(%r1) | ||
282 | lpsw 0(%r1) | 283 | lpsw 0(%r1) |
283 | sysc_restore_trace: | 284 | sysc_restore_trace: |
284 | TRACE_IRQS_CHECK | 285 | TRACE_IRQS_CHECK |
@@ -289,10 +290,15 @@ sysc_leave: | |||
289 | sysc_done: | 290 | sysc_done: |
290 | 291 | ||
291 | #ifdef CONFIG_TRACE_IRQFLAGS | 292 | #ifdef CONFIG_TRACE_IRQFLAGS |
293 | sysc_restore_trace_psw_addr: | ||
294 | .long sysc_restore_trace_psw | ||
295 | |||
296 | .section .data,"aw",@progbits | ||
292 | .align 8 | 297 | .align 8 |
293 | .globl sysc_restore_trace_psw | 298 | .globl sysc_restore_trace_psw |
294 | sysc_restore_trace_psw: | 299 | sysc_restore_trace_psw: |
295 | .long 0, sysc_restore_trace + 0x80000000 | 300 | .long 0, sysc_restore_trace + 0x80000000 |
301 | .previous | ||
296 | #endif | 302 | #endif |
297 | 303 | ||
298 | # | 304 | # |
@@ -606,7 +612,8 @@ io_return: | |||
606 | bnz BASED(io_work) # there is work to do (signals etc.) | 612 | bnz BASED(io_work) # there is work to do (signals etc.) |
607 | io_restore: | 613 | io_restore: |
608 | #ifdef CONFIG_TRACE_IRQFLAGS | 614 | #ifdef CONFIG_TRACE_IRQFLAGS |
609 | la %r1,BASED(io_restore_trace_psw) | 615 | la %r1,BASED(io_restore_trace_psw_addr) |
616 | l %r1,0(%r1) | ||
610 | lpsw 0(%r1) | 617 | lpsw 0(%r1) |
611 | io_restore_trace: | 618 | io_restore_trace: |
612 | TRACE_IRQS_CHECK | 619 | TRACE_IRQS_CHECK |
@@ -617,10 +624,15 @@ io_leave: | |||
617 | io_done: | 624 | io_done: |
618 | 625 | ||
619 | #ifdef CONFIG_TRACE_IRQFLAGS | 626 | #ifdef CONFIG_TRACE_IRQFLAGS |
627 | io_restore_trace_psw_addr: | ||
628 | .long io_restore_trace_psw | ||
629 | |||
630 | .section .data,"aw",@progbits | ||
620 | .align 8 | 631 | .align 8 |
621 | .globl io_restore_trace_psw | 632 | .globl io_restore_trace_psw |
622 | io_restore_trace_psw: | 633 | io_restore_trace_psw: |
623 | .long 0, io_restore_trace + 0x80000000 | 634 | .long 0, io_restore_trace + 0x80000000 |
635 | .previous | ||
624 | #endif | 636 | #endif |
625 | 637 | ||
626 | # | 638 | # |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index f6618e9e15ef..009ca6175db9 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -284,10 +284,12 @@ sysc_leave: | |||
284 | sysc_done: | 284 | sysc_done: |
285 | 285 | ||
286 | #ifdef CONFIG_TRACE_IRQFLAGS | 286 | #ifdef CONFIG_TRACE_IRQFLAGS |
287 | .section .data,"aw",@progbits | ||
287 | .align 8 | 288 | .align 8 |
288 | .globl sysc_restore_trace_psw | 289 | .globl sysc_restore_trace_psw |
289 | sysc_restore_trace_psw: | 290 | sysc_restore_trace_psw: |
290 | .quad 0, sysc_restore_trace | 291 | .quad 0, sysc_restore_trace |
292 | .previous | ||
291 | #endif | 293 | #endif |
292 | 294 | ||
293 | # | 295 | # |
@@ -595,10 +597,12 @@ io_leave: | |||
595 | io_done: | 597 | io_done: |
596 | 598 | ||
597 | #ifdef CONFIG_TRACE_IRQFLAGS | 599 | #ifdef CONFIG_TRACE_IRQFLAGS |
600 | .section .data,"aw",@progbits | ||
598 | .align 8 | 601 | .align 8 |
599 | .globl io_restore_trace_psw | 602 | .globl io_restore_trace_psw |
600 | io_restore_trace_psw: | 603 | io_restore_trace_psw: |
601 | .quad 0, io_restore_trace | 604 | .quad 0, io_restore_trace |
605 | .previous | ||
602 | #endif | 606 | #endif |
603 | 607 | ||
604 | # | 608 | # |
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index ec6882348520..c52b4f7742fa 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/asm-offsets.h> | 27 | #include <asm/asm-offsets.h> |
28 | #include <asm/thread_info.h> | 28 | #include <asm/thread_info.h> |
29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
30 | #include <asm/cpu.h> | ||
30 | 31 | ||
31 | #ifdef CONFIG_64BIT | 32 | #ifdef CONFIG_64BIT |
32 | #define ARCH_OFFSET 4 | 33 | #define ARCH_OFFSET 4 |
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 2ced846065b7..602b508cd4c4 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
@@ -24,6 +24,7 @@ startup_continue: | |||
24 | # Setup stack | 24 | # Setup stack |
25 | # | 25 | # |
26 | l %r15,.Linittu-.LPG1(%r13) | 26 | l %r15,.Linittu-.LPG1(%r13) |
27 | st %r15,__LC_THREAD_INFO # cache thread info in lowcore | ||
27 | mvc __LC_CURRENT(4),__TI_task(%r15) | 28 | mvc __LC_CURRENT(4),__TI_task(%r15) |
28 | ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE | 29 | ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE |
29 | st %r15,__LC_KERNEL_STACK # set end of kernel stack | 30 | st %r15,__LC_KERNEL_STACK # set end of kernel stack |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 65667b2e65ce..6a250808092b 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -62,9 +62,9 @@ startup_continue: | |||
62 | clr %r11,%r12 | 62 | clr %r11,%r12 |
63 | je 5f # no more space in prefix array | 63 | je 5f # no more space in prefix array |
64 | 4: | 64 | 4: |
65 | ahi %r8,1 # next cpu (r8 += 1) | 65 | ahi %r8,1 # next cpu (r8 += 1) |
66 | cl %r8,.Llast_cpu-.LPG1(%r13) # is last possible cpu ? | 66 | chi %r8,MAX_CPU_ADDRESS # is last possible cpu ? |
67 | jl 1b # jump if not last cpu | 67 | jle 1b # jump if not last cpu |
68 | 5: | 68 | 5: |
69 | lhi %r1,2 # mode 2 = esame (dump) | 69 | lhi %r1,2 # mode 2 = esame (dump) |
70 | j 6f | 70 | j 6f |
@@ -92,6 +92,7 @@ startup_continue: | |||
92 | # Setup stack | 92 | # Setup stack |
93 | # | 93 | # |
94 | larl %r15,init_thread_union | 94 | larl %r15,init_thread_union |
95 | stg %r15,__LC_THREAD_INFO # cache thread info in lowcore | ||
95 | lg %r14,__TI_task(%r15) # cache current in lowcore | 96 | lg %r14,__TI_task(%r15) # cache current in lowcore |
96 | stg %r14,__LC_CURRENT | 97 | stg %r14,__LC_CURRENT |
97 | aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE | 98 | aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE |
@@ -129,8 +130,6 @@ startup_continue: | |||
129 | #ifdef CONFIG_ZFCPDUMP | 130 | #ifdef CONFIG_ZFCPDUMP |
130 | .Lcurrent_cpu: | 131 | .Lcurrent_cpu: |
131 | .long 0x0 | 132 | .long 0x0 |
132 | .Llast_cpu: | ||
133 | .long 0x0000ffff | ||
134 | .Lpref_arr_ptr: | 133 | .Lpref_arr_ptr: |
135 | .long zfcpdump_prefix_array | 134 | .long zfcpdump_prefix_array |
136 | #endif /* CONFIG_ZFCPDUMP */ | 135 | #endif /* CONFIG_ZFCPDUMP */ |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 371a2d88f4ac..ee57a42e6e93 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -272,17 +272,18 @@ static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr, | |||
272 | static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); | 272 | static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); |
273 | 273 | ||
274 | /* VM IPL PARM routines */ | 274 | /* VM IPL PARM routines */ |
275 | static void reipl_get_ascii_vmparm(char *dest, | 275 | size_t reipl_get_ascii_vmparm(char *dest, size_t size, |
276 | const struct ipl_parameter_block *ipb) | 276 | const struct ipl_parameter_block *ipb) |
277 | { | 277 | { |
278 | int i; | 278 | int i; |
279 | int len = 0; | 279 | size_t len; |
280 | char has_lowercase = 0; | 280 | char has_lowercase = 0; |
281 | 281 | ||
282 | len = 0; | ||
282 | if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) && | 283 | if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) && |
283 | (ipb->ipl_info.ccw.vm_parm_len > 0)) { | 284 | (ipb->ipl_info.ccw.vm_parm_len > 0)) { |
284 | 285 | ||
285 | len = ipb->ipl_info.ccw.vm_parm_len; | 286 | len = min_t(size_t, size - 1, ipb->ipl_info.ccw.vm_parm_len); |
286 | memcpy(dest, ipb->ipl_info.ccw.vm_parm, len); | 287 | memcpy(dest, ipb->ipl_info.ccw.vm_parm, len); |
287 | /* If at least one character is lowercase, we assume mixed | 288 | /* If at least one character is lowercase, we assume mixed |
288 | * case; otherwise we convert everything to lowercase. | 289 | * case; otherwise we convert everything to lowercase. |
@@ -299,14 +300,20 @@ static void reipl_get_ascii_vmparm(char *dest, | |||
299 | EBCASC(dest, len); | 300 | EBCASC(dest, len); |
300 | } | 301 | } |
301 | dest[len] = 0; | 302 | dest[len] = 0; |
303 | |||
304 | return len; | ||
302 | } | 305 | } |
303 | 306 | ||
304 | void get_ipl_vmparm(char *dest) | 307 | size_t append_ipl_vmparm(char *dest, size_t size) |
305 | { | 308 | { |
309 | size_t rc; | ||
310 | |||
311 | rc = 0; | ||
306 | if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)) | 312 | if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)) |
307 | reipl_get_ascii_vmparm(dest, &ipl_block); | 313 | rc = reipl_get_ascii_vmparm(dest, size, &ipl_block); |
308 | else | 314 | else |
309 | dest[0] = 0; | 315 | dest[0] = 0; |
316 | return rc; | ||
310 | } | 317 | } |
311 | 318 | ||
312 | static ssize_t ipl_vm_parm_show(struct kobject *kobj, | 319 | static ssize_t ipl_vm_parm_show(struct kobject *kobj, |
@@ -314,10 +321,65 @@ static ssize_t ipl_vm_parm_show(struct kobject *kobj, | |||
314 | { | 321 | { |
315 | char parm[DIAG308_VMPARM_SIZE + 1] = {}; | 322 | char parm[DIAG308_VMPARM_SIZE + 1] = {}; |
316 | 323 | ||
317 | get_ipl_vmparm(parm); | 324 | append_ipl_vmparm(parm, sizeof(parm)); |
318 | return sprintf(page, "%s\n", parm); | 325 | return sprintf(page, "%s\n", parm); |
319 | } | 326 | } |
320 | 327 | ||
328 | static size_t scpdata_length(const char* buf, size_t count) | ||
329 | { | ||
330 | while (count) { | ||
331 | if (buf[count - 1] != '\0' && buf[count - 1] != ' ') | ||
332 | break; | ||
333 | count--; | ||
334 | } | ||
335 | return count; | ||
336 | } | ||
337 | |||
338 | size_t reipl_append_ascii_scpdata(char *dest, size_t size, | ||
339 | const struct ipl_parameter_block *ipb) | ||
340 | { | ||
341 | size_t count; | ||
342 | size_t i; | ||
343 | int has_lowercase; | ||
344 | |||
345 | count = min(size - 1, scpdata_length(ipb->ipl_info.fcp.scp_data, | ||
346 | ipb->ipl_info.fcp.scp_data_len)); | ||
347 | if (!count) | ||
348 | goto out; | ||
349 | |||
350 | has_lowercase = 0; | ||
351 | for (i = 0; i < count; i++) { | ||
352 | if (!isascii(ipb->ipl_info.fcp.scp_data[i])) { | ||
353 | count = 0; | ||
354 | goto out; | ||
355 | } | ||
356 | if (!has_lowercase && islower(ipb->ipl_info.fcp.scp_data[i])) | ||
357 | has_lowercase = 1; | ||
358 | } | ||
359 | |||
360 | if (has_lowercase) | ||
361 | memcpy(dest, ipb->ipl_info.fcp.scp_data, count); | ||
362 | else | ||
363 | for (i = 0; i < count; i++) | ||
364 | dest[i] = tolower(ipb->ipl_info.fcp.scp_data[i]); | ||
365 | out: | ||
366 | dest[count] = '\0'; | ||
367 | return count; | ||
368 | } | ||
369 | |||
370 | size_t append_ipl_scpdata(char *dest, size_t len) | ||
371 | { | ||
372 | size_t rc; | ||
373 | |||
374 | rc = 0; | ||
375 | if (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP) | ||
376 | rc = reipl_append_ascii_scpdata(dest, len, &ipl_block); | ||
377 | else | ||
378 | dest[0] = 0; | ||
379 | return rc; | ||
380 | } | ||
381 | |||
382 | |||
321 | static struct kobj_attribute sys_ipl_vm_parm_attr = | 383 | static struct kobj_attribute sys_ipl_vm_parm_attr = |
322 | __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); | 384 | __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); |
323 | 385 | ||
@@ -553,7 +615,7 @@ static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb, | |||
553 | { | 615 | { |
554 | char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; | 616 | char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; |
555 | 617 | ||
556 | reipl_get_ascii_vmparm(vmparm, ipb); | 618 | reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); |
557 | return sprintf(page, "%s\n", vmparm); | 619 | return sprintf(page, "%s\n", vmparm); |
558 | } | 620 | } |
559 | 621 | ||
@@ -626,6 +688,59 @@ static struct kobj_attribute sys_reipl_ccw_vmparm_attr = | |||
626 | 688 | ||
627 | /* FCP reipl device attributes */ | 689 | /* FCP reipl device attributes */ |
628 | 690 | ||
691 | static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj, | ||
692 | struct bin_attribute *attr, | ||
693 | char *buf, loff_t off, size_t count) | ||
694 | { | ||
695 | size_t size = reipl_block_fcp->ipl_info.fcp.scp_data_len; | ||
696 | void *scp_data = reipl_block_fcp->ipl_info.fcp.scp_data; | ||
697 | |||
698 | return memory_read_from_buffer(buf, count, &off, scp_data, size); | ||
699 | } | ||
700 | |||
701 | static ssize_t reipl_fcp_scpdata_write(struct kobject *kobj, | ||
702 | struct bin_attribute *attr, | ||
703 | char *buf, loff_t off, size_t count) | ||
704 | { | ||
705 | size_t padding; | ||
706 | size_t scpdata_len; | ||
707 | |||
708 | if (off < 0) | ||
709 | return -EINVAL; | ||
710 | |||
711 | if (off >= DIAG308_SCPDATA_SIZE) | ||
712 | return -ENOSPC; | ||
713 | |||
714 | if (count > DIAG308_SCPDATA_SIZE - off) | ||
715 | count = DIAG308_SCPDATA_SIZE - off; | ||
716 | |||
717 | memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf + off, count); | ||
718 | scpdata_len = off + count; | ||
719 | |||
720 | if (scpdata_len % 8) { | ||
721 | padding = 8 - (scpdata_len % 8); | ||
722 | memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len, | ||
723 | 0, padding); | ||
724 | scpdata_len += padding; | ||
725 | } | ||
726 | |||
727 | reipl_block_fcp->ipl_info.fcp.scp_data_len = scpdata_len; | ||
728 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN + scpdata_len; | ||
729 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN + scpdata_len; | ||
730 | |||
731 | return count; | ||
732 | } | ||
733 | |||
734 | static struct bin_attribute sys_reipl_fcp_scp_data_attr = { | ||
735 | .attr = { | ||
736 | .name = "scp_data", | ||
737 | .mode = S_IRUGO | S_IWUSR, | ||
738 | }, | ||
739 | .size = PAGE_SIZE, | ||
740 | .read = reipl_fcp_scpdata_read, | ||
741 | .write = reipl_fcp_scpdata_write, | ||
742 | }; | ||
743 | |||
629 | DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", | 744 | DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", |
630 | reipl_block_fcp->ipl_info.fcp.wwpn); | 745 | reipl_block_fcp->ipl_info.fcp.wwpn); |
631 | DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", | 746 | DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", |
@@ -647,7 +762,6 @@ static struct attribute *reipl_fcp_attrs[] = { | |||
647 | }; | 762 | }; |
648 | 763 | ||
649 | static struct attribute_group reipl_fcp_attr_group = { | 764 | static struct attribute_group reipl_fcp_attr_group = { |
650 | .name = IPL_FCP_STR, | ||
651 | .attrs = reipl_fcp_attrs, | 765 | .attrs = reipl_fcp_attrs, |
652 | }; | 766 | }; |
653 | 767 | ||
@@ -895,6 +1009,7 @@ static struct kobj_attribute reipl_type_attr = | |||
895 | __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); | 1009 | __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); |
896 | 1010 | ||
897 | static struct kset *reipl_kset; | 1011 | static struct kset *reipl_kset; |
1012 | static struct kset *reipl_fcp_kset; | ||
898 | 1013 | ||
899 | static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, | 1014 | static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, |
900 | const enum ipl_method m) | 1015 | const enum ipl_method m) |
@@ -906,7 +1021,7 @@ static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, | |||
906 | 1021 | ||
907 | reipl_get_ascii_loadparm(loadparm, ipb); | 1022 | reipl_get_ascii_loadparm(loadparm, ipb); |
908 | reipl_get_ascii_nss_name(nss_name, ipb); | 1023 | reipl_get_ascii_nss_name(nss_name, ipb); |
909 | reipl_get_ascii_vmparm(vmparm, ipb); | 1024 | reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); |
910 | 1025 | ||
911 | switch (m) { | 1026 | switch (m) { |
912 | case REIPL_METHOD_CCW_VM: | 1027 | case REIPL_METHOD_CCW_VM: |
@@ -1076,23 +1191,44 @@ static int __init reipl_fcp_init(void) | |||
1076 | int rc; | 1191 | int rc; |
1077 | 1192 | ||
1078 | if (!diag308_set_works) { | 1193 | if (!diag308_set_works) { |
1079 | if (ipl_info.type == IPL_TYPE_FCP) | 1194 | if (ipl_info.type == IPL_TYPE_FCP) { |
1080 | make_attrs_ro(reipl_fcp_attrs); | 1195 | make_attrs_ro(reipl_fcp_attrs); |
1081 | else | 1196 | sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO; |
1197 | } else | ||
1082 | return 0; | 1198 | return 0; |
1083 | } | 1199 | } |
1084 | 1200 | ||
1085 | reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); | 1201 | reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); |
1086 | if (!reipl_block_fcp) | 1202 | if (!reipl_block_fcp) |
1087 | return -ENOMEM; | 1203 | return -ENOMEM; |
1088 | rc = sysfs_create_group(&reipl_kset->kobj, &reipl_fcp_attr_group); | 1204 | |
1205 | /* sysfs: create fcp kset for mixing attr group and bin attrs */ | ||
1206 | reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL, | ||
1207 | &reipl_kset->kobj); | ||
1208 | if (!reipl_kset) { | ||
1209 | free_page((unsigned long) reipl_block_fcp); | ||
1210 | return -ENOMEM; | ||
1211 | } | ||
1212 | |||
1213 | rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); | ||
1214 | if (rc) { | ||
1215 | kset_unregister(reipl_fcp_kset); | ||
1216 | free_page((unsigned long) reipl_block_fcp); | ||
1217 | return rc; | ||
1218 | } | ||
1219 | |||
1220 | rc = sysfs_create_bin_file(&reipl_fcp_kset->kobj, | ||
1221 | &sys_reipl_fcp_scp_data_attr); | ||
1089 | if (rc) { | 1222 | if (rc) { |
1090 | free_page((unsigned long)reipl_block_fcp); | 1223 | sysfs_remove_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); |
1224 | kset_unregister(reipl_fcp_kset); | ||
1225 | free_page((unsigned long) reipl_block_fcp); | ||
1091 | return rc; | 1226 | return rc; |
1092 | } | 1227 | } |
1093 | if (ipl_info.type == IPL_TYPE_FCP) { | 1228 | |
1229 | if (ipl_info.type == IPL_TYPE_FCP) | ||
1094 | memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); | 1230 | memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); |
1095 | } else { | 1231 | else { |
1096 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; | 1232 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; |
1097 | reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; | 1233 | reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; |
1098 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; | 1234 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; |
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 2a0a5e97ba8c..dfe015d7398c 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S | |||
@@ -11,111 +11,27 @@ | |||
11 | ftrace_stub: | 11 | ftrace_stub: |
12 | br %r14 | 12 | br %r14 |
13 | 13 | ||
14 | #ifdef CONFIG_64BIT | ||
15 | |||
16 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
17 | |||
18 | .globl _mcount | 14 | .globl _mcount |
19 | _mcount: | 15 | _mcount: |
20 | br %r14 | 16 | #ifdef CONFIG_DYNAMIC_FTRACE |
21 | |||
22 | .globl ftrace_caller | ||
23 | ftrace_caller: | ||
24 | larl %r1,function_trace_stop | ||
25 | icm %r1,0xf,0(%r1) | ||
26 | bnzr %r14 | ||
27 | stmg %r2,%r5,32(%r15) | ||
28 | stg %r14,112(%r15) | ||
29 | lgr %r1,%r15 | ||
30 | aghi %r15,-160 | ||
31 | stg %r1,__SF_BACKCHAIN(%r15) | ||
32 | lgr %r2,%r14 | ||
33 | lg %r3,168(%r15) | ||
34 | larl %r14,ftrace_dyn_func | ||
35 | lg %r14,0(%r14) | ||
36 | basr %r14,%r14 | ||
37 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
38 | .globl ftrace_graph_caller | ||
39 | ftrace_graph_caller: | ||
40 | # This unconditional branch gets runtime patched. Change only if | ||
41 | # you know what you are doing. See ftrace_enable_graph_caller(). | ||
42 | j 0f | ||
43 | lg %r2,272(%r15) | ||
44 | lg %r3,168(%r15) | ||
45 | brasl %r14,prepare_ftrace_return | ||
46 | stg %r2,168(%r15) | ||
47 | 0: | ||
48 | #endif | ||
49 | aghi %r15,160 | ||
50 | lmg %r2,%r5,32(%r15) | ||
51 | lg %r14,112(%r15) | ||
52 | br %r14 | 17 | br %r14 |
53 | 18 | ||
54 | .data | 19 | .data |
55 | .globl ftrace_dyn_func | 20 | .globl ftrace_dyn_func |
56 | ftrace_dyn_func: | 21 | ftrace_dyn_func: |
57 | .quad ftrace_stub | 22 | .long ftrace_stub |
58 | .previous | 23 | .previous |
59 | 24 | ||
60 | #else /* CONFIG_DYNAMIC_FTRACE */ | ||
61 | |||
62 | .globl _mcount | ||
63 | _mcount: | ||
64 | larl %r1,function_trace_stop | ||
65 | icm %r1,0xf,0(%r1) | ||
66 | bnzr %r14 | ||
67 | stmg %r2,%r5,32(%r15) | ||
68 | stg %r14,112(%r15) | ||
69 | lgr %r1,%r15 | ||
70 | aghi %r15,-160 | ||
71 | stg %r1,__SF_BACKCHAIN(%r15) | ||
72 | lgr %r2,%r14 | ||
73 | lg %r3,168(%r15) | ||
74 | larl %r14,ftrace_trace_function | ||
75 | lg %r14,0(%r14) | ||
76 | basr %r14,%r14 | ||
77 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
78 | lg %r2,272(%r15) | ||
79 | lg %r3,168(%r15) | ||
80 | brasl %r14,prepare_ftrace_return | ||
81 | stg %r2,168(%r15) | ||
82 | #endif | ||
83 | aghi %r15,160 | ||
84 | lmg %r2,%r5,32(%r15) | ||
85 | lg %r14,112(%r15) | ||
86 | br %r14 | ||
87 | |||
88 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
89 | |||
90 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
91 | |||
92 | .globl return_to_handler | ||
93 | return_to_handler: | ||
94 | stmg %r2,%r5,32(%r15) | ||
95 | lgr %r1,%r15 | ||
96 | aghi %r15,-160 | ||
97 | stg %r1,__SF_BACKCHAIN(%r15) | ||
98 | brasl %r14,ftrace_return_to_handler | ||
99 | aghi %r15,160 | ||
100 | lgr %r14,%r2 | ||
101 | lmg %r2,%r5,32(%r15) | ||
102 | br %r14 | ||
103 | |||
104 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
105 | |||
106 | #else /* CONFIG_64BIT */ | ||
107 | |||
108 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
109 | |||
110 | .globl _mcount | ||
111 | _mcount: | ||
112 | br %r14 | ||
113 | |||
114 | .globl ftrace_caller | 25 | .globl ftrace_caller |
115 | ftrace_caller: | 26 | ftrace_caller: |
27 | #endif | ||
116 | stm %r2,%r5,16(%r15) | 28 | stm %r2,%r5,16(%r15) |
117 | bras %r1,2f | 29 | bras %r1,2f |
30 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
31 | 0: .long ftrace_dyn_func | ||
32 | #else | ||
118 | 0: .long ftrace_trace_function | 33 | 0: .long ftrace_trace_function |
34 | #endif | ||
119 | 1: .long function_trace_stop | 35 | 1: .long function_trace_stop |
120 | 2: l %r2,1b-0b(%r1) | 36 | 2: l %r2,1b-0b(%r1) |
121 | icm %r2,0xf,0(%r2) | 37 | icm %r2,0xf,0(%r2) |
@@ -131,53 +47,13 @@ ftrace_caller: | |||
131 | l %r14,0(%r14) | 47 | l %r14,0(%r14) |
132 | basr %r14,%r14 | 48 | basr %r14,%r14 |
133 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 49 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
50 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
134 | .globl ftrace_graph_caller | 51 | .globl ftrace_graph_caller |
135 | ftrace_graph_caller: | 52 | ftrace_graph_caller: |
136 | # This unconditional branch gets runtime patched. Change only if | 53 | # This unconditional branch gets runtime patched. Change only if |
137 | # you know what you are doing. See ftrace_enable_graph_caller(). | 54 | # you know what you are doing. See ftrace_enable_graph_caller(). |
138 | j 1f | 55 | j 1f |
139 | bras %r1,0f | ||
140 | .long prepare_ftrace_return | ||
141 | 0: l %r2,152(%r15) | ||
142 | l %r4,0(%r1) | ||
143 | l %r3,100(%r15) | ||
144 | basr %r14,%r4 | ||
145 | st %r2,100(%r15) | ||
146 | 1: | ||
147 | #endif | 56 | #endif |
148 | ahi %r15,96 | ||
149 | l %r14,56(%r15) | ||
150 | 3: lm %r2,%r5,16(%r15) | ||
151 | br %r14 | ||
152 | |||
153 | .data | ||
154 | .globl ftrace_dyn_func | ||
155 | ftrace_dyn_func: | ||
156 | .long ftrace_stub | ||
157 | .previous | ||
158 | |||
159 | #else /* CONFIG_DYNAMIC_FTRACE */ | ||
160 | |||
161 | .globl _mcount | ||
162 | _mcount: | ||
163 | stm %r2,%r5,16(%r15) | ||
164 | bras %r1,2f | ||
165 | 0: .long ftrace_trace_function | ||
166 | 1: .long function_trace_stop | ||
167 | 2: l %r2,1b-0b(%r1) | ||
168 | icm %r2,0xf,0(%r2) | ||
169 | jnz 3f | ||
170 | st %r14,56(%r15) | ||
171 | lr %r0,%r15 | ||
172 | ahi %r15,-96 | ||
173 | l %r3,100(%r15) | ||
174 | la %r2,0(%r14) | ||
175 | st %r0,__SF_BACKCHAIN(%r15) | ||
176 | la %r3,0(%r3) | ||
177 | l %r14,0b-0b(%r1) | ||
178 | l %r14,0(%r14) | ||
179 | basr %r14,%r14 | ||
180 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
181 | bras %r1,0f | 57 | bras %r1,0f |
182 | .long prepare_ftrace_return | 58 | .long prepare_ftrace_return |
183 | 0: l %r2,152(%r15) | 59 | 0: l %r2,152(%r15) |
@@ -185,14 +61,13 @@ _mcount: | |||
185 | l %r3,100(%r15) | 61 | l %r3,100(%r15) |
186 | basr %r14,%r4 | 62 | basr %r14,%r4 |
187 | st %r2,100(%r15) | 63 | st %r2,100(%r15) |
64 | 1: | ||
188 | #endif | 65 | #endif |
189 | ahi %r15,96 | 66 | ahi %r15,96 |
190 | l %r14,56(%r15) | 67 | l %r14,56(%r15) |
191 | 3: lm %r2,%r5,16(%r15) | 68 | 3: lm %r2,%r5,16(%r15) |
192 | br %r14 | 69 | br %r14 |
193 | 70 | ||
194 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
195 | |||
196 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 71 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
197 | 72 | ||
198 | .globl return_to_handler | 73 | .globl return_to_handler |
@@ -211,6 +86,4 @@ return_to_handler: | |||
211 | lm %r2,%r5,16(%r15) | 86 | lm %r2,%r5,16(%r15) |
212 | br %r14 | 87 | br %r14 |
213 | 88 | ||
214 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 89 | #endif |
215 | |||
216 | #endif /* CONFIG_64BIT */ | ||
diff --git a/arch/s390/kernel/mcount64.S b/arch/s390/kernel/mcount64.S new file mode 100644 index 000000000000..c37211c6092b --- /dev/null +++ b/arch/s390/kernel/mcount64.S | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * Copyright IBM Corp. 2008,2009 | ||
3 | * | ||
4 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #include <asm/asm-offsets.h> | ||
9 | |||
10 | .globl ftrace_stub | ||
11 | ftrace_stub: | ||
12 | br %r14 | ||
13 | |||
14 | .globl _mcount | ||
15 | _mcount: | ||
16 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
17 | br %r14 | ||
18 | |||
19 | .data | ||
20 | .globl ftrace_dyn_func | ||
21 | ftrace_dyn_func: | ||
22 | .quad ftrace_stub | ||
23 | .previous | ||
24 | |||
25 | .globl ftrace_caller | ||
26 | ftrace_caller: | ||
27 | #endif | ||
28 | larl %r1,function_trace_stop | ||
29 | icm %r1,0xf,0(%r1) | ||
30 | bnzr %r14 | ||
31 | stmg %r2,%r5,32(%r15) | ||
32 | stg %r14,112(%r15) | ||
33 | lgr %r1,%r15 | ||
34 | aghi %r15,-160 | ||
35 | stg %r1,__SF_BACKCHAIN(%r15) | ||
36 | lgr %r2,%r14 | ||
37 | lg %r3,168(%r15) | ||
38 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
39 | larl %r14,ftrace_dyn_func | ||
40 | #else | ||
41 | larl %r14,ftrace_trace_function | ||
42 | #endif | ||
43 | lg %r14,0(%r14) | ||
44 | basr %r14,%r14 | ||
45 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
46 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
47 | .globl ftrace_graph_caller | ||
48 | ftrace_graph_caller: | ||
49 | # This unconditional branch gets runtime patched. Change only if | ||
50 | # you know what you are doing. See ftrace_enable_graph_caller(). | ||
51 | j 0f | ||
52 | #endif | ||
53 | lg %r2,272(%r15) | ||
54 | lg %r3,168(%r15) | ||
55 | brasl %r14,prepare_ftrace_return | ||
56 | stg %r2,168(%r15) | ||
57 | 0: | ||
58 | #endif | ||
59 | aghi %r15,160 | ||
60 | lmg %r2,%r5,32(%r15) | ||
61 | lg %r14,112(%r15) | ||
62 | br %r14 | ||
63 | |||
64 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
65 | |||
66 | .globl return_to_handler | ||
67 | return_to_handler: | ||
68 | stmg %r2,%r5,32(%r15) | ||
69 | lgr %r1,%r15 | ||
70 | aghi %r15,-160 | ||
71 | stg %r1,__SF_BACKCHAIN(%r15) | ||
72 | brasl %r14,ftrace_return_to_handler | ||
73 | aghi %r15,160 | ||
74 | lgr %r14,%r2 | ||
75 | lmg %r2,%r5,32(%r15) | ||
76 | br %r14 | ||
77 | |||
78 | #endif | ||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index cbb897bc50bd..9ed13a1ed376 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -156,15 +156,11 @@ __setup("condev=", condev_setup); | |||
156 | 156 | ||
157 | static void __init set_preferred_console(void) | 157 | static void __init set_preferred_console(void) |
158 | { | 158 | { |
159 | if (MACHINE_IS_KVM) { | 159 | if (MACHINE_IS_KVM) |
160 | add_preferred_console("hvc", 0, NULL); | 160 | add_preferred_console("hvc", 0, NULL); |
161 | s390_virtio_console_init(); | 161 | else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) |
162 | return; | ||
163 | } | ||
164 | |||
165 | if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) | ||
166 | add_preferred_console("ttyS", 0, NULL); | 162 | add_preferred_console("ttyS", 0, NULL); |
167 | if (CONSOLE_IS_3270) | 163 | else if (CONSOLE_IS_3270) |
168 | add_preferred_console("tty3270", 0, NULL); | 164 | add_preferred_console("tty3270", 0, NULL); |
169 | } | 165 | } |
170 | 166 | ||
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index be2cae083406..56c16876b919 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <asm/sclp.h> | 49 | #include <asm/sclp.h> |
50 | #include <asm/cputime.h> | 50 | #include <asm/cputime.h> |
51 | #include <asm/vdso.h> | 51 | #include <asm/vdso.h> |
52 | #include <asm/cpu.h> | ||
52 | #include "entry.h" | 53 | #include "entry.h" |
53 | 54 | ||
54 | static struct task_struct *current_set[NR_CPUS]; | 55 | static struct task_struct *current_set[NR_CPUS]; |
@@ -70,6 +71,23 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); | |||
70 | 71 | ||
71 | static void smp_ext_bitcall(int, ec_bit_sig); | 72 | static void smp_ext_bitcall(int, ec_bit_sig); |
72 | 73 | ||
74 | static int cpu_stopped(int cpu) | ||
75 | { | ||
76 | __u32 status; | ||
77 | |||
78 | switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { | ||
79 | case sigp_order_code_accepted: | ||
80 | case sigp_status_stored: | ||
81 | /* Check for stopped and check stop state */ | ||
82 | if (status & 0x50) | ||
83 | return 1; | ||
84 | break; | ||
85 | default: | ||
86 | break; | ||
87 | } | ||
88 | return 0; | ||
89 | } | ||
90 | |||
73 | void smp_send_stop(void) | 91 | void smp_send_stop(void) |
74 | { | 92 | { |
75 | int cpu, rc; | 93 | int cpu, rc; |
@@ -86,7 +104,7 @@ void smp_send_stop(void) | |||
86 | rc = signal_processor(cpu, sigp_stop); | 104 | rc = signal_processor(cpu, sigp_stop); |
87 | } while (rc == sigp_busy); | 105 | } while (rc == sigp_busy); |
88 | 106 | ||
89 | while (!smp_cpu_not_running(cpu)) | 107 | while (!cpu_stopped(cpu)) |
90 | cpu_relax(); | 108 | cpu_relax(); |
91 | } | 109 | } |
92 | } | 110 | } |
@@ -269,19 +287,6 @@ static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { } | |||
269 | 287 | ||
270 | #endif /* CONFIG_ZFCPDUMP */ | 288 | #endif /* CONFIG_ZFCPDUMP */ |
271 | 289 | ||
272 | static int cpu_stopped(int cpu) | ||
273 | { | ||
274 | __u32 status; | ||
275 | |||
276 | /* Check for stopped state */ | ||
277 | if (signal_processor_ps(&status, 0, cpu, sigp_sense) == | ||
278 | sigp_status_stored) { | ||
279 | if (status & 0x40) | ||
280 | return 1; | ||
281 | } | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int cpu_known(int cpu_id) | 290 | static int cpu_known(int cpu_id) |
286 | { | 291 | { |
287 | int cpu; | 292 | int cpu; |
@@ -300,7 +305,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail) | |||
300 | logical_cpu = cpumask_first(&avail); | 305 | logical_cpu = cpumask_first(&avail); |
301 | if (logical_cpu >= nr_cpu_ids) | 306 | if (logical_cpu >= nr_cpu_ids) |
302 | return 0; | 307 | return 0; |
303 | for (cpu_id = 0; cpu_id <= 65535; cpu_id++) { | 308 | for (cpu_id = 0; cpu_id <= MAX_CPU_ADDRESS; cpu_id++) { |
304 | if (cpu_known(cpu_id)) | 309 | if (cpu_known(cpu_id)) |
305 | continue; | 310 | continue; |
306 | __cpu_logical_map[logical_cpu] = cpu_id; | 311 | __cpu_logical_map[logical_cpu] = cpu_id; |
@@ -379,7 +384,7 @@ static void __init smp_detect_cpus(void) | |||
379 | /* Use sigp detection algorithm if sclp doesn't work. */ | 384 | /* Use sigp detection algorithm if sclp doesn't work. */ |
380 | if (sclp_get_cpu_info(info)) { | 385 | if (sclp_get_cpu_info(info)) { |
381 | smp_use_sigp_detection = 1; | 386 | smp_use_sigp_detection = 1; |
382 | for (cpu = 0; cpu <= 65535; cpu++) { | 387 | for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) { |
383 | if (cpu == boot_cpu_addr) | 388 | if (cpu == boot_cpu_addr) |
384 | continue; | 389 | continue; |
385 | __cpu_logical_map[CPU_INIT_NO] = cpu; | 390 | __cpu_logical_map[CPU_INIT_NO] = cpu; |
@@ -635,7 +640,7 @@ int __cpu_disable(void) | |||
635 | void __cpu_die(unsigned int cpu) | 640 | void __cpu_die(unsigned int cpu) |
636 | { | 641 | { |
637 | /* Wait until target cpu is down */ | 642 | /* Wait until target cpu is down */ |
638 | while (!smp_cpu_not_running(cpu)) | 643 | while (!cpu_stopped(cpu)) |
639 | cpu_relax(); | 644 | cpu_relax(); |
640 | smp_free_lowcore(cpu); | 645 | smp_free_lowcore(cpu); |
641 | pr_info("Processor %d stopped\n", cpu); | 646 | pr_info("Processor %d stopped\n", cpu); |
diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c new file mode 100644 index 000000000000..086bee970cae --- /dev/null +++ b/arch/s390/kernel/suspend.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Suspend support specific for s390. | ||
3 | * | ||
4 | * Copyright IBM Corp. 2009 | ||
5 | * | ||
6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/suspend.h> | ||
10 | #include <linux/reboot.h> | ||
11 | #include <linux/pfn.h> | ||
12 | #include <linux/mm.h> | ||
13 | #include <asm/sections.h> | ||
14 | #include <asm/system.h> | ||
15 | #include <asm/ipl.h> | ||
16 | |||
17 | /* | ||
18 | * References to section boundaries | ||
19 | */ | ||
20 | extern const void __nosave_begin, __nosave_end; | ||
21 | |||
22 | /* | ||
23 | * check if given pfn is in the 'nosave' or in the read only NSS section | ||
24 | */ | ||
25 | int pfn_is_nosave(unsigned long pfn) | ||
26 | { | ||
27 | unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; | ||
28 | unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) | ||
29 | >> PAGE_SHIFT; | ||
30 | unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1; | ||
31 | unsigned long stext_pfn = PFN_DOWN(__pa(&_stext)); | ||
32 | |||
33 | if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) | ||
34 | return 1; | ||
35 | if (pfn >= stext_pfn && pfn <= eshared_pfn) { | ||
36 | if (ipl_info.type == IPL_TYPE_NSS) | ||
37 | return 1; | ||
38 | } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0)) | ||
39 | return 1; | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | void save_processor_state(void) | ||
44 | { | ||
45 | /* swsusp_arch_suspend() actually saves all cpu register contents. | ||
46 | * Machine checks must be disabled since swsusp_arch_suspend() stores | ||
47 | * register contents to their lowcore save areas. That's the same | ||
48 | * place where register contents on machine checks would be saved. | ||
49 | * To avoid register corruption disable machine checks. | ||
50 | * We must also disable machine checks in the new psw mask for | ||
51 | * program checks, since swsusp_arch_suspend() may generate program | ||
52 | * checks. Disabling machine checks for all other new psw masks is | ||
53 | * just paranoia. | ||
54 | */ | ||
55 | local_mcck_disable(); | ||
56 | /* Disable lowcore protection */ | ||
57 | __ctl_clear_bit(0,28); | ||
58 | S390_lowcore.external_new_psw.mask &= ~PSW_MASK_MCHECK; | ||
59 | S390_lowcore.svc_new_psw.mask &= ~PSW_MASK_MCHECK; | ||
60 | S390_lowcore.io_new_psw.mask &= ~PSW_MASK_MCHECK; | ||
61 | S390_lowcore.program_new_psw.mask &= ~PSW_MASK_MCHECK; | ||
62 | } | ||
63 | |||
64 | void restore_processor_state(void) | ||
65 | { | ||
66 | S390_lowcore.external_new_psw.mask |= PSW_MASK_MCHECK; | ||
67 | S390_lowcore.svc_new_psw.mask |= PSW_MASK_MCHECK; | ||
68 | S390_lowcore.io_new_psw.mask |= PSW_MASK_MCHECK; | ||
69 | S390_lowcore.program_new_psw.mask |= PSW_MASK_MCHECK; | ||
70 | /* Enable lowcore protection */ | ||
71 | __ctl_set_bit(0,28); | ||
72 | local_mcck_enable(); | ||
73 | } | ||
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S new file mode 100644 index 000000000000..7cd6b096f0d1 --- /dev/null +++ b/arch/s390/kernel/swsusp_asm64.S | |||
@@ -0,0 +1,184 @@ | |||
1 | /* | ||
2 | * S390 64-bit swsusp implementation | ||
3 | * | ||
4 | * Copyright IBM Corp. 2009 | ||
5 | * | ||
6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | ||
7 | * Michael Holzheu <holzheu@linux.vnet.ibm.com> | ||
8 | */ | ||
9 | |||
10 | #include <asm/page.h> | ||
11 | #include <asm/ptrace.h> | ||
12 | #include <asm/asm-offsets.h> | ||
13 | |||
14 | /* | ||
15 | * Save register context in absolute 0 lowcore and call swsusp_save() to | ||
16 | * create in-memory kernel image. The context is saved in the designated | ||
17 | * "store status" memory locations (see POP). | ||
18 | * We return from this function twice. The first time during the suspend to | ||
19 | * disk process. The second time via the swsusp_arch_resume() function | ||
20 | * (see below) in the resume process. | ||
21 | * This function runs with disabled interrupts. | ||
22 | */ | ||
23 | .section .text | ||
24 | .align 4 | ||
25 | .globl swsusp_arch_suspend | ||
26 | swsusp_arch_suspend: | ||
27 | stmg %r6,%r15,__SF_GPRS(%r15) | ||
28 | lgr %r1,%r15 | ||
29 | aghi %r15,-STACK_FRAME_OVERHEAD | ||
30 | stg %r1,__SF_BACKCHAIN(%r15) | ||
31 | |||
32 | /* Deactivate DAT */ | ||
33 | stnsm __SF_EMPTY(%r15),0xfb | ||
34 | |||
35 | /* Store prefix register on stack */ | ||
36 | stpx __SF_EMPTY(%r15) | ||
37 | |||
38 | /* Save prefix register contents for lowcore */ | ||
39 | llgf %r4,__SF_EMPTY(%r15) | ||
40 | |||
41 | /* Get pointer to save area */ | ||
42 | lghi %r1,0x1000 | ||
43 | |||
44 | /* Store registers */ | ||
45 | mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ | ||
46 | stfpc 0x31c(%r1) /* store fpu control */ | ||
47 | std 0,0x200(%r1) /* store f0 */ | ||
48 | std 1,0x208(%r1) /* store f1 */ | ||
49 | std 2,0x210(%r1) /* store f2 */ | ||
50 | std 3,0x218(%r1) /* store f3 */ | ||
51 | std 4,0x220(%r1) /* store f4 */ | ||
52 | std 5,0x228(%r1) /* store f5 */ | ||
53 | std 6,0x230(%r1) /* store f6 */ | ||
54 | std 7,0x238(%r1) /* store f7 */ | ||
55 | std 8,0x240(%r1) /* store f8 */ | ||
56 | std 9,0x248(%r1) /* store f9 */ | ||
57 | std 10,0x250(%r1) /* store f10 */ | ||
58 | std 11,0x258(%r1) /* store f11 */ | ||
59 | std 12,0x260(%r1) /* store f12 */ | ||
60 | std 13,0x268(%r1) /* store f13 */ | ||
61 | std 14,0x270(%r1) /* store f14 */ | ||
62 | std 15,0x278(%r1) /* store f15 */ | ||
63 | stam %a0,%a15,0x340(%r1) /* store access registers */ | ||
64 | stctg %c0,%c15,0x380(%r1) /* store control registers */ | ||
65 | stmg %r0,%r15,0x280(%r1) /* store general registers */ | ||
66 | |||
67 | stpt 0x328(%r1) /* store timer */ | ||
68 | stckc 0x330(%r1) /* store clock comparator */ | ||
69 | |||
70 | /* Activate DAT */ | ||
71 | stosm __SF_EMPTY(%r15),0x04 | ||
72 | |||
73 | /* Set prefix page to zero */ | ||
74 | xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) | ||
75 | spx __SF_EMPTY(%r15) | ||
76 | |||
77 | lghi %r2,0 | ||
78 | lghi %r3,2*PAGE_SIZE | ||
79 | lghi %r5,2*PAGE_SIZE | ||
80 | 1: mvcle %r2,%r4,0 | ||
81 | jo 1b | ||
82 | |||
83 | /* Save image */ | ||
84 | brasl %r14,swsusp_save | ||
85 | |||
86 | /* Restore prefix register and return */ | ||
87 | lghi %r1,0x1000 | ||
88 | spx 0x318(%r1) | ||
89 | lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) | ||
90 | lghi %r2,0 | ||
91 | br %r14 | ||
92 | |||
93 | /* | ||
94 | * Restore saved memory image to correct place and restore register context. | ||
95 | * Then we return to the function that called swsusp_arch_suspend(). | ||
96 | * swsusp_arch_resume() runs with disabled interrupts. | ||
97 | */ | ||
98 | .globl swsusp_arch_resume | ||
99 | swsusp_arch_resume: | ||
100 | stmg %r6,%r15,__SF_GPRS(%r15) | ||
101 | lgr %r1,%r15 | ||
102 | aghi %r15,-STACK_FRAME_OVERHEAD | ||
103 | stg %r1,__SF_BACKCHAIN(%r15) | ||
104 | |||
105 | #ifdef CONFIG_SMP | ||
106 | /* Save boot cpu number */ | ||
107 | brasl %r14,smp_get_phys_cpu_id | ||
108 | lgr %r10,%r2 | ||
109 | #endif | ||
110 | /* Deactivate DAT */ | ||
111 | stnsm __SF_EMPTY(%r15),0xfb | ||
112 | |||
113 | /* Set prefix page to zero */ | ||
114 | xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) | ||
115 | spx __SF_EMPTY(%r15) | ||
116 | |||
117 | /* Restore saved image */ | ||
118 | larl %r1,restore_pblist | ||
119 | lg %r1,0(%r1) | ||
120 | ltgr %r1,%r1 | ||
121 | jz 2f | ||
122 | 0: | ||
123 | lg %r2,8(%r1) | ||
124 | lg %r4,0(%r1) | ||
125 | lghi %r3,PAGE_SIZE | ||
126 | lghi %r5,PAGE_SIZE | ||
127 | 1: | ||
128 | mvcle %r2,%r4,0 | ||
129 | jo 1b | ||
130 | lg %r1,16(%r1) | ||
131 | ltgr %r1,%r1 | ||
132 | jnz 0b | ||
133 | 2: | ||
134 | ptlb /* flush tlb */ | ||
135 | |||
136 | /* Restore registers */ | ||
137 | lghi %r13,0x1000 /* %r1 = pointer to save arae */ | ||
138 | |||
139 | spt 0x328(%r13) /* reprogram timer */ | ||
140 | //sckc 0x330(%r13) /* set clock comparator */ | ||
141 | |||
142 | lctlg %c0,%c15,0x380(%r13) /* load control registers */ | ||
143 | lam %a0,%a15,0x340(%r13) /* load access registers */ | ||
144 | |||
145 | lfpc 0x31c(%r13) /* load fpu control */ | ||
146 | ld 0,0x200(%r13) /* load f0 */ | ||
147 | ld 1,0x208(%r13) /* load f1 */ | ||
148 | ld 2,0x210(%r13) /* load f2 */ | ||
149 | ld 3,0x218(%r13) /* load f3 */ | ||
150 | ld 4,0x220(%r13) /* load f4 */ | ||
151 | ld 5,0x228(%r13) /* load f5 */ | ||
152 | ld 6,0x230(%r13) /* load f6 */ | ||
153 | ld 7,0x238(%r13) /* load f7 */ | ||
154 | ld 8,0x240(%r13) /* load f8 */ | ||
155 | ld 9,0x248(%r13) /* load f9 */ | ||
156 | ld 10,0x250(%r13) /* load f10 */ | ||
157 | ld 11,0x258(%r13) /* load f11 */ | ||
158 | ld 12,0x260(%r13) /* load f12 */ | ||
159 | ld 13,0x268(%r13) /* load f13 */ | ||
160 | ld 14,0x270(%r13) /* load f14 */ | ||
161 | ld 15,0x278(%r13) /* load f15 */ | ||
162 | |||
163 | /* Load old stack */ | ||
164 | lg %r15,0x2f8(%r13) | ||
165 | |||
166 | /* Pointer to save area */ | ||
167 | lghi %r13,0x1000 | ||
168 | |||
169 | #ifdef CONFIG_SMP | ||
170 | /* Switch CPUs */ | ||
171 | lgr %r2,%r10 /* get cpu id */ | ||
172 | llgf %r3,0x318(%r13) | ||
173 | brasl %r14,smp_switch_boot_cpu_in_resume | ||
174 | #endif | ||
175 | /* Restore prefix register */ | ||
176 | spx 0x318(%r13) | ||
177 | |||
178 | /* Activate DAT */ | ||
179 | stosm __SF_EMPTY(%r15),0x04 | ||
180 | |||
181 | /* Return 0 */ | ||
182 | lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) | ||
183 | lghi %r2,0 | ||
184 | br %r14 | ||
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index d4c8e9c47c81..54e327e9af04 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #define TICK_SIZE tick | 60 | #define TICK_SIZE tick |
61 | 61 | ||
62 | u64 sched_clock_base_cc = -1; /* Force to data section. */ | 62 | u64 sched_clock_base_cc = -1; /* Force to data section. */ |
63 | EXPORT_SYMBOL_GPL(sched_clock_base_cc); | ||
63 | 64 | ||
64 | static DEFINE_PER_CPU(struct clock_event_device, comparators); | 65 | static DEFINE_PER_CPU(struct clock_event_device, comparators); |
65 | 66 | ||
@@ -68,7 +69,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators); | |||
68 | */ | 69 | */ |
69 | unsigned long long notrace sched_clock(void) | 70 | unsigned long long notrace sched_clock(void) |
70 | { | 71 | { |
71 | return ((get_clock_xt() - sched_clock_base_cc) * 125) >> 9; | 72 | return (get_clock_monotonic() * 125) >> 9; |
72 | } | 73 | } |
73 | 74 | ||
74 | /* | 75 | /* |
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index a53db23ee092..7315f9e67e1d 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S | |||
@@ -52,55 +52,18 @@ SECTIONS | |||
52 | . = ALIGN(PAGE_SIZE); | 52 | . = ALIGN(PAGE_SIZE); |
53 | _eshared = .; /* End of shareable data */ | 53 | _eshared = .; /* End of shareable data */ |
54 | 54 | ||
55 | . = ALIGN(16); /* Exception table */ | 55 | EXCEPTION_TABLE(16) :data |
56 | __ex_table : { | ||
57 | __start___ex_table = .; | ||
58 | *(__ex_table) | ||
59 | __stop___ex_table = .; | ||
60 | } :data | ||
61 | |||
62 | .data : { /* Data */ | ||
63 | DATA_DATA | ||
64 | CONSTRUCTORS | ||
65 | } | ||
66 | |||
67 | . = ALIGN(PAGE_SIZE); | ||
68 | .data_nosave : { | ||
69 | __nosave_begin = .; | ||
70 | *(.data.nosave) | ||
71 | } | ||
72 | . = ALIGN(PAGE_SIZE); | ||
73 | __nosave_end = .; | ||
74 | |||
75 | . = ALIGN(PAGE_SIZE); | ||
76 | .data.page_aligned : { | ||
77 | *(.data.idt) | ||
78 | } | ||
79 | 56 | ||
80 | . = ALIGN(0x100); | 57 | RW_DATA_SECTION(0x100, PAGE_SIZE, THREAD_SIZE) |
81 | .data.cacheline_aligned : { | ||
82 | *(.data.cacheline_aligned) | ||
83 | } | ||
84 | 58 | ||
85 | . = ALIGN(0x100); | ||
86 | .data.read_mostly : { | ||
87 | *(.data.read_mostly) | ||
88 | } | ||
89 | _edata = .; /* End of data section */ | 59 | _edata = .; /* End of data section */ |
90 | 60 | ||
91 | . = ALIGN(THREAD_SIZE); /* init_task */ | ||
92 | .data.init_task : { | ||
93 | *(.data.init_task) | ||
94 | } | ||
95 | |||
96 | /* will be freed after init */ | 61 | /* will be freed after init */ |
97 | . = ALIGN(PAGE_SIZE); /* Init code and data */ | 62 | . = ALIGN(PAGE_SIZE); /* Init code and data */ |
98 | __init_begin = .; | 63 | __init_begin = .; |
99 | .init.text : { | 64 | |
100 | _sinittext = .; | 65 | INIT_TEXT_SECTION(PAGE_SIZE) |
101 | INIT_TEXT | 66 | |
102 | _einittext = .; | ||
103 | } | ||
104 | /* | 67 | /* |
105 | * .exit.text is discarded at runtime, not link time, | 68 | * .exit.text is discarded at runtime, not link time, |
106 | * to deal with references from __bug_table | 69 | * to deal with references from __bug_table |
@@ -111,49 +74,13 @@ SECTIONS | |||
111 | 74 | ||
112 | /* early.c uses stsi, which requires page aligned data. */ | 75 | /* early.c uses stsi, which requires page aligned data. */ |
113 | . = ALIGN(PAGE_SIZE); | 76 | . = ALIGN(PAGE_SIZE); |
114 | .init.data : { | 77 | INIT_DATA_SECTION(0x100) |
115 | INIT_DATA | ||
116 | } | ||
117 | . = ALIGN(0x100); | ||
118 | .init.setup : { | ||
119 | __setup_start = .; | ||
120 | *(.init.setup) | ||
121 | __setup_end = .; | ||
122 | } | ||
123 | .initcall.init : { | ||
124 | __initcall_start = .; | ||
125 | INITCALLS | ||
126 | __initcall_end = .; | ||
127 | } | ||
128 | |||
129 | .con_initcall.init : { | ||
130 | __con_initcall_start = .; | ||
131 | *(.con_initcall.init) | ||
132 | __con_initcall_end = .; | ||
133 | } | ||
134 | SECURITY_INIT | ||
135 | |||
136 | #ifdef CONFIG_BLK_DEV_INITRD | ||
137 | . = ALIGN(0x100); | ||
138 | .init.ramfs : { | ||
139 | __initramfs_start = .; | ||
140 | *(.init.ramfs) | ||
141 | . = ALIGN(2); | ||
142 | __initramfs_end = .; | ||
143 | } | ||
144 | #endif | ||
145 | 78 | ||
146 | PERCPU(PAGE_SIZE) | 79 | PERCPU(PAGE_SIZE) |
147 | . = ALIGN(PAGE_SIZE); | 80 | . = ALIGN(PAGE_SIZE); |
148 | __init_end = .; /* freed after init ends here */ | 81 | __init_end = .; /* freed after init ends here */ |
149 | 82 | ||
150 | /* BSS */ | 83 | BSS_SECTION(0, 2, 0) |
151 | .bss : { | ||
152 | __bss_start = .; | ||
153 | *(.bss) | ||
154 | . = ALIGN(2); | ||
155 | __bss_stop = .; | ||
156 | } | ||
157 | 84 | ||
158 | _end = . ; | 85 | _end = . ; |
159 | 86 | ||