1 /* 2 * s390x SIGP instruction handling 3 * 4 * Copyright (c) 2009 Alexander Graf <agraf@suse.de> 5 * Copyright IBM Corp. 2012 6 * 7 * This work is licensed under the terms of the GNU GPL, version 2 or later. 8 * See the COPYING file in the top-level directory. 9 */ 10 11 #include "qemu/osdep.h" 12 #include "cpu.h" 13 #include "internal.h" 14 #include "sysemu/hw_accel.h" 15 #include "sysemu/runstate.h" 16 #include "exec/address-spaces.h" 17 #include "exec/exec-all.h" 18 #include "sysemu/tcg.h" 19 #include "trace.h" 20 #include "qapi/qapi-types-machine.h" 21 22 QemuMutex qemu_sigp_mutex; 23 24 typedef struct SigpInfo { 25 uint64_t param; 26 int cc; 27 uint64_t *status_reg; 28 } SigpInfo; 29 30 static void set_sigp_status(SigpInfo *si, uint64_t status) 31 { 32 *si->status_reg &= 0xffffffff00000000ULL; 33 *si->status_reg |= status; 34 si->cc = SIGP_CC_STATUS_STORED; 35 } 36 37 static void sigp_sense(S390CPU *dst_cpu, SigpInfo *si) 38 { 39 uint8_t state = s390_cpu_get_state(dst_cpu); 40 bool ext_call = dst_cpu->env.pending_int & INTERRUPT_EXTERNAL_CALL; 41 uint64_t status = 0; 42 43 if (!tcg_enabled()) { 44 /* handled in KVM */ 45 set_sigp_status(si, SIGP_STAT_INVALID_ORDER); 46 return; 47 } 48 49 /* sensing without locks is racy, but it's the same for real hw */ 50 if (state != S390_CPU_STATE_STOPPED && !ext_call) { 51 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 52 } else { 53 if (ext_call) { 54 status |= SIGP_STAT_EXT_CALL_PENDING; 55 } 56 if (state == S390_CPU_STATE_STOPPED) { 57 status |= SIGP_STAT_STOPPED; 58 } 59 set_sigp_status(si, status); 60 } 61 } 62 63 static void sigp_external_call(S390CPU *src_cpu, S390CPU *dst_cpu, SigpInfo *si) 64 { 65 int ret; 66 67 if (!tcg_enabled()) { 68 /* handled in KVM */ 69 set_sigp_status(si, SIGP_STAT_INVALID_ORDER); 70 return; 71 } 72 73 ret = cpu_inject_external_call(dst_cpu, src_cpu->env.core_id); 74 if (!ret) { 75 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 76 } else { 77 set_sigp_status(si, SIGP_STAT_EXT_CALL_PENDING); 78 } 79 } 80 81 static void sigp_emergency(S390CPU *src_cpu, S390CPU *dst_cpu, SigpInfo *si) 82 { 83 if (!tcg_enabled()) { 84 /* handled in KVM */ 85 set_sigp_status(si, SIGP_STAT_INVALID_ORDER); 86 return; 87 } 88 89 cpu_inject_emergency_signal(dst_cpu, src_cpu->env.core_id); 90 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 91 } 92 93 static void sigp_start(CPUState *cs, run_on_cpu_data arg) 94 { 95 S390CPU *cpu = S390_CPU(cs); 96 SigpInfo *si = arg.host_ptr; 97 98 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) { 99 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 100 return; 101 } 102 103 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); 104 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 105 } 106 107 static void sigp_stop(CPUState *cs, run_on_cpu_data arg) 108 { 109 S390CPU *cpu = S390_CPU(cs); 110 SigpInfo *si = arg.host_ptr; 111 112 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING) { 113 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 114 return; 115 } 116 117 /* disabled wait - sleeping in user space */ 118 if (cs->halted) { 119 s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu); 120 } else { 121 /* execute the stop function */ 122 cpu->env.sigp_order = SIGP_STOP; 123 cpu_inject_stop(cpu); 124 } 125 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 126 } 127 128 static void sigp_stop_and_store_status(CPUState *cs, run_on_cpu_data arg) 129 { 130 S390CPU *cpu = S390_CPU(cs); 131 SigpInfo *si = arg.host_ptr; 132 133 /* disabled wait - sleeping in user space */ 134 if (s390_cpu_get_state(cpu) == S390_CPU_STATE_OPERATING && cs->halted) { 135 s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu); 136 } 137 138 switch (s390_cpu_get_state(cpu)) { 139 case S390_CPU_STATE_OPERATING: 140 cpu->env.sigp_order = SIGP_STOP_STORE_STATUS; 141 cpu_inject_stop(cpu); 142 /* store will be performed in do_stop_interrup() */ 143 break; 144 case S390_CPU_STATE_STOPPED: 145 /* already stopped, just store the status */ 146 cpu_synchronize_state(cs); 147 s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true); 148 break; 149 } 150 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 151 } 152 153 static void sigp_store_status_at_address(CPUState *cs, run_on_cpu_data arg) 154 { 155 S390CPU *cpu = S390_CPU(cs); 156 SigpInfo *si = arg.host_ptr; 157 uint32_t address = si->param & 0x7ffffe00u; 158 159 /* cpu has to be stopped */ 160 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) { 161 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE); 162 return; 163 } 164 165 cpu_synchronize_state(cs); 166 167 if (s390_store_status(cpu, address, false)) { 168 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER); 169 return; 170 } 171 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 172 } 173 174 #define ADTL_SAVE_LC_MASK 0xfUL 175 static void sigp_store_adtl_status(CPUState *cs, run_on_cpu_data arg) 176 { 177 S390CPU *cpu = S390_CPU(cs); 178 SigpInfo *si = arg.host_ptr; 179 uint8_t lc = si->param & ADTL_SAVE_LC_MASK; 180 hwaddr addr = si->param & ~ADTL_SAVE_LC_MASK; 181 hwaddr len = 1UL << (lc ? lc : 10); 182 183 if (!s390_has_feat(S390_FEAT_VECTOR) && 184 !s390_has_feat(S390_FEAT_GUARDED_STORAGE)) { 185 set_sigp_status(si, SIGP_STAT_INVALID_ORDER); 186 return; 187 } 188 189 /* cpu has to be stopped */ 190 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) { 191 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE); 192 return; 193 } 194 195 /* address must be aligned to length */ 196 if (addr & (len - 1)) { 197 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER); 198 return; 199 } 200 201 /* no GS: only lc == 0 is valid */ 202 if (!s390_has_feat(S390_FEAT_GUARDED_STORAGE) && 203 lc != 0) { 204 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER); 205 return; 206 } 207 208 /* GS: 0, 10, 11, 12 are valid */ 209 if (s390_has_feat(S390_FEAT_GUARDED_STORAGE) && 210 lc != 0 && 211 lc != 10 && 212 lc != 11 && 213 lc != 12) { 214 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER); 215 return; 216 } 217 218 cpu_synchronize_state(cs); 219 220 if (s390_store_adtl_status(cpu, addr, len)) { 221 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER); 222 return; 223 } 224 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 225 } 226 227 static void sigp_restart(CPUState *cs, run_on_cpu_data arg) 228 { 229 S390CPU *cpu = S390_CPU(cs); 230 SigpInfo *si = arg.host_ptr; 231 232 switch (s390_cpu_get_state(cpu)) { 233 case S390_CPU_STATE_STOPPED: 234 /* the restart irq has to be delivered prior to any other pending irq */ 235 cpu_synchronize_state(cs); 236 /* 237 * Set OPERATING (and unhalting) before loading the restart PSW. 238 * load_psw() will then properly halt the CPU again if necessary (TCG). 239 */ 240 s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); 241 do_restart_interrupt(&cpu->env); 242 break; 243 case S390_CPU_STATE_OPERATING: 244 cpu_inject_restart(cpu); 245 break; 246 } 247 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 248 } 249 250 static void sigp_initial_cpu_reset(CPUState *cs, run_on_cpu_data arg) 251 { 252 S390CPU *cpu = S390_CPU(cs); 253 S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); 254 SigpInfo *si = arg.host_ptr; 255 256 cpu_synchronize_state(cs); 257 scc->reset(cs, S390_CPU_RESET_INITIAL); 258 cpu_synchronize_post_reset(cs); 259 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 260 } 261 262 static void sigp_cpu_reset(CPUState *cs, run_on_cpu_data arg) 263 { 264 S390CPU *cpu = S390_CPU(cs); 265 S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); 266 SigpInfo *si = arg.host_ptr; 267 268 cpu_synchronize_state(cs); 269 scc->reset(cs, S390_CPU_RESET_NORMAL); 270 cpu_synchronize_post_reset(cs); 271 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 272 } 273 274 static void sigp_set_prefix(CPUState *cs, run_on_cpu_data arg) 275 { 276 S390CPU *cpu = S390_CPU(cs); 277 SigpInfo *si = arg.host_ptr; 278 uint32_t addr = si->param & 0x7fffe000u; 279 280 cpu_synchronize_state(cs); 281 282 if (!address_space_access_valid(&address_space_memory, addr, 283 sizeof(struct LowCore), false, 284 MEMTXATTRS_UNSPECIFIED)) { 285 set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER); 286 return; 287 } 288 289 /* cpu has to be stopped */ 290 if (s390_cpu_get_state(cpu) != S390_CPU_STATE_STOPPED) { 291 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE); 292 return; 293 } 294 295 cpu->env.psa = addr; 296 tlb_flush(cs); 297 cpu_synchronize_post_init(cs); 298 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 299 } 300 301 static void sigp_cond_emergency(S390CPU *src_cpu, S390CPU *dst_cpu, 302 SigpInfo *si) 303 { 304 const uint64_t psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT; 305 uint16_t p_asn, s_asn, asn; 306 uint64_t psw_addr, psw_mask; 307 bool idle; 308 309 if (!tcg_enabled()) { 310 /* handled in KVM */ 311 set_sigp_status(si, SIGP_STAT_INVALID_ORDER); 312 return; 313 } 314 315 /* this looks racy, but these values are only used when STOPPED */ 316 idle = CPU(dst_cpu)->halted; 317 psw_addr = dst_cpu->env.psw.addr; 318 psw_mask = dst_cpu->env.psw.mask; 319 asn = si->param; 320 p_asn = dst_cpu->env.cregs[4] & 0xffff; /* Primary ASN */ 321 s_asn = dst_cpu->env.cregs[3] & 0xffff; /* Secondary ASN */ 322 323 if (s390_cpu_get_state(dst_cpu) != S390_CPU_STATE_STOPPED || 324 (psw_mask & psw_int_mask) != psw_int_mask || 325 (idle && psw_addr != 0) || 326 (!idle && (asn == p_asn || asn == s_asn))) { 327 cpu_inject_emergency_signal(dst_cpu, src_cpu->env.core_id); 328 } else { 329 set_sigp_status(si, SIGP_STAT_INCORRECT_STATE); 330 } 331 332 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 333 } 334 335 static void sigp_sense_running(S390CPU *dst_cpu, SigpInfo *si) 336 { 337 if (!tcg_enabled()) { 338 /* handled in KVM */ 339 set_sigp_status(si, SIGP_STAT_INVALID_ORDER); 340 return; 341 } 342 343 /* sensing without locks is racy, but it's the same for real hw */ 344 if (!s390_has_feat(S390_FEAT_SENSE_RUNNING_STATUS)) { 345 set_sigp_status(si, SIGP_STAT_INVALID_ORDER); 346 return; 347 } 348 349 /* If halted (which includes also STOPPED), it is not running */ 350 if (CPU(dst_cpu)->halted) { 351 si->cc = SIGP_CC_ORDER_CODE_ACCEPTED; 352 } else { 353 set_sigp_status(si, SIGP_STAT_NOT_RUNNING); 354 } 355 } 356 357 static int handle_sigp_single_dst(S390CPU *cpu, S390CPU *dst_cpu, uint8_t order, 358 uint64_t param, uint64_t *status_reg) 359 { 360 SigpInfo si = { 361 .param = param, 362 .status_reg = status_reg, 363 }; 364 365 /* cpu available? */ 366 if (dst_cpu == NULL) { 367 return SIGP_CC_NOT_OPERATIONAL; 368 } 369 370 /* only resets can break pending orders */ 371 if (dst_cpu->env.sigp_order != 0 && 372 order != SIGP_CPU_RESET && 373 order != SIGP_INITIAL_CPU_RESET) { 374 return SIGP_CC_BUSY; 375 } 376 377 switch (order) { 378 case SIGP_SENSE: 379 sigp_sense(dst_cpu, &si); 380 break; 381 case SIGP_EXTERNAL_CALL: 382 sigp_external_call(cpu, dst_cpu, &si); 383 break; 384 case SIGP_EMERGENCY: 385 sigp_emergency(cpu, dst_cpu, &si); 386 break; 387 case SIGP_START: 388 run_on_cpu(CPU(dst_cpu), sigp_start, RUN_ON_CPU_HOST_PTR(&si)); 389 break; 390 case SIGP_STOP: 391 run_on_cpu(CPU(dst_cpu), sigp_stop, RUN_ON_CPU_HOST_PTR(&si)); 392 break; 393 case SIGP_RESTART: 394 run_on_cpu(CPU(dst_cpu), sigp_restart, RUN_ON_CPU_HOST_PTR(&si)); 395 break; 396 case SIGP_STOP_STORE_STATUS: 397 run_on_cpu(CPU(dst_cpu), sigp_stop_and_store_status, RUN_ON_CPU_HOST_PTR(&si)); 398 break; 399 case SIGP_STORE_STATUS_ADDR: 400 run_on_cpu(CPU(dst_cpu), sigp_store_status_at_address, RUN_ON_CPU_HOST_PTR(&si)); 401 break; 402 case SIGP_STORE_ADTL_STATUS: 403 run_on_cpu(CPU(dst_cpu), sigp_store_adtl_status, RUN_ON_CPU_HOST_PTR(&si)); 404 break; 405 case SIGP_SET_PREFIX: 406 run_on_cpu(CPU(dst_cpu), sigp_set_prefix, RUN_ON_CPU_HOST_PTR(&si)); 407 break; 408 case SIGP_INITIAL_CPU_RESET: 409 run_on_cpu(CPU(dst_cpu), sigp_initial_cpu_reset, RUN_ON_CPU_HOST_PTR(&si)); 410 break; 411 case SIGP_CPU_RESET: 412 run_on_cpu(CPU(dst_cpu), sigp_cpu_reset, RUN_ON_CPU_HOST_PTR(&si)); 413 break; 414 case SIGP_COND_EMERGENCY: 415 sigp_cond_emergency(cpu, dst_cpu, &si); 416 break; 417 case SIGP_SENSE_RUNNING: 418 sigp_sense_running(dst_cpu, &si); 419 break; 420 default: 421 set_sigp_status(&si, SIGP_STAT_INVALID_ORDER); 422 } 423 424 return si.cc; 425 } 426 427 static int sigp_set_architecture(S390CPU *cpu, uint32_t param, 428 uint64_t *status_reg) 429 { 430 CPUState *cur_cs; 431 S390CPU *cur_cpu; 432 bool all_stopped = true; 433 434 CPU_FOREACH(cur_cs) { 435 cur_cpu = S390_CPU(cur_cs); 436 437 if (cur_cpu == cpu) { 438 continue; 439 } 440 if (s390_cpu_get_state(cur_cpu) != S390_CPU_STATE_STOPPED) { 441 all_stopped = false; 442 } 443 } 444 445 *status_reg &= 0xffffffff00000000ULL; 446 447 /* Reject set arch order, with czam we're always in z/Arch mode. */ 448 *status_reg |= (all_stopped ? SIGP_STAT_INVALID_PARAMETER : 449 SIGP_STAT_INCORRECT_STATE); 450 return SIGP_CC_STATUS_STORED; 451 } 452 453 int handle_sigp(CPUS390XState *env, uint8_t order, uint64_t r1, uint64_t r3) 454 { 455 uint64_t *status_reg = &env->regs[r1]; 456 uint64_t param = (r1 % 2) ? env->regs[r1] : env->regs[r1 + 1]; 457 S390CPU *cpu = env_archcpu(env); 458 S390CPU *dst_cpu = NULL; 459 int ret; 460 461 if (qemu_mutex_trylock(&qemu_sigp_mutex)) { 462 ret = SIGP_CC_BUSY; 463 goto out; 464 } 465 466 switch (order) { 467 case SIGP_SET_ARCH: 468 ret = sigp_set_architecture(cpu, param, status_reg); 469 break; 470 default: 471 /* all other sigp orders target a single vcpu */ 472 dst_cpu = s390_cpu_addr2state(env->regs[r3]); 473 ret = handle_sigp_single_dst(cpu, dst_cpu, order, param, status_reg); 474 } 475 qemu_mutex_unlock(&qemu_sigp_mutex); 476 477 out: 478 trace_sigp_finished(order, CPU(cpu)->cpu_index, 479 dst_cpu ? CPU(dst_cpu)->cpu_index : -1, ret); 480 g_assert(ret >= 0); 481 482 return ret; 483 } 484 485 int s390_cpu_restart(S390CPU *cpu) 486 { 487 SigpInfo si = {}; 488 489 run_on_cpu(CPU(cpu), sigp_restart, RUN_ON_CPU_HOST_PTR(&si)); 490 return 0; 491 } 492 493 void do_stop_interrupt(CPUS390XState *env) 494 { 495 S390CPU *cpu = env_archcpu(env); 496 497 if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) { 498 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); 499 } 500 if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) { 501 s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true); 502 } 503 env->sigp_order = 0; 504 env->pending_int &= ~INTERRUPT_STOP; 505 } 506 507 void s390_init_sigp(void) 508 { 509 qemu_mutex_init(&qemu_sigp_mutex); 510 } 511