nmi.c (89aa02edaa30e4327ebc8fca9b80795bbfd4ce9b) | nmi.c (208da1d5fc3c67d8ae5d34e844fd67cc47a136f0) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Machine check handler 4 * 5 * Copyright IBM Corp. 2000, 2009 6 * Author(s): Ingo Adlung <adlung@de.ibm.com>, 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>, 8 * Cornelia Huck <cornelia.huck@de.ibm.com>, --- 111 unchanged lines hidden (view full) --- 120 union ctlreg0 cr0, cr0_new; 121 char message[100]; 122 psw_t psw_save; 123 char *ptr; 124 125 smp_emergency_stop(); 126 diag_amode31_ops.diag308_reset(); 127 ptr = nmi_puts(message, "System stopped due to unrecoverable machine check, code: 0x"); | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Machine check handler 4 * 5 * Copyright IBM Corp. 2000, 2009 6 * Author(s): Ingo Adlung <adlung@de.ibm.com>, 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>, 8 * Cornelia Huck <cornelia.huck@de.ibm.com>, --- 111 unchanged lines hidden (view full) --- 120 union ctlreg0 cr0, cr0_new; 121 char message[100]; 122 psw_t psw_save; 123 char *ptr; 124 125 smp_emergency_stop(); 126 diag_amode31_ops.diag308_reset(); 127 ptr = nmi_puts(message, "System stopped due to unrecoverable machine check, code: 0x"); |
128 u64_to_hex(ptr, S390_lowcore.mcck_interruption_code); | 128 u64_to_hex(ptr, get_lowcore()->mcck_interruption_code); |
129 130 /* 131 * Disable low address protection and make machine check new PSW a 132 * disabled wait PSW. Any additional machine check cannot be handled. 133 */ 134 local_ctl_store(0, &cr0.reg); 135 cr0_new = cr0; 136 cr0_new.lap = 0; 137 local_ctl_load(0, &cr0_new.reg); | 129 130 /* 131 * Disable low address protection and make machine check new PSW a 132 * disabled wait PSW. Any additional machine check cannot be handled. 133 */ 134 local_ctl_store(0, &cr0.reg); 135 cr0_new = cr0; 136 cr0_new.lap = 0; 137 local_ctl_load(0, &cr0_new.reg); |
138 psw_save = S390_lowcore.mcck_new_psw; 139 psw_bits(S390_lowcore.mcck_new_psw).io = 0; 140 psw_bits(S390_lowcore.mcck_new_psw).ext = 0; 141 psw_bits(S390_lowcore.mcck_new_psw).wait = 1; | 138 psw_save = get_lowcore()->mcck_new_psw; 139 psw_bits(get_lowcore()->mcck_new_psw).io = 0; 140 psw_bits(get_lowcore()->mcck_new_psw).ext = 0; 141 psw_bits(get_lowcore()->mcck_new_psw).wait = 1; |
142 sclp_emergency_printk(message); 143 144 /* 145 * Restore machine check new PSW and control register 0 to original 146 * values. This makes possible system dump analysis easier. 147 */ | 142 sclp_emergency_printk(message); 143 144 /* 145 * Restore machine check new PSW and control register 0 to original 146 * values. This makes possible system dump analysis easier. 147 */ |
148 S390_lowcore.mcck_new_psw = psw_save; | 148 get_lowcore()->mcck_new_psw = psw_save; |
149 local_ctl_load(0, &cr0.reg); 150 disabled_wait(); 151 while (1); 152} 153NOKPROBE_SYMBOL(s390_handle_damage); 154 155/* 156 * Main machine check handler function. Will be called with interrupts disabled --- 64 unchanged lines hidden (view full) --- 221 * field of the TOD clock. Disregard the TOD programmable register 222 * validity bit and load the CPU number into the TOD programmable field 223 * unconditionally. 224 */ 225 set_tod_programmable_field(raw_smp_processor_id()); 226 /* 227 * Set the clock comparator register to the next expected value. 228 */ | 149 local_ctl_load(0, &cr0.reg); 150 disabled_wait(); 151 while (1); 152} 153NOKPROBE_SYMBOL(s390_handle_damage); 154 155/* 156 * Main machine check handler function. Will be called with interrupts disabled --- 64 unchanged lines hidden (view full) --- 221 * field of the TOD clock. Disregard the TOD programmable register 222 * validity bit and load the CPU number into the TOD programmable field 223 * unconditionally. 224 */ 225 set_tod_programmable_field(raw_smp_processor_id()); 226 /* 227 * Set the clock comparator register to the next expected value. 228 */ |
229 set_clock_comparator(S390_lowcore.clock_comparator); | 229 set_clock_comparator(get_lowcore()->clock_comparator); |
230 if (!mci.gr || !mci.fp || !mci.fc) 231 return false; 232 /* 233 * The vector validity must only be checked if not running a 234 * KVM guest. For KVM guests the machine check is forwarded by 235 * KVM and it is the responsibility of the guest to take 236 * appropriate actions. The host vector or FPU values have been 237 * saved by KVM and will be restored by KVM. --- 9 unchanged lines hidden (view full) --- 247 * For kernel or userspace the userspace values of guarded storage 248 * control can not be recreated, the process must be terminated. 249 * For SIE the guest values of guarded storage can not be recreated. 250 * This is either due to a bug or due to GS being disabled in the 251 * guest. The guest will be notified by KVM code and the guests machine 252 * check handling must take care of this. The host values are saved by 253 * KVM and are not affected. 254 */ | 230 if (!mci.gr || !mci.fp || !mci.fc) 231 return false; 232 /* 233 * The vector validity must only be checked if not running a 234 * KVM guest. For KVM guests the machine check is forwarded by 235 * KVM and it is the responsibility of the guest to take 236 * appropriate actions. The host vector or FPU values have been 237 * saved by KVM and will be restored by KVM. --- 9 unchanged lines hidden (view full) --- 247 * For kernel or userspace the userspace values of guarded storage 248 * control can not be recreated, the process must be terminated. 249 * For SIE the guest values of guarded storage can not be recreated. 250 * This is either due to a bug or due to GS being disabled in the 251 * guest. The guest will be notified by KVM code and the guests machine 252 * check handling must take care of this. The host values are saved by 253 * KVM and are not affected. 254 */ |
255 cr2.reg = S390_lowcore.cregs_save_area[2]; | 255 cr2.reg = get_lowcore()->cregs_save_area[2]; |
256 if (cr2.gse && !mci.gs && !test_cpu_flag(CIF_MCCK_GUEST)) 257 return false; 258 if (!mci.ms || !mci.pm || !mci.ia) 259 return false; 260 return true; 261} 262NOKPROBE_SYMBOL(nmi_registers_valid); 263 --- 9 unchanged lines hidden (view full) --- 273 struct kvm_s390_sie_block *sie_block = phys_to_virt(regs->gprs[14]); 274 275 if (sie_block == NULL) 276 /* Something's seriously wrong, stop system. */ 277 s390_handle_damage(); 278 279 sie_page = container_of(sie_block, struct sie_page, sie_block); 280 mcck_backup = &sie_page->mcck_info; | 256 if (cr2.gse && !mci.gs && !test_cpu_flag(CIF_MCCK_GUEST)) 257 return false; 258 if (!mci.ms || !mci.pm || !mci.ia) 259 return false; 260 return true; 261} 262NOKPROBE_SYMBOL(nmi_registers_valid); 263 --- 9 unchanged lines hidden (view full) --- 273 struct kvm_s390_sie_block *sie_block = phys_to_virt(regs->gprs[14]); 274 275 if (sie_block == NULL) 276 /* Something's seriously wrong, stop system. */ 277 s390_handle_damage(); 278 279 sie_page = container_of(sie_block, struct sie_page, sie_block); 280 mcck_backup = &sie_page->mcck_info; |
281 mcck_backup->mcic = S390_lowcore.mcck_interruption_code & | 281 mcck_backup->mcic = get_lowcore()->mcck_interruption_code & |
282 ~(MCCK_CODE_CP | MCCK_CODE_EXT_DAMAGE); | 282 ~(MCCK_CODE_CP | MCCK_CODE_EXT_DAMAGE); |
283 mcck_backup->ext_damage_code = S390_lowcore.external_damage_code; 284 mcck_backup->failing_storage_address 285 = S390_lowcore.failing_storage_address; | 283 mcck_backup->ext_damage_code = get_lowcore()->external_damage_code; 284 mcck_backup->failing_storage_address = get_lowcore()->failing_storage_address; |
286} 287NOKPROBE_SYMBOL(s390_backup_mcck_info); 288 289#define MAX_IPD_COUNT 29 290#define MAX_IPD_TIME (5 * 60 * USEC_PER_SEC) /* 5 minutes */ 291 292#define ED_STP_ISLAND 6 /* External damage STP island check */ 293#define ED_STP_SYNC 7 /* External damage STP sync check */ --- 15 unchanged lines hidden (view full) --- 309 unsigned long mcck_dam_code; 310 int mcck_pending = 0; 311 312 irq_state = irqentry_nmi_enter(regs); 313 314 if (user_mode(regs)) 315 update_timer_mcck(); 316 inc_irq_stat(NMI_NMI); | 285} 286NOKPROBE_SYMBOL(s390_backup_mcck_info); 287 288#define MAX_IPD_COUNT 29 289#define MAX_IPD_TIME (5 * 60 * USEC_PER_SEC) /* 5 minutes */ 290 291#define ED_STP_ISLAND 6 /* External damage STP island check */ 292#define ED_STP_SYNC 7 /* External damage STP sync check */ --- 15 unchanged lines hidden (view full) --- 308 unsigned long mcck_dam_code; 309 int mcck_pending = 0; 310 311 irq_state = irqentry_nmi_enter(regs); 312 313 if (user_mode(regs)) 314 update_timer_mcck(); 315 inc_irq_stat(NMI_NMI); |
317 mci.val = S390_lowcore.mcck_interruption_code; | 316 mci.val = get_lowcore()->mcck_interruption_code; |
318 mcck = this_cpu_ptr(&cpu_mcck); 319 320 /* 321 * Reinject the instruction processing damages' machine checks 322 * including Delayed Access Exception into the guest 323 * instead of damaging the host if they happen in the guest. 324 */ 325 if (mci.pd && !test_cpu_flag(CIF_MCCK_GUEST)) { --- 51 unchanged lines hidden (view full) --- 377 s390_backup_mcck_info(regs); 378 379 if (mci.cd) { 380 /* Timing facility damage */ 381 s390_handle_damage(); 382 } 383 if (mci.ed && mci.ec) { 384 /* External damage */ | 317 mcck = this_cpu_ptr(&cpu_mcck); 318 319 /* 320 * Reinject the instruction processing damages' machine checks 321 * including Delayed Access Exception into the guest 322 * instead of damaging the host if they happen in the guest. 323 */ 324 if (mci.pd && !test_cpu_flag(CIF_MCCK_GUEST)) { --- 51 unchanged lines hidden (view full) --- 376 s390_backup_mcck_info(regs); 377 378 if (mci.cd) { 379 /* Timing facility damage */ 380 s390_handle_damage(); 381 } 382 if (mci.ed && mci.ec) { 383 /* External damage */ |
385 if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC)) | 384 if (get_lowcore()->external_damage_code & (1U << ED_STP_SYNC)) |
386 mcck->stp_queue |= stp_sync_check(); | 385 mcck->stp_queue |= stp_sync_check(); |
387 if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND)) | 386 if (get_lowcore()->external_damage_code & (1U << ED_STP_ISLAND)) |
388 mcck->stp_queue |= stp_island_check(); 389 mcck_pending = 1; 390 } 391 /* 392 * Reinject storage related machine checks into the guest if they 393 * happen when the guest is running. 394 */ 395 if (!test_cpu_flag(CIF_MCCK_GUEST)) { --- 49 unchanged lines hidden --- | 387 mcck->stp_queue |= stp_island_check(); 388 mcck_pending = 1; 389 } 390 /* 391 * Reinject storage related machine checks into the guest if they 392 * happen when the guest is running. 393 */ 394 if (!test_cpu_flag(CIF_MCCK_GUEST)) { --- 49 unchanged lines hidden --- |