cpu_get_pic_interrupt() returns -1 when neither PIC nor APIC has anything to deliver, and skipping this check produces a bogus #GP inside the guest with an error code of 0xFFFFFFFA (aka -1 * 8 | (1 << 1)) due to a failed IDT limit check in do_interrupt_x86_hardirq().
The KVM path already drops such interrupts in kvm_arch_pre_run(), so just do the same thing. Signed-off-by: Daniil Tatianin <[email protected]> --- target/i386/tcg/system/seg_helper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/i386/tcg/system/seg_helper.c b/target/i386/tcg/system/seg_helper.c index 8c7856be81..d1c626f120 100644 --- a/target/i386/tcg/system/seg_helper.c +++ b/target/i386/tcg/system/seg_helper.c @@ -204,6 +204,9 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request) cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0, 0); cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); intno = cpu_get_pic_interrupt(env); + if (intno < 0) { + break; + } qemu_log_mask(CPU_LOG_INT, "Servicing hardware INT=0x%02x\n", intno); do_interrupt_x86_hardirq(env, intno, 1); -- 2.43.0
