summary refs log tree commit diff stats
path: root/cpu-exec.c
diff options
context:
space:
mode:
authorMatthew Ogilvie <mmogilvi_qemu@miniinfo.net>2012-08-23 00:24:43 -0600
committermalc <av1474@comtv.ru>2012-08-24 07:44:39 +0400
commitf278d4947fff814dcde2ef2acad36d172ff8be35 (patch)
treec483f5871bb83294728a3b3026206c56ad7485a9 /cpu-exec.c
parent482f7bf86b43af9f6903c52726fedf82b28bf953 (diff)
downloadfocaccia-qemu-f278d4947fff814dcde2ef2acad36d172ff8be35.tar.gz
focaccia-qemu-f278d4947fff814dcde2ef2acad36d172ff8be35.zip
i8259: add -no-spurious-interrupt-hack option
This patch provides a way to optionally suppress spurious interrupts,
as a workaround for systems described below:

Some old operating systems do not handle spurious interrupts well,
and qemu tends to generate them significantly more often than
real hardware.

Examples:
  - Microport UNIX System V/386 v 2.1 (ca 1987)
    (The main problem I'm fixing: Without this patch, it panics
    sporadically when accessing the hard disk.)
  - AT&T UNIX System V/386 Release 4.0 Version 2.1a (ca 1991)
    See screenshot in "QEMU Official OS Support List":
    http://www.claunia.com/qemu/objectManager.php?sClass=application&iId=9
    (I don't have this system to test.)
  - A report about OS/2 boot lockup from 2004 by Hampa Hug:
    http://lists.nongnu.org/archive/html/qemu-devel/2004-09/msg00367.html
    (My patch was partially inspired by his.)
    Also: http://lists.nongnu.org/archive/html/qemu-devel/2005-06/msg00243.html
    (I don't have this system to test.)

Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
Signed-off-by: malc <av1474@comtv.ru>
Diffstat (limited to 'cpu-exec.c')
-rw-r--r--cpu-exec.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/cpu-exec.c b/cpu-exec.c
index 134b3c4fcf..625fbb0e0f 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -329,11 +329,15 @@ int cpu_exec(CPUArchState *env)
                                                           0);
                             env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
                             intno = cpu_get_pic_interrupt(env);
-                            qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
-                            do_interrupt_x86_hardirq(env, intno, 1);
-                            /* ensure that no TB jump will be modified as
-                               the program flow was changed */
-                            next_tb = 0;
+                            if (intno >= 0) {
+                                qemu_log_mask(CPU_LOG_TB_IN_ASM,
+                                              "Servicing hardware INT=0x%02x\n",
+                                              intno);
+                                do_interrupt_x86_hardirq(env, intno, 1);
+                                /* ensure that no TB jump will be modified as
+                                   the program flow was changed */
+                                next_tb = 0;
+                            }
 #if !defined(CONFIG_USER_ONLY)
                         } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
                                    (env->eflags & IF_MASK) &&