On 2011-09-03 10:58, Blue Swirl wrote: > On Thu, Sep 1, 2011 at 9:08 AM, Jan Kiszka wrote: >> The master PIC is connected to the LINTIN0 of the APICs. As the APIC >> currently does not track the state of that line, we have to ask the PIC >> to reinject its IRQ after the CPU picked up an event from the APIC. >> >> This introduces pic_get_output to read the master PIC IRQ line state >> without changing it. The APIC uses this function to decide if a PIC IRQ >> should be reinjected on apic_update_irq. This reflects better how the >> real hardware works. >> >> The patch fixes some failures of the kvm unit tests apic and eventinj by >> allowing to enable the proper CPU IRQ deassertion when the guest masks >> some pending IRQs at PIC level. >> >> Signed-off-by: Jan Kiszka >> --- >> >> Changes in v2: >> - Avoid adding pic_level to the APIC state, obtain PIC output via >> pic_get_level instead >> - Do not reassert PIC interrupt if APIC is not accepting it >> - Use apic_deliver_pic_intr for reassertion to ensure correct >> processing >> >> This is not as nice as the previous version /wrt the interaction of PIC >> and APIC. But it avoids breaking the APIC vmstate for the sake of >> internal changes, also keeping it compatible with the upcoming KVM >> in-kernel APIC (that allows no easy pic_level state extraction). The >> interconnection between PIC and APIC may look nicer in the future with >> QOM. And in the end this just reflects the "beauty" of the x86 >> architecture. >> >> hw/apic.c | 4 ++++ >> hw/i8259.c | 15 +++++++-------- >> hw/pc.c | 3 --- >> hw/pc.h | 2 +- >> 4 files changed, 12 insertions(+), 12 deletions(-) >> >> diff --git a/hw/apic.c b/hw/apic.c >> index d8f56c8..8289eef 100644 >> --- a/hw/apic.c >> +++ b/hw/apic.c >> @@ -23,6 +23,7 @@ >> #include "host-utils.h" >> #include "sysbus.h" >> #include "trace.h" >> +#include "pc.h" >> >> /* APIC Local Vector Table */ >> #define APIC_LVT_TIMER 0 >> @@ -399,6 +400,9 @@ static void apic_update_irq(APICState *s) >> } >> if (apic_irq_pending(s) > 0) { >> cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); >> + } else if (apic_accept_pic_intr(&s->busdev.qdev) && >> + pic_get_output(isa_pic)) { > > This is indeed ugly. Why doesn't APIC track PIC output? For the reasons explained above. Jan