From patchwork Mon Mar 27 10:18:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 9646345 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 93A9F602D6 for ; Mon, 27 Mar 2017 10:20:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9224C2837F for ; Mon, 27 Mar 2017 10:20:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 85EB328387; Mon, 27 Mar 2017 10:20:59 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 61FE52837F for ; Mon, 27 Mar 2017 10:20:58 +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 1csRjY-00073t-U6; Mon, 27 Mar 2017 10:18:44 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1csRjY-00073O-AU for xen-devel@lists.xenproject.org; Mon, 27 Mar 2017 10:18:44 +0000 Received: from [193.109.254.147] by server-6.bemta-6.messagelabs.com id 55/AD-15112-307E8D85; Mon, 27 Mar 2017 10:18:43 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrCIsWRWlGSWpSXmKPExsWyU9JRQpfp+Y0 Ig7vLbSy+b5nM5MDocfjDFZYAxijWzLyk/IoE1oxf0/gL5kdV7Dwg3cC43L2LkZNDQsBPYsL5 b8wgNpuAjsTFuTvZuhg5OEQEVCRu7zUAMZkFyiVm3IgHqRAWCJH4fuEcC4jNIqAq8WnOA0YQm 1fAUmLO29PsEBPlJR5tegQ2hVPASuLsvgqQsBBQSee+LnaIckGJkzOfgI1hFtCUaN3+mx3Clp do3jqbGaJeUaJ/3gM2iJHpElv//mKewMg/C0n7LCTts5C0L2BkXsWoUZxaVJZapGtkoZdUlJm eUZKbmJmja2hgppebWlycmJ6ak5hUrJecn7uJERh6DECwg/H82sBDjJIcTEqivB9O34gQ4kvK T6nMSCzOiC8qzUktPsQow8GhJMGb/RQoJ1iUmp5akZaZA4wCmLQEB4+SCO+BJ0Bp3uKCxNziz HSI1ClGRSlx3kKQPgGQREZpHlwbLPIuMcpKCfMyAh0ixFOQWpSbWYIq/4pRnINRSZh3M8gUns y8Erjpr4AWMwEtPjwfbHFJIkJKqoFRJ9LNNrxGr3n78wrmpQ5a8h+bFgkzxotySYi0T+Kaz51 0slSAT+MX1/ezTxV3ytcqsDdnn50m7Mq06dKRZ2eF2l/xJvJ8PRIj+yH31468BPlG2bDfk6Nt n/Skq7659+/3319vSw5pTXnA8l5qPcdWCbfIbOXtkm/cY47sestWE7vGWI3huKMSS3FGoqEWc 1FxIgD69ie6twIAAA== X-Env-Sender: prvs=25239713d=roger.pau@citrix.com X-Msg-Ref: server-8.tower-27.messagelabs.com!1490609913!83588185!4 X-Originating-IP: [185.25.65.24] X-SpamReason: No, hits=0.0 required=7.0 tests=received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 26225 invoked from network); 27 Mar 2017 10:18:42 -0000 Received: from smtp.eu.citrix.com (HELO SMTP.EU.CITRIX.COM) (185.25.65.24) by server-8.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 27 Mar 2017 10:18:42 -0000 X-IronPort-AV: E=Sophos;i="5.36,231,1486425600"; d="scan'208";a="43158876" From: Roger Pau Monne To: Date: Mon, 27 Mar 2017 11:18:19 +0100 Message-ID: <20170327101823.99368-4-roger.pau@citrix.com> X-Mailer: git-send-email 2.12.1 In-Reply-To: <20170327101823.99368-1-roger.pau@citrix.com> References: <20170327101823.99368-1-roger.pau@citrix.com> MIME-Version: 1.0 X-ClientProxiedBy: AMSPEX02CAS01.citrite.net (10.69.22.112) To AMSPEX02CL02.citrite.net (10.69.22.126) Cc: Andrew Cooper , Jan Beulich , Roger Pau Monne Subject: [Xen-devel] [PATCH v2 3/7] x86/hvm: convert gsi_assert_count into a variable size array 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-Virus-Scanned: ClamAV using ClamSMTP Rearrange the fields of hvm_irq so that gsi_assert_count can be converted into a variable size array and add a new field to account the number of GSIs. Due to this changes the irq member in the hvm_domain struct also needs to become a pointer set at runtime. Signed-off-by: Roger Pau Monné --- Cc: Jan Beulich Cc: Andrew Cooper --- xen/arch/x86/hvm/hvm.c | 13 +++++++++++-- xen/arch/x86/hvm/irq.c | 27 +++++++++++++++++++++------ xen/drivers/passthrough/io.c | 8 ++++---- xen/drivers/passthrough/pci.c | 2 +- xen/include/asm-x86/domain.h | 2 +- xen/include/asm-x86/hvm/domain.h | 2 +- xen/include/asm-x86/hvm/irq.h | 28 +++++++++++++++------------- 7 files changed, 54 insertions(+), 28 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 0282986738..9a6cd9c9bf 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -457,7 +457,7 @@ void hvm_migrate_pirqs(struct vcpu *v) { struct domain *d = v->domain; - if ( !iommu_enabled || !d->arch.hvm_domain.irq.dpci ) + if ( !iommu_enabled || !d->arch.hvm_domain.irq->dpci ) return; spin_lock(&d->event_lock); @@ -619,11 +619,16 @@ int hvm_domain_initialise(struct domain *d) d->arch.hvm_domain.params = xzalloc_array(uint64_t, HVM_NR_PARAMS); d->arch.hvm_domain.io_handler = xzalloc_array(struct hvm_io_handler, NR_IO_HANDLERS); + d->arch.hvm_domain.irq = xzalloc_bytes(hvm_irq_size(VIOAPIC_NUM_PINS)); + rc = -ENOMEM; - if ( !d->arch.hvm_domain.pl_time || + if ( !d->arch.hvm_domain.pl_time || !d->arch.hvm_domain.irq || !d->arch.hvm_domain.params || !d->arch.hvm_domain.io_handler ) goto fail1; + /* Set the default number of GSIs */ + hvm_domain_irq(d)->nr_gsis = VIOAPIC_NUM_PINS; + /* need link to containing domain */ d->arch.hvm_domain.pl_time->domain = d; @@ -680,6 +685,7 @@ int hvm_domain_initialise(struct domain *d) xfree(d->arch.hvm_domain.io_handler); xfree(d->arch.hvm_domain.params); xfree(d->arch.hvm_domain.pl_time); + xfree(d->arch.hvm_domain.irq); fail0: hvm_destroy_cacheattr_region_list(d); return rc; @@ -722,6 +728,9 @@ void hvm_domain_destroy(struct domain *d) xfree(d->arch.hvm_domain.pl_time); d->arch.hvm_domain.pl_time = NULL; + + xfree(d->arch.hvm_domain.irq); + d->arch.hvm_domain.irq = NULL; } static int hvm_save_tsc_adjust(struct domain *d, hvm_domain_context_t *h) diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c index c2951ccf8a..6e67cae9bd 100644 --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -69,6 +69,7 @@ static void __hvm_pci_intx_assert( return; gsi = hvm_pci_intx_gsi(device, intx); + ASSERT(gsi < hvm_irq->nr_gsis); if ( hvm_irq->gsi_assert_count[gsi]++ == 0 ) assert_gsi(d, gsi); @@ -99,6 +100,7 @@ static void __hvm_pci_intx_deassert( return; gsi = hvm_pci_intx_gsi(device, intx); + ASSERT(gsi < hvm_irq->nr_gsis); --hvm_irq->gsi_assert_count[gsi]; link = hvm_pci_intx_link(device, intx); @@ -122,7 +124,7 @@ void hvm_isa_irq_assert( struct hvm_irq *hvm_irq = hvm_domain_irq(d); unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq); - ASSERT(isa_irq <= 15); + ASSERT(isa_irq <= 15 && isa_irq < hvm_irq->nr_gsis); spin_lock(&d->arch.hvm_domain.irq_lock); @@ -139,7 +141,7 @@ void hvm_isa_irq_deassert( struct hvm_irq *hvm_irq = hvm_domain_irq(d); unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq); - ASSERT(isa_irq <= 15); + ASSERT(isa_irq <= 15 && isa_irq < hvm_irq->nr_gsis); spin_lock(&d->arch.hvm_domain.irq_lock); @@ -363,7 +365,7 @@ void hvm_set_callback_via(struct domain *d, uint64_t via) { case HVMIRQ_callback_gsi: gsi = hvm_irq->callback_via.gsi = (uint8_t)via; - if ( (gsi == 0) || (gsi >= ARRAY_SIZE(hvm_irq->gsi_assert_count)) ) + if ( (gsi == 0) || (gsi >= hvm_irq->nr_gsis) ) hvm_irq->callback_via_type = HVMIRQ_callback_none; else if ( hvm_irq->callback_via_asserted && (hvm_irq->gsi_assert_count[gsi]++ == 0) ) @@ -419,9 +421,9 @@ struct hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v) if ( unlikely(v->mce_pending) ) return hvm_intack_mce; - if ( (plat->irq.callback_via_type == HVMIRQ_callback_vector) + if ( (plat->irq->callback_via_type == HVMIRQ_callback_vector) && vcpu_info(v, evtchn_upcall_pending) ) - return hvm_intack_vector(plat->irq.callback_via.vector); + return hvm_intack_vector(plat->irq->callback_via.vector); if ( vlapic_accept_pic_intr(v) && plat->vpic[0].int_output ) return hvm_intack_pic(0); @@ -495,7 +497,7 @@ static void irq_dump(struct domain *d) (uint32_t) hvm_irq->isa_irq.pad[0], hvm_irq->pci_link.route[0], hvm_irq->pci_link.route[1], hvm_irq->pci_link.route[2], hvm_irq->pci_link.route[3]); - for ( i = 0 ; i < VIOAPIC_NUM_PINS; i += 8 ) + for ( i = 0; i < hvm_irq->nr_gsis && i + 8 <= hvm_irq->nr_gsis; i += 8 ) printk("GSI [%x - %x] %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8 " %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8"\n", i, i+7, @@ -507,6 +509,13 @@ static void irq_dump(struct domain *d) hvm_irq->gsi_assert_count[i+5], hvm_irq->gsi_assert_count[i+6], hvm_irq->gsi_assert_count[i+7]); + if ( i != hvm_irq->nr_gsis ) + { + printk("GSI [%x - %x]", i, hvm_irq->nr_gsis - 1); + for ( ; i < hvm_irq->nr_gsis; i++) + printk(" %2.2"PRIu8, hvm_irq->gsi_assert_count[i]); + printk("\n"); + } printk("Link %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8"\n", hvm_irq->pci_link_assert_count[0], hvm_irq->pci_link_assert_count[1], @@ -545,6 +554,9 @@ static int irq_save_pci(struct domain *d, hvm_domain_context_t *h) unsigned int asserted, pdev, pintx; int rc; + if ( hvm_irq->nr_gsis != VIOAPIC_NUM_PINS ) + return -EOPNOTSUPP; + spin_lock(&d->arch.hvm_domain.irq_lock); pdev = hvm_irq->callback_via.pci.dev; @@ -592,6 +604,9 @@ static int irq_load_pci(struct domain *d, hvm_domain_context_t *h) struct hvm_irq *hvm_irq = hvm_domain_irq(d); int link, dev, intx, gsi; + if ( hvm_irq->nr_gsis != VIOAPIC_NUM_PINS ) + return -EOPNOTSUPP; + /* Load the PCI IRQ lines */ if ( hvm_load_entry(PCI_IRQ, h, &hvm_irq->pci_intx) != 0 ) return -EINVAL; diff --git a/xen/drivers/passthrough/io.c b/xen/drivers/passthrough/io.c index 080183ea31..50e2f00214 100644 --- a/xen/drivers/passthrough/io.c +++ b/xen/drivers/passthrough/io.c @@ -195,7 +195,7 @@ struct hvm_irq_dpci *domain_get_irq_dpci(const struct domain *d) if ( !d || !is_hvm_domain(d) ) return NULL; - return d->arch.hvm_domain.irq.dpci; + return d->arch.hvm_domain.irq->dpci; } void free_hvm_irq_dpci(struct hvm_irq_dpci *dpci) @@ -333,7 +333,7 @@ int pt_irq_create_bind( for ( i = 0; i < NR_HVM_IRQS; i++ ) INIT_LIST_HEAD(&hvm_irq_dpci->girq[i]); - d->arch.hvm_domain.irq.dpci = hvm_irq_dpci; + d->arch.hvm_domain.irq->dpci = hvm_irq_dpci; } info = pirq_get_info(d, pirq); @@ -788,7 +788,7 @@ static int _hvm_dpci_msi_eoi(struct domain *d, void hvm_dpci_msi_eoi(struct domain *d, int vector) { - if ( !iommu_enabled || !d->arch.hvm_domain.irq.dpci ) + if ( !iommu_enabled || !d->arch.hvm_domain.irq->dpci ) return; spin_lock(&d->event_lock); @@ -798,7 +798,7 @@ void hvm_dpci_msi_eoi(struct domain *d, int vector) static void hvm_dirq_assist(struct domain *d, struct hvm_pirq_dpci *pirq_dpci) { - if ( unlikely(!d->arch.hvm_domain.irq.dpci) ) + if ( unlikely(!d->arch.hvm_domain.irq->dpci) ) { ASSERT_UNREACHABLE(); return; diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index beddd42701..b5b865a2d4 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -815,7 +815,7 @@ static int pci_clean_dpci_irqs(struct domain *d) return ret; } - d->arch.hvm_domain.irq.dpci = NULL; + d->arch.hvm_domain.irq->dpci = NULL; free_hvm_irq_dpci(hvm_irq_dpci); } spin_unlock(&d->event_lock); diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index ec14cce81f..0b7e43fa16 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -17,7 +17,7 @@ #define is_pv_32bit_vcpu(v) (is_pv_32bit_domain((v)->domain)) #define is_hvm_pv_evtchn_domain(d) (is_hvm_domain(d) && \ - d->arch.hvm_domain.irq.callback_via_type == HVMIRQ_callback_vector) + d->arch.hvm_domain.irq->callback_via_type == HVMIRQ_callback_vector) #define is_hvm_pv_evtchn_vcpu(v) (is_hvm_pv_evtchn_domain(v->domain)) #define is_domain_direct_mapped(d) ((void)(d), 0) diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h index 420cbdc609..c3cca94a97 100644 --- a/xen/include/asm-x86/hvm/domain.h +++ b/xen/include/asm-x86/hvm/domain.h @@ -125,7 +125,7 @@ struct hvm_domain { /* Lock protects access to irq, vpic and vioapic. */ spinlock_t irq_lock; - struct hvm_irq irq; + struct hvm_irq *irq; struct hvm_hw_vpic vpic[2]; /* 0=master; 1=slave */ struct hvm_vioapic *vioapic; struct hvm_hw_stdvga stdvga; diff --git a/xen/include/asm-x86/hvm/irq.h b/xen/include/asm-x86/hvm/irq.h index 17a957d4b5..7d45293aed 100644 --- a/xen/include/asm-x86/hvm/irq.h +++ b/xen/include/asm-x86/hvm/irq.h @@ -67,18 +67,6 @@ struct hvm_irq { u8 pci_link_assert_count[4]; /* - * Number of wires asserting each GSI. - * - * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space - * except ISA IRQ 0, which is connected to GSI 2. - * PCI links map into this space via the PCI-ISA bridge. - * - * GSIs 16+ are used only be PCI devices. The mapping from PCI device to - * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16 - */ - u8 gsi_assert_count[VIOAPIC_NUM_PINS]; - - /* * GSIs map onto PIC/IO-APIC in the usual way: * 0-7: Master 8259 PIC, IO-APIC pins 0-7 * 8-15: Slave 8259 PIC, IO-APIC pins 8-15 @@ -89,13 +77,27 @@ struct hvm_irq { u8 round_robin_prev_vcpu; struct hvm_irq_dpci *dpci; + + /* + * Number of wires asserting each GSI. + * + * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space + * except ISA IRQ 0, which is connected to GSI 2. + * PCI links map into this space via the PCI-ISA bridge. + * + * GSIs 16+ are used only be PCI devices. The mapping from PCI device to + * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16 + */ + unsigned int nr_gsis; + u8 gsi_assert_count[]; }; #define hvm_pci_intx_gsi(dev, intx) \ (((((dev)<<2) + ((dev)>>3) + (intx)) & 31) + 16) #define hvm_pci_intx_link(dev, intx) \ (((dev) + (intx)) & 3) -#define hvm_domain_irq(d) (&(d)->arch.hvm_domain.irq) +#define hvm_domain_irq(d) ((d)->arch.hvm_domain.irq) +#define hvm_irq_size(cnt) offsetof(struct hvm_irq, gsi_assert_count[cnt]) #define hvm_isa_irq_to_gsi(isa_irq) ((isa_irq) ? : 2)