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