mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 02:03:56 -06:00
s390x/tcg: deliver multiple interrupts in a row
We have to consider all deliverable interrupts. We now have to take care of the special scenario, where we first inject an interrupt with a WAIT PSW, followed by a !WAIT PSW. (very unlikely but possible) Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20180129125623.21729-2-david@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
parent
12f15c9155
commit
ce204cba74
1 changed files with 16 additions and 4 deletions
|
@ -433,10 +433,12 @@ void s390_cpu_do_interrupt(CPUState *cs)
|
||||||
{
|
{
|
||||||
S390CPU *cpu = S390_CPU(cs);
|
S390CPU *cpu = S390_CPU(cs);
|
||||||
CPUS390XState *env = &cpu->env;
|
CPUS390XState *env = &cpu->env;
|
||||||
|
bool stopped = false;
|
||||||
|
|
||||||
qemu_log_mask(CPU_LOG_INT, "%s: %d at pc=%" PRIx64 "\n",
|
qemu_log_mask(CPU_LOG_INT, "%s: %d at pc=%" PRIx64 "\n",
|
||||||
__func__, cs->exception_index, env->psw.addr);
|
__func__, cs->exception_index, env->psw.addr);
|
||||||
|
|
||||||
|
try_deliver:
|
||||||
/* handle machine checks */
|
/* handle machine checks */
|
||||||
if (cs->exception_index == -1 && s390_cpu_has_mcck_int(cpu)) {
|
if (cs->exception_index == -1 && s390_cpu_has_mcck_int(cpu)) {
|
||||||
cs->exception_index = EXCP_MCHK;
|
cs->exception_index = EXCP_MCHK;
|
||||||
|
@ -479,13 +481,14 @@ void s390_cpu_do_interrupt(CPUState *cs)
|
||||||
break;
|
break;
|
||||||
case EXCP_STOP:
|
case EXCP_STOP:
|
||||||
do_stop_interrupt(env);
|
do_stop_interrupt(env);
|
||||||
|
stopped = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WAIT PSW during interrupt injection or STOP interrupt */
|
if (cs->exception_index != -1 && !stopped) {
|
||||||
if (cs->exception_index == EXCP_HLT) {
|
/* check if there are more pending interrupts to deliver */
|
||||||
/* don't trigger a cpu_loop_exit(), use an interrupt instead */
|
cs->exception_index = -1;
|
||||||
cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HALT);
|
goto try_deliver;
|
||||||
}
|
}
|
||||||
cs->exception_index = -1;
|
cs->exception_index = -1;
|
||||||
|
|
||||||
|
@ -493,6 +496,15 @@ void s390_cpu_do_interrupt(CPUState *cs)
|
||||||
if (!env->pending_int) {
|
if (!env->pending_int) {
|
||||||
cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
|
cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* WAIT PSW during interrupt injection or STOP interrupt */
|
||||||
|
if ((env->psw.mask & PSW_MASK_WAIT) || stopped) {
|
||||||
|
/* don't trigger a cpu_loop_exit(), use an interrupt instead */
|
||||||
|
cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HALT);
|
||||||
|
} else if (cs->halted) {
|
||||||
|
/* unhalt if we had a WAIT PSW somehwere in our injection chain */
|
||||||
|
s390_cpu_unhalt(cpu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue