From f278d4947fff814dcde2ef2acad36d172ff8be35 Mon Sep 17 00:00:00 2001 From: Matthew Ogilvie Date: Thu, 23 Aug 2012 00:24:43 -0600 Subject: 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 Signed-off-by: malc --- cpu-exec.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'cpu-exec.c') diff --git a/cpu-exec.c b/cpu-exec.c index 134b3c4..625fbb0 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) && -- cgit v1.1