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


Reply via email to