diff options
Diffstat (limited to 'arch/s390/kernel/nmi.c')
-rw-r--r-- | arch/s390/kernel/nmi.c | 92 |
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) || |