From nobody Tue Feb 10 13:16:27 2026 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1511444544729730.8722047335025; Thu, 23 Nov 2017 05:42:24 -0800 (PST) Received: from localhost ([::1]:44415 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrlh-00021A-4I for importer@patchew.org; Thu, 23 Nov 2017 08:42:17 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37905) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eHrb8-0000qh-Mi for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eHrb6-0000Xg-Ip for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:22 -0500 Received: from 10.mo3.mail-out.ovh.net ([87.98.165.232]:50037) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eHrb6-0000WM-9h for qemu-devel@nongnu.org; Thu, 23 Nov 2017 08:31:20 -0500 Received: from player797.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id C15DD171A49 for ; Thu, 23 Nov 2017 14:31:18 +0100 (CET) Received: from zorba.kaod.org.com (LFbn-1-2231-173.w90-76.abo.wanadoo.fr [90.76.52.173]) (Authenticated sender: clg@kaod.org) by player797.ha.ovh.net (Postfix) with ESMTPSA id 673092E009B; Thu, 23 Nov 2017 14:31:13 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt Date: Thu, 23 Nov 2017 14:29:34 +0100 Message-Id: <20171123132955.1261-5-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171123132955.1261-1-clg@kaod.org> References: <20171123132955.1261-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 14818531626810968915 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedttddrledtgdefhecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 87.98.165.232 Subject: [Qemu-devel] [PATCH 04/25] spapr: move the IRQ allocation routines under the machine 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: , Cc: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Also change the prototype to use a sPAPRMachineState and prefix them with spapr_irq_. It will let us synchronise the IRQ allocation with the XIVE interrupt mode when available. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: David Gibson Reviewed-by: Greg Kurz --- hw/intc/trace-events | 4 -- hw/intc/xics_spapr.c | 114 ---------------------------------------------= ---- hw/ppc/spapr.c | 114 +++++++++++++++++++++++++++++++++++++++++++++= ++++ hw/ppc/spapr_events.c | 4 +- hw/ppc/spapr_pci.c | 8 ++-- hw/ppc/spapr_vio.c | 2 +- hw/ppc/trace-events | 4 ++ include/hw/ppc/spapr.h | 6 +++ include/hw/ppc/xics.h | 4 -- 9 files changed, 131 insertions(+), 129 deletions(-) diff --git a/hw/intc/trace-events b/hw/intc/trace-events index b298fac7c6a8..7077aaaee6d0 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -64,10 +64,6 @@ xics_ics_simple_set_irq_lsi(int srcno, int nr) "set_irq_= lsi: srcno %d [irq 0x%x] xics_ics_simple_write_xive(int nr, int srcno, int server, uint8_t priority= ) "ics_write_xive: irq 0x%x [src %d] server 0x%x prio 0x%x" xics_ics_simple_reject(int nr, int srcno) "reject irq 0x%x [src %d]" xics_ics_simple_eoi(int nr) "ics_eoi: irq 0x%x" -xics_alloc(int irq) "irq %d" -xics_alloc_block(int first, int num, bool lsi, int align) "first irq %d, %= d irqs, lsi=3D%d, alignnum %d" -xics_ics_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs" -xics_ics_free_warn(int src, int irq) "Source#%d, irq %d is already free" =20 # hw/intc/s390_flic_kvm.c flic_create_device(int err) "flic: create device failed %d" diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index e8c0a1b3e903..5a0967caf430 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -245,120 +245,6 @@ void xics_spapr_init(sPAPRMachineState *spapr) spapr_register_hypercall(H_IPOLL, h_ipoll); } =20 -#define ICS_IRQ_FREE(ics, srcno) \ - (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK))) - -static int ics_find_free_block(ICSState *ics, int num, int alignnum) -{ - int first, i; - - for (first =3D 0; first < ics->nr_irqs; first +=3D alignnum) { - if (num > (ics->nr_irqs - first)) { - return -1; - } - for (i =3D first; i < first + num; ++i) { - if (!ICS_IRQ_FREE(ics, i)) { - break; - } - } - if (i =3D=3D (first + num)) { - return first; - } - } - - return -1; -} - -int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp) -{ - int irq; - - if (!ics) { - return -1; - } - if (irq_hint) { - if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) { - error_setg(errp, "can't allocate IRQ %d: already in use", irq_= hint); - return -1; - } - irq =3D irq_hint; - } else { - irq =3D ics_find_free_block(ics, 1, 1); - if (irq < 0) { - error_setg(errp, "can't allocate IRQ: no IRQ left"); - return -1; - } - irq +=3D ics->offset; - } - - ics_set_irq_type(ics, irq - ics->offset, lsi); - trace_xics_alloc(irq); - - return irq; -} - -/* - * Allocate block of consecutive IRQs, and return the number of the first = IRQ in - * the block. If align=3D=3Dtrue, aligns the first IRQ number to num. - */ -int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, - bool align, Error **errp) -{ - int i, first =3D -1; - - if (!ics) { - return -1; - } - - /* - * MSIMesage::data is used for storing VIRQ so - * it has to be aligned to num to support multiple - * MSI vectors. MSI-X is not affected by this. - * The hint is used for the first IRQ, the rest should - * be allocated continuously. - */ - if (align) { - assert((num =3D=3D 1) || (num =3D=3D 2) || (num =3D=3D 4) || - (num =3D=3D 8) || (num =3D=3D 16) || (num =3D=3D 32)); - first =3D ics_find_free_block(ics, num, num); - } else { - first =3D ics_find_free_block(ics, num, 1); - } - if (first < 0) { - error_setg(errp, "can't find a free %d-IRQ block", num); - return -1; - } - - for (i =3D first; i < first + num; ++i) { - ics_set_irq_type(ics, i, lsi); - } - first +=3D ics->offset; - - trace_xics_alloc_block(first, num, lsi, align); - - return first; -} - -static void ics_free(ICSState *ics, int srcno, int num) -{ - int i; - - for (i =3D srcno; i < srcno + num; ++i) { - if (ICS_IRQ_FREE(ics, i)) { - trace_xics_ics_free_warn(0, i + ics->offset); - } - memset(&ics->irqs[i], 0, sizeof(ICSIRQState)); - } -} - -void spapr_ics_free(ICSState *ics, int irq, int num) -{ - if (ics_valid_irq(ics, irq)) { - trace_xics_ics_free(0, irq, num); - ics_free(ics, irq - ics->offset, num); - } -} - void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle) { uint32_t interrupt_server_ranges_prop[] =3D { diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 925cbd3c1bf4..7ae84d40bdb4 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3570,6 +3570,120 @@ Object *spapr_icp_create(sPAPRMachineState *spapr, = CPUState *cs, Error **errp) return obj; } =20 +#define ICS_IRQ_FREE(ics, srcno) \ + (!((ics)->irqs[(srcno)].flags & (XICS_FLAGS_IRQ_MASK))) + +static int ics_find_free_block(ICSState *ics, int num, int alignnum) +{ + int first, i; + + for (first =3D 0; first < ics->nr_irqs; first +=3D alignnum) { + if (num > (ics->nr_irqs - first)) { + return -1; + } + for (i =3D first; i < first + num; ++i) { + if (!ICS_IRQ_FREE(ics, i)) { + break; + } + } + if (i =3D=3D (first + num)) { + return first; + } + } + + return -1; +} + +int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, + Error **errp) +{ + ICSState *ics =3D spapr->ics; + int irq; + + if (!ics) { + return -1; + } + if (irq_hint) { + if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) { + error_setg(errp, "can't allocate IRQ %d: already in use", irq_= hint); + return -1; + } + irq =3D irq_hint; + } else { + irq =3D ics_find_free_block(ics, 1, 1); + if (irq < 0) { + error_setg(errp, "can't allocate IRQ: no IRQ left"); + return -1; + } + irq +=3D ics->offset; + } + + ics_set_irq_type(ics, irq - ics->offset, lsi); + trace_spapr_irq_alloc(irq); + + return irq; +} + +/* + * Allocate block of consecutive IRQs, and return the number of the first = IRQ in + * the block. If align=3D=3Dtrue, aligns the first IRQ number to num. + */ +int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, + bool align, Error **errp) +{ + ICSState *ics =3D spapr->ics; + int i, first =3D -1; + + if (!ics) { + return -1; + } + + /* + * MSIMesage::data is used for storing VIRQ so + * it has to be aligned to num to support multiple + * MSI vectors. MSI-X is not affected by this. + * The hint is used for the first IRQ, the rest should + * be allocated continuously. + */ + if (align) { + assert((num =3D=3D 1) || (num =3D=3D 2) || (num =3D=3D 4) || + (num =3D=3D 8) || (num =3D=3D 16) || (num =3D=3D 32)); + first =3D ics_find_free_block(ics, num, num); + } else { + first =3D ics_find_free_block(ics, num, 1); + } + if (first < 0) { + error_setg(errp, "can't find a free %d-IRQ block", num); + return -1; + } + + for (i =3D first; i < first + num; ++i) { + ics_set_irq_type(ics, i, lsi); + } + first +=3D ics->offset; + + trace_spapr_irq_alloc_block(first, num, lsi, align); + + return first; +} + +void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num) +{ + ICSState *ics =3D spapr->ics; + int srcno =3D irq - ics->offset; + int i; + + if (ics_valid_irq(ics, irq)) { + trace_spapr_irq_free(0, irq, num); + for (i =3D srcno; i < srcno + num; ++i) { + if (ICS_IRQ_FREE(ics, i)) { + trace_spapr_irq_free_warn(0, i + ics->offset); + } + memset(&ics->irqs[i], 0, sizeof(ICSIRQState)); + } + } +} + static void spapr_pic_print_info(InterruptStatsProvider *obj, Monitor *mon) { diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index e377fc7ddea2..cead596f3e7a 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -718,7 +718,7 @@ void spapr_events_init(sPAPRMachineState *spapr) spapr->event_sources =3D spapr_event_sources_new(); =20 spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_EPOW, - spapr_ics_alloc(spapr->ics, 0, false, + spapr_irq_alloc(spapr, 0, false, &error_fatal)); =20 /* NOTE: if machine supports modern/dedicated hotplug event source, @@ -731,7 +731,7 @@ void spapr_events_init(sPAPRMachineState *spapr) */ if (spapr->use_hotplug_event_source) { spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_HOT= _PLUG, - spapr_ics_alloc(spapr->ics, 0, false, + spapr_irq_alloc(spapr, 0, false, &error_fatal)); } =20 diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 5a3122a9f9f9..e0ef77a480e5 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -314,7 +314,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRM= achineState *spapr, return; } =20 - spapr_ics_free(spapr->ics, msi->first_irq, msi->num); + spapr_irq_free(spapr, msi->first_irq, msi->num); if (msi_present(pdev)) { spapr_msi_setmsg(pdev, 0, false, 0, 0); } @@ -352,7 +352,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRM= achineState *spapr, } =20 /* Allocate MSIs */ - irq =3D spapr_ics_alloc_block(spapr->ics, req_num, false, + irq =3D spapr_irq_alloc_block(spapr, req_num, false, ret_intr_type =3D=3D RTAS_TYPE_MSI, &err); if (err) { error_reportf_err(err, "Can't allocate MSIs for device %x: ", @@ -363,7 +363,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRM= achineState *spapr, =20 /* Release previous MSIs */ if (msi) { - spapr_ics_free(spapr->ics, msi->first_irq, msi->num); + spapr_irq_free(spapr, msi->first_irq, msi->num); g_hash_table_remove(phb->msi, &config_addr); } =20 @@ -1675,7 +1675,7 @@ static void spapr_phb_realize(DeviceState *dev, Error= **errp) uint32_t irq; Error *local_err =3D NULL; =20 - irq =3D spapr_ics_alloc_block(spapr->ics, 1, true, false, &local_e= rr); + irq =3D spapr_irq_alloc_block(spapr, 1, true, false, &local_err); if (local_err) { error_propagate(errp, local_err); error_prepend(errp, "can't allocate LSIs: "); diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index ea3bc8bd9e21..bb7ed2c537b0 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -454,7 +454,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev,= Error **errp) dev->qdev.id =3D id; } =20 - dev->irq =3D spapr_ics_alloc(spapr->ics, dev->irq, false, &local_err); + dev->irq =3D spapr_irq_alloc(spapr, dev->irq, false, &local_err); if (local_err) { error_propagate(errp, local_err); return; diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index 4a6a6490fa78..b7c3e64b5ee7 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -12,6 +12,10 @@ spapr_pci_msi_retry(unsigned config_addr, unsigned req_n= um, unsigned max_irqs) " # hw/ppc/spapr.c spapr_cas_failed(unsigned long n) "DT diff buffer is too small: %ld bytes" spapr_cas_continue(unsigned long n) "Copy changes to the guest: %ld bytes" +spapr_irq_alloc(int irq) "irq %d" +spapr_irq_alloc_block(int first, int num, bool lsi, int align) "first irq = %d, %d irqs, lsi=3D%d, alignnum %d" +spapr_irq_free(int src, int irq, int num) "Source#%d, first irq %d, %d irq= s" +spapr_irq_free_warn(int src, int irq) "Source#%d, irq %d is already free" =20 # hw/ppc/spapr_hcall.c spapr_cas_pvr_try(uint32_t pvr) "0x%x" diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 9da38de34277..7a133f80411a 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -709,4 +709,10 @@ PowerPCCPU *spapr_find_cpu(int vcpu_id); =20 Object *spapr_icp_create(sPAPRMachineState *spapr, CPUState *cs, Error **e= rrp); =20 +int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, + Error **errp); +int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, + bool align, Error **errp); +void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num); + #endif /* HW_SPAPR_H */ diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 126b47dec38b..cea462bc7f3e 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -181,10 +181,6 @@ typedef struct XICSFabricClass { =20 #define XICS_IRQS_SPAPR 1024 =20 -int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp); -int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align, - Error **errp); -void spapr_ics_free(ICSState *ics, int irq, int num); void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle); =20 qemu_irq xics_get_qirq(XICSFabric *xi, int irq); --=20 2.13.6