From patchwork Wed May 1 00:57:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Scott Wood X-Patchwork-Id: 240712 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 18D282C00D3 for ; Wed, 1 May 2013 10:57:33 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933970Ab3EAA51 (ORCPT ); Tue, 30 Apr 2013 20:57:27 -0400 Received: from ch1ehsobe005.messaging.microsoft.com ([216.32.181.185]:54127 "EHLO ch1outboundpool.messaging.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932661Ab3EAA50 (ORCPT ); Tue, 30 Apr 2013 20:57:26 -0400 Received: from mail81-ch1-R.bigfish.com (10.43.68.228) by CH1EHSOBE008.bigfish.com (10.43.70.58) with Microsoft SMTP Server id 14.1.225.23; Wed, 1 May 2013 00:57:25 +0000 Received: from mail81-ch1 (localhost [127.0.0.1]) by mail81-ch1-R.bigfish.com (Postfix) with ESMTP id 3B8701C0490; Wed, 1 May 2013 00:57:25 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1f42h1fc6h1ee6h1de0h1fdah1202h1e76h1d1ah1d2ahzz8275bhz2dh2a8h668h839hd24he5bhf0ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1d0ch1d2eh1155h) Received: from mail81-ch1 (localhost.localdomain [127.0.0.1]) by mail81-ch1 (MessageSwitch) id 1367369843558519_27036; Wed, 1 May 2013 00:57:23 +0000 (UTC) Received: from CH1EHSMHS028.bigfish.com (snatpool1.int.messaging.microsoft.com [10.43.68.253]) by mail81-ch1.bigfish.com (Postfix) with ESMTP id 863FF120073; Wed, 1 May 2013 00:57:23 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CH1EHSMHS028.bigfish.com (10.43.70.28) with Microsoft SMTP Server (TLS) id 14.1.225.23; Wed, 1 May 2013 00:57:17 +0000 Received: from az84smr01.freescale.net (10.64.34.197) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server (TLS) id 14.2.328.11; Wed, 1 May 2013 00:57:16 +0000 Received: from snotra.am.freescale.net ([10.214.82.239]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id r410vEuA004666; Tue, 30 Apr 2013 17:57:15 -0700 From: Scott Wood To: Alexander Graf CC: , , Scott Wood Subject: [PATCH 1/2] kvm/ppc/mpic: fix mmio region lists when multiple guests used Date: Tue, 30 Apr 2013 19:57:13 -0500 Message-ID: <1367369834-14349-1-git-send-email-scottwood@freescale.com> X-Mailer: git-send-email 1.7.10.4 MIME-Version: 1.0 X-OriginatorOrg: freescale.com Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org Keeping a linked list of statically defined objects doesn't work very well when we have multiple guests. :-P Switch to an array of constant objects. This fixes a hang when multiple guests are used. Signed-off-by: Scott Wood --- arch/powerpc/kvm/mpic.c | 52 +++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index f3148f8..80ea3cb 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -184,11 +184,14 @@ struct irq_dest { uint32_t outputs_active[NUM_OUTPUTS]; }; +#define MAX_MMIO_REGIONS 10 + struct openpic { struct kvm *kvm; struct kvm_device *dev; struct kvm_io_device mmio; - struct list_head mmio_regions; + const struct mem_reg *mmio_regions[MAX_MMIO_REGIONS]; + int num_mmio_regions; atomic_t users; gpa_t reg_base; @@ -1245,55 +1248,65 @@ struct mem_reg { int size; }; -static struct mem_reg openpic_gbl_mmio = { +static const struct mem_reg openpic_gbl_mmio = { .write = openpic_gbl_write, .read = openpic_gbl_read, .start_addr = OPENPIC_GLB_REG_START, .size = OPENPIC_GLB_REG_SIZE, }; -static struct mem_reg openpic_tmr_mmio = { +static const struct mem_reg openpic_tmr_mmio = { .write = openpic_tmr_write, .read = openpic_tmr_read, .start_addr = OPENPIC_TMR_REG_START, .size = OPENPIC_TMR_REG_SIZE, }; -static struct mem_reg openpic_cpu_mmio = { +static const struct mem_reg openpic_cpu_mmio = { .write = openpic_cpu_write, .read = openpic_cpu_read, .start_addr = OPENPIC_CPU_REG_START, .size = OPENPIC_CPU_REG_SIZE, }; -static struct mem_reg openpic_src_mmio = { +static const struct mem_reg openpic_src_mmio = { .write = openpic_src_write, .read = openpic_src_read, .start_addr = OPENPIC_SRC_REG_START, .size = OPENPIC_SRC_REG_SIZE, }; -static struct mem_reg openpic_msi_mmio = { +static const struct mem_reg openpic_msi_mmio = { .read = openpic_msi_read, .write = openpic_msi_write, .start_addr = OPENPIC_MSI_REG_START, .size = OPENPIC_MSI_REG_SIZE, }; -static struct mem_reg openpic_summary_mmio = { +static const struct mem_reg openpic_summary_mmio = { .read = openpic_summary_read, .write = openpic_summary_write, .start_addr = OPENPIC_SUMMARY_REG_START, .size = OPENPIC_SUMMARY_REG_SIZE, }; +static void add_mmio_region(struct openpic *opp, const struct mem_reg *mr) +{ + if (opp->num_mmio_regions >= MAX_MMIO_REGIONS) { + WARN(1, "kvm mpic: too many mmio regions\n"); + return; + } + + opp->mmio_regions[opp->num_mmio_regions++] = mr; +} + static void fsl_common_init(struct openpic *opp) { int i; int virq = MAX_SRC; - list_add(&openpic_msi_mmio.list, &opp->mmio_regions); - list_add(&openpic_summary_mmio.list, &opp->mmio_regions); + add_mmio_region(opp, &openpic_msi_mmio); + add_mmio_region(opp, &openpic_summary_mmio); opp->vid = VID_REVISION_1_2; opp->vir = VIR_GENERIC; @@ -1330,10 +1343,10 @@ static void fsl_common_init(struct openpic *opp) static int kvm_mpic_read_internal(struct openpic *opp, gpa_t addr, u32 *ptr) { - struct list_head *node; + int i; - list_for_each(node, &opp->mmio_regions) { - struct mem_reg *mr = list_entry(node, struct mem_reg, list); + for (i = 0; i < opp->num_mmio_regions; i++) { + const struct mem_reg *mr = opp->mmio_regions[i]; if (mr->start_addr > addr || addr >= mr->start_addr + mr->size) continue; @@ -1346,10 +1359,10 @@ static int kvm_mpic_read_internal(struct openpic *opp, gpa_t addr, u32 *ptr) static int kvm_mpic_write_internal(struct openpic *opp, gpa_t addr, u32 val) { - struct list_head *node; + int i; - list_for_each(node, &opp->mmio_regions) { - struct mem_reg *mr = list_entry(node, struct mem_reg, list); + for (i = 0; i < opp->num_mmio_regions; i++) { + const struct mem_reg *mr = opp->mmio_regions[i]; if (mr->start_addr > addr || addr >= mr->start_addr + mr->size) continue; @@ -1660,11 +1673,10 @@ static int mpic_create(struct kvm_device *dev, u32 type) opp->model = type; spin_lock_init(&opp->lock); - INIT_LIST_HEAD(&opp->mmio_regions); - list_add(&openpic_gbl_mmio.list, &opp->mmio_regions); - list_add(&openpic_tmr_mmio.list, &opp->mmio_regions); - list_add(&openpic_src_mmio.list, &opp->mmio_regions); - list_add(&openpic_cpu_mmio.list, &opp->mmio_regions); + add_mmio_region(opp, &openpic_gbl_mmio); + add_mmio_region(opp, &openpic_tmr_mmio); + add_mmio_region(opp, &openpic_src_mmio); + add_mmio_region(opp, &openpic_cpu_mmio); switch (opp->model) { case KVM_DEV_TYPE_FSL_MPIC_20: