From patchwork Thu Oct 30 14:06:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFkaW0gS3LEjW3DocWZ?= X-Patchwork-Id: 5197991 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A6A9FC11AC for ; Thu, 30 Oct 2014 14:10:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CDF8A20165 for ; Thu, 30 Oct 2014 14:10:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D80422015D for ; Thu, 30 Oct 2014 14:10:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760213AbaJ3OIw (ORCPT ); Thu, 30 Oct 2014 10:08:52 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40863 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760163AbaJ3OIv (ORCPT ); Thu, 30 Oct 2014 10:08:51 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s9UE8nvn011650 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 30 Oct 2014 10:08:49 -0400 Received: from potion (dhcp-1-103.brq.redhat.com [10.34.1.103]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id s9UE8kJG031279; Thu, 30 Oct 2014 10:08:47 -0400 Received: by potion (sSMTP sendmail emulation); Thu, 30 Oct 2014 15:08:46 +0100 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= To: linux-kernel@vger.kernel.org Cc: kvm@vger.kernel.org, Paolo Bonzini , Gleb Natapov , Marcelo Tosatti Subject: [PATCH 1/3] KVM: x86: detect SPIV changes under APICv Date: Thu, 30 Oct 2014 15:06:45 +0100 Message-Id: <1414678007-9377-2-git-send-email-rkrcmar@redhat.com> In-Reply-To: <1414678007-9377-1-git-send-email-rkrcmar@redhat.com> References: <1414678007-9377-1-git-send-email-rkrcmar@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.5 required=5.0 tests=BAYES_00,HK_RANDOM_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP APICv traps register writes, so we can't retrieve previous value. (A bit of blame on Intel.) This caused a migration bug: LAPIC is enabled, so our restore code correctly lowers apic_sw_enabled, but doesn't increase it after APICv is disabled, so we get below zero when freeing it; resulting in this trace: WARNING: at kernel/jump_label.c:81 __static_key_slow_dec+0xa6/0xb0() jump label: negative count! [] dump_stack+0x19/0x1b [] warn_slowpath_common+0x61/0x80 [] warn_slowpath_fmt+0x5c/0x80 [] __static_key_slow_dec+0xa6/0xb0 [] static_key_slow_dec_deferred+0x16/0x20 [] kvm_free_lapic+0x88/0xa0 [kvm] [] kvm_arch_vcpu_uninit+0x2e/0xe0 [kvm] [] kvm_vcpu_uninit+0x21/0x40 [kvm] [] vmx_free_vcpu+0x47/0x70 [kvm_intel] [] kvm_arch_vcpu_free+0x50/0x60 [kvm] [] kvm_arch_destroy_vm+0x102/0x260 [kvm] [] ? synchronize_srcu+0x1d/0x20 [] kvm_put_kvm+0xe1/0x1c0 [kvm] [] kvm_vcpu_release+0x18/0x20 [kvm] [] __fput+0x102/0x310 [] ____fput+0xe/0x10 [] task_work_run+0xb4/0xe0 [] do_exit+0x304/0xc60 [] ? _raw_spin_unlock_irq+0x2c/0x50 [] ? trace_hardirqs_on_caller+0xfd/0x1c0 [] do_group_exit+0x4c/0xc0 [] SyS_exit_group+0x14/0x20 [] system_call_fastpath+0x16/0x1b Signed-off-by: Radim Kr?má? --- arch/x86/kvm/lapic.c | 10 ++++++---- arch/x86/kvm/lapic.h | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index b8345dd..f538b14 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -201,11 +201,13 @@ out: static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) { - u32 prev = kvm_apic_get_reg(apic, APIC_SPIV); + bool enabled = val & APIC_SPIV_APIC_ENABLED; apic_set_reg(apic, APIC_SPIV, val); - if ((prev ^ val) & APIC_SPIV_APIC_ENABLED) { - if (val & APIC_SPIV_APIC_ENABLED) { + + if (enabled != apic->sw_enabled) { + apic->sw_enabled = enabled; + if (enabled) { static_key_slow_dec_deferred(&apic_sw_disabled); recalculate_apic_map(apic->vcpu->kvm); } else @@ -1320,7 +1322,7 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu) if (!(vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE)) static_key_slow_dec_deferred(&apic_hw_disabled); - if (!(kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED)) + if (!apic->sw_enabled) static_key_slow_dec_deferred(&apic_sw_disabled); if (apic->regs) diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 6a11845..5fcc3d3 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -33,6 +33,7 @@ struct kvm_lapic { * Note: Only one register, the TPR, is used by the microcode. */ void *regs; + bool sw_enabled; gpa_t vapic_addr; struct gfn_to_hva_cache vapic_cache; unsigned long pending_events;