HP-UX (all versions) is losing timer interrupts, which leads to hangs. Pressing a key on the console fixes this, so it looks like QEMU is just looping trough TBs without checking for interrupts. Further investion showed that this happens when interrupts are triggered, without PSW_I enabled. Calling eval_interrupt() after PSW_I is set seems to fix this.
Signed-off-by: Sven Schnelle <sv...@stackframe.org> --- target/hppa/cpu.h | 1 + target/hppa/int_helper.c | 2 +- target/hppa/op_helper.c | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index d808796ee3..3440ccad28 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -366,5 +366,6 @@ void hppa_cpu_alarm_timer(void *); int hppa_artype_for_page(CPUHPPAState *env, target_ulong vaddr); #endif void QEMU_NORETURN hppa_dynamic_excp(CPUHPPAState *env, int excp, uintptr_t ra); +void eval_interrupt(HPPACPU *cpu); #endif /* HPPA_CPU_H */ diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c index 8d5edd3a20..e3acaa39eb 100644 --- a/target/hppa/int_helper.c +++ b/target/hppa/int_helper.c @@ -25,7 +25,7 @@ #include "qom/cpu.h" #ifndef CONFIG_USER_ONLY -static void eval_interrupt(HPPACPU *cpu) +void eval_interrupt(HPPACPU *cpu) { CPUState *cs = CPU(cpu); if (cpu->env.cr[CR_EIRR] & cpu->env.cr[CR_EIEM]) { diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c index a55a5dfc02..f93211c84f 100644 --- a/target/hppa/op_helper.c +++ b/target/hppa/op_helper.c @@ -662,6 +662,7 @@ void HELPER(reset)(CPUHPPAState *env) target_ureg HELPER(swap_system_mask)(CPUHPPAState *env, target_ureg nsm) { + HPPACPU *cpu = hppa_env_get_cpu(env); target_ulong psw = env->psw; /* * Setting the PSW Q bit to 1, if it was not already 1, is an @@ -673,6 +674,11 @@ target_ureg HELPER(swap_system_mask)(CPUHPPAState *env, target_ureg nsm) * so let this go without comment. */ env->psw = (psw & ~PSW_SM) | (nsm & PSW_SM); + if (!(psw & PSW_I) && (nsm & PSW_I)) { + qemu_mutex_lock_iothread(); + eval_interrupt(cpu); + qemu_mutex_unlock_iothread(); + } return psw & PSW_SM; } -- 2.20.1