From patchwork Thu Mar 24 17:19:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Durrant X-Patchwork-Id: 8663271 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 321F09F44D for ; Thu, 24 Mar 2016 17:33:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3CA0B20382 for ; Thu, 24 Mar 2016 17:33:26 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3CD632035B for ; Thu, 24 Mar 2016 17:33:25 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1aj95r-0002ND-DA; Thu, 24 Mar 2016 17:30:47 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1aj95q-0002Mo-0x for xen-devel@lists.xenproject.org; Thu, 24 Mar 2016 17:30:46 +0000 Received: from [193.109.254.147] by server-12.bemta-14.messagelabs.com id E2/F2-02979-54424F65; Thu, 24 Mar 2016 17:30:45 +0000 X-Env-Sender: prvs=88499b8e4=Paul.Durrant@citrix.com X-Msg-Ref: server-3.tower-27.messagelabs.com!1458840643!33363698!1 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 8.11; banners=-,-,- X-VirusChecked: Checked Received: (qmail 2191 invoked from network); 24 Mar 2016 17:30:44 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-3.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 24 Mar 2016 17:30:44 -0000 X-IronPort-AV: E=Sophos;i="5.24,386,1454976000"; d="scan'208";a="348476656" From: Paul Durrant To: Date: Thu, 24 Mar 2016 17:19:57 +0000 Message-ID: <1458839997-6597-1-git-send-email-paul.durrant@citrix.com> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 X-DLP: MIA2 Cc: Paul Durrant , Jan Beulich Subject: [Xen-devel] [PATCH] x86/hvm/viridian: save APIC assist vector X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 If any vcpu has a pending APIC assist when the domain is suspended then the vector needs to be saved. If this is not done then it's possible for the vector to remain pending in the vlapic ISR indefinitely after resume. This patch adds code to save the APIC assist vector value in the viridian vcpu save record. This means that the record is now zero- extended on load and, because this implies a loaded value of zero means nothing is pending (for backwards compatibility with hosts not implementing APIC assist), the rest of the viridian APIC assist code is adjusted to treat a zero value in this way. Signed-off-by: Paul Durrant Cc: Jan Beulich --- xen/arch/x86/hvm/viridian.c | 27 ++++++++++++++++++--------- xen/include/public/arch-x86/hvm/save.h | 3 ++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/hvm/viridian.c b/xen/arch/x86/hvm/viridian.c index 410320c..8e858d2 100644 --- a/xen/arch/x86/hvm/viridian.c +++ b/xen/arch/x86/hvm/viridian.c @@ -252,7 +252,6 @@ static void initialize_apic_assist(struct vcpu *v) if ( viridian_feature_mask(v->domain) & HVMPV_apic_assist ) { v->arch.hvm_vcpu.viridian.apic_assist.va = va; - v->arch.hvm_vcpu.viridian.apic_assist.vector = -1; return; } @@ -293,10 +292,11 @@ void viridian_start_apic_assist(struct vcpu *v, int vector) * wrong and the VM will most likely hang so force a crash now * to make the problem clear. */ - if ( v->arch.hvm_vcpu.viridian.apic_assist.vector >= 0 ) + if ( v->arch.hvm_vcpu.viridian.apic_assist.vector != 0 ) domain_crash(v->domain); - v->arch.hvm_vcpu.viridian.apic_assist.vector = vector; + /* Increment the value so that zero is always invalid. */ + v->arch.hvm_vcpu.viridian.apic_assist.vector = vector + 1; *va |= 1u; } @@ -311,8 +311,8 @@ int viridian_complete_apic_assist(struct vcpu *v) if ( *va & 1u ) return -1; /* Interrupt not yet processed by the guest. */ - vector = v->arch.hvm_vcpu.viridian.apic_assist.vector; - v->arch.hvm_vcpu.viridian.apic_assist.vector = -1; + vector = v->arch.hvm_vcpu.viridian.apic_assist.vector - 1; + v->arch.hvm_vcpu.viridian.apic_assist.vector = 0; return vector; } @@ -325,7 +325,7 @@ void viridian_abort_apic_assist(struct vcpu *v) return; *va &= ~1u; - v->arch.hvm_vcpu.viridian.apic_assist.vector = -1; + v->arch.hvm_vcpu.viridian.apic_assist.vector = 0; } static void update_reference_tsc(struct domain *d, bool_t initialize) @@ -806,7 +806,8 @@ static int viridian_save_vcpu_ctxt(struct domain *d, hvm_domain_context_t *h) for_each_vcpu( d, v ) { struct hvm_viridian_vcpu_context ctxt; - ctxt.apic_assist = v->arch.hvm_vcpu.viridian.apic_assist.msr.raw; + ctxt.apic_assist_msr = v->arch.hvm_vcpu.viridian.apic_assist.msr.raw; + ctxt.apic_assist_vector = v->arch.hvm_vcpu.viridian.apic_assist.vector; if ( hvm_save_entry(VIRIDIAN_VCPU, v->vcpu_id, h, &ctxt) != 0 ) return 1; @@ -829,13 +830,21 @@ static int viridian_load_vcpu_ctxt(struct domain *d, hvm_domain_context_t *h) return -EINVAL; } - if ( hvm_load_entry(VIRIDIAN_VCPU, h, &ctxt) != 0 ) + if ( hvm_load_entry_zeroextend(VIRIDIAN_VCPU, h, &ctxt) != 0 ) return -EINVAL; - v->arch.hvm_vcpu.viridian.apic_assist.msr.raw = ctxt.apic_assist; + v->arch.hvm_vcpu.viridian.apic_assist.msr.raw = ctxt.apic_assist_msr; if ( v->arch.hvm_vcpu.viridian.apic_assist.msr.fields.enabled ) initialize_apic_assist(v); + /* + * Guests that were saved on a host that did not use APIC assist + * will clearly never have a pending assist, so reading the zero + * value for apic_assist_vector from the zero extended save record + * will always be correct. + */ + v->arch.hvm_vcpu.viridian.apic_assist.vector = ctxt.apic_assist_vector; + return 0; } diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/arch-x86/hvm/save.h index fbd1c6a..fc8e8f9 100644 --- a/xen/include/public/arch-x86/hvm/save.h +++ b/xen/include/public/arch-x86/hvm/save.h @@ -588,7 +588,8 @@ struct hvm_viridian_domain_context { DECLARE_HVM_SAVE_TYPE(VIRIDIAN_DOMAIN, 15, struct hvm_viridian_domain_context); struct hvm_viridian_vcpu_context { - uint64_t apic_assist; + uint64_t apic_assist_msr; + uint16_t apic_assist_vector; }; DECLARE_HVM_SAVE_TYPE(VIRIDIAN_VCPU, 17, struct hvm_viridian_vcpu_context);