[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 08/17] pc: apic: fix touch LAPIC when irqchip is spli
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PULL 08/17] pc: apic: fix touch LAPIC when irqchip is split |
Date: |
Thu, 15 Sep 2016 16:21:47 +0200 |
From: Wanpeng Li <address@hidden>
Add -kernel_irqchip=split
./x86-run x86/eventinj.flat
qemu-system-x86_64 -enable-kvm -machine kernel_irqchip=split -cpu host
-device pc-testdev -device isa-debug-exit,iobase=0xf4,iosize=0x4 -vnc
none -serial stdio -device pci-testdev -kernel x86/eventinj.flat
enabling apic
paging enabled
cr0 = 80010011
cr3 = 7fff000
cr4 = 20
Sending vec 33 and 62 and mask one with TPR
irq1 running
irq1 running
After 33/62 TPR test
FAIL: TPR
irq0 running
irq0 running
Both irq1 and irq0 are executing twice.
kvm_entry: vcpu 0
kvm_exit: reason MSR_WRITE rip 0x401f33 info 0 0
kvm_apic: apic_write APIC_EOI = 0x0
kvm_eoi: apicid 0 vector 62
kvm_msr: msr_write 80b = 0x0
kvm_entry: vcpu 0
kvm_exit: reason PENDING_INTERRUPT rip 0x401f35 info 0 0
kvm_userspace_exit: reason KVM_EXIT_IRQ_WINDOW_OPEN (7)
kvm_inj_virq: irq 62
kvm_entry: vcpu 0
kvm_exit: reason IO_INSTRUCTION rip 0x4016ec info 3fd0008 0
>From the trace we can see there is an interrupt window exit
after the first interrupt EOI(irq 62), and the same irq(62)
is injected duplicately after the interrupt window.
QEMU does KVM_INTERRUPT(62) ioctl after KVM exits with
KVM_EXIT_IRQ_WINDOW_OPEN, which QEMU requested while the
guest was printing. The printing calls
serial_update_irq() -> qemu_irq_lower() -> qemu_set_irq() ->
gsi_handler() -> qemu_set_irq() -> pic_irq_request() ->
apic_deliver_pic_intr() -> kvm_handle_interrupt()
kvm_handle_interrupt() does
interrupt_request |= CPU_INTERRUPT_HARD
which later calls cpu_get_pic_interrupt() in kvm_arch_pre_run(),
but that function uses stale information from APIC and injects
62 again. If we synchronized the APIC, then the test would #GP,
because there would be no injectable interrupt in LAPIC or PIC,
so pic_read_irq() would return 15, thinking it was spurious.
This patch fix it by don't touch LAPIC if LAPIC is in kernel.
Suggested-by: Paolo Bonzini <address@hidden>
Suggested-by: Radim Krčmář <address@hidden>
Cc: address@hidden
Cc: Paolo Bonzini <address@hidden>
Cc: Radim Krčmář <address@hidden>
Cc: Michael S. Tsirkin <address@hidden>
Cc: Eduardo Habkost <address@hidden>
Signed-off-by: Wanpeng Li <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
hw/i386/pc.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e31f70f..2d6d792 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -161,13 +161,15 @@ int cpu_get_pic_interrupt(CPUX86State *env)
X86CPU *cpu = x86_env_get_cpu(env);
int intno;
- intno = apic_get_interrupt(cpu->apic_state);
- if (intno >= 0) {
- return intno;
- }
- /* read the irq from the PIC */
- if (!apic_accept_pic_intr(cpu->apic_state)) {
- return -1;
+ if (!kvm_irqchip_in_kernel()) {
+ intno = apic_get_interrupt(cpu->apic_state);
+ if (intno >= 0) {
+ return intno;
+ }
+ /* read the irq from the PIC */
+ if (!apic_accept_pic_intr(cpu->apic_state)) {
+ return -1;
+ }
}
intno = pic_read_irq(isa_pic);
@@ -180,7 +182,7 @@ static void pic_irq_request(void *opaque, int irq, int
level)
X86CPU *cpu = X86_CPU(cs);
DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
- if (cpu->apic_state) {
+ if (cpu->apic_state && !kvm_irqchip_in_kernel()) {
CPU_FOREACH(cs) {
cpu = X86_CPU(cs);
if (apic_accept_pic_intr(cpu->apic_state)) {
--
1.8.3.1
- [Qemu-devel] [PULL 00/17] Second batch of misc patches for QEMU 2.8, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 01/17] scsi-disk: Cleaning up around tray open state, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 03/17] scsi: mptsas: use g_new0 to allocate MPTSASRequest object, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 02/17] virtio-scsi: Don't abort when media is ejected, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 04/17] cutils: Rewrite x86 buffer zero checking, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 05/17] Change net/socket.c to use socket_*() functions, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 06/17] memory: remove memory_region_destructor_rom_device, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 07/17] scsi: pvscsi: limit process IO loop to ring size, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 08/17] pc: apic: fix touch LAPIC when irqchip is split,
Paolo Bonzini <=
- [Qemu-devel] [PULL 09/17] target-i386: fix ordering of fields in CPUX86State, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 10/17] linux-user: complete omission of removing uses of strdup, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 11/17] build-sys: add make 'help' target, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 12/17] qemu-char: avoid segfault if user lacks of permisson of a given logfile, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 13/17] log: fix parsing of multiple trace:PATTERN log args, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 14/17] target-i386: Fixed syscall posssible segfault, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 15/17] pc: apic: introduce APIC macro, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 16/17] kvmvapic: fix state change handler, Paolo Bonzini, 2016/09/15
- [Qemu-devel] [PULL 17/17] pcspk: adding vmstate for save/restore, Paolo Bonzini, 2016/09/15
- Re: [Qemu-devel] [PULL 00/17] Second batch of misc patches for QEMU 2.8, no-reply, 2016/09/15