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