aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/nmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/nmi.c')
-rw-r--r--arch/s390/kernel/nmi.c92
1 files changed, 28 insertions, 64 deletions
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c
index 3f51cf4e8f02..505c17c0ae1a 100644
--- a/arch/s390/kernel/nmi.c
+++ b/arch/s390/kernel/nmi.c
@@ -117,55 +117,36 @@ static int notrace s390_revalidate_registers(struct mci *mci)
117 */ 117 */
118 kill_task = 1; 118 kill_task = 1;
119 } 119 }
120#ifndef CONFIG_64BIT 120 fpt_save_area = &S390_lowcore.floating_pt_save_area;
121 fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
122 if (!mci->fc) {
123 /*
124 * Floating point control register can't be restored.
125 * Task will be terminated.
126 */
127 asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
128 kill_task = 1;
129 } else
130 asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area));
131
121 asm volatile( 132 asm volatile(
122 " ld 0,0(%0)\n" 133 " ld 0,0(%0)\n"
123 " ld 2,8(%0)\n" 134 " ld 1,8(%0)\n"
124 " ld 4,16(%0)\n" 135 " ld 2,16(%0)\n"
125 " ld 6,24(%0)" 136 " ld 3,24(%0)\n"
126 : : "a" (&S390_lowcore.floating_pt_save_area)); 137 " ld 4,32(%0)\n"
127#endif 138 " ld 5,40(%0)\n"
128 139 " ld 6,48(%0)\n"
129 if (MACHINE_HAS_IEEE) { 140 " ld 7,56(%0)\n"
130#ifdef CONFIG_64BIT 141 " ld 8,64(%0)\n"
131 fpt_save_area = &S390_lowcore.floating_pt_save_area; 142 " ld 9,72(%0)\n"
132 fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area; 143 " ld 10,80(%0)\n"
133#else 144 " ld 11,88(%0)\n"
134 fpt_save_area = (void *) S390_lowcore.extended_save_area_addr; 145 " ld 12,96(%0)\n"
135 fpt_creg_save_area = fpt_save_area + 128; 146 " ld 13,104(%0)\n"
136#endif 147 " ld 14,112(%0)\n"
137 if (!mci->fc) { 148 " ld 15,120(%0)\n"
138 /* 149 : : "a" (fpt_save_area));
139 * Floating point control register can't be restored.
140 * Task will be terminated.
141 */
142 asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
143 kill_task = 1;
144
145 } else
146 asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area));
147
148 asm volatile(
149 " ld 0,0(%0)\n"
150 " ld 1,8(%0)\n"
151 " ld 2,16(%0)\n"
152 " ld 3,24(%0)\n"
153 " ld 4,32(%0)\n"
154 " ld 5,40(%0)\n"
155 " ld 6,48(%0)\n"
156 " ld 7,56(%0)\n"
157 " ld 8,64(%0)\n"
158 " ld 9,72(%0)\n"
159 " ld 10,80(%0)\n"
160 " ld 11,88(%0)\n"
161 " ld 12,96(%0)\n"
162 " ld 13,104(%0)\n"
163 " ld 14,112(%0)\n"
164 " ld 15,120(%0)\n"
165 : : "a" (fpt_save_area));
166 }
167
168#ifdef CONFIG_64BIT
169 /* Revalidate vector registers */ 150 /* Revalidate vector registers */
170 if (MACHINE_HAS_VX && current->thread.vxrs) { 151 if (MACHINE_HAS_VX && current->thread.vxrs) {
171 if (!mci->vr) { 152 if (!mci->vr) {
@@ -178,7 +159,6 @@ static int notrace s390_revalidate_registers(struct mci *mci)
178 restore_vx_regs((__vector128 *) 159 restore_vx_regs((__vector128 *)
179 S390_lowcore.vector_save_area_addr); 160 S390_lowcore.vector_save_area_addr);
180 } 161 }
181#endif
182 /* Revalidate access registers */ 162 /* Revalidate access registers */
183 asm volatile( 163 asm volatile(
184 " lam 0,15,0(%0)" 164 " lam 0,15,0(%0)"
@@ -198,21 +178,14 @@ static int notrace s390_revalidate_registers(struct mci *mci)
198 */ 178 */
199 s390_handle_damage("invalid control registers."); 179 s390_handle_damage("invalid control registers.");
200 } else { 180 } else {
201#ifdef CONFIG_64BIT
202 asm volatile( 181 asm volatile(
203 " lctlg 0,15,0(%0)" 182 " lctlg 0,15,0(%0)"
204 : : "a" (&S390_lowcore.cregs_save_area)); 183 : : "a" (&S390_lowcore.cregs_save_area));
205#else
206 asm volatile(
207 " lctl 0,15,0(%0)"
208 : : "a" (&S390_lowcore.cregs_save_area));
209#endif
210 } 184 }
211 /* 185 /*
212 * We don't even try to revalidate the TOD register, since we simply 186 * We don't even try to revalidate the TOD register, since we simply
213 * can't write something sensible into that register. 187 * can't write something sensible into that register.
214 */ 188 */
215#ifdef CONFIG_64BIT
216 /* 189 /*
217 * See if we can revalidate the TOD programmable register with its 190 * See if we can revalidate the TOD programmable register with its
218 * old contents (should be zero) otherwise set it to zero. 191 * old contents (should be zero) otherwise set it to zero.
@@ -228,7 +201,6 @@ static int notrace s390_revalidate_registers(struct mci *mci)
228 " sckpf" 201 " sckpf"
229 : : "a" (&S390_lowcore.tod_progreg_save_area) 202 : : "a" (&S390_lowcore.tod_progreg_save_area)
230 : "0", "cc"); 203 : "0", "cc");
231#endif
232 /* Revalidate clock comparator register */ 204 /* Revalidate clock comparator register */
233 set_clock_comparator(S390_lowcore.clock_comparator); 205 set_clock_comparator(S390_lowcore.clock_comparator);
234 /* Check if old PSW is valid */ 206 /* Check if old PSW is valid */
@@ -280,19 +252,11 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
280 if (mci->b) { 252 if (mci->b) {
281 /* Processing backup -> verify if we can survive this */ 253 /* Processing backup -> verify if we can survive this */
282 u64 z_mcic, o_mcic, t_mcic; 254 u64 z_mcic, o_mcic, t_mcic;
283#ifdef CONFIG_64BIT
284 z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29); 255 z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
285 o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 | 256 o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
286 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 | 257 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
287 1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 | 258 1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 |
288 1ULL<<16); 259 1ULL<<16);
289#else
290 z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 |
291 1ULL<<29);
292 o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
293 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
294 1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16);
295#endif
296 t_mcic = *(u64 *)mci; 260 t_mcic = *(u64 *)mci;
297 261
298 if (((t_mcic & z_mcic) != 0) || 262 if (((t_mcic & z_mcic) != 0) ||