Hello,
I am seeing a weird crash in my system and I am trying to figure out if
it is a software bug or a qemu emulation bug. From the software
perspective I am getting a GP fault at a time where it looks like
everything should be running normally. After digging into the Qemu
source code I found out where the GPF was coming from. It looks like
intno = -1 when it was being passed into do_interrupt64, which was
triggering one of the GPF checks. From what I can tell, intno was being
set to -1 by an interrupt_request in cpu-exec.c, which was going down
the following if statement around line 409 of that file:
else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
(((env->hflags2 & HF2_VINTR_MASK) &&
(env->hflags2 & HF2_HIF_MASK)) ||
(!(env->hflags2 & HF2_VINTR_MASK) &&
(env->eflags & IF_MASK &&
!(env->hflags &
HF_INHIBIT_IRQ_MASK)))))
and from within that else if statement, env has the following state:
hflags2 = 0x00000001
eflags = 0x00003202
hflags = 0x0040c0b7
interrupt request = 0x00000002
But intno is being set equal to -1 by the call to cpu_get_pic_interrupt,
from the call to apic_accept_pic_intr returning 0. If I change the
cpu_get_pic_interrupt code to this:
int cpu_get_pic_interrupt(CPUState *env)
{
int intno;
intno = apic_get_interrupt(env);
if (intno >= 0) {
/* set irq request if a PIC irq is still pending */
/* XXX: improve that */
pic_update_irq(isa_pic);
return intno;
}
/* read the irq from the PIC */
if (!apic_accept_pic_intr(env)) {
//return -1;
}
intno = pic_read_irq(isa_pic);
return intno;
}
Then the issue manifests as a spurious interrupt and the software
ignores it, avoiding the GPF. Does anyone have any ideas as to what is
going wrong here? Should I look more closely at the Qemu emulation code
or my software? Any help is appreciated.
Thanks!
--Sam