aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/Makefile3
-rw-r--r--arch/s390/kernel/asm-offsets.c99
-rw-r--r--arch/s390/kernel/base.S2
-rw-r--r--arch/s390/kernel/dis.c369
-rw-r--r--arch/s390/kernel/early.c22
-rw-r--r--arch/s390/kernel/entry.S1
-rw-r--r--arch/s390/kernel/entry64.S2
-rw-r--r--arch/s390/kernel/ftrace.c12
-rw-r--r--arch/s390/kernel/head.S60
-rw-r--r--arch/s390/kernel/head31.S16
-rw-r--r--arch/s390/kernel/head64.S92
-rw-r--r--arch/s390/kernel/ipl.c41
-rw-r--r--arch/s390/kernel/machine_kexec.c10
-rw-r--r--arch/s390/kernel/ptrace.c58
-rw-r--r--arch/s390/kernel/reipl.S2
-rw-r--r--arch/s390/kernel/reipl64.S2
-rw-r--r--arch/s390/kernel/sclp.S36
-rw-r--r--arch/s390/kernel/setup.c11
-rw-r--r--arch/s390/kernel/smp.c108
-rw-r--r--arch/s390/kernel/switch_cpu.S58
-rw-r--r--arch/s390/kernel/switch_cpu64.S51
-rw-r--r--arch/s390/kernel/swsusp_asm64.S2
-rw-r--r--arch/s390/kernel/time.c8
-rw-r--r--arch/s390/kernel/vdso.c1
24 files changed, 750 insertions, 316 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 683f6381cc5..64230bc392f 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -29,9 +29,12 @@ obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
29obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) 29obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
30 30
31extra-y += head.o init_task.o vmlinux.lds 31extra-y += head.o init_task.o vmlinux.lds
32extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o)
32 33
33obj-$(CONFIG_MODULES) += s390_ksyms.o module.o 34obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
34obj-$(CONFIG_SMP) += smp.o topology.o 35obj-$(CONFIG_SMP) += smp.o topology.o
36obj-$(CONFIG_SMP) += $(if $(CONFIG_64BIT),switch_cpu64.o, \
37 switch_cpu.o)
35obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o 38obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o
36obj-$(CONFIG_AUDIT) += audit.o 39obj-$(CONFIG_AUDIT) += audit.o
37compat-obj-$(CONFIG_AUDIT) += compat_audit.o 40compat-obj-$(CONFIG_AUDIT) += compat_audit.o
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 63e46433e81..08db736dded 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -4,18 +4,27 @@
4 * and format the required data. 4 * and format the required data.
5 */ 5 */
6 6
7#include <linux/sched.h> 7#define ASM_OFFSETS_C
8
8#include <linux/kbuild.h> 9#include <linux/kbuild.h>
10#include <linux/sched.h>
9#include <asm/vdso.h> 11#include <asm/vdso.h>
10#include <asm/sigp.h> 12#include <asm/sigp.h>
11 13
14/*
15 * Make sure that the compiler is new enough. We want a compiler that
16 * is known to work with the "Q" assembler constraint.
17 */
18#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
19#error Your compiler is too old; please use version 3.3.3 or newer
20#endif
21
12int main(void) 22int main(void)
13{ 23{
14 DEFINE(__THREAD_info, offsetof(struct task_struct, stack)); 24 DEFINE(__THREAD_info, offsetof(struct task_struct, stack));
15 DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp)); 25 DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp));
16 DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info)); 26 DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info));
17 DEFINE(__THREAD_mm_segment, 27 DEFINE(__THREAD_mm_segment, offsetof(struct task_struct, thread.mm_segment));
18 offsetof(struct task_struct, thread.mm_segment));
19 BLANK(); 28 BLANK();
20 DEFINE(__TASK_pid, offsetof(struct task_struct, pid)); 29 DEFINE(__TASK_pid, offsetof(struct task_struct, pid));
21 BLANK(); 30 BLANK();
@@ -52,18 +61,94 @@ int main(void)
52 DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); 61 DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
53 DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest)); 62 DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
54 DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available)); 63 DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
55 DEFINE(__VDSO_ECTG_BASE, 64 DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
56 offsetof(struct vdso_per_cpu_data, ectg_timer_base)); 65 DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
57 DEFINE(__VDSO_ECTG_USER,
58 offsetof(struct vdso_per_cpu_data, ectg_user_time));
59 /* constants used by the vdso */ 66 /* constants used by the vdso */
60 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); 67 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
61 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); 68 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
62 DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); 69 DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
70 BLANK();
63 /* constants for SIGP */ 71 /* constants for SIGP */
64 DEFINE(__SIGP_STOP, sigp_stop); 72 DEFINE(__SIGP_STOP, sigp_stop);
65 DEFINE(__SIGP_RESTART, sigp_restart); 73 DEFINE(__SIGP_RESTART, sigp_restart);
66 DEFINE(__SIGP_SENSE, sigp_sense); 74 DEFINE(__SIGP_SENSE, sigp_sense);
67 DEFINE(__SIGP_INITIAL_CPU_RESET, sigp_initial_cpu_reset); 75 DEFINE(__SIGP_INITIAL_CPU_RESET, sigp_initial_cpu_reset);
76 BLANK();
77 /* lowcore offsets */
78 DEFINE(__LC_EXT_PARAMS, offsetof(struct _lowcore, ext_params));
79 DEFINE(__LC_CPU_ADDRESS, offsetof(struct _lowcore, cpu_addr));
80 DEFINE(__LC_EXT_INT_CODE, offsetof(struct _lowcore, ext_int_code));
81 DEFINE(__LC_SVC_ILC, offsetof(struct _lowcore, svc_ilc));
82 DEFINE(__LC_SVC_INT_CODE, offsetof(struct _lowcore, svc_code));
83 DEFINE(__LC_PGM_ILC, offsetof(struct _lowcore, pgm_ilc));
84 DEFINE(__LC_PGM_INT_CODE, offsetof(struct _lowcore, pgm_code));
85 DEFINE(__LC_PER_ATMID, offsetof(struct _lowcore, per_perc_atmid));
86 DEFINE(__LC_PER_ADDRESS, offsetof(struct _lowcore, per_address));
87 DEFINE(__LC_PER_ACCESS_ID, offsetof(struct _lowcore, per_access_id));
88 DEFINE(__LC_AR_MODE_ID, offsetof(struct _lowcore, ar_access_id));
89 DEFINE(__LC_SUBCHANNEL_ID, offsetof(struct _lowcore, subchannel_id));
90 DEFINE(__LC_SUBCHANNEL_NR, offsetof(struct _lowcore, subchannel_nr));
91 DEFINE(__LC_IO_INT_PARM, offsetof(struct _lowcore, io_int_parm));
92 DEFINE(__LC_IO_INT_WORD, offsetof(struct _lowcore, io_int_word));
93 DEFINE(__LC_STFL_FAC_LIST, offsetof(struct _lowcore, stfl_fac_list));
94 DEFINE(__LC_MCCK_CODE, offsetof(struct _lowcore, mcck_interruption_code));
95 DEFINE(__LC_DUMP_REIPL, offsetof(struct _lowcore, ipib));
96 BLANK();
97 DEFINE(__LC_RST_NEW_PSW, offsetof(struct _lowcore, restart_psw));
98 DEFINE(__LC_RST_OLD_PSW, offsetof(struct _lowcore, restart_old_psw));
99 DEFINE(__LC_EXT_OLD_PSW, offsetof(struct _lowcore, external_old_psw));
100 DEFINE(__LC_SVC_OLD_PSW, offsetof(struct _lowcore, svc_old_psw));
101 DEFINE(__LC_PGM_OLD_PSW, offsetof(struct _lowcore, program_old_psw));
102 DEFINE(__LC_MCK_OLD_PSW, offsetof(struct _lowcore, mcck_old_psw));
103 DEFINE(__LC_IO_OLD_PSW, offsetof(struct _lowcore, io_old_psw));
104 DEFINE(__LC_EXT_NEW_PSW, offsetof(struct _lowcore, external_new_psw));
105 DEFINE(__LC_SVC_NEW_PSW, offsetof(struct _lowcore, svc_new_psw));
106 DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw));
107 DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw));
108 DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw));
109 DEFINE(__LC_SAVE_AREA, offsetof(struct _lowcore, save_area));
110 DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw));
111 DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw));
112 DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer));
113 DEFINE(__LC_ASYNC_ENTER_TIMER, offsetof(struct _lowcore, async_enter_timer));
114 DEFINE(__LC_EXIT_TIMER, offsetof(struct _lowcore, exit_timer));
115 DEFINE(__LC_USER_TIMER, offsetof(struct _lowcore, user_timer));
116 DEFINE(__LC_SYSTEM_TIMER, offsetof(struct _lowcore, system_timer));
117 DEFINE(__LC_STEAL_TIMER, offsetof(struct _lowcore, steal_timer));
118 DEFINE(__LC_LAST_UPDATE_TIMER, offsetof(struct _lowcore, last_update_timer));
119 DEFINE(__LC_LAST_UPDATE_CLOCK, offsetof(struct _lowcore, last_update_clock));
120 DEFINE(__LC_CURRENT, offsetof(struct _lowcore, current_task));
121 DEFINE(__LC_THREAD_INFO, offsetof(struct _lowcore, thread_info));
122 DEFINE(__LC_KERNEL_STACK, offsetof(struct _lowcore, kernel_stack));
123 DEFINE(__LC_ASYNC_STACK, offsetof(struct _lowcore, async_stack));
124 DEFINE(__LC_PANIC_STACK, offsetof(struct _lowcore, panic_stack));
125 DEFINE(__LC_KERNEL_ASCE, offsetof(struct _lowcore, kernel_asce));
126 DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce));
127 DEFINE(__LC_USER_EXEC_ASCE, offsetof(struct _lowcore, user_exec_asce));
128 DEFINE(__LC_CPUID, offsetof(struct _lowcore, cpu_id));
129 DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock));
130 DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags));
131 DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func));
132 DEFINE(__LC_IRB, offsetof(struct _lowcore, irb));
133 DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area));
134 DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area));
135 DEFINE(__LC_PSW_SAVE_AREA, offsetof(struct _lowcore, psw_save_area));
136 DEFINE(__LC_PREFIX_SAVE_AREA, offsetof(struct _lowcore, prefixreg_save_area));
137 DEFINE(__LC_AREGS_SAVE_AREA, offsetof(struct _lowcore, access_regs_save_area));
138 DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area));
139 DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
140 DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
141#ifdef CONFIG_32BIT
142 DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params));
143 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
144#else /* CONFIG_32BIT */
145 DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params2));
146 DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2));
147 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area));
148 DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste));
149 DEFINE(__LC_FP_CREG_SAVE_AREA, offsetof(struct _lowcore, fpt_creg_save_area));
150 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr));
151 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
152#endif /* CONFIG_32BIT */
68 return 0; 153 return 0;
69} 154}
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S
index dc7e5259770..15e46ca9433 100644
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -6,8 +6,8 @@
6 * Michael Holzheu <holzheu@de.ibm.com> 6 * Michael Holzheu <holzheu@de.ibm.com>
7 */ 7 */
8 8
9#include <asm/asm-offsets.h>
9#include <asm/ptrace.h> 10#include <asm/ptrace.h>
10#include <asm/lowcore.h>
11 11
12#ifdef CONFIG_64BIT 12#ifdef CONFIG_64BIT
13 13
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index db943a7ec51..b39b27d68b4 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -86,10 +86,17 @@ enum {
86 U4_12, /* 4 bit unsigned value starting at 12 */ 86 U4_12, /* 4 bit unsigned value starting at 12 */
87 U4_16, /* 4 bit unsigned value starting at 16 */ 87 U4_16, /* 4 bit unsigned value starting at 16 */
88 U4_20, /* 4 bit unsigned value starting at 20 */ 88 U4_20, /* 4 bit unsigned value starting at 20 */
89 U4_32, /* 4 bit unsigned value starting at 32 */
89 U8_8, /* 8 bit unsigned value starting at 8 */ 90 U8_8, /* 8 bit unsigned value starting at 8 */
90 U8_16, /* 8 bit unsigned value starting at 16 */ 91 U8_16, /* 8 bit unsigned value starting at 16 */
92 U8_24, /* 8 bit unsigned value starting at 24 */
93 U8_32, /* 8 bit unsigned value starting at 32 */
94 I8_8, /* 8 bit signed value starting at 8 */
95 I8_32, /* 8 bit signed value starting at 32 */
91 I16_16, /* 16 bit signed value starting at 16 */ 96 I16_16, /* 16 bit signed value starting at 16 */
97 I16_32, /* 32 bit signed value starting at 16 */
92 U16_16, /* 16 bit unsigned value starting at 16 */ 98 U16_16, /* 16 bit unsigned value starting at 16 */
99 U16_32, /* 32 bit unsigned value starting at 16 */
93 J16_16, /* PC relative jump offset at 16 */ 100 J16_16, /* PC relative jump offset at 16 */
94 J32_16, /* PC relative long offset at 16 */ 101 J32_16, /* PC relative long offset at 16 */
95 I32_16, /* 32 bit signed value starting at 16 */ 102 I32_16, /* 32 bit signed value starting at 16 */
@@ -104,21 +111,37 @@ enum {
104 */ 111 */
105enum { 112enum {
106 INSTR_INVALID, 113 INSTR_INVALID,
107 INSTR_E, INSTR_RIE_RRP, INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU, 114 INSTR_E,
108 INSTR_RIL_UP, INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP, 115 INSTR_RIE_R0IU, INSTR_RIE_R0UU, INSTR_RIE_RRP, INSTR_RIE_RRPU,
116 INSTR_RIE_RRUUU, INSTR_RIE_RUPI, INSTR_RIE_RUPU,
117 INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU, INSTR_RIL_UP,
118 INSTR_RIS_R0RDU, INSTR_RIS_R0UU, INSTR_RIS_RURDI, INSTR_RIS_RURDU,
119 INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP,
109 INSTR_RRE_00, INSTR_RRE_0R, INSTR_RRE_AA, INSTR_RRE_AR, INSTR_RRE_F0, 120 INSTR_RRE_00, INSTR_RRE_0R, INSTR_RRE_AA, INSTR_RRE_AR, INSTR_RRE_F0,
110 INSTR_RRE_FF, INSTR_RRE_R0, INSTR_RRE_RA, INSTR_RRE_RF, INSTR_RRE_RR, 121 INSTR_RRE_FF, INSTR_RRE_FR, INSTR_RRE_R0, INSTR_RRE_RA, INSTR_RRE_RF,
111 INSTR_RRE_RR_OPT, INSTR_RRF_F0FF, INSTR_RRF_FUFF, INSTR_RRF_M0RR, 122 INSTR_RRE_RR, INSTR_RRE_RR_OPT,
112 INSTR_RRF_R0RR, INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF, 123 INSTR_RRF_0UFF, INSTR_RRF_F0FF, INSTR_RRF_F0FF2, INSTR_RRF_F0FR,
124 INSTR_RRF_FFRU, INSTR_RRF_FUFF, INSTR_RRF_M0RR, INSTR_RRF_R0RR,
125 INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF, INSTR_RRF_U0RR,
126 INSTR_RRF_UUFF, INSTR_RRR_F0FF, INSTR_RRS_RRRDU,
113 INSTR_RR_FF, INSTR_RR_R0, INSTR_RR_RR, INSTR_RR_U0, INSTR_RR_UR, 127 INSTR_RR_FF, INSTR_RR_R0, INSTR_RR_RR, INSTR_RR_U0, INSTR_RR_UR,
114 INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD, INSTR_RSI_RRP, 128 INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD,
115 INSTR_RSL_R0RD, INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, 129 INSTR_RSI_RRP,
116 INSTR_RSY_RURD, INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, 130 INSTR_RSL_R0RD,
117 INSTR_RS_RRRD, INSTR_RS_RURD, INSTR_RXE_FRRD, INSTR_RXE_RRRD, 131 INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD,
118 INSTR_RXF_FRRDF, INSTR_RXY_FRRD, INSTR_RXY_RRRD, INSTR_RX_FRRD, 132 INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD,
119 INSTR_RX_RRRD, INSTR_RX_URRD, INSTR_SIY_URD, INSTR_SI_URD, 133 INSTR_RS_RURD,
120 INSTR_SSE_RDRD, INSTR_SSF_RRDRD, INSTR_SS_L0RDRD, INSTR_SS_LIRDRD, 134 INSTR_RXE_FRRD, INSTR_RXE_RRRD,
121 INSTR_SS_LLRDRD, INSTR_SS_RRRDRD, INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3, 135 INSTR_RXF_FRRDF,
136 INSTR_RXY_FRRD, INSTR_RXY_RRRD, INSTR_RXY_URRD,
137 INSTR_RX_FRRD, INSTR_RX_RRRD, INSTR_RX_URRD,
138 INSTR_SIL_RDI, INSTR_SIL_RDU,
139 INSTR_SIY_IRD, INSTR_SIY_URD,
140 INSTR_SI_URD,
141 INSTR_SSE_RDRD,
142 INSTR_SSF_RRDRD,
143 INSTR_SS_L0RDRD, INSTR_SS_LIRDRD, INSTR_SS_LLRDRD, INSTR_SS_RRRDRD,
144 INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3,
122 INSTR_S_00, INSTR_S_RD, 145 INSTR_S_00, INSTR_S_RD,
123}; 146};
124 147
@@ -129,7 +152,7 @@ struct operand {
129}; 152};
130 153
131struct insn { 154struct insn {
132 const char name[5]; 155 const char name[6];
133 unsigned char opfrag; 156 unsigned char opfrag;
134 unsigned char format; 157 unsigned char format;
135}; 158};
@@ -170,11 +193,16 @@ static const struct operand operands[] =
170 [U4_12] = { 4, 12, 0 }, 193 [U4_12] = { 4, 12, 0 },
171 [U4_16] = { 4, 16, 0 }, 194 [U4_16] = { 4, 16, 0 },
172 [U4_20] = { 4, 20, 0 }, 195 [U4_20] = { 4, 20, 0 },
196 [U4_32] = { 4, 32, 0 },
173 [U8_8] = { 8, 8, 0 }, 197 [U8_8] = { 8, 8, 0 },
174 [U8_16] = { 8, 16, 0 }, 198 [U8_16] = { 8, 16, 0 },
199 [U8_24] = { 8, 24, 0 },
200 [U8_32] = { 8, 32, 0 },
175 [I16_16] = { 16, 16, OPERAND_SIGNED }, 201 [I16_16] = { 16, 16, OPERAND_SIGNED },
176 [U16_16] = { 16, 16, 0 }, 202 [U16_16] = { 16, 16, 0 },
203 [U16_32] = { 16, 32, 0 },
177 [J16_16] = { 16, 16, OPERAND_PCREL }, 204 [J16_16] = { 16, 16, OPERAND_PCREL },
205 [I16_32] = { 16, 32, OPERAND_SIGNED },
178 [J32_16] = { 32, 16, OPERAND_PCREL }, 206 [J32_16] = { 32, 16, OPERAND_PCREL },
179 [I32_16] = { 32, 16, OPERAND_SIGNED }, 207 [I32_16] = { 32, 16, OPERAND_SIGNED },
180 [U32_16] = { 32, 16, 0 }, 208 [U32_16] = { 32, 16, 0 },
@@ -183,82 +211,93 @@ static const struct operand operands[] =
183}; 211};
184 212
185static const unsigned char formats[][7] = { 213static const unsigned char formats[][7] = {
186 [INSTR_E] = { 0xff, 0,0,0,0,0,0 }, /* e.g. pr */ 214 [INSTR_E] = { 0xff, 0,0,0,0,0,0 },
187 [INSTR_RIE_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 }, /* e.g. brxhg */ 215 [INSTR_RIE_R0UU] = { 0xff, R_8,U16_16,U4_32,0,0,0 },
188 [INSTR_RIL_RP] = { 0x0f, R_8,J32_16,0,0,0,0 }, /* e.g. brasl */ 216 [INSTR_RIE_RRPU] = { 0xff, R_8,R_12,U4_32,J16_16,0,0 },
189 [INSTR_RIL_UP] = { 0x0f, U4_8,J32_16,0,0,0,0 }, /* e.g. brcl */ 217 [INSTR_RIE_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 },
190 [INSTR_RIL_RI] = { 0x0f, R_8,I32_16,0,0,0,0 }, /* e.g. afi */ 218 [INSTR_RIE_RRUUU] = { 0xff, R_8,R_12,U8_16,U8_24,U8_32,0 },
191 [INSTR_RIL_RU] = { 0x0f, R_8,U32_16,0,0,0,0 }, /* e.g. alfi */ 219 [INSTR_RIE_RUPI] = { 0xff, R_8,I8_32,U4_12,J16_16,0,0 },
192 [INSTR_RI_RI] = { 0x0f, R_8,I16_16,0,0,0,0 }, /* e.g. ahi */ 220 [INSTR_RIL_RI] = { 0x0f, R_8,I32_16,0,0,0,0 },
193 [INSTR_RI_RP] = { 0x0f, R_8,J16_16,0,0,0,0 }, /* e.g. brct */ 221 [INSTR_RIL_RP] = { 0x0f, R_8,J32_16,0,0,0,0 },
194 [INSTR_RI_RU] = { 0x0f, R_8,U16_16,0,0,0,0 }, /* e.g. tml */ 222 [INSTR_RIL_RU] = { 0x0f, R_8,U32_16,0,0,0,0 },
195 [INSTR_RI_UP] = { 0x0f, U4_8,J16_16,0,0,0,0 }, /* e.g. brc */ 223 [INSTR_RIL_UP] = { 0x0f, U4_8,J32_16,0,0,0,0 },
196 [INSTR_RRE_00] = { 0xff, 0,0,0,0,0,0 }, /* e.g. palb */ 224 [INSTR_RIS_R0RDU] = { 0xff, R_8,U8_32,D_20,B_16,0,0 },
197 [INSTR_RRE_0R] = { 0xff, R_28,0,0,0,0,0 }, /* e.g. tb */ 225 [INSTR_RIS_RURDI] = { 0xff, R_8,I8_32,U4_12,D_20,B_16,0 },
198 [INSTR_RRE_AA] = { 0xff, A_24,A_28,0,0,0,0 }, /* e.g. cpya */ 226 [INSTR_RIS_RURDU] = { 0xff, R_8,U8_32,U4_12,D_20,B_16,0 },
199 [INSTR_RRE_AR] = { 0xff, A_24,R_28,0,0,0,0 }, /* e.g. sar */ 227 [INSTR_RI_RI] = { 0x0f, R_8,I16_16,0,0,0,0 },
200 [INSTR_RRE_F0] = { 0xff, F_24,0,0,0,0,0 }, /* e.g. sqer */ 228 [INSTR_RI_RP] = { 0x0f, R_8,J16_16,0,0,0,0 },
201 [INSTR_RRE_FF] = { 0xff, F_24,F_28,0,0,0,0 }, /* e.g. debr */ 229 [INSTR_RI_RU] = { 0x0f, R_8,U16_16,0,0,0,0 },
202 [INSTR_RRE_R0] = { 0xff, R_24,0,0,0,0,0 }, /* e.g. ipm */ 230 [INSTR_RI_UP] = { 0x0f, U4_8,J16_16,0,0,0,0 },
203 [INSTR_RRE_RA] = { 0xff, R_24,A_28,0,0,0,0 }, /* e.g. ear */ 231 [INSTR_RRE_00] = { 0xff, 0,0,0,0,0,0 },
204 [INSTR_RRE_RF] = { 0xff, R_24,F_28,0,0,0,0 }, /* e.g. cefbr */ 232 [INSTR_RRE_0R] = { 0xff, R_28,0,0,0,0,0 },
205 [INSTR_RRE_RR] = { 0xff, R_24,R_28,0,0,0,0 }, /* e.g. lura */ 233 [INSTR_RRE_AA] = { 0xff, A_24,A_28,0,0,0,0 },
206 [INSTR_RRE_RR_OPT]= { 0xff, R_24,RO_28,0,0,0,0 }, /* efpc, sfpc */ 234 [INSTR_RRE_AR] = { 0xff, A_24,R_28,0,0,0,0 },
207 [INSTR_RRF_F0FF] = { 0xff, F_16,F_24,F_28,0,0,0 }, /* e.g. madbr */ 235 [INSTR_RRE_F0] = { 0xff, F_24,0,0,0,0,0 },
208 [INSTR_RRF_FUFF] = { 0xff, F_24,F_16,F_28,U4_20,0,0 },/* e.g. didbr */ 236 [INSTR_RRE_FF] = { 0xff, F_24,F_28,0,0,0,0 },
209 [INSTR_RRF_RURR] = { 0xff, R_24,R_28,R_16,U4_20,0,0 },/* e.g. .insn */ 237 [INSTR_RRE_FR] = { 0xff, F_24,R_28,0,0,0,0 },
210 [INSTR_RRF_R0RR] = { 0xff, R_24,R_16,R_28,0,0,0 }, /* e.g. idte */ 238 [INSTR_RRE_R0] = { 0xff, R_24,0,0,0,0,0 },
211 [INSTR_RRF_U0FF] = { 0xff, F_24,U4_16,F_28,0,0,0 }, /* e.g. fixr */ 239 [INSTR_RRE_RA] = { 0xff, R_24,A_28,0,0,0,0 },
212 [INSTR_RRF_U0RF] = { 0xff, R_24,U4_16,F_28,0,0,0 }, /* e.g. cfebr */ 240 [INSTR_RRE_RF] = { 0xff, R_24,F_28,0,0,0,0 },
213 [INSTR_RRF_M0RR] = { 0xff, R_24,R_28,M_16,0,0,0 }, /* e.g. sske */ 241 [INSTR_RRE_RR] = { 0xff, R_24,R_28,0,0,0,0 },
214 [INSTR_RR_FF] = { 0xff, F_8,F_12,0,0,0,0 }, /* e.g. adr */ 242 [INSTR_RRE_RR_OPT]= { 0xff, R_24,RO_28,0,0,0,0 },
215 [INSTR_RR_R0] = { 0xff, R_8, 0,0,0,0,0 }, /* e.g. spm */ 243 [INSTR_RRF_0UFF] = { 0xff, F_24,F_28,U4_20,0,0,0 },
216 [INSTR_RR_RR] = { 0xff, R_8,R_12,0,0,0,0 }, /* e.g. lr */ 244 [INSTR_RRF_F0FF2] = { 0xff, F_24,F_16,F_28,0,0,0 },
217 [INSTR_RR_U0] = { 0xff, U8_8, 0,0,0,0,0 }, /* e.g. svc */ 245 [INSTR_RRF_F0FF] = { 0xff, F_16,F_24,F_28,0,0,0 },
218 [INSTR_RR_UR] = { 0xff, U4_8,R_12,0,0,0,0 }, /* e.g. bcr */ 246 [INSTR_RRF_F0FR] = { 0xff, F_24,F_16,R_28,0,0,0 },
219 [INSTR_RSE_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 }, /* e.g. lmh */ 247 [INSTR_RRF_FFRU] = { 0xff, F_24,F_16,R_28,U4_20,0,0 },
220 [INSTR_RSE_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 }, /* e.g. lmh */ 248 [INSTR_RRF_FUFF] = { 0xff, F_24,F_16,F_28,U4_20,0,0 },
221 [INSTR_RSE_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, /* e.g. icmh */ 249 [INSTR_RRF_M0RR] = { 0xff, R_24,R_28,M_16,0,0,0 },
222 [INSTR_RSL_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 }, /* e.g. tp */ 250 [INSTR_RRF_R0RR] = { 0xff, R_24,R_16,R_28,0,0,0 },
223 [INSTR_RSI_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 }, /* e.g. brxh */ 251 [INSTR_RRF_RURR] = { 0xff, R_24,R_28,R_16,U4_20,0,0 },
224 [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 },/* e.g. stmy */ 252 [INSTR_RRF_U0FF] = { 0xff, F_24,U4_16,F_28,0,0,0 },
253 [INSTR_RRF_U0RF] = { 0xff, R_24,U4_16,F_28,0,0,0 },
254 [INSTR_RRF_U0RR] = { 0xff, R_24,R_28,U4_16,0,0,0 },
255 [INSTR_RRF_UUFF] = { 0xff, F_24,U4_16,F_28,U4_20,0,0 },
256 [INSTR_RRR_F0FF] = { 0xff, F_24,F_28,F_16,0,0,0 },
257 [INSTR_RRS_RRRDU] = { 0xff, R_8,R_12,U4_32,D_20,B_16,0 },
258 [INSTR_RR_FF] = { 0xff, F_8,F_12,0,0,0,0 },
259 [INSTR_RR_R0] = { 0xff, R_8, 0,0,0,0,0 },
260 [INSTR_RR_RR] = { 0xff, R_8,R_12,0,0,0,0 },
261 [INSTR_RR_U0] = { 0xff, U8_8, 0,0,0,0,0 },
262 [INSTR_RR_UR] = { 0xff, U4_8,R_12,0,0,0,0 },
263 [INSTR_RSE_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 },
264 [INSTR_RSE_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 },
265 [INSTR_RSE_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 },
266 [INSTR_RSI_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 },
267 [INSTR_RSL_R0RD] = { 0xff, D_20,L4_8,B_16,0,0,0 },
268 [INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 },
269 [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 },
270 [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 },
225 [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 }, 271 [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 },
226 /* e.g. icmh */ 272 [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 },
227 [INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 },/* e.g. lamy */ 273 [INSTR_RS_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 },
228 [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 },/* e.g. lamy */ 274 [INSTR_RS_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 },
229 [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 }, /* e.g. lam */ 275 [INSTR_RS_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 },
230 [INSTR_RS_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 }, /* e.g. lctl */ 276 [INSTR_RS_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 },
231 [INSTR_RS_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 }, /* e.g. sll */ 277 [INSTR_RXE_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 },
232 [INSTR_RS_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 }, /* e.g. cs */ 278 [INSTR_RXE_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 },
233 [INSTR_RS_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, /* e.g. icm */
234 [INSTR_RXE_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 }, /* e.g. axbr */
235 [INSTR_RXE_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 }, /* e.g. lg */
236 [INSTR_RXF_FRRDF] = { 0xff, F_32,F_8,D_20,X_12,B_16,0 }, 279 [INSTR_RXF_FRRDF] = { 0xff, F_32,F_8,D_20,X_12,B_16,0 },
237 /* e.g. madb */ 280 [INSTR_RXY_FRRD] = { 0xff, F_8,D20_20,X_12,B_16,0,0 },
238 [INSTR_RXY_RRRD] = { 0xff, R_8,D20_20,X_12,B_16,0,0 },/* e.g. ly */ 281 [INSTR_RXY_RRRD] = { 0xff, R_8,D20_20,X_12,B_16,0,0 },
239 [INSTR_RXY_FRRD] = { 0xff, F_8,D20_20,X_12,B_16,0,0 },/* e.g. ley */ 282 [INSTR_RXY_URRD] = { 0xff, U4_8,D20_20,X_12,B_16,0,0 },
240 [INSTR_RX_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 }, /* e.g. ae */ 283 [INSTR_RX_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 },
241 [INSTR_RX_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 }, /* e.g. l */ 284 [INSTR_RX_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 },
242 [INSTR_RX_URRD] = { 0xff, U4_8,D_20,X_12,B_16,0,0 }, /* e.g. bc */ 285 [INSTR_RX_URRD] = { 0xff, U4_8,D_20,X_12,B_16,0,0 },
243 [INSTR_SI_URD] = { 0xff, D_20,B_16,U8_8,0,0,0 }, /* e.g. cli */ 286 [INSTR_SIL_RDI] = { 0xff, D_20,B_16,I16_32,0,0,0 },
244 [INSTR_SIY_URD] = { 0xff, D20_20,B_16,U8_8,0,0,0 }, /* e.g. tmy */ 287 [INSTR_SIL_RDU] = { 0xff, D_20,B_16,U16_32,0,0,0 },
245 [INSTR_SSE_RDRD] = { 0xff, D_20,B_16,D_36,B_32,0,0 }, /* e.g. mvsdk */ 288 [INSTR_SIY_IRD] = { 0xff, D20_20,B_16,I8_8,0,0,0 },
289 [INSTR_SIY_URD] = { 0xff, D20_20,B_16,U8_8,0,0,0 },
290 [INSTR_SI_URD] = { 0xff, D_20,B_16,U8_8,0,0,0 },
291 [INSTR_SSE_RDRD] = { 0xff, D_20,B_16,D_36,B_32,0,0 },
292 [INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 },
246 [INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 }, 293 [INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 },
247 /* e.g. mvc */
248 [INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 }, 294 [INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 },
249 /* e.g. srp */
250 [INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 }, 295 [INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 },
251 /* e.g. pack */
252 [INSTR_SS_RRRDRD] = { 0xff, D_20,R_8,B_16,D_36,B_32,R_12 },
253 /* e.g. mvck */
254 [INSTR_SS_RRRDRD2]= { 0xff, R_8,D_20,B_16,R_12,D_36,B_32 }, 296 [INSTR_SS_RRRDRD2]= { 0xff, R_8,D_20,B_16,R_12,D_36,B_32 },
255 /* e.g. plo */
256 [INSTR_SS_RRRDRD3]= { 0xff, R_8,R_12,D_20,B_16,D_36,B_32 }, 297 [INSTR_SS_RRRDRD3]= { 0xff, R_8,R_12,D_20,B_16,D_36,B_32 },
257 /* e.g. lmd */ 298 [INSTR_SS_RRRDRD] = { 0xff, D_20,R_8,B_16,D_36,B_32,R_12 },
258 [INSTR_S_00] = { 0xff, 0,0,0,0,0,0 }, /* e.g. hsch */ 299 [INSTR_S_00] = { 0xff, 0,0,0,0,0,0 },
259 [INSTR_S_RD] = { 0xff, D_20,B_16,0,0,0,0 }, /* e.g. lpsw */ 300 [INSTR_S_RD] = { 0xff, D_20,B_16,0,0,0,0 },
260 [INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 },
261 /* e.g. mvcos */
262}; 301};
263 302
264static struct insn opcode[] = { 303static struct insn opcode[] = {
@@ -454,6 +493,8 @@ static struct insn opcode[] = {
454static struct insn opcode_01[] = { 493static struct insn opcode_01[] = {
455#ifdef CONFIG_64BIT 494#ifdef CONFIG_64BIT
456 { "sam64", 0x0e, INSTR_E }, 495 { "sam64", 0x0e, INSTR_E },
496 { "pfpo", 0x0a, INSTR_E },
497 { "ptff", 0x04, INSTR_E },
457#endif 498#endif
458 { "pr", 0x01, INSTR_E }, 499 { "pr", 0x01, INSTR_E },
459 { "upt", 0x02, INSTR_E }, 500 { "upt", 0x02, INSTR_E },
@@ -519,6 +560,8 @@ static struct insn opcode_b2[] = {
519 { "cutfu", 0xa7, INSTR_RRF_M0RR }, 560 { "cutfu", 0xa7, INSTR_RRF_M0RR },
520 { "stfle", 0xb0, INSTR_S_RD }, 561 { "stfle", 0xb0, INSTR_S_RD },
521 { "lpswe", 0xb2, INSTR_S_RD }, 562 { "lpswe", 0xb2, INSTR_S_RD },
563 { "srnmt", 0xb9, INSTR_S_RD },
564 { "lfas", 0xbd, INSTR_S_RD },
522#endif 565#endif
523 { "stidp", 0x02, INSTR_S_RD }, 566 { "stidp", 0x02, INSTR_S_RD },
524 { "sck", 0x04, INSTR_S_RD }, 567 { "sck", 0x04, INSTR_S_RD },
@@ -589,7 +632,6 @@ static struct insn opcode_b2[] = {
589 { "clst", 0x5d, INSTR_RRE_RR }, 632 { "clst", 0x5d, INSTR_RRE_RR },
590 { "srst", 0x5e, INSTR_RRE_RR }, 633 { "srst", 0x5e, INSTR_RRE_RR },
591 { "cmpsc", 0x63, INSTR_RRE_RR }, 634 { "cmpsc", 0x63, INSTR_RRE_RR },
592 { "cmpsc", 0x63, INSTR_RRE_RR },
593 { "siga", 0x74, INSTR_S_RD }, 635 { "siga", 0x74, INSTR_S_RD },
594 { "xsch", 0x76, INSTR_S_00 }, 636 { "xsch", 0x76, INSTR_S_00 },
595 { "rp", 0x77, INSTR_S_RD }, 637 { "rp", 0x77, INSTR_S_RD },
@@ -630,6 +672,57 @@ static struct insn opcode_b3[] = {
630 { "cger", 0xc8, INSTR_RRF_U0RF }, 672 { "cger", 0xc8, INSTR_RRF_U0RF },
631 { "cgdr", 0xc9, INSTR_RRF_U0RF }, 673 { "cgdr", 0xc9, INSTR_RRF_U0RF },
632 { "cgxr", 0xca, INSTR_RRF_U0RF }, 674 { "cgxr", 0xca, INSTR_RRF_U0RF },
675 { "lpdfr", 0x70, INSTR_RRE_FF },
676 { "lndfr", 0x71, INSTR_RRE_FF },
677 { "cpsdr", 0x72, INSTR_RRF_F0FF2 },
678 { "lcdfr", 0x73, INSTR_RRE_FF },
679 { "ldgr", 0xc1, INSTR_RRE_FR },
680 { "lgdr", 0xcd, INSTR_RRE_RF },
681 { "adtr", 0xd2, INSTR_RRR_F0FF },
682 { "axtr", 0xda, INSTR_RRR_F0FF },
683 { "cdtr", 0xe4, INSTR_RRE_FF },
684 { "cxtr", 0xec, INSTR_RRE_FF },
685 { "kdtr", 0xe0, INSTR_RRE_FF },
686 { "kxtr", 0xe8, INSTR_RRE_FF },
687 { "cedtr", 0xf4, INSTR_RRE_FF },
688 { "cextr", 0xfc, INSTR_RRE_FF },
689 { "cdgtr", 0xf1, INSTR_RRE_FR },
690 { "cxgtr", 0xf9, INSTR_RRE_FR },
691 { "cdstr", 0xf3, INSTR_RRE_FR },
692 { "cxstr", 0xfb, INSTR_RRE_FR },
693 { "cdutr", 0xf2, INSTR_RRE_FR },
694 { "cxutr", 0xfa, INSTR_RRE_FR },
695 { "cgdtr", 0xe1, INSTR_RRF_U0RF },
696 { "cgxtr", 0xe9, INSTR_RRF_U0RF },
697 { "csdtr", 0xe3, INSTR_RRE_RF },
698 { "csxtr", 0xeb, INSTR_RRE_RF },
699 { "cudtr", 0xe2, INSTR_RRE_RF },
700 { "cuxtr", 0xea, INSTR_RRE_RF },
701 { "ddtr", 0xd1, INSTR_RRR_F0FF },
702 { "dxtr", 0xd9, INSTR_RRR_F0FF },
703 { "eedtr", 0xe5, INSTR_RRE_RF },
704 { "eextr", 0xed, INSTR_RRE_RF },
705 { "esdtr", 0xe7, INSTR_RRE_RF },
706 { "esxtr", 0xef, INSTR_RRE_RF },
707 { "iedtr", 0xf6, INSTR_RRF_F0FR },
708 { "iextr", 0xfe, INSTR_RRF_F0FR },
709 { "ltdtr", 0xd6, INSTR_RRE_FF },
710 { "ltxtr", 0xde, INSTR_RRE_FF },
711 { "fidtr", 0xd7, INSTR_RRF_UUFF },
712 { "fixtr", 0xdf, INSTR_RRF_UUFF },
713 { "ldetr", 0xd4, INSTR_RRF_0UFF },
714 { "lxdtr", 0xdc, INSTR_RRF_0UFF },
715 { "ledtr", 0xd5, INSTR_RRF_UUFF },
716 { "ldxtr", 0xdd, INSTR_RRF_UUFF },
717 { "mdtr", 0xd0, INSTR_RRR_F0FF },
718 { "mxtr", 0xd8, INSTR_RRR_F0FF },
719 { "qadtr", 0xf5, INSTR_RRF_FUFF },
720 { "qaxtr", 0xfd, INSTR_RRF_FUFF },
721 { "rrdtr", 0xf7, INSTR_RRF_FFRU },
722 { "rrxtr", 0xff, INSTR_RRF_FFRU },
723 { "sfasr", 0x85, INSTR_RRE_R0 },
724 { "sdtr", 0xd3, INSTR_RRR_F0FF },
725 { "sxtr", 0xdb, INSTR_RRR_F0FF },
633#endif 726#endif
634 { "lpebr", 0x00, INSTR_RRE_FF }, 727 { "lpebr", 0x00, INSTR_RRE_FF },
635 { "lnebr", 0x01, INSTR_RRE_FF }, 728 { "lnebr", 0x01, INSTR_RRE_FF },
@@ -780,6 +873,14 @@ static struct insn opcode_b9[] = {
780 { "cu24", 0xb1, INSTR_RRF_M0RR }, 873 { "cu24", 0xb1, INSTR_RRF_M0RR },
781 { "cu41", 0xb2, INSTR_RRF_M0RR }, 874 { "cu41", 0xb2, INSTR_RRF_M0RR },
782 { "cu42", 0xb3, INSTR_RRF_M0RR }, 875 { "cu42", 0xb3, INSTR_RRF_M0RR },
876 { "crt", 0x72, INSTR_RRF_U0RR },
877 { "cgrt", 0x60, INSTR_RRF_U0RR },
878 { "clrt", 0x73, INSTR_RRF_U0RR },
879 { "clgrt", 0x61, INSTR_RRF_U0RR },
880 { "ptf", 0xa2, INSTR_RRE_R0 },
881 { "pfmf", 0xaf, INSTR_RRE_RR },
882 { "trte", 0xbf, INSTR_RRF_M0RR },
883 { "trtre", 0xbd, INSTR_RRF_M0RR },
783#endif 884#endif
784 { "kmac", 0x1e, INSTR_RRE_RR }, 885 { "kmac", 0x1e, INSTR_RRE_RR },
785 { "lrvr", 0x1f, INSTR_RRE_RR }, 886 { "lrvr", 0x1f, INSTR_RRE_RR },
@@ -835,6 +936,43 @@ static struct insn opcode_c2[] = {
835 { "cfi", 0x0d, INSTR_RIL_RI }, 936 { "cfi", 0x0d, INSTR_RIL_RI },
836 { "clgfi", 0x0e, INSTR_RIL_RU }, 937 { "clgfi", 0x0e, INSTR_RIL_RU },
837 { "clfi", 0x0f, INSTR_RIL_RU }, 938 { "clfi", 0x0f, INSTR_RIL_RU },
939 { "msfi", 0x01, INSTR_RIL_RI },
940 { "msgfi", 0x00, INSTR_RIL_RI },
941#endif
942 { "", 0, INSTR_INVALID }
943};
944
945static struct insn opcode_c4[] = {
946#ifdef CONFIG_64BIT
947 { "lrl", 0x0d, INSTR_RIL_RP },
948 { "lgrl", 0x08, INSTR_RIL_RP },
949 { "lgfrl", 0x0c, INSTR_RIL_RP },
950 { "lhrl", 0x05, INSTR_RIL_RP },
951 { "lghrl", 0x04, INSTR_RIL_RP },
952 { "llgfrl", 0x0e, INSTR_RIL_RP },
953 { "llhrl", 0x02, INSTR_RIL_RP },
954 { "llghrl", 0x06, INSTR_RIL_RP },
955 { "strl", 0x0f, INSTR_RIL_RP },
956 { "stgrl", 0x0b, INSTR_RIL_RP },
957 { "sthrl", 0x07, INSTR_RIL_RP },
958#endif
959 { "", 0, INSTR_INVALID }
960};
961
962static struct insn opcode_c6[] = {
963#ifdef CONFIG_64BIT
964 { "crl", 0x0d, INSTR_RIL_RP },
965 { "cgrl", 0x08, INSTR_RIL_RP },
966 { "cgfrl", 0x0c, INSTR_RIL_RP },
967 { "chrl", 0x05, INSTR_RIL_RP },
968 { "cghrl", 0x04, INSTR_RIL_RP },
969 { "clrl", 0x0f, INSTR_RIL_RP },
970 { "clgrl", 0x0a, INSTR_RIL_RP },
971 { "clgfrl", 0x0e, INSTR_RIL_RP },
972 { "clhrl", 0x07, INSTR_RIL_RP },
973 { "clghrl", 0x06, INSTR_RIL_RP },
974 { "pfdrl", 0x02, INSTR_RIL_UP },
975 { "exrl", 0x00, INSTR_RIL_RP },
838#endif 976#endif
839 { "", 0, INSTR_INVALID } 977 { "", 0, INSTR_INVALID }
840}; 978};
@@ -842,6 +980,8 @@ static struct insn opcode_c2[] = {
842static struct insn opcode_c8[] = { 980static struct insn opcode_c8[] = {
843#ifdef CONFIG_64BIT 981#ifdef CONFIG_64BIT
844 { "mvcos", 0x00, INSTR_SSF_RRDRD }, 982 { "mvcos", 0x00, INSTR_SSF_RRDRD },
983 { "ectg", 0x01, INSTR_SSF_RRDRD },
984 { "csst", 0x02, INSTR_SSF_RRDRD },
845#endif 985#endif
846 { "", 0, INSTR_INVALID } 986 { "", 0, INSTR_INVALID }
847}; 987};
@@ -917,6 +1057,12 @@ static struct insn opcode_e3[] = {
917 { "llgh", 0x91, INSTR_RXY_RRRD }, 1057 { "llgh", 0x91, INSTR_RXY_RRRD },
918 { "llc", 0x94, INSTR_RXY_RRRD }, 1058 { "llc", 0x94, INSTR_RXY_RRRD },
919 { "llh", 0x95, INSTR_RXY_RRRD }, 1059 { "llh", 0x95, INSTR_RXY_RRRD },
1060 { "cgh", 0x34, INSTR_RXY_RRRD },
1061 { "laey", 0x75, INSTR_RXY_RRRD },
1062 { "ltgf", 0x32, INSTR_RXY_RRRD },
1063 { "mfy", 0x5c, INSTR_RXY_RRRD },
1064 { "mhy", 0x7c, INSTR_RXY_RRRD },
1065 { "pfd", 0x36, INSTR_RXY_URRD },
920#endif 1066#endif
921 { "lrv", 0x1e, INSTR_RXY_RRRD }, 1067 { "lrv", 0x1e, INSTR_RXY_RRRD },
922 { "lrvh", 0x1f, INSTR_RXY_RRRD }, 1068 { "lrvh", 0x1f, INSTR_RXY_RRRD },
@@ -931,6 +1077,15 @@ static struct insn opcode_e3[] = {
931static struct insn opcode_e5[] = { 1077static struct insn opcode_e5[] = {
932#ifdef CONFIG_64BIT 1078#ifdef CONFIG_64BIT
933 { "strag", 0x02, INSTR_SSE_RDRD }, 1079 { "strag", 0x02, INSTR_SSE_RDRD },
1080 { "chhsi", 0x54, INSTR_SIL_RDI },
1081 { "chsi", 0x5c, INSTR_SIL_RDI },
1082 { "cghsi", 0x58, INSTR_SIL_RDI },
1083 { "clhhsi", 0x55, INSTR_SIL_RDU },
1084 { "clfhsi", 0x5d, INSTR_SIL_RDU },
1085 { "clghsi", 0x59, INSTR_SIL_RDU },
1086 { "mvhhi", 0x44, INSTR_SIL_RDI },
1087 { "mvhi", 0x4c, INSTR_SIL_RDI },
1088 { "mvghi", 0x48, INSTR_SIL_RDI },
934#endif 1089#endif
935 { "lasp", 0x00, INSTR_SSE_RDRD }, 1090 { "lasp", 0x00, INSTR_SSE_RDRD },
936 { "tprot", 0x01, INSTR_SSE_RDRD }, 1091 { "tprot", 0x01, INSTR_SSE_RDRD },
@@ -977,6 +1132,11 @@ static struct insn opcode_eb[] = {
977 { "lmy", 0x98, INSTR_RSY_RRRD }, 1132 { "lmy", 0x98, INSTR_RSY_RRRD },
978 { "lamy", 0x9a, INSTR_RSY_AARD }, 1133 { "lamy", 0x9a, INSTR_RSY_AARD },
979 { "stamy", 0x9b, INSTR_RSY_AARD }, 1134 { "stamy", 0x9b, INSTR_RSY_AARD },
1135 { "asi", 0x6a, INSTR_SIY_IRD },
1136 { "agsi", 0x7a, INSTR_SIY_IRD },
1137 { "alsi", 0x6e, INSTR_SIY_IRD },
1138 { "algsi", 0x7e, INSTR_SIY_IRD },
1139 { "ecag", 0x4c, INSTR_RSY_RRRD },
980#endif 1140#endif
981 { "rll", 0x1d, INSTR_RSY_RRRD }, 1141 { "rll", 0x1d, INSTR_RSY_RRRD },
982 { "mvclu", 0x8e, INSTR_RSY_RRRD }, 1142 { "mvclu", 0x8e, INSTR_RSY_RRRD },
@@ -988,6 +1148,30 @@ static struct insn opcode_ec[] = {
988#ifdef CONFIG_64BIT 1148#ifdef CONFIG_64BIT
989 { "brxhg", 0x44, INSTR_RIE_RRP }, 1149 { "brxhg", 0x44, INSTR_RIE_RRP },
990 { "brxlg", 0x45, INSTR_RIE_RRP }, 1150 { "brxlg", 0x45, INSTR_RIE_RRP },
1151 { "crb", 0xf6, INSTR_RRS_RRRDU },
1152 { "cgrb", 0xe4, INSTR_RRS_RRRDU },
1153 { "crj", 0x76, INSTR_RIE_RRPU },
1154 { "cgrj", 0x64, INSTR_RIE_RRPU },
1155 { "cib", 0xfe, INSTR_RIS_RURDI },
1156 { "cgib", 0xfc, INSTR_RIS_RURDI },
1157 { "cij", 0x7e, INSTR_RIE_RUPI },
1158 { "cgij", 0x7c, INSTR_RIE_RUPI },
1159 { "cit", 0x72, INSTR_RIE_R0IU },
1160 { "cgit", 0x70, INSTR_RIE_R0IU },
1161 { "clrb", 0xf7, INSTR_RRS_RRRDU },
1162 { "clgrb", 0xe5, INSTR_RRS_RRRDU },
1163 { "clrj", 0x77, INSTR_RIE_RRPU },
1164 { "clgrj", 0x65, INSTR_RIE_RRPU },
1165 { "clib", 0xff, INSTR_RIS_RURDU },
1166 { "clgib", 0xfd, INSTR_RIS_RURDU },
1167 { "clij", 0x7f, INSTR_RIE_RUPU },
1168 { "clgij", 0x7d, INSTR_RIE_RUPU },
1169 { "clfit", 0x73, INSTR_RIE_R0UU },
1170 { "clgit", 0x71, INSTR_RIE_R0UU },
1171 { "rnsbg", 0x54, INSTR_RIE_RRUUU },
1172 { "rxsbg", 0x57, INSTR_RIE_RRUUU },
1173 { "rosbg", 0x56, INSTR_RIE_RRUUU },
1174 { "risbg", 0x55, INSTR_RIE_RRUUU },
991#endif 1175#endif
992 { "", 0, INSTR_INVALID } 1176 { "", 0, INSTR_INVALID }
993}; 1177};
@@ -1004,6 +1188,16 @@ static struct insn opcode_ed[] = {
1004 { "ldy", 0x65, INSTR_RXY_FRRD }, 1188 { "ldy", 0x65, INSTR_RXY_FRRD },
1005 { "stey", 0x66, INSTR_RXY_FRRD }, 1189 { "stey", 0x66, INSTR_RXY_FRRD },
1006 { "stdy", 0x67, INSTR_RXY_FRRD }, 1190 { "stdy", 0x67, INSTR_RXY_FRRD },
1191 { "sldt", 0x40, INSTR_RXF_FRRDF },
1192 { "slxt", 0x48, INSTR_RXF_FRRDF },
1193 { "srdt", 0x41, INSTR_RXF_FRRDF },
1194 { "srxt", 0x49, INSTR_RXF_FRRDF },
1195 { "tdcet", 0x50, INSTR_RXE_FRRD },
1196 { "tdcdt", 0x54, INSTR_RXE_FRRD },
1197 { "tdcxt", 0x58, INSTR_RXE_FRRD },
1198 { "tdget", 0x51, INSTR_RXE_FRRD },
1199 { "tdgdt", 0x55, INSTR_RXE_FRRD },
1200 { "tdgxt", 0x59, INSTR_RXE_FRRD },
1007#endif 1201#endif
1008 { "ldeb", 0x04, INSTR_RXE_FRRD }, 1202 { "ldeb", 0x04, INSTR_RXE_FRRD },
1009 { "lxdb", 0x05, INSTR_RXE_FRRD }, 1203 { "lxdb", 0x05, INSTR_RXE_FRRD },
@@ -1037,6 +1231,7 @@ static struct insn opcode_ed[] = {
1037 { "mae", 0x2e, INSTR_RXF_FRRDF }, 1231 { "mae", 0x2e, INSTR_RXF_FRRDF },
1038 { "mse", 0x2f, INSTR_RXF_FRRDF }, 1232 { "mse", 0x2f, INSTR_RXF_FRRDF },
1039 { "sqe", 0x34, INSTR_RXE_FRRD }, 1233 { "sqe", 0x34, INSTR_RXE_FRRD },
1234 { "sqd", 0x35, INSTR_RXE_FRRD },
1040 { "mee", 0x37, INSTR_RXE_FRRD }, 1235 { "mee", 0x37, INSTR_RXE_FRRD },
1041 { "mad", 0x3e, INSTR_RXF_FRRDF }, 1236 { "mad", 0x3e, INSTR_RXF_FRRDF },
1042 { "msd", 0x3f, INSTR_RXF_FRRDF }, 1237 { "msd", 0x3f, INSTR_RXF_FRRDF },
@@ -1117,6 +1312,12 @@ static struct insn *find_insn(unsigned char *code)
1117 case 0xc2: 1312 case 0xc2:
1118 table = opcode_c2; 1313 table = opcode_c2;
1119 break; 1314 break;
1315 case 0xc4:
1316 table = opcode_c4;
1317 break;
1318 case 0xc6:
1319 table = opcode_c6;
1320 break;
1120 case 0xc8: 1321 case 0xc8:
1121 table = opcode_c8; 1322 table = opcode_c8;
1122 break; 1323 break;
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index e49e9e0c69f..31d618a443a 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -214,10 +214,13 @@ static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE);
214 214
215static noinline __init void detect_machine_type(void) 215static noinline __init void detect_machine_type(void)
216{ 216{
217 /* No VM information? Looks like LPAR */ 217 /* Check current-configuration-level */
218 if (stsi(&vmms, 3, 2, 2) == -ENOSYS) 218 if ((stsi(NULL, 0, 0, 0) >> 28) <= 2) {
219 S390_lowcore.machine_flags |= MACHINE_FLAG_LPAR;
219 return; 220 return;
220 if (!vmms.count) 221 }
222 /* Get virtual-machine cpu information. */
223 if (stsi(&vmms, 3, 2, 2) == -ENOSYS || !vmms.count)
221 return; 224 return;
222 225
223 /* Running under KVM? If not we assume z/VM */ 226 /* Running under KVM? If not we assume z/VM */
@@ -402,8 +405,19 @@ static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t))
402 405
403static void __init setup_boot_command_line(void) 406static void __init setup_boot_command_line(void)
404{ 407{
408 int i;
409
410 /* convert arch command line to ascii */
411 for (i = 0; i < ARCH_COMMAND_LINE_SIZE; i++)
412 if (COMMAND_LINE[i] & 0x80)
413 break;
414 if (i < ARCH_COMMAND_LINE_SIZE)
415 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
416 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE-1] = 0;
417
405 /* copy arch command line */ 418 /* copy arch command line */
406 strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); 419 strlcpy(boot_command_line, strstrip(COMMAND_LINE),
420 ARCH_COMMAND_LINE_SIZE);
407 421
408 /* append IPL PARM data to the boot command line */ 422 /* append IPL PARM data to the boot command line */
409 if (MACHINE_IS_VM) 423 if (MACHINE_IS_VM)
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index e8ef21c51bb..4348f9bc539 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -13,7 +13,6 @@
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <asm/cache.h> 15#include <asm/cache.h>
16#include <asm/lowcore.h>
17#include <asm/errno.h> 16#include <asm/errno.h>
18#include <asm/ptrace.h> 17#include <asm/ptrace.h>
19#include <asm/thread_info.h> 18#include <asm/thread_info.h>
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index f33658f09dd..29fd0f1e6ec 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -9,11 +9,9 @@
9 * Heiko Carstens <heiko.carstens@de.ibm.com> 9 * Heiko Carstens <heiko.carstens@de.ibm.com>
10 */ 10 */
11 11
12#include <linux/sys.h>
13#include <linux/linkage.h> 12#include <linux/linkage.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <asm/cache.h> 14#include <asm/cache.h>
16#include <asm/lowcore.h>
17#include <asm/errno.h> 15#include <asm/errno.h>
18#include <asm/ptrace.h> 16#include <asm/ptrace.h>
19#include <asm/thread_info.h> 17#include <asm/thread_info.h>
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index 5a82bc68193..6a83d058131 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -13,7 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/types.h> 14#include <linux/types.h>
15#include <trace/syscall.h> 15#include <trace/syscall.h>
16#include <asm/lowcore.h> 16#include <asm/asm-offsets.h>
17 17
18#ifdef CONFIG_DYNAMIC_FTRACE 18#ifdef CONFIG_DYNAMIC_FTRACE
19 19
@@ -200,13 +200,3 @@ out:
200 return parent; 200 return parent;
201} 201}
202#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 202#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
203
204#ifdef CONFIG_FTRACE_SYSCALLS
205
206extern unsigned int sys_call_table[];
207
208unsigned long __init arch_syscall_addr(int nr)
209{
210 return (unsigned long)sys_call_table[nr];
211}
212#endif
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index c52b4f7742f..ca4a62bd862 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright IBM Corp. 1999,2009 2 * Copyright IBM Corp. 1999,2010
3 * 3 *
4 * Author(s): Hartmut Penner <hp@de.ibm.com> 4 * Author(s): Hartmut Penner <hp@de.ibm.com>
5 * Martin Schwidefsky <schwidefsky@de.ibm.com> 5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -22,12 +22,9 @@
22 */ 22 */
23 23
24#include <linux/init.h> 24#include <linux/init.h>
25#include <asm/setup.h>
26#include <asm/lowcore.h>
27#include <asm/asm-offsets.h> 25#include <asm/asm-offsets.h>
28#include <asm/thread_info.h> 26#include <asm/thread_info.h>
29#include <asm/page.h> 27#include <asm/page.h>
30#include <asm/cpu.h>
31 28
32#ifdef CONFIG_64BIT 29#ifdef CONFIG_64BIT
33#define ARCH_OFFSET 4 30#define ARCH_OFFSET 4
@@ -288,19 +285,7 @@ iplstart:
288 bz .Lagain1 # skip dateset trailer 285 bz .Lagain1 # skip dateset trailer
289 la %r5,0(%r4,%r2) 286 la %r5,0(%r4,%r2)
290 lr %r3,%r2 287 lr %r3,%r2
291.Lidebc: 288 la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
292 tm 0(%r5),0x80 # high order bit set ?
293 bo .Ldocv # yes -> convert from EBCDIC
294 ahi %r5,-1
295 bct %r3,.Lidebc
296 b .Lnocv
297.Ldocv:
298 l %r3,.Lcvtab
299 tr 0(256,%r4),0(%r3) # convert parameters to ascii
300 tr 256(256,%r4),0(%r3)
301 tr 512(256,%r4),0(%r3)
302 tr 768(122,%r4),0(%r3)
303.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
304 mvc 0(256,%r3),0(%r4) 289 mvc 0(256,%r3),0(%r4)
305 mvc 256(256,%r3),256(%r4) 290 mvc 256(256,%r3),256(%r4)
306 mvc 512(256,%r3),512(%r4) 291 mvc 512(256,%r3),512(%r4)
@@ -384,7 +369,6 @@ iplstart:
384.Linitrd:.long _end + 0x400000 # default address of initrd 369.Linitrd:.long _end + 0x400000 # default address of initrd
385.Lparm: .long PARMAREA 370.Lparm: .long PARMAREA
386.Lstartup: .long startup 371.Lstartup: .long startup
387.Lcvtab:.long _ebcasc # ebcdic to ascii table
388.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 372.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
389 .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6 373 .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
390 .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" 374 .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
@@ -417,13 +401,10 @@ start:
417.sk8x8: 401.sk8x8:
418 mvc 0(240,%r8),0(%r9) # copy iplparms into buffer 402 mvc 0(240,%r8),0(%r9) # copy iplparms into buffer
419.gotr: 403.gotr:
420 l %r10,.tbl # EBCDIC to ASCII table
421 tr 0(240,%r8),0(%r10)
422 slr %r0,%r0 404 slr %r0,%r0
423 st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11) 405 st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
424 st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11) 406 st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
425 j startup # continue with startup 407 j startup # continue with startup
426.tbl: .long _ebcasc # translate table
427.cmd: .long COMMAND_LINE # address of command line buffer 408.cmd: .long COMMAND_LINE # address of command line buffer
428.parm: .long PARMAREA 409.parm: .long PARMAREA
429.lowcase: 410.lowcase:
@@ -467,16 +448,15 @@ start:
467# or linload or SALIPL 448# or linload or SALIPL
468# 449#
469 .org 0x10000 450 .org 0x10000
470startup:basr %r13,0 # get base 451 .globl startup
452startup:
453 basr %r13,0 # get base
471.LPG0: 454.LPG0:
472 xc 0x200(256),0x200 # partially clear lowcore 455 xc 0x200(256),0x200 # partially clear lowcore
473 xc 0x300(256),0x300 456 xc 0x300(256),0x300
474 l %r1,5f-.LPG0(%r13) 457 stck __LC_LAST_UPDATE_CLOCK
475 stck 0(%r1) 458 spt 5f-.LPG0(%r13)
476 spt 6f-.LPG0(%r13) 459 mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
477 mvc __LC_LAST_UPDATE_CLOCK(8),0(%r1)
478 mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
479 mvc __LC_EXIT_TIMER(8),5f-.LPG0(%r13)
480#ifndef CONFIG_MARCH_G5 460#ifndef CONFIG_MARCH_G5
481 # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} 461 # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
482 xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST 462 xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
@@ -494,7 +474,6 @@ startup:basr %r13,0 # get base
494 cl %r0,2f+12-.LPG0(%r13) 474 cl %r0,2f+12-.LPG0(%r13)
495 je 3f 475 je 3f
4961: l %r15,.Lstack-.LPG0(%r13) 4761: l %r15,.Lstack-.LPG0(%r13)
497 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
498 ahi %r15,-96 477 ahi %r15,-96
499 la %r2,.Lals_string-.LPG0(%r13) 478 la %r2,.Lals_string-.LPG0(%r13)
500 l %r3,.Lsclp_print-.LPG0(%r13) 479 l %r3,.Lsclp_print-.LPG0(%r13)
@@ -505,7 +484,7 @@ startup:basr %r13,0 # get base
505.Lsclp_print: 484.Lsclp_print:
506 .long _sclp_print_early 485 .long _sclp_print_early
507.Lstack: 486.Lstack:
508 .long init_thread_union 487 .long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
509 .align 16 488 .align 16
5102: .long 0x000a0000,0x8badcccc 4892: .long 0x000a0000,0x8badcccc
511#if defined(CONFIG_64BIT) 490#if defined(CONFIG_64BIT)
@@ -532,13 +511,22 @@ startup:basr %r13,0 # get base
5323: 5113:
533#endif 512#endif
534 513
514#ifdef CONFIG_64BIT
515 mvi __LC_AR_MODE_ID,1 # set esame flag
516 slr %r0,%r0 # set cpuid to zero
517 lhi %r1,2 # mode 2 = esame (dump)
518 sigp %r1,%r0,0x12 # switch to esame mode
519 sam64 # switch to 64 bit mode
520 jg startup_continue
521#else
522 mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
535 l %r13,4f-.LPG0(%r13) 523 l %r13,4f-.LPG0(%r13)
536 b 0(%r13) 524 b 0(%r13)
537 .align 4 525 .align 8
5384: .long startup_continue 5264: .long startup_continue
5395: .long sched_clock_base_cc 527#endif
540 .align 8 528 .align 8
5416: .long 0x7fffffff,0xffffffff 5295: .long 0x7fffffff,0xffffffff
542 530
543# 531#
544# params at 10400 (setup.h) 532# params at 10400 (setup.h)
@@ -552,8 +540,4 @@ startup:basr %r13,0 # get base
552 .byte "root=/dev/ram0 ro" 540 .byte "root=/dev/ram0 ro"
553 .byte 0 541 .byte 0
554 542
555#ifdef CONFIG_64BIT 543 .org 0x11000
556#include "head64.S"
557#else
558#include "head31.S"
559#endif
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index 602b508cd4c..1bbcc499d45 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -1,7 +1,7 @@
1/* 1/*
2 * arch/s390/kernel/head31.S 2 * arch/s390/kernel/head31.S
3 * 3 *
4 * Copyright (C) IBM Corp. 2005,2006 4 * Copyright (C) IBM Corp. 2005,2010
5 * 5 *
6 * Author(s): Hartmut Penner <hp@de.ibm.com> 6 * Author(s): Hartmut Penner <hp@de.ibm.com>
7 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -10,13 +10,19 @@
10 * 10 *
11 */ 11 */
12 12
13 .org 0x11000 13#include <linux/init.h>
14#include <asm/asm-offsets.h>
15#include <asm/thread_info.h>
16#include <asm/page.h>
14 17
18__HEAD
19 .globl startup_continue
15startup_continue: 20startup_continue:
16 basr %r13,0 # get base 21 basr %r13,0 # get base
17.LPG1: 22.LPG1:
18 23
19 mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0) 24 l %r1,.Lbase_cc-.LPG1(%r13)
25 mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
20 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers 26 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
21 l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area 27 l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
22 # move IPL device to lowcore 28 # move IPL device to lowcore
@@ -69,10 +75,12 @@ startup_continue:
69.Lduald:.rept 8 75.Lduald:.rept 8
70 .long 0x80000000,0,0,0 # invalid access-list entries 76 .long 0x80000000,0,0,0 # invalid access-list entries
71 .endr 77 .endr
78.Lbase_cc:
79 .long sched_clock_base_cc
72 80
73 .org 0x12000
74 .globl _ehead 81 .globl _ehead
75_ehead: 82_ehead:
83
76#ifdef CONFIG_SHARED_KERNEL 84#ifdef CONFIG_SHARED_KERNEL
77 .org 0x100000 85 .org 0x100000
78#endif 86#endif
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index d984a2a380c..39580e76865 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -1,7 +1,7 @@
1/* 1/*
2 * arch/s390/kernel/head64.S 2 * arch/s390/kernel/head64.S
3 * 3 *
4 * Copyright (C) IBM Corp. 1999,2006 4 * Copyright (C) IBM Corp. 1999,2010
5 * 5 *
6 * Author(s): Hartmut Penner <hp@de.ibm.com> 6 * Author(s): Hartmut Penner <hp@de.ibm.com>
7 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -10,80 +10,17 @@
10 * 10 *
11 */ 11 */
12 12
13 .org 0x11000 13#include <linux/init.h>
14#include <asm/asm-offsets.h>
15#include <asm/thread_info.h>
16#include <asm/page.h>
14 17
18__HEAD
19 .globl startup_continue
15startup_continue: 20startup_continue:
16 basr %r13,0 # get base 21 larl %r1,sched_clock_base_cc
17.LPG1: sll %r13,1 # remove high order bit 22 mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
18 srl %r13,1 23 larl %r13,.LPG1 # get base
19
20#ifdef CONFIG_ZFCPDUMP
21
22 # check if we have been ipled using zfcp dump:
23
24 tm 0xb9,0x01 # test if subchannel is enabled
25 jno .nodump # subchannel disabled
26 l %r1,0xb8
27 la %r5,.Lipl_schib-.LPG1(%r13)
28 stsch 0(%r5) # get schib of subchannel
29 jne .nodump # schib not available
30 tm 5(%r5),0x01 # devno valid?
31 jno .nodump
32 tm 4(%r5),0x80 # qdio capable device?
33 jno .nodump
34 l %r2,20(%r0) # address of ipl parameter block
35 lhi %r3,0
36 ic %r3,0x148(%r2) # get opt field
37 chi %r3,0x20 # load with dump?
38 jne .nodump
39
40 # store all prefix registers in case of load with dump:
41
42 la %r7,0 # base register for 0 page
43 la %r8,0 # first cpu
44 l %r11,.Lpref_arr_ptr-.LPG1(%r13) # address of prefix array
45 ahi %r11,4 # skip boot cpu
46 lr %r12,%r11
47 ahi %r12,(CONFIG_NR_CPUS*4) # end of prefix array
48 stap .Lcurrent_cpu+2-.LPG1(%r13) # store current cpu addr
491:
50 cl %r8,.Lcurrent_cpu-.LPG1(%r13) # is ipl cpu ?
51 je 4f # if yes get next cpu
522:
53 lr %r9,%r7
54 sigp %r9,%r8,0x9 # stop & store status of cpu
55 brc 8,3f # accepted
56 brc 4,4f # status stored: next cpu
57 brc 2,2b # busy: try again
58 brc 1,4f # not op: next cpu
593:
60 mvc 0(4,%r11),264(%r7) # copy prefix register to prefix array
61 ahi %r11,4 # next element in prefix array
62 clr %r11,%r12
63 je 5f # no more space in prefix array
644:
65 ahi %r8,1 # next cpu (r8 += 1)
66 chi %r8,MAX_CPU_ADDRESS # is last possible cpu ?
67 jle 1b # jump if not last cpu
685:
69 lhi %r1,2 # mode 2 = esame (dump)
70 j 6f
71 .align 4
72.Lipl_schib:
73 .rept 13
74 .long 0
75 .endr
76.nodump:
77 lhi %r1,1 # mode 1 = esame (normal ipl)
786:
79#else
80 lhi %r1,1 # mode 1 = esame (normal ipl)
81#endif /* CONFIG_ZFCPDUMP */
82 mvi __LC_AR_MODE_ID,1 # set esame flag
83 slr %r0,%r0 # set cpuid to zero
84 sigp %r1,%r0,0x12 # switch to esame mode
85 sam64 # switch to 64 bit mode
86 llgfr %r13,%r13 # clear high-order half of base reg
87 lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half 24 lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half
88 lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers 25 lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
89 lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area 26 lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
@@ -108,6 +45,7 @@ startup_continue:
108 lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, 45 lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space,
109 # virtual and never return ... 46 # virtual and never return ...
110 .align 16 47 .align 16
48.LPG1:
111.Lentry:.quad 0x0000000180000000,_stext 49.Lentry:.quad 0x0000000180000000,_stext
112.Lctl: .quad 0x04350002 # cr0: various things 50.Lctl: .quad 0x04350002 # cr0: various things
113 .quad 0 # cr1: primary space segment table 51 .quad 0 # cr1: primary space segment table
@@ -130,12 +68,6 @@ startup_continue:
130.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 68.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
131.Lnop: .long 0x07000700 69.Lnop: .long 0x07000700
132.Lzero64:.fill 16,4,0x0 70.Lzero64:.fill 16,4,0x0
133#ifdef CONFIG_ZFCPDUMP
134.Lcurrent_cpu:
135 .long 0x0
136.Lpref_arr_ptr:
137 .long zfcpdump_prefix_array
138#endif /* CONFIG_ZFCPDUMP */
139.Lparmaddr: 71.Lparmaddr:
140 .quad PARMAREA 72 .quad PARMAREA
141 .align 64 73 .align 64
@@ -146,9 +78,9 @@ startup_continue:
146 .long 0x80000000,0,0,0 # invalid access-list entries 78 .long 0x80000000,0,0,0 # invalid access-list entries
147 .endr 79 .endr
148 80
149 .org 0x12000
150 .globl _ehead 81 .globl _ehead
151_ehead: 82_ehead:
83
152#ifdef CONFIG_SHARED_KERNEL 84#ifdef CONFIG_SHARED_KERNEL
153 .org 0x100000 85 .org 0x100000
154#endif 86#endif
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 4d73296fed7..7eedbbcb54a 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -553,7 +553,7 @@ out:
553 return rc; 553 return rc;
554} 554}
555 555
556static void ipl_run(struct shutdown_trigger *trigger) 556static void __ipl_run(void *unused)
557{ 557{
558 diag308(DIAG308_IPL, NULL); 558 diag308(DIAG308_IPL, NULL);
559 if (MACHINE_IS_VM) 559 if (MACHINE_IS_VM)
@@ -562,6 +562,11 @@ static void ipl_run(struct shutdown_trigger *trigger)
562 reipl_ccw_dev(&ipl_info.data.ccw.dev_id); 562 reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
563} 563}
564 564
565static void ipl_run(struct shutdown_trigger *trigger)
566{
567 smp_switch_to_ipl_cpu(__ipl_run, NULL);
568}
569
565static int __init ipl_init(void) 570static int __init ipl_init(void)
566{ 571{
567 int rc; 572 int rc;
@@ -1039,7 +1044,7 @@ static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb,
1039 sprintf(dst + pos, " PARM %s", vmparm); 1044 sprintf(dst + pos, " PARM %s", vmparm);
1040} 1045}
1041 1046
1042static void reipl_run(struct shutdown_trigger *trigger) 1047static void __reipl_run(void *unused)
1043{ 1048{
1044 struct ccw_dev_id devid; 1049 struct ccw_dev_id devid;
1045 static char buf[128]; 1050 static char buf[128];
@@ -1087,6 +1092,11 @@ static void reipl_run(struct shutdown_trigger *trigger)
1087 disabled_wait((unsigned long) __builtin_return_address(0)); 1092 disabled_wait((unsigned long) __builtin_return_address(0));
1088} 1093}
1089 1094
1095static void reipl_run(struct shutdown_trigger *trigger)
1096{
1097 smp_switch_to_ipl_cpu(__reipl_run, NULL);
1098}
1099
1090static void reipl_block_ccw_init(struct ipl_parameter_block *ipb) 1100static void reipl_block_ccw_init(struct ipl_parameter_block *ipb)
1091{ 1101{
1092 ipb->hdr.len = IPL_PARM_BLK_CCW_LEN; 1102 ipb->hdr.len = IPL_PARM_BLK_CCW_LEN;
@@ -1369,20 +1379,18 @@ static struct kobj_attribute dump_type_attr =
1369 1379
1370static struct kset *dump_kset; 1380static struct kset *dump_kset;
1371 1381
1372static void dump_run(struct shutdown_trigger *trigger) 1382static void __dump_run(void *unused)
1373{ 1383{
1374 struct ccw_dev_id devid; 1384 struct ccw_dev_id devid;
1375 static char buf[100]; 1385 static char buf[100];
1376 1386
1377 switch (dump_method) { 1387 switch (dump_method) {
1378 case DUMP_METHOD_CCW_CIO: 1388 case DUMP_METHOD_CCW_CIO:
1379 smp_send_stop();
1380 devid.devno = dump_block_ccw->ipl_info.ccw.devno; 1389 devid.devno = dump_block_ccw->ipl_info.ccw.devno;
1381 devid.ssid = 0; 1390 devid.ssid = 0;
1382 reipl_ccw_dev(&devid); 1391 reipl_ccw_dev(&devid);
1383 break; 1392 break;
1384 case DUMP_METHOD_CCW_VM: 1393 case DUMP_METHOD_CCW_VM:
1385 smp_send_stop();
1386 sprintf(buf, "STORE STATUS"); 1394 sprintf(buf, "STORE STATUS");
1387 __cpcmd(buf, NULL, 0, NULL); 1395 __cpcmd(buf, NULL, 0, NULL);
1388 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); 1396 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
@@ -1396,10 +1404,17 @@ static void dump_run(struct shutdown_trigger *trigger)
1396 diag308(DIAG308_SET, dump_block_fcp); 1404 diag308(DIAG308_SET, dump_block_fcp);
1397 diag308(DIAG308_DUMP, NULL); 1405 diag308(DIAG308_DUMP, NULL);
1398 break; 1406 break;
1399 case DUMP_METHOD_NONE: 1407 default:
1400 return; 1408 break;
1401 } 1409 }
1402 printk(KERN_EMERG "Dump failed!\n"); 1410}
1411
1412static void dump_run(struct shutdown_trigger *trigger)
1413{
1414 if (dump_method == DUMP_METHOD_NONE)
1415 return;
1416 smp_send_stop();
1417 smp_switch_to_ipl_cpu(__dump_run, NULL);
1403} 1418}
1404 1419
1405static int __init dump_ccw_init(void) 1420static int __init dump_ccw_init(void)
@@ -1577,7 +1592,7 @@ static void vmcmd_run(struct shutdown_trigger *trigger)
1577static int vmcmd_init(void) 1592static int vmcmd_init(void)
1578{ 1593{
1579 if (!MACHINE_IS_VM) 1594 if (!MACHINE_IS_VM)
1580 return -ENOTSUPP; 1595 return -EOPNOTSUPP;
1581 vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj); 1596 vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
1582 if (!vmcmd_kset) 1597 if (!vmcmd_kset)
1583 return -ENOMEM; 1598 return -ENOMEM;
@@ -1595,7 +1610,7 @@ static void stop_run(struct shutdown_trigger *trigger)
1595{ 1610{
1596 if (strcmp(trigger->name, ON_PANIC_STR) == 0) 1611 if (strcmp(trigger->name, ON_PANIC_STR) == 0)
1597 disabled_wait((unsigned long) __builtin_return_address(0)); 1612 disabled_wait((unsigned long) __builtin_return_address(0));
1598 while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) 1613 while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
1599 cpu_relax(); 1614 cpu_relax();
1600 for (;;); 1615 for (;;);
1601} 1616}
@@ -1902,7 +1917,6 @@ void __init ipl_update_parameters(void)
1902void __init ipl_save_parameters(void) 1917void __init ipl_save_parameters(void)
1903{ 1918{
1904 struct cio_iplinfo iplinfo; 1919 struct cio_iplinfo iplinfo;
1905 unsigned int *ipl_ptr;
1906 void *src, *dst; 1920 void *src, *dst;
1907 1921
1908 if (cio_get_iplinfo(&iplinfo)) 1922 if (cio_get_iplinfo(&iplinfo))
@@ -1913,11 +1927,10 @@ void __init ipl_save_parameters(void)
1913 if (!iplinfo.is_qdio) 1927 if (!iplinfo.is_qdio)
1914 return; 1928 return;
1915 ipl_flags |= IPL_PARMBLOCK_VALID; 1929 ipl_flags |= IPL_PARMBLOCK_VALID;
1916 ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR; 1930 src = (void *)(unsigned long)S390_lowcore.ipl_parmblock_ptr;
1917 src = (void *)(unsigned long)*ipl_ptr;
1918 dst = (void *)IPL_PARMBLOCK_ORIGIN; 1931 dst = (void *)IPL_PARMBLOCK_ORIGIN;
1919 memmove(dst, src, PAGE_SIZE); 1932 memmove(dst, src, PAGE_SIZE);
1920 *ipl_ptr = IPL_PARMBLOCK_ORIGIN; 1933 S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
1921} 1934}
1922 1935
1923static LIST_HEAD(rcall); 1936static LIST_HEAD(rcall);
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 131d7ee8b41..a922d51df6b 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -54,11 +54,11 @@ void machine_shutdown(void)
54{ 54{
55} 55}
56 56
57void machine_kexec(struct kimage *image) 57static void __machine_kexec(void *data)
58{ 58{
59 relocate_kernel_t data_mover; 59 relocate_kernel_t data_mover;
60 struct kimage *image = data;
60 61
61 smp_send_stop();
62 pfault_fini(); 62 pfault_fini();
63 s390_reset_system(); 63 s390_reset_system();
64 64
@@ -68,3 +68,9 @@ void machine_kexec(struct kimage *image)
68 (*data_mover)(&image->head, image->start); 68 (*data_mover)(&image->head, image->start);
69 for (;;); 69 for (;;);
70} 70}
71
72void machine_kexec(struct kimage *image)
73{
74 smp_send_stop();
75 smp_switch_to_ipl_cpu(__machine_kexec, image);
76}
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 7cf46423441..33fdc5a7976 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -992,3 +992,61 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
992#endif 992#endif
993 return &user_s390_view; 993 return &user_s390_view;
994} 994}
995
996static const char *gpr_names[NUM_GPRS] = {
997 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
998 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
999};
1000
1001unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset)
1002{
1003 if (offset >= NUM_GPRS)
1004 return 0;
1005 return regs->gprs[offset];
1006}
1007
1008int regs_query_register_offset(const char *name)
1009{
1010 unsigned long offset;
1011
1012 if (!name || *name != 'r')
1013 return -EINVAL;
1014 if (strict_strtoul(name + 1, 10, &offset))
1015 return -EINVAL;
1016 if (offset >= NUM_GPRS)
1017 return -EINVAL;
1018 return offset;
1019}
1020
1021const char *regs_query_register_name(unsigned int offset)
1022{
1023 if (offset >= NUM_GPRS)
1024 return NULL;
1025 return gpr_names[offset];
1026}
1027
1028static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
1029{
1030 unsigned long ksp = kernel_stack_pointer(regs);
1031
1032 return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1));
1033}
1034
1035/**
1036 * regs_get_kernel_stack_nth() - get Nth entry of the stack
1037 * @regs:pt_regs which contains kernel stack pointer.
1038 * @n:stack entry number.
1039 *
1040 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
1041 * is specifined by @regs. If the @n th entry is NOT in the kernel stack,
1042 * this returns 0.
1043 */
1044unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
1045{
1046 unsigned long addr;
1047
1048 addr = kernel_stack_pointer(regs) + n * sizeof(long);
1049 if (!regs_within_kernel_stack(regs, addr))
1050 return 0;
1051 return *(unsigned long *)addr;
1052}
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index 2f481cc3d1c..cb899d9f850 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -6,7 +6,7 @@
6 * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com) 6 * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com)
7 */ 7 */
8 8
9#include <asm/lowcore.h> 9#include <asm/asm-offsets.h>
10 10
11# 11#
12# do_reipl_asm 12# do_reipl_asm
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index 774147824c3..5e73dee63ba 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -4,7 +4,7 @@
4 * Denis Joseph Barrow, 4 * Denis Joseph Barrow,
5 */ 5 */
6 6
7#include <asm/lowcore.h> 7#include <asm/asm-offsets.h>
8 8
9# 9#
10# do_reipl_asm 10# do_reipl_asm
diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S
index e27ca63076d..27af3bf3a00 100644
--- a/arch/s390/kernel/sclp.S
+++ b/arch/s390/kernel/sclp.S
@@ -9,8 +9,10 @@
9 */ 9 */
10 10
11LC_EXT_NEW_PSW = 0x58 # addr of ext int handler 11LC_EXT_NEW_PSW = 0x58 # addr of ext int handler
12LC_EXT_NEW_PSW_64 = 0x1b0 # addr of ext int handler 64 bit
12LC_EXT_INT_PARAM = 0x80 # addr of ext int parameter 13LC_EXT_INT_PARAM = 0x80 # addr of ext int parameter
13LC_EXT_INT_CODE = 0x86 # addr of ext int code 14LC_EXT_INT_CODE = 0x86 # addr of ext int code
15LC_AR_MODE_ID = 0xa3
14 16
15# 17#
16# Subroutine which waits synchronously until either an external interruption 18# Subroutine which waits synchronously until either an external interruption
@@ -30,8 +32,16 @@ _sclp_wait_int:
30.LbaseS1: 32.LbaseS1:
31 ahi %r15,-96 # create stack frame 33 ahi %r15,-96 # create stack frame
32 la %r8,LC_EXT_NEW_PSW # register int handler 34 la %r8,LC_EXT_NEW_PSW # register int handler
33 mvc .LoldpswS1-.LbaseS1(8,%r13),0(%r8) 35 la %r9,.LextpswS1-.LbaseS1(%r13)
34 mvc 0(8,%r8),.LextpswS1-.LbaseS1(%r13) 36#ifdef CONFIG_64BIT
37 tm LC_AR_MODE_ID,1
38 jno .Lesa1
39 la %r8,LC_EXT_NEW_PSW_64 # register int handler 64 bit
40 la %r9,.LextpswS1_64-.LbaseS1(%r13)
41.Lesa1:
42#endif
43 mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8)
44 mvc 0(16,%r8),0(%r9)
35 lhi %r6,0x0200 # cr mask for ext int (cr0.54) 45 lhi %r6,0x0200 # cr mask for ext int (cr0.54)
36 ltr %r2,%r2 46 ltr %r2,%r2
37 jz .LsetctS1 47 jz .LsetctS1
@@ -64,15 +74,19 @@ _sclp_wait_int:
64.LtimeoutS1: 74.LtimeoutS1:
65 lctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # restore interrupt setting 75 lctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # restore interrupt setting
66 # restore old handler 76 # restore old handler
67 mvc 0(8,%r8),.LoldpswS1-.LbaseS1(%r13) 77 mvc 0(16,%r8),.LoldpswS1-.LbaseS1(%r13)
68 lm %r6,%r15,120(%r15) # restore registers 78 lm %r6,%r15,120(%r15) # restore registers
69 br %r14 # return to caller 79 br %r14 # return to caller
70 80
71 .align 8 81 .align 8
72.LoldpswS1: 82.LoldpswS1:
73 .long 0, 0 # old ext int PSW 83 .long 0, 0, 0, 0 # old ext int PSW
74.LextpswS1: 84.LextpswS1:
75 .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int 85 .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int
86#ifdef CONFIG_64BIT
87.LextpswS1_64:
88 .quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit
89#endif
76.LwaitpswS1: 90.LwaitpswS1:
77 .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int 91 .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int
78.LtimeS1: 92.LtimeS1:
@@ -250,6 +264,13 @@ _sclp_print:
250_sclp_print_early: 264_sclp_print_early:
251 stm %r6,%r15,24(%r15) # save registers 265 stm %r6,%r15,24(%r15) # save registers
252 ahi %r15,-96 # create stack frame 266 ahi %r15,-96 # create stack frame
267#ifdef CONFIG_64BIT
268 tm LC_AR_MODE_ID,1
269 jno .Lesa2
270 ahi %r15,-80
271 stmh %r6,%r15,96(%r15) # store upper register halves
272.Lesa2:
273#endif
253 lr %r10,%r2 # save string pointer 274 lr %r10,%r2 # save string pointer
254 lhi %r2,0 275 lhi %r2,0
255 bras %r14,_sclp_setup # enable console 276 bras %r14,_sclp_setup # enable console
@@ -262,6 +283,13 @@ _sclp_print_early:
262 lhi %r2,1 283 lhi %r2,1
263 bras %r14,_sclp_setup # disable console 284 bras %r14,_sclp_setup # disable console
264.LendS5: 285.LendS5:
286#ifdef CONFIG_64BIT
287 tm LC_AR_MODE_ID,1
288 jno .Lesa3
289 lmh %r6,%r15,96(%r15) # store upper register halves
290 ahi %r15,80
291.Lesa3:
292#endif
265 lm %r6,%r15,120(%r15) # restore registers 293 lm %r6,%r15,120(%r15) # restore registers
266 br %r14 294 br %r14
267 295
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 8d8957b38ab..77a63ae419f 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -396,15 +396,12 @@ static void __init
396setup_lowcore(void) 396setup_lowcore(void)
397{ 397{
398 struct _lowcore *lc; 398 struct _lowcore *lc;
399 int lc_pages;
400 399
401 /* 400 /*
402 * Setup lowcore for boot cpu 401 * Setup lowcore for boot cpu
403 */ 402 */
404 lc_pages = sizeof(void *) == 8 ? 2 : 1; 403 BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
405 lc = (struct _lowcore *) 404 lc = __alloc_bootmem(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
406 __alloc_bootmem(lc_pages * PAGE_SIZE, lc_pages * PAGE_SIZE, 0);
407 memset(lc, 0, lc_pages * PAGE_SIZE);
408 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; 405 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
409 lc->restart_psw.addr = 406 lc->restart_psw.addr =
410 PSW_ADDR_AMODE | (unsigned long) restart_int_handler; 407 PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
@@ -804,7 +801,7 @@ setup_arch(char **cmdline_p)
804 if (MACHINE_IS_VM) 801 if (MACHINE_IS_VM)
805 pr_info("Linux is running as a z/VM " 802 pr_info("Linux is running as a z/VM "
806 "guest operating system in 31-bit mode\n"); 803 "guest operating system in 31-bit mode\n");
807 else 804 else if (MACHINE_IS_LPAR)
808 pr_info("Linux is running natively in 31-bit mode\n"); 805 pr_info("Linux is running natively in 31-bit mode\n");
809 if (MACHINE_HAS_IEEE) 806 if (MACHINE_HAS_IEEE)
810 pr_info("The hardware system has IEEE compatible " 807 pr_info("The hardware system has IEEE compatible "
@@ -818,7 +815,7 @@ setup_arch(char **cmdline_p)
818 "guest operating system in 64-bit mode\n"); 815 "guest operating system in 64-bit mode\n");
819 else if (MACHINE_IS_KVM) 816 else if (MACHINE_IS_KVM)
820 pr_info("Linux is running under KVM in 64-bit mode\n"); 817 pr_info("Linux is running under KVM in 64-bit mode\n");
821 else 818 else if (MACHINE_IS_LPAR)
822 pr_info("Linux is running natively in 64-bit mode\n"); 819 pr_info("Linux is running natively in 64-bit mode\n");
823#endif /* CONFIG_64BIT */ 820#endif /* CONFIG_64BIT */
824 821
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 76a6fdd46c4..8b10127c00a 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -36,6 +36,7 @@
36#include <linux/cpu.h> 36#include <linux/cpu.h>
37#include <linux/timex.h> 37#include <linux/timex.h>
38#include <linux/bootmem.h> 38#include <linux/bootmem.h>
39#include <asm/asm-offsets.h>
39#include <asm/ipl.h> 40#include <asm/ipl.h>
40#include <asm/setup.h> 41#include <asm/setup.h>
41#include <asm/sigp.h> 42#include <asm/sigp.h>
@@ -53,7 +54,7 @@
53#include "entry.h" 54#include "entry.h"
54 55
55/* logical cpu to cpu address */ 56/* logical cpu to cpu address */
56int __cpu_logical_map[NR_CPUS]; 57unsigned short __cpu_logical_map[NR_CPUS];
57 58
58static struct task_struct *current_set[NR_CPUS]; 59static struct task_struct *current_set[NR_CPUS];
59 60
@@ -72,13 +73,13 @@ static int cpu_management;
72 73
73static DEFINE_PER_CPU(struct cpu, cpu_devices); 74static DEFINE_PER_CPU(struct cpu, cpu_devices);
74 75
75static void smp_ext_bitcall(int, ec_bit_sig); 76static void smp_ext_bitcall(int, int);
76 77
77static int cpu_stopped(int cpu) 78static int raw_cpu_stopped(int cpu)
78{ 79{
79 __u32 status; 80 u32 status;
80 81
81 switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { 82 switch (raw_sigp_ps(&status, 0, cpu, sigp_sense)) {
82 case sigp_status_stored: 83 case sigp_status_stored:
83 /* Check for stopped and check stop state */ 84 /* Check for stopped and check stop state */
84 if (status & 0x50) 85 if (status & 0x50)
@@ -90,6 +91,44 @@ static int cpu_stopped(int cpu)
90 return 0; 91 return 0;
91} 92}
92 93
94static inline int cpu_stopped(int cpu)
95{
96 return raw_cpu_stopped(cpu_logical_map(cpu));
97}
98
99void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
100{
101 struct _lowcore *lc, *current_lc;
102 struct stack_frame *sf;
103 struct pt_regs *regs;
104 unsigned long sp;
105
106 if (smp_processor_id() == 0)
107 func(data);
108 __load_psw_mask(PSW_BASE_BITS | PSW_DEFAULT_KEY);
109 /* Disable lowcore protection */
110 __ctl_clear_bit(0, 28);
111 current_lc = lowcore_ptr[smp_processor_id()];
112 lc = lowcore_ptr[0];
113 if (!lc)
114 lc = current_lc;
115 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
116 lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu;
117 if (!cpu_online(0))
118 smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]);
119 while (sigp(0, sigp_stop_and_store_status) == sigp_busy)
120 cpu_relax();
121 sp = lc->panic_stack;
122 sp -= sizeof(struct pt_regs);
123 regs = (struct pt_regs *) sp;
124 memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs));
125 regs->psw = lc->psw_save_area;
126 sp -= STACK_FRAME_OVERHEAD;
127 sf = (struct stack_frame *) sp;
128 sf->back_chain = regs->gprs[15];
129 smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]);
130}
131
93void smp_send_stop(void) 132void smp_send_stop(void)
94{ 133{
95 int cpu, rc; 134 int cpu, rc;
@@ -103,7 +142,7 @@ void smp_send_stop(void)
103 if (cpu == smp_processor_id()) 142 if (cpu == smp_processor_id())
104 continue; 143 continue;
105 do { 144 do {
106 rc = signal_processor(cpu, sigp_stop); 145 rc = sigp(cpu, sigp_stop);
107 } while (rc == sigp_busy); 146 } while (rc == sigp_busy);
108 147
109 while (!cpu_stopped(cpu)) 148 while (!cpu_stopped(cpu))
@@ -139,13 +178,13 @@ static void do_ext_call_interrupt(__u16 code)
139 * Send an external call sigp to another cpu and return without waiting 178 * Send an external call sigp to another cpu and return without waiting
140 * for its completion. 179 * for its completion.
141 */ 180 */
142static void smp_ext_bitcall(int cpu, ec_bit_sig sig) 181static void smp_ext_bitcall(int cpu, int sig)
143{ 182{
144 /* 183 /*
145 * Set signaling bit in lowcore of target cpu and kick it 184 * Set signaling bit in lowcore of target cpu and kick it
146 */ 185 */
147 set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); 186 set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
148 while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy) 187 while (sigp(cpu, sigp_emergency_signal) == sigp_busy)
149 udelay(10); 188 udelay(10);
150} 189}
151 190
@@ -239,24 +278,8 @@ void smp_ctl_clear_bit(int cr, int bit)
239} 278}
240EXPORT_SYMBOL(smp_ctl_clear_bit); 279EXPORT_SYMBOL(smp_ctl_clear_bit);
241 280
242/*
243 * In early ipl state a temp. logically cpu number is needed, so the sigp
244 * functions can be used to sense other cpus. Since NR_CPUS is >= 2 on
245 * CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1.
246 */
247#define CPU_INIT_NO 1
248
249#ifdef CONFIG_ZFCPDUMP 281#ifdef CONFIG_ZFCPDUMP
250 282
251/*
252 * zfcpdump_prefix_array holds prefix registers for the following scenario:
253 * 64 bit zfcpdump kernel and 31 bit kernel which is to be dumped. We have to
254 * save its prefix registers, since they get lost, when switching from 31 bit
255 * to 64 bit.
256 */
257unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \
258 __attribute__((__section__(".data")));
259
260static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) 283static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
261{ 284{
262 if (ipl_info.type != IPL_TYPE_FCP_DUMP) 285 if (ipl_info.type != IPL_TYPE_FCP_DUMP)
@@ -266,21 +289,15 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
266 "the dump\n", cpu, NR_CPUS - 1); 289 "the dump\n", cpu, NR_CPUS - 1);
267 return; 290 return;
268 } 291 }
269 zfcpdump_save_areas[cpu] = kmalloc(sizeof(union save_area), GFP_KERNEL); 292 zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL);
270 __cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu; 293 while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy)
271 while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) ==
272 sigp_busy)
273 cpu_relax(); 294 cpu_relax();
274 memcpy(zfcpdump_save_areas[cpu], 295 memcpy(zfcpdump_save_areas[cpu],
275 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, 296 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
276 SAVE_AREA_SIZE); 297 sizeof(struct save_area));
277#ifdef CONFIG_64BIT
278 /* copy original prefix register */
279 zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu];
280#endif
281} 298}
282 299
283union save_area *zfcpdump_save_areas[NR_CPUS + 1]; 300struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
284EXPORT_SYMBOL_GPL(zfcpdump_save_areas); 301EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
285 302
286#else 303#else
@@ -389,8 +406,7 @@ static void __init smp_detect_cpus(void)
389 for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) { 406 for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) {
390 if (cpu == boot_cpu_addr) 407 if (cpu == boot_cpu_addr)
391 continue; 408 continue;
392 __cpu_logical_map[CPU_INIT_NO] = cpu; 409 if (!raw_cpu_stopped(cpu))
393 if (!cpu_stopped(CPU_INIT_NO))
394 continue; 410 continue;
395 smp_get_save_area(c_cpus, cpu); 411 smp_get_save_area(c_cpus, cpu);
396 c_cpus++; 412 c_cpus++;
@@ -413,8 +429,7 @@ static void __init smp_detect_cpus(void)
413 cpu_addr = info->cpu[cpu].address; 429 cpu_addr = info->cpu[cpu].address;
414 if (cpu_addr == boot_cpu_addr) 430 if (cpu_addr == boot_cpu_addr)
415 continue; 431 continue;
416 __cpu_logical_map[CPU_INIT_NO] = cpu_addr; 432 if (!raw_cpu_stopped(cpu_addr)) {
417 if (!cpu_stopped(CPU_INIT_NO)) {
418 s_cpus++; 433 s_cpus++;
419 continue; 434 continue;
420 } 435 }
@@ -533,18 +548,18 @@ static void smp_free_lowcore(int cpu)
533/* Upping and downing of CPUs */ 548/* Upping and downing of CPUs */
534int __cpuinit __cpu_up(unsigned int cpu) 549int __cpuinit __cpu_up(unsigned int cpu)
535{ 550{
536 struct task_struct *idle;
537 struct _lowcore *cpu_lowcore; 551 struct _lowcore *cpu_lowcore;
552 struct task_struct *idle;
538 struct stack_frame *sf; 553 struct stack_frame *sf;
539 sigp_ccode ccode;
540 u32 lowcore; 554 u32 lowcore;
555 int ccode;
541 556
542 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED) 557 if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
543 return -EIO; 558 return -EIO;
544 if (smp_alloc_lowcore(cpu)) 559 if (smp_alloc_lowcore(cpu))
545 return -ENOMEM; 560 return -ENOMEM;
546 do { 561 do {
547 ccode = signal_processor(cpu, sigp_initial_cpu_reset); 562 ccode = sigp(cpu, sigp_initial_cpu_reset);
548 if (ccode == sigp_busy) 563 if (ccode == sigp_busy)
549 udelay(10); 564 udelay(10);
550 if (ccode == sigp_not_operational) 565 if (ccode == sigp_not_operational)
@@ -552,7 +567,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
552 } while (ccode == sigp_busy); 567 } while (ccode == sigp_busy);
553 568
554 lowcore = (u32)(unsigned long)lowcore_ptr[cpu]; 569 lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
555 while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy) 570 while (sigp_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
556 udelay(10); 571 udelay(10);
557 572
558 idle = current_set[cpu]; 573 idle = current_set[cpu];
@@ -578,7 +593,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
578 cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func; 593 cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func;
579 eieio(); 594 eieio();
580 595
581 while (signal_processor(cpu, sigp_restart) == sigp_busy) 596 while (sigp(cpu, sigp_restart) == sigp_busy)
582 udelay(10); 597 udelay(10);
583 598
584 while (!cpu_online(cpu)) 599 while (!cpu_online(cpu))
@@ -640,7 +655,7 @@ void __cpu_die(unsigned int cpu)
640 /* Wait until target cpu is down */ 655 /* Wait until target cpu is down */
641 while (!cpu_stopped(cpu)) 656 while (!cpu_stopped(cpu))
642 cpu_relax(); 657 cpu_relax();
643 while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy) 658 while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy)
644 udelay(10); 659 udelay(10);
645 smp_free_lowcore(cpu); 660 smp_free_lowcore(cpu);
646 pr_info("Processor %d stopped\n", cpu); 661 pr_info("Processor %d stopped\n", cpu);
@@ -649,7 +664,7 @@ void __cpu_die(unsigned int cpu)
649void cpu_die(void) 664void cpu_die(void)
650{ 665{
651 idle_task_exit(); 666 idle_task_exit();
652 while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) 667 while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
653 cpu_relax(); 668 cpu_relax();
654 for (;;); 669 for (;;);
655} 670}
@@ -765,7 +780,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev,
765 get_online_cpus(); 780 get_online_cpus();
766 mutex_lock(&smp_cpu_state_mutex); 781 mutex_lock(&smp_cpu_state_mutex);
767 rc = -EBUSY; 782 rc = -EBUSY;
768 if (cpu_online(cpu)) 783 /* disallow configuration changes of online cpus and cpu 0 */
784 if (cpu_online(cpu) || cpu == 0)
769 goto out; 785 goto out;
770 rc = 0; 786 rc = 0;
771 switch (val) { 787 switch (val) {
diff --git a/arch/s390/kernel/switch_cpu.S b/arch/s390/kernel/switch_cpu.S
new file mode 100644
index 00000000000..469f11b574f
--- /dev/null
+++ b/arch/s390/kernel/switch_cpu.S
@@ -0,0 +1,58 @@
1/*
2 * 31-bit switch cpu code
3 *
4 * Copyright IBM Corp. 2009
5 *
6 */
7
8#include <asm/asm-offsets.h>
9#include <asm/ptrace.h>
10
11# smp_switch_to_cpu switches to destination cpu and executes the passed function
12# Parameter: %r2 - function to call
13# %r3 - function parameter
14# %r4 - stack poiner
15# %r5 - current cpu
16# %r6 - destination cpu
17
18 .section .text
19 .align 4
20 .globl smp_switch_to_cpu
21smp_switch_to_cpu:
22 stm %r6,%r15,__SF_GPRS(%r15)
23 lr %r1,%r15
24 ahi %r15,-STACK_FRAME_OVERHEAD
25 st %r1,__SF_BACKCHAIN(%r15)
26 basr %r13,0
270: la %r1,.gprregs_addr-0b(%r13)
28 l %r1,0(%r1)
29 stm %r0,%r15,0(%r1)
301: sigp %r0,%r6,__SIGP_RESTART /* start destination CPU */
31 brc 2,1b /* busy, try again */
322: sigp %r0,%r5,__SIGP_STOP /* stop current CPU */
33 brc 2,2b /* busy, try again */
343: j 3b
35
36 .globl smp_restart_cpu
37smp_restart_cpu:
38 basr %r13,0
390: la %r1,.gprregs_addr-0b(%r13)
40 l %r1,0(%r1)
41 lm %r0,%r15,0(%r1)
421: sigp %r0,%r5,__SIGP_SENSE /* Wait for calling CPU */
43 brc 10,1b /* busy, accepted (status 0), running */
44 tmll %r0,0x40 /* Test if calling CPU is stopped */
45 jz 1b
46 ltr %r4,%r4 /* New stack ? */
47 jz 1f
48 lr %r15,%r4
491: basr %r14,%r2
50
51.gprregs_addr:
52 .long .gprregs
53
54 .section .data,"aw",@progbits
55.gprregs:
56 .rept 16
57 .long 0
58 .endr
diff --git a/arch/s390/kernel/switch_cpu64.S b/arch/s390/kernel/switch_cpu64.S
new file mode 100644
index 00000000000..d94aacc898c
--- /dev/null
+++ b/arch/s390/kernel/switch_cpu64.S
@@ -0,0 +1,51 @@
1/*
2 * 64-bit switch cpu code
3 *
4 * Copyright IBM Corp. 2009
5 *
6 */
7
8#include <asm/asm-offsets.h>
9#include <asm/ptrace.h>
10
11# smp_switch_to_cpu switches to destination cpu and executes the passed function
12# Parameter: %r2 - function to call
13# %r3 - function parameter
14# %r4 - stack poiner
15# %r5 - current cpu
16# %r6 - destination cpu
17
18 .section .text
19 .align 4
20 .globl smp_switch_to_cpu
21smp_switch_to_cpu:
22 stmg %r6,%r15,__SF_GPRS(%r15)
23 lgr %r1,%r15
24 aghi %r15,-STACK_FRAME_OVERHEAD
25 stg %r1,__SF_BACKCHAIN(%r15)
26 larl %r1,.gprregs
27 stmg %r0,%r15,0(%r1)
281: sigp %r0,%r6,__SIGP_RESTART /* start destination CPU */
29 brc 2,1b /* busy, try again */
302: sigp %r0,%r5,__SIGP_STOP /* stop current CPU */
31 brc 2,2b /* busy, try again */
323: j 3b
33
34 .globl smp_restart_cpu
35smp_restart_cpu:
36 larl %r1,.gprregs
37 lmg %r0,%r15,0(%r1)
381: sigp %r0,%r5,__SIGP_SENSE /* Wait for calling CPU */
39 brc 10,1b /* busy, accepted (status 0), running */
40 tmll %r0,0x40 /* Test if calling CPU is stopped */
41 jz 1b
42 ltgr %r4,%r4 /* New stack ? */
43 jz 1f
44 lgr %r15,%r4
451: basr %r14,%r2
46
47 .section .data,"aw",@progbits
48.gprregs:
49 .rept 16
50 .quad 0
51 .endr
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index 0c26cc1898e..b354427e03b 100644
--- a/arch/s390/kernel/swsusp_asm64.S
+++ b/arch/s390/kernel/swsusp_asm64.S
@@ -176,7 +176,7 @@ pgm_check_entry:
176 cgr %r1,%r2 176 cgr %r1,%r2
177 je restore_registers /* r1 = r2 -> nothing to do */ 177 je restore_registers /* r1 = r2 -> nothing to do */
178 larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */ 178 larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */
179 mvc __LC_RESTART_PSW(16,%r0),0(%r4) 179 mvc __LC_RST_NEW_PSW(16,%r0),0(%r4)
1803: 1803:
181 sigp %r9,%r1,__SIGP_INITIAL_CPU_RESET 181 sigp %r9,%r1,__SIGP_INITIAL_CPU_RESET
182 brc 8,4f /* accepted */ 182 brc 8,4f /* accepted */
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 65065ac48ed..a8f93f1705a 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -51,14 +51,6 @@
51#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ) 51#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ)
52#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12) 52#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12)
53 53
54/*
55 * Create a small time difference between the timer interrupts
56 * on the different cpus to avoid lock contention.
57 */
58#define CPU_DEVIATION (smp_processor_id() << 12)
59
60#define TICK_SIZE tick
61
62u64 sched_clock_base_cc = -1; /* Force to data section. */ 54u64 sched_clock_base_cc = -1; /* Force to data section. */
63EXPORT_SYMBOL_GPL(sched_clock_base_cc); 55EXPORT_SYMBOL_GPL(sched_clock_base_cc);
64 56
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 5f99e66c51c..6bc9c197aa9 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -23,6 +23,7 @@
23#include <linux/security.h> 23#include <linux/security.h>
24#include <linux/bootmem.h> 24#include <linux/bootmem.h>
25#include <linux/compat.h> 25#include <linux/compat.h>
26#include <asm/asm-offsets.h>
26#include <asm/pgtable.h> 27#include <asm/pgtable.h>
27#include <asm/system.h> 28#include <asm/system.h>
28#include <asm/processor.h> 29#include <asm/processor.h>