From patchwork Tue Sep 13 09:56:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Dr. David Alan Gilbert" X-Patchwork-Id: 9328677 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id F39FC6077F for ; Tue, 13 Sep 2016 09:56:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E54E12925D for ; Tue, 13 Sep 2016 09:56:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D8BF429286; Tue, 13 Sep 2016 09:56:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_HK_NAME_DR autolearn=ham version=3.3.1 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 mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4D8A62925D for ; Tue, 13 Sep 2016 09:56:57 +0000 (UTC) Received: from localhost ([::1]:47601 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjkSX-0000nO-85 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 13 Sep 2016 05:56:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59408) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjkRq-0000ZC-Oi for qemu-devel@nongnu.org; Tue, 13 Sep 2016 05:56:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bjkRl-0008Gr-PN for qemu-devel@nongnu.org; Tue, 13 Sep 2016 05:56:13 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49102) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjkRl-0008Gm-IP for qemu-devel@nongnu.org; Tue, 13 Sep 2016 05:56:09 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E115643A3D; Tue, 13 Sep 2016 09:56:08 +0000 (UTC) Received: from dgilbert-t530.redhat.com (ovpn-116-91.ams2.redhat.com [10.36.116.91]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8D9u7PI000596; Tue, 13 Sep 2016 05:56:07 -0400 From: "Dr. David Alan Gilbert (git)" To: qemu-devel@nongnu.org, pbonzini@redhat.com, rth@twiddle.net, ehabkost@redhat.com Date: Tue, 13 Sep 2016 10:56:06 +0100 Message-Id: <1473760566-12374-1-git-send-email-dgilbert@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 13 Sep 2016 09:56:09 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH] x86/lapic: Load LAPIC state at post_load 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: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: "Dr. David Alan Gilbert" Load the LAPIC state during post_load (rather than when the CPU starts). This allows an interrupt to be delivered from the ioapic to the lapic prior to cpu loading, in particular the RTC that starts ticking as soon as we load it's state. Partially fixes a case where Windows hangs after migration due to RTC interrupts disappearing; it survived ~30 iterations of my test where as without it we didn't get to 2. Still something else to be found yet. Signed-off-by: Dr. David Alan Gilbert Suggested-by: Paolo Bonzini --- hw/i386/kvm/apic.c | 27 +++++++++++++++++++++++++-- include/sysemu/kvm.h | 1 - target-i386/kvm.c | 17 ----------------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c index 2bd0de8..343d250 100644 --- a/hw/i386/kvm/apic.c +++ b/hw/i386/kvm/apic.c @@ -28,9 +28,9 @@ static inline uint32_t kvm_apic_get_reg(struct kvm_lapic_state *kapic, return *((uint32_t *)(kapic->regs + (reg_id << 4))); } -void kvm_put_apic_state(DeviceState *dev, struct kvm_lapic_state *kapic) +static void kvm_put_apic_state(APICCommonState *s, + struct kvm_lapic_state *kapic) { - APICCommonState *s = APIC_COMMON(dev); int i; memset(kapic, 0, sizeof(*kapic)); @@ -125,6 +125,26 @@ static void kvm_apic_vapic_base_update(APICCommonState *s) } } +static void kvm_apic_put(void *data) +{ + APICCommonState *s = data; + struct kvm_lapic_state kapic; + int ret; + + kvm_put_apic_state(s, &kapic); + + ret = kvm_vcpu_ioctl(CPU(s->cpu), KVM_SET_LAPIC, &kapic); + if (ret < 0) { + fprintf(stderr, "KVM_SET_LAPIC failed: %s\n", strerror(ret)); + abort(); + } +} + +static void kvm_apic_post_load(APICCommonState *s) +{ + run_on_cpu(CPU(s->cpu), kvm_apic_put, s); +} + static void do_inject_external_nmi(void *data) { APICCommonState *s = data; @@ -178,6 +198,8 @@ static void kvm_apic_reset(APICCommonState *s) { /* Not used by KVM, which uses the CPU mp_state instead. */ s->wait_for_sipi = 0; + + run_on_cpu(CPU(s->cpu), kvm_apic_put, s); } static void kvm_apic_realize(DeviceState *dev, Error **errp) @@ -206,6 +228,7 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data) k->set_base = kvm_apic_set_base; k->set_tpr = kvm_apic_set_tpr; k->get_tpr = kvm_apic_get_tpr; + k->post_load = kvm_apic_post_load; k->enable_tpr_reporting = kvm_apic_enable_tpr_reporting; k->vapic_base_update = kvm_apic_vapic_base_update; k->external_nmi = kvm_apic_external_nmi; diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index c9c2436..ae5d81b 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -372,7 +372,6 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg); void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin); -void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic); void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic); struct kvm_guest_debug; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index d1a25c5..f1ad805 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -2416,19 +2416,6 @@ static int kvm_get_apic(X86CPU *cpu) return 0; } -static int kvm_put_apic(X86CPU *cpu) -{ - DeviceState *apic = cpu->apic_state; - struct kvm_lapic_state kapic; - - if (apic && kvm_irqchip_in_kernel()) { - kvm_put_apic_state(apic, &kapic); - - return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_LAPIC, &kapic); - } - return 0; -} - static int kvm_put_vcpu_events(X86CPU *cpu, int level) { CPUState *cs = CPU(cpu); @@ -2670,10 +2657,6 @@ int kvm_arch_put_registers(CPUState *cpu, int level) if (ret < 0) { return ret; } - ret = kvm_put_apic(x86_cpu); - if (ret < 0) { - return ret; - } } ret = kvm_put_tscdeadline_msr(x86_cpu);