target/s390x: special handling when starting a CPU with WAIT PSW
When we try to start a CPU with a WAIT PSW, we have to take care that TCG will actually try to continue executing instructions. We must therefore really only unhalt the CPU if we don't have a WAIT PSW. Also document the special order for restart interrupts, which load a new PSW and change the state to operating. To keep KVM working, simply don't have a look at the WAIT bit when loading the PSW. Otherwise the behavior of a restart interrupt when a CPU stopped would be changed. Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20170928203708.9376-31-david@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
parent
f74990a5d0
commit
741a4ec186
@ -337,8 +337,15 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
|
||||
break;
|
||||
case CPU_STATE_OPERATING:
|
||||
case CPU_STATE_LOAD:
|
||||
/* unhalt the cpu for common infrastructure */
|
||||
s390_cpu_unhalt(cpu);
|
||||
/*
|
||||
* Starting a CPU with a PSW WAIT bit set:
|
||||
* KVM: handles this internally and triggers another WAIT exit.
|
||||
* TCG: will actually try to continue to run. Don't unhalt, will
|
||||
* be done when the CPU actually has work (an interrupt).
|
||||
*/
|
||||
if (!tcg_enabled() || !(cpu->env.psw.mask & PSW_MASK_WAIT)) {
|
||||
s390_cpu_unhalt(cpu);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error_report("Requested CPU state is not a valid S390 CPU state: %u",
|
||||
|
@ -232,8 +232,12 @@ static void sigp_restart(CPUState *cs, run_on_cpu_data arg)
|
||||
case CPU_STATE_STOPPED:
|
||||
/* the restart irq has to be delivered prior to any other pending irq */
|
||||
cpu_synchronize_state(cs);
|
||||
do_restart_interrupt(&cpu->env);
|
||||
/*
|
||||
* Set OPERATING (and unhalting) before loading the restart PSW.
|
||||
* load_psw() will then properly halt the CPU again if necessary (TCG).
|
||||
*/
|
||||
s390_cpu_set_state(CPU_STATE_OPERATING, cpu);
|
||||
do_restart_interrupt(&cpu->env);
|
||||
break;
|
||||
case CPU_STATE_OPERATING:
|
||||
cpu_inject_restart(cpu);
|
||||
|
Loading…
Reference in New Issue
Block a user