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