From patchwork Wed Sep 14 05:54:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Wanpeng Li X-Patchwork-Id: 669732 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sYrQy4S10z9s9x for ; Wed, 14 Sep 2016 15:56:58 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=AmPe12qx; dkim-atps=neutral Received: from localhost ([::1]:53258 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bk3Bo-00036b-6d for incoming@patchwork.ozlabs.org; Wed, 14 Sep 2016 01:56:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33251) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bk3Ab-0002EK-2j for qemu-devel@nongnu.org; Wed, 14 Sep 2016 01:55:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bk3AV-0003Z4-W1 for qemu-devel@nongnu.org; Wed, 14 Sep 2016 01:55:41 -0400 Received: from mail-pa0-f66.google.com ([209.85.220.66]:35873) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bk3AV-0003Yj-KF for qemu-devel@nongnu.org; Wed, 14 Sep 2016 01:55:35 -0400 Received: by mail-pa0-f66.google.com with SMTP id p2so243464pap.3 for ; Tue, 13 Sep 2016 22:55:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=RbLNnThRN89HXLdhgXbGP40neovcnKuQCAajIvjdTy8=; b=AmPe12qxIdqaRPIEXeB4WXU/fJFvXyvNPXowXJKje7Qld4oQCFWTkAjRXC9saa52zD 6T04Gtx5Qh53V+gyyIwfTyNhPVoccXQEGCJxD8APyhisnMULRCoMdUrFTMfX9j1li8wa RzTbGjuPbK6A0+6bBRO4nZqHEVb/QeiPhxEpp9SdOyAiuulzs62Fvuwb4QP0bs530Zs6 Q5PV3CJQdyHY4eIy8W+35FCOc8lm17J6j6laQ52gjthU8PiWzy08Ya4k/qZo6X/NEp+T aO4JEkb1amftloF8q8A9Mz4nLO0moP2UBwlzH6NN/8f7A5UkkR95EtHDJ4iAx6QDjSGG Kt7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=RbLNnThRN89HXLdhgXbGP40neovcnKuQCAajIvjdTy8=; b=SNc0qQ9rcFtOCd3KP0b5DeIjmNQec3D8hcGSxXAPQbIpVSBiigcIuIMubNmUuygyxj VKH8kyqsVsbrlegIp3Dd6GOmbS3DzL1wns1KnudePGR2JokShfOWusynZYW973t2wPDN B9mMeqI7QDqGbOMvTdMSksKRpFHKDz60uS49qi82z0pmfoCAwz3vpt0oYMBtklSgaME+ /q55uRfeHsxz9Vg6eIh64zadiEXlR6VYgjqyfEmyRCyKX/8mSvtXynPZpLqqtWiV/TTL lF89YbyhVSIbEDCn0/vDLCPQDuOeH/BpOw8EcTk6PNcTq24P44Fg93Fvy7V6TYnGHOJB 7XaA== X-Gm-Message-State: AE9vXwO8dvDxtsR2FAVJOYNONxKKU+O/k0XSWyNykic5dNFhMe6mM4oS3PeMlj3W2lA8Zg== X-Received: by 10.66.72.8 with SMTP id z8mr1308660pau.141.1473832474651; Tue, 13 Sep 2016 22:54:34 -0700 (PDT) Received: from kernel.kingsoft.cn ([114.255.44.132]) by smtp.gmail.com with ESMTPSA id d14sm34864652pfb.50.2016.09.13.22.54.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 13 Sep 2016 22:54:33 -0700 (PDT) From: Wanpeng Li X-Google-Original-From: Wanpeng Li To: kvm@vger.kernel.org, qemu-devel@nongnu.org Date: Wed, 14 Sep 2016 13:54:24 +0800 Message-Id: <1473832464-3478-1-git-send-email-wanpeng.li@hotmail.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.85.220.66 Subject: [Qemu-devel] [PATCH v2] pc: apic: fix touch LAPIC when irqchip is split X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , "Michael S. Tsirkin" , Eduardo Habkost , Wanpeng Li , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Wanpeng Li 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 Suggested-by: Radim Krčmář Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Michael S. Tsirkin Cc: Eduardo Habkost Signed-off-by: Wanpeng Li Reviewed-by: Radim Krčmář --- v1 -> v2: * cleanup coding style issue hw/i386/pc.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e31f70f..4f3d508 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -161,14 +161,16 @@ 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); return intno; @@ -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)) {