From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512809366515974.4704407484277; Sat, 9 Dec 2017 00:49:26 -0800 (PST) Received: from localhost ([::1]:40438 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNap3-0005XD-1b for importer@patchew.org; Sat, 09 Dec 2017 03:49:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45161) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNajv-0000iX-QA for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNajr-0006pP-Uh for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:07 -0500 Received: from 2.mo6.mail-out.ovh.net ([46.105.76.65]:37173) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNajr-0006or-Pf for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:03 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 5C3E812605C for ; Sat, 9 Dec 2017 09:44:02 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 2EC2A160090; Sat, 9 Dec 2017 09:43:56 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:20 +0100 Message-Id: <20171209084338.29395-2-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11696411183965244243 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 46.105.76.65 Subject: [Qemu-devel] [PATCH v2 01/19] dma-helpers: add a return value to store helpers 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Signed-off-by: C=C3=A9dric Le Goater --- include/sysemu/dma.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h index c228c6651360..74a9558af39c 100644 --- a/include/sysemu/dma.h +++ b/include/sysemu/dma.h @@ -153,12 +153,12 @@ static inline void dma_memory_unmap(AddressSpace *as, dma_memory_read(as, addr, &val, (_bits) / 8); \ return _end##_bits##_to_cpu(val); \ } \ - static inline void st##_sname##_##_end##_dma(AddressSpace *as, \ + static inline int st##_sname##_##_end##_dma(AddressSpace *as, \ dma_addr_t addr, \ uint##_bits##_t val) \ { \ val =3D cpu_to_##_end##_bits(val); \ - dma_memory_write(as, addr, &val, (_bits) / 8); \ + return dma_memory_write(as, addr, &val, (_bits) / 8); \ } =20 static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr) --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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 151280955687433.04480553870428; Sat, 9 Dec 2017 00:52:36 -0800 (PST) Received: from localhost ([::1]:40457 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNarr-0007sZ-Uh for importer@patchew.org; Sat, 09 Dec 2017 03:52:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45203) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNak2-0000o9-9Z for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNajy-0006r3-Au for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:14 -0500 Received: from 19.mo6.mail-out.ovh.net ([188.165.56.177]:57595) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNajy-0006qe-1D for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:10 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 85B88127131 for ; Sat, 9 Dec 2017 09:44:08 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 5ACAF160090; Sat, 9 Dec 2017 09:44:02 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:21 +0100 Message-Id: <20171209084338.29395-3-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11698100032250481491 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 188.165.56.177 Subject: [Qemu-devel] [PATCH v2 02/19] spapr: introduce a skeleton for the XIVE interrupt controller 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" With the POWER9 processor comes a new interrupt controller called XIVE. It is composed of three sub-engines : - Interrupt Virtualization Source Engine (IVSE). These are in PHBs, in the main controller for the IPIS and in the PSI host bridge. They are configured to feed the IVRE with events. - Interrupt Virtualization Routing Engine (IVRE). Their job is to match an event source with a Notification Virtualization Target (NVT), a priority and an Event Queue (EQ) to determine if a Virtual Processor can handle the event. - Interrupt Virtualization Presentation Engine (IVPE). It maintains the interrupt state of each hardware thread and present the notification as an external exception. Each of the engines uses a set of internal tables to redirect exceptions from event sources to CPU threads. The first table we introduce is the Interrupt Virtualization Entry (IVE) table, part of the virtualization engine in charge of routing events. It associates event sources (IRQ numbers) to event queues which will forward, or not, the event notification to the presentation controller. The XIVE model is designed to make use of the full range of the IRQ number space and does not use an offset like the XICS mode does. Hence, the IVE table is directly indexed by the IRQ number. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1 : - used g_new0 instead of g_malloc0 - removed VMSTATE_STRUCT_VARRAY_UINT32_ALLOC=20 - introduced a device reset handler. the object needs to be parented to sysbus when created. - renamed spapr_xive_irq_set to spapr_xive_irq_enable - renamed spapr_xive_irq_unset to spapr_xive_irq_disable - moved the PPC_BIT macros under target/ppc/cpu.h - shrinked file copyright header default-configs/ppc64-softmmu.mak | 1 + hw/intc/Makefile.objs | 1 + hw/intc/spapr_xive.c | 156 ++++++++++++++++++++++++++++++++++= ++++ hw/intc/xive-internal.h | 41 ++++++++++ include/hw/ppc/spapr_xive.h | 35 +++++++++ 5 files changed, 234 insertions(+) create mode 100644 hw/intc/spapr_xive.c create mode 100644 hw/intc/xive-internal.h create mode 100644 include/hw/ppc/spapr_xive.h diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-soft= mmu.mak index d1b3a6dd50f8..4a7f6a0696de 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -56,6 +56,7 @@ CONFIG_SM501=3Dy CONFIG_XICS=3D$(CONFIG_PSERIES) CONFIG_XICS_SPAPR=3D$(CONFIG_PSERIES) CONFIG_XICS_KVM=3D$(call land,$(CONFIG_PSERIES),$(CONFIG_KVM)) +CONFIG_XIVE_SPAPR=3D$(CONFIG_PSERIES) # For PReP CONFIG_SERIAL_ISA=3Dy CONFIG_MC146818RTC=3Dy diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index ae358569a155..49e13e7aeeee 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -35,6 +35,7 @@ obj-$(CONFIG_SH4) +=3D sh_intc.o obj-$(CONFIG_XICS) +=3D xics.o obj-$(CONFIG_XICS_SPAPR) +=3D xics_spapr.o obj-$(CONFIG_XICS_KVM) +=3D xics_kvm.o +obj-$(CONFIG_XIVE_SPAPR) +=3D spapr_xive.o obj-$(CONFIG_POWERNV) +=3D xics_pnv.o obj-$(CONFIG_ALLWINNER_A10_PIC) +=3D allwinner-a10-pic.o obj-$(CONFIG_S390_FLIC) +=3D s390_flic.o diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c new file mode 100644 index 000000000000..e6e8841add17 --- /dev/null +++ b/hw/intc/spapr_xive.c @@ -0,0 +1,156 @@ +/* + * QEMU PowerPC sPAPR XIVE interrupt controller model + * + * Copyright (c) 2017, IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "target/ppc/cpu.h" +#include "sysemu/cpus.h" +#include "sysemu/dma.h" +#include "monitor/monitor.h" +#include "hw/ppc/spapr_xive.h" + +#include "xive-internal.h" + +/* + * Main XIVE object + */ + +void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon) +{ + int i; + + for (i =3D 0; i < xive->nr_irqs; i++) { + XiveIVE *ive =3D &xive->ivt[i]; + + if (!(ive->w & IVE_VALID)) { + continue; + } + + monitor_printf(mon, " %4x %s %08x %08x\n", i, + ive->w & IVE_MASKED ? "M" : " ", + (int) GETFIELD(IVE_EQ_INDEX, ive->w), + (int) GETFIELD(IVE_EQ_DATA, ive->w)); + } +} + +static void spapr_xive_reset(DeviceState *dev) +{ + sPAPRXive *xive =3D SPAPR_XIVE(dev); + int i; + + /* Mask all valid IVEs in the IRQ number space. */ + for (i =3D 0; i < xive->nr_irqs; i++) { + XiveIVE *ive =3D &xive->ivt[i]; + if (ive->w & IVE_VALID) { + ive->w |=3D IVE_MASKED; + } + } +} + +static void spapr_xive_realize(DeviceState *dev, Error **errp) +{ + sPAPRXive *xive =3D SPAPR_XIVE(dev); + + if (!xive->nr_irqs) { + error_setg(errp, "Number of interrupt needs to be greater 0"); + return; + } + + /* Allocate the IVT (Interrupt Virtualization Table) */ + xive->ivt =3D g_new0(XiveIVE, xive->nr_irqs); +} + +static const VMStateDescription vmstate_spapr_xive_ive =3D { + .name =3D TYPE_SPAPR_XIVE "/ive", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField []) { + VMSTATE_UINT64(w, XiveIVE), + VMSTATE_END_OF_LIST() + }, +}; + +static bool vmstate_spapr_xive_needed(void *opaque) +{ + /* TODO check machine XIVE support */ + return true; +} + +static const VMStateDescription vmstate_spapr_xive =3D { + .name =3D TYPE_SPAPR_XIVE, + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D vmstate_spapr_xive_needed, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32_EQUAL(nr_irqs, sPAPRXive, NULL), + VMSTATE_STRUCT_VARRAY_UINT32(ivt, sPAPRXive, nr_irqs, 1, + vmstate_spapr_xive_ive, XiveIVE), + VMSTATE_END_OF_LIST() + }, +}; + +static Property spapr_xive_properties[] =3D { + DEFINE_PROP_UINT32("nr-irqs", sPAPRXive, nr_irqs, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void spapr_xive_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D spapr_xive_realize; + dc->reset =3D spapr_xive_reset; + dc->props =3D spapr_xive_properties; + dc->desc =3D "sPAPR XIVE interrupt controller"; + dc->vmsd =3D &vmstate_spapr_xive; +} + +static const TypeInfo spapr_xive_info =3D { + .name =3D TYPE_SPAPR_XIVE, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(sPAPRXive), + .class_init =3D spapr_xive_class_init, +}; + +static void spapr_xive_register_types(void) +{ + type_register_static(&spapr_xive_info); +} + +type_init(spapr_xive_register_types) + +XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn) +{ + return lisn < xive->nr_irqs ? &xive->ivt[lisn] : NULL; +} + +bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn) +{ + XiveIVE *ive =3D spapr_xive_get_ive(xive, lisn); + + if (!ive) { + return false; + } + + ive->w |=3D IVE_VALID; + return true; +} + +bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn) +{ + XiveIVE *ive =3D spapr_xive_get_ive(xive, lisn); + + if (!ive) { + return false; + } + + ive->w &=3D ~IVE_VALID; + return true; +} diff --git a/hw/intc/xive-internal.h b/hw/intc/xive-internal.h new file mode 100644 index 000000000000..132b71a6daf0 --- /dev/null +++ b/hw/intc/xive-internal.h @@ -0,0 +1,41 @@ +/* + * QEMU PowerPC XIVE interrupt controller model + * + * Copyright (c) 2016-2017, IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ + +#ifndef _INTC_XIVE_INTERNAL_H +#define _INTC_XIVE_INTERNAL_H + +/* Utilities to manipulate these (originaly from OPAL) */ +#define MASK_TO_LSH(m) (__builtin_ffsl(m) - 1) +#define GETFIELD(m, v) (((v) & (m)) >> MASK_TO_LSH(m)) +#define SETFIELD(m, v, val) \ + (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_TO_LSH(m)) & (m))) + +/* IVE/EAS + * + * One per interrupt source. Targets that interrupt to a given EQ + * and provides the corresponding logical interrupt number (EQ data) + * + * We also map this structure to the escalation descriptor inside + * an EQ, though in that case the valid and masked bits are not used. + */ +typedef struct XiveIVE { + /* Use a single 64-bit definition to make it easier to + * perform atomic updates + */ + uint64_t w; +#define IVE_VALID PPC_BIT(0) +#define IVE_EQ_BLOCK PPC_BITMASK(4, 7) /* Destination EQ block# = */ +#define IVE_EQ_INDEX PPC_BITMASK(8, 31) /* Destination EQ index */ +#define IVE_MASKED PPC_BIT(32) /* Masked */ +#define IVE_EQ_DATA PPC_BITMASK(33, 63) /* Data written to the EQ= */ +} XiveIVE; + +XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn); + +#endif /* _INTC_XIVE_INTERNAL_H */ diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h new file mode 100644 index 000000000000..5b1f78e06a1e --- /dev/null +++ b/include/hw/ppc/spapr_xive.h @@ -0,0 +1,35 @@ +/* + * QEMU PowerPC sPAPR XIVE interrupt controller model + * + * Copyright (c) 2017, IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ + +#ifndef PPC_SPAPR_XIVE_H +#define PPC_SPAPR_XIVE_H + +#include + +typedef struct sPAPRXive sPAPRXive; +typedef struct XiveIVE XiveIVE; + +#define TYPE_SPAPR_XIVE "spapr-xive" +#define SPAPR_XIVE(obj) OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE) + +struct sPAPRXive { + SysBusDevice parent; + + /* Properties */ + uint32_t nr_irqs; + + /* XIVE internal tables */ + XiveIVE *ivt; +}; + +bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn); +bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn); +void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); + +#endif /* PPC_SPAPR_XIVE_H */ --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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 1512809234348331.46922673663073; Sat, 9 Dec 2017 00:47:14 -0800 (PST) Received: from localhost ([::1]:40424 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNami-0002Ob-By for importer@patchew.org; Sat, 09 Dec 2017 03:47:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45246) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNak8-0000rl-E7 for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNak4-0006tK-Dg for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:20 -0500 Received: from 7.mo6.mail-out.ovh.net ([46.105.59.196]:38836) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNak4-0006sp-3O for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:16 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id B34381276E5 for ; Sat, 9 Dec 2017 09:44:14 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 87179160090; Sat, 9 Dec 2017 09:44:08 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:22 +0100 Message-Id: <20171209084338.29395-4-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11699788884279593811 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 46.105.59.196 Subject: [Qemu-devel] [PATCH v2 03/19] spapr: introduce the XIVE interrupt sources 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Each XIVE interrupt source is associated with a two bit state machine called an Event State Buffer (ESB) : the first bit "P" means that an interrupt is "pending" and waiting for an EOI and the bit "Q" (queued) means a new interrupt was triggered while another was still pending. When an event is triggered, the associated interrupt state bits are fetched and modified and forwarded to the virtualization engine of the controller doing the routing. These can also be controlled by MMIO, to trigger events or turn off the sources for instance. See code for more details on the states and transitions. The MMIO space for the ESBs is 512GB large on the bare-metal system (PowerNV) and the BAR depends on the chip id. In our model for the sPAPR machine, we choose to only map the sub-region for the provisioned IRQ numbers and to use the mapping address of chip 0 of a real system. In the real world, each source may have different characteristics depending on the revision of a controller or the CPU. Early systems had two different MMIO pages for trigger and for EOI. We choose to use the same characteristics for all sources to simplify the model. The minimum CPU level for XIVE exploitation mode will be DD2.X as it has full support. The OS will obtain the address of the MMIO page of the ESB entry associated with a source and its characteristic using the H_INT_GET_SOURCE_INFO hcall. This will be addressed in the patch introducing the hcalls. The spapr_xive_irq() routine in charge of triggering the CPU interrupt line will be filled later on. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: - merged in the same patch the qemu_irq handlers - reworked the event notification logic of the qemu_irq handlers. =20 - introduced XIVE_ESB_STORE_EOI support - removed 'esb_shift' field=20 - removed a useless check on the validity of the IVE in the memory region handlers. - fixed spapr_xive_pq_trigger() to return true when XIVE_ESB_QUEUED is set - removed the overall ESB memory region. We now have only one region for the provisioned sources. - improved 'info pic' output hw/intc/spapr_xive.c | 254 ++++++++++++++++++++++++++++++++++++++++= +++- hw/intc/xive-internal.h | 10 ++ include/hw/ppc/spapr_xive.h | 9 ++ 3 files changed, 271 insertions(+), 2 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index e6e8841add17..43df6814619d 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -18,23 +18,252 @@ =20 #include "xive-internal.h" =20 +static void spapr_xive_irq(sPAPRXive *xive, int lisn) +{ + +} + /* - * Main XIVE object + * XIVE Interrupt Source + */ + +/* + * "magic" Event State Buffer (ESB) MMIO offsets. + * + * Each interrupt source has a 2-bit state machine called ESB + * which can be controlled by MMIO. It's made of 2 bits, P and + * Q. P indicates that an interrupt is pending (has been sent + * to a queue and is waiting for an EOI). Q indicates that the + * interrupt has been triggered while pending. + * + * This acts as a coalescing mechanism in order to guarantee + * that a given interrupt only occurs at most once in a queue. + * + * When doing an EOI, the Q bit will indicate if the interrupt + * needs to be re-triggered. + * + * The following offsets into the ESB MMIO allow to read or + * manipulate the PQ bits. They must be used with an 8-bytes + * load instruction. They all return the previous state of the + * interrupt (atomically). + * + * Additionally, some ESB pages support doing an EOI via a + * store at 0 and some ESBs support doing a trigger via a + * separate trigger page. + */ +#define XIVE_ESB_STORE_EOI 0x400 /* Store */ +#define XIVE_ESB_LOAD_EOI 0x000 /* Load */ +#define XIVE_ESB_GET 0x800 /* Load */ +#define XIVE_ESB_SET_PQ_00 0xc00 /* Load */ +#define XIVE_ESB_SET_PQ_01 0xd00 /* Load */ +#define XIVE_ESB_SET_PQ_10 0xe00 /* Load */ +#define XIVE_ESB_SET_PQ_11 0xf00 /* Load */ + +#define XIVE_ESB_VAL_P 0x2 +#define XIVE_ESB_VAL_Q 0x1 + +#define XIVE_ESB_RESET 0x0 +#define XIVE_ESB_PENDING XIVE_ESB_VAL_P +#define XIVE_ESB_QUEUED (XIVE_ESB_VAL_P | XIVE_ESB_VAL_Q) +#define XIVE_ESB_OFF XIVE_ESB_VAL_Q + +static uint8_t spapr_xive_pq_get(sPAPRXive *xive, uint32_t lisn) +{ + uint32_t byte =3D lisn / 4; + uint32_t bit =3D (lisn % 4) * 2; + + assert(byte < xive->sbe_size); + + return (xive->sbe[byte] >> bit) & 0x3; +} + +static uint8_t spapr_xive_pq_set(sPAPRXive *xive, uint32_t lisn, uint8_t p= q) +{ + uint32_t byte =3D lisn / 4; + uint32_t bit =3D (lisn % 4) * 2; + uint8_t old, new; + + assert(byte < xive->sbe_size); + + old =3D xive->sbe[byte]; + + new =3D xive->sbe[byte] & ~(0x3 << bit); + new |=3D (pq & 0x3) << bit; + + xive->sbe[byte] =3D new; + + return (old >> bit) & 0x3; +} + +static bool spapr_xive_pq_eoi(sPAPRXive *xive, uint32_t lisn) +{ + uint8_t old_pq =3D spapr_xive_pq_get(xive, lisn); + + switch (old_pq) { + case XIVE_ESB_RESET: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_RESET); + return false; + case XIVE_ESB_PENDING: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_RESET); + return false; + case XIVE_ESB_QUEUED: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_PENDING); + return true; + case XIVE_ESB_OFF: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_OFF); + return false; + default: + g_assert_not_reached(); + } +} + +/* + * Returns whether the event notification should be forwarded to the + * IVE for routing. */ +static bool spapr_xive_pq_trigger(sPAPRXive *xive, uint32_t lisn) +{ + uint8_t old_pq =3D spapr_xive_pq_get(xive, lisn); =20 + switch (old_pq) { + case XIVE_ESB_RESET: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_PENDING); + return true; + case XIVE_ESB_PENDING: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_QUEUED); + return false; + case XIVE_ESB_QUEUED: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_QUEUED); + return false; + case XIVE_ESB_OFF: + spapr_xive_pq_set(xive, lisn, XIVE_ESB_OFF); + return false; + default: + g_assert_not_reached(); + } +} + +/* + * XIVE Interrupt Source MMIOs + */ + +/* + * Some HW use a separate page for trigger. We only support the case + * in which the trigger can be done in the same page as the EOI. + */ +static uint64_t spapr_xive_esb_read(void *opaque, hwaddr addr, unsigned si= ze) +{ + sPAPRXive *xive =3D SPAPR_XIVE(opaque); + uint32_t offset =3D addr & 0xF00; + uint32_t lisn =3D addr >> ESB_SHIFT; + uint64_t ret =3D -1; + + switch (offset) { + case XIVE_ESB_LOAD_EOI: + /* + * EOI on load is not used anymore as we now advertise + * XIVE_ESB_STORE_EOI support for the interrupt sources + */ + ret =3D spapr_xive_pq_eoi(xive, lisn); + break; + + case XIVE_ESB_GET: + ret =3D spapr_xive_pq_get(xive, lisn); + break; + + case XIVE_ESB_SET_PQ_00: + case XIVE_ESB_SET_PQ_01: + case XIVE_ESB_SET_PQ_10: + case XIVE_ESB_SET_PQ_11: + ret =3D spapr_xive_pq_set(xive, lisn, (offset >> 8) & 0x3); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid ESB addr %d\n", offs= et); + } + + return ret; +} + +static void spapr_xive_esb_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) +{ + sPAPRXive *xive =3D SPAPR_XIVE(opaque); + uint32_t offset =3D addr & 0xF00; + uint32_t lisn =3D addr >> ESB_SHIFT; + bool notify =3D false; + + switch (offset) { + case 0: + notify =3D spapr_xive_pq_trigger(xive, lisn); + break; + case XIVE_ESB_STORE_EOI: + /* If the Q bit is set, we should forward a new source event + * notification + */ + notify =3D spapr_xive_pq_eoi(xive, lisn); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid ESB write addr %d\n", + offset); + return; + } + + /* Forward the source event notification for routing */ + if (notify) { + spapr_xive_irq(xive, lisn); + } +} + +static const MemoryRegionOps spapr_xive_esb_ops =3D { + .read =3D spapr_xive_esb_read, + .write =3D spapr_xive_esb_write, + .endianness =3D DEVICE_BIG_ENDIAN, + .valid =3D { + .min_access_size =3D 8, + .max_access_size =3D 8, + }, + .impl =3D { + .min_access_size =3D 8, + .max_access_size =3D 8, + }, +}; + +static void spapr_xive_source_set_irq(void *opaque, int lisn, int val) +{ + sPAPRXive *xive =3D SPAPR_XIVE(opaque); + bool notify =3D false; + + if (val) { + notify =3D spapr_xive_pq_trigger(xive, lisn); + } + + /* Forward the source event notification for routing */ + if (notify) { + spapr_xive_irq(xive, lisn); + } +} + +/* + * Main XIVE object + */ void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon) { int i; =20 for (i =3D 0; i < xive->nr_irqs; i++) { XiveIVE *ive =3D &xive->ivt[i]; + uint8_t pq; =20 if (!(ive->w & IVE_VALID)) { continue; } =20 - monitor_printf(mon, " %4x %s %08x %08x\n", i, + pq =3D spapr_xive_pq_get(xive, i); + + monitor_printf(mon, " %4x %s %c%c %08x %08x\n", i, ive->w & IVE_MASKED ? "M" : " ", + pq & XIVE_ESB_VAL_P ? 'P' : '-', + pq & XIVE_ESB_VAL_Q ? 'Q' : '-', (int) GETFIELD(IVE_EQ_INDEX, ive->w), (int) GETFIELD(IVE_EQ_DATA, ive->w)); } @@ -52,6 +281,9 @@ static void spapr_xive_reset(DeviceState *dev) ive->w |=3D IVE_MASKED; } } + + /* SBEs are initialized to 0b01 which corresponds to "ints off" */ + memset(xive->sbe, 0x55, xive->sbe_size); } =20 static void spapr_xive_realize(DeviceState *dev, Error **errp) @@ -65,6 +297,23 @@ static void spapr_xive_realize(DeviceState *dev, Error = **errp) =20 /* Allocate the IVT (Interrupt Virtualization Table) */ xive->ivt =3D g_new0(XiveIVE, xive->nr_irqs); + + /* QEMU IRQs */ + xive->qirqs =3D qemu_allocate_irqs(spapr_xive_source_set_irq, xive, + xive->nr_irqs); + + /* Allocate SBEs (State Bit Entry). 2 bits, so 4 entries per byte */ + xive->sbe_size =3D DIV_ROUND_UP(xive->nr_irqs, 4); + xive->sbe =3D g_malloc0(xive->sbe_size); + + /* VC BAR. Use address of chip 0 to install the ESB memory region + * for *all* interrupt sources */ + xive->esb_base =3D (P9_MMIO_BASE | VC_BAR_DEFAULT); + + memory_region_init_io(&xive->esb_iomem, OBJECT(xive), + &spapr_xive_esb_ops, xive, "xive.esb", + (1ull << ESB_SHIFT) * xive->nr_irqs); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &xive->esb_iomem); } =20 static const VMStateDescription vmstate_spapr_xive_ive =3D { @@ -92,6 +341,7 @@ static const VMStateDescription vmstate_spapr_xive =3D { VMSTATE_UINT32_EQUAL(nr_irqs, sPAPRXive, NULL), VMSTATE_STRUCT_VARRAY_UINT32(ivt, sPAPRXive, nr_irqs, 1, vmstate_spapr_xive_ive, XiveIVE), + VMSTATE_VBUFFER_UINT32(sbe, sPAPRXive, 1, NULL, sbe_size), VMSTATE_END_OF_LIST() }, }; diff --git a/hw/intc/xive-internal.h b/hw/intc/xive-internal.h index 132b71a6daf0..872648dd96a2 100644 --- a/hw/intc/xive-internal.h +++ b/hw/intc/xive-internal.h @@ -16,6 +16,16 @@ #define SETFIELD(m, v, val) \ (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_TO_LSH(m)) & (m))) =20 +/* + * XIVE MMIO regions + */ +#define P9_MMIO_BASE 0x006000000000000ull + +/* VC BAR contains set translations for the ESBs and the EQs. */ +#define VC_BAR_DEFAULT 0x10000000000ull +#define VC_BAR_SIZE 0x08000000000ull +#define ESB_SHIFT 16 /* One 64k page. OPAL has two */ + /* IVE/EAS * * One per interrupt source. Targets that interrupt to a given EQ diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 5b1f78e06a1e..ecc15d889b74 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -24,8 +24,17 @@ struct sPAPRXive { /* Properties */ uint32_t nr_irqs; =20 + /* IRQ */ + qemu_irq *qirqs; + /* XIVE internal tables */ XiveIVE *ivt; + uint8_t *sbe; + uint32_t sbe_size; + + /* ESB memory region */ + hwaddr esb_base; + MemoryRegion esb_iomem; }; =20 bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn); --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512809717447186.57047286483578; Sat, 9 Dec 2017 00:55:17 -0800 (PST) Received: from localhost ([::1]:40470 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNaue-0001xj-Pv for importer@patchew.org; Sat, 09 Dec 2017 03:55:12 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45305) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNakE-0000xV-M1 for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNakA-0006v1-Nw for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:26 -0500 Received: from 3.mo6.mail-out.ovh.net ([178.33.253.26]:54886) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNakA-0006uK-Ek for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:22 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id E03EC1277A1 for ; Sat, 9 Dec 2017 09:44:20 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id B388C160090; Sat, 9 Dec 2017 09:44:14 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:23 +0100 Message-Id: <20171209084338.29395-5-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11701477735902972755 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 178.33.253.26 Subject: [Qemu-devel] [PATCH v2 04/19] spapr: add support for the LSI interrupt sources 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The 'sent' status of the LSI interrupt source is modeled with the 'P' bit of the ESB and the assertion status of the source is maintained in an array under the main sPAPRXive object. The type of the source is stored in the same array for practical reasons. The OS will use the H_INT_GET_SOURCE_INFO hcall to determine the type of an interrupt source. Signed-off-by: C=C3=A9dric Le Goater --- hw/intc/spapr_xive.c | 54 +++++++++++++++++++++++++++++++++++++++++= ---- include/hw/ppc/spapr_xive.h | 10 ++++++++- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 43df6814619d..c772c726667f 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -144,6 +144,21 @@ static bool spapr_xive_pq_trigger(sPAPRXive *xive, uin= t32_t lisn) } =20 /* + * LSI interrupt sources use the P bit and a custom assertion flag + */ +static bool spapr_xive_lsi_trigger(sPAPRXive *xive, uint32_t lisn) +{ + uint8_t old_pq =3D spapr_xive_pq_get(xive, lisn); + + if (old_pq =3D=3D XIVE_ESB_RESET && + xive->status[lisn] & XIVE_STATUS_ASSERTED) { + spapr_xive_pq_set(xive, lisn, XIVE_ESB_PENDING); + return true; + } + return false; +} + +/* * XIVE Interrupt Source MMIOs */ =20 @@ -165,6 +180,14 @@ static uint64_t spapr_xive_esb_read(void *opaque, hwad= dr addr, unsigned size) * XIVE_ESB_STORE_EOI support for the interrupt sources */ ret =3D spapr_xive_pq_eoi(xive, lisn); + + /* If the LSI source is still asserted, forward a new source + * event notification */ + if (spapr_xive_irq_is_lsi(xive, lisn)) { + if (spapr_xive_lsi_trigger(xive, lisn)) { + spapr_xive_irq(xive, lisn); + } + } break; =20 case XIVE_ESB_GET: @@ -201,6 +224,14 @@ static void spapr_xive_esb_write(void *opaque, hwaddr = addr, * notification */ notify =3D spapr_xive_pq_eoi(xive, lisn); + + /* LSI sources do not set the Q bit but they can still be + * asserted, in which case we should forward a new source + * event notification + */ + if (spapr_xive_irq_is_lsi(xive, lisn)) { + notify =3D spapr_xive_lsi_trigger(xive, lisn); + } break; default: qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid ESB write addr %d\n", @@ -233,8 +264,17 @@ static void spapr_xive_source_set_irq(void *opaque, in= t lisn, int val) sPAPRXive *xive =3D SPAPR_XIVE(opaque); bool notify =3D false; =20 - if (val) { - notify =3D spapr_xive_pq_trigger(xive, lisn); + if (spapr_xive_irq_is_lsi(xive, lisn)) { + if (val) { + xive->status[lisn] |=3D XIVE_STATUS_ASSERTED; + } else { + xive->status[lisn] &=3D ~XIVE_STATUS_ASSERTED; + } + notify =3D spapr_xive_lsi_trigger(xive, lisn); + } else { + if (val) { + notify =3D spapr_xive_pq_trigger(xive, lisn); + } } =20 /* Forward the source event notification for routing */ @@ -260,7 +300,8 @@ void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor= *mon) =20 pq =3D spapr_xive_pq_get(xive, i); =20 - monitor_printf(mon, " %4x %s %c%c %08x %08x\n", i, + monitor_printf(mon, " %4x %s %s %c%c %08x %08x\n", i, + spapr_xive_irq_is_lsi(xive, i) ? "LSI" : "MSI", ive->w & IVE_MASKED ? "M" : " ", pq & XIVE_ESB_VAL_P ? 'P' : '-', pq & XIVE_ESB_VAL_Q ? 'Q' : '-', @@ -274,6 +315,8 @@ static void spapr_xive_reset(DeviceState *dev) sPAPRXive *xive =3D SPAPR_XIVE(dev); int i; =20 + /* Do not clear IRQ's status */ + /* Mask all valid IVEs in the IRQ number space. */ for (i =3D 0; i < xive->nr_irqs; i++) { XiveIVE *ive =3D &xive->ivt[i]; @@ -301,6 +344,7 @@ static void spapr_xive_realize(DeviceState *dev, Error = **errp) /* QEMU IRQs */ xive->qirqs =3D qemu_allocate_irqs(spapr_xive_source_set_irq, xive, xive->nr_irqs); + xive->status =3D g_malloc0(xive->nr_irqs); =20 /* Allocate SBEs (State Bit Entry). 2 bits, so 4 entries per byte */ xive->sbe_size =3D DIV_ROUND_UP(xive->nr_irqs, 4); @@ -381,7 +425,7 @@ XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t l= isn) return lisn < xive->nr_irqs ? &xive->ivt[lisn] : NULL; } =20 -bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn) +bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn, bool lsi) { XiveIVE *ive =3D spapr_xive_get_ive(xive, lisn); =20 @@ -390,6 +434,7 @@ bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t li= sn) } =20 ive->w |=3D IVE_VALID; + xive->status[lisn] |=3D lsi ? XIVE_STATUS_LSI : 0; return true; } =20 @@ -402,5 +447,6 @@ bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t l= isn) } =20 ive->w &=3D ~IVE_VALID; + xive->status[lisn] =3D 0; return true; } diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index ecc15d889b74..a7e59fd601d7 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -23,6 +23,9 @@ struct sPAPRXive { =20 /* Properties */ uint32_t nr_irqs; +#define XIVE_STATUS_LSI 0x1 +#define XIVE_STATUS_ASSERTED 0x2 + uint8_t *status; =20 /* IRQ */ qemu_irq *qirqs; @@ -37,7 +40,12 @@ struct sPAPRXive { MemoryRegion esb_iomem; }; =20 -bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn); +static inline bool spapr_xive_irq_is_lsi(sPAPRXive *xive, int lisn) +{ + return xive->status[lisn] & XIVE_STATUS_LSI; +} + +bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn, bool lsi); bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn); void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); =20 --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151280923657773.95377025472521; Sat, 9 Dec 2017 00:47:16 -0800 (PST) Received: from localhost ([::1]:40425 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNaml-0002QX-C2 for importer@patchew.org; Sat, 09 Dec 2017 03:47:04 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45337) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNakK-00012c-QX for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNakG-0006yM-Qk for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:32 -0500 Received: from 20.mo6.mail-out.ovh.net ([178.32.124.17]:58784) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNakG-0006wm-HW for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:28 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 17E9D1277C8 for ; Sat, 9 Dec 2017 09:44:27 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id DEEC0160090; Sat, 9 Dec 2017 09:44:20 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:24 +0100 Message-Id: <20171209084338.29395-6-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11703448058253183827 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 178.32.124.17 Subject: [Qemu-devel] [PATCH v2 05/19] spapr: introduce a XIVE interrupt presenter model 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Once an event has been routed by the IVRE, it reaches the XIVE virtualization presentation engine which, simply speaking, raises one bit in the Interrupt Pending Buffer (IBP) register corresponding to the priority of the pending interrupt. This indicates there is an event pending in one of the 8 priority queues and the interrupt can then be delivered to the Virtual Processor. The XIVE presenter engine uses a set of registers to handle priority management and interrupt acknowledgment among other things. The most important being : - Interrupt Priority Register (PIPR) - Interrupt Pending Buffer (IPB) - Current Processor Priority (CPPR) - Notification Source Register (NSR) There is one set of registers per level of privilege, four in all : HW, HV pool, OS and User. These are called rings. All registers are accessible through a specific MMIO region called the Thread Interrupt Management Areas (TIMA) but, depending on the privilege level of the CPU, the view of the TIMA is filtered. The sPAPR machine runs at the OS privilege and therefore can only accesses the OS and the User rings. The others are for hypervisor levels. The CPU interrupt state is modeled with a sPAPRXiveNVT object which stores the values of the different registers. The different TIMA views are mapped at the same address for each CPU and 'current_cpu' is used to retrieve the sPAPRXiveNVT holding the ring registers. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: - renamed 'sPAPRXiveICP' to 'sPAPRXiveNVT' - renamed 'tima' to 'regs'=20 - renamed 'tima_os' to 'ring_os' - introduced TM_RING_SIZE=20 - removed 'tm_shift' field - introduced a memory region to model the User TIMA and another one for the OS TIMA. One page size for each. - removed useless checks in the memory region handlers - removed support for 970 ... =20 hw/intc/spapr_xive.c | 281 ++++++++++++++++++++++++++++++++++++++++= ++++ hw/intc/xive-internal.h | 92 +++++++++++++++ include/hw/ppc/spapr_xive.h | 11 ++ 3 files changed, 384 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index c772c726667f..53f0e698e135 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -15,9 +15,177 @@ #include "sysemu/dma.h" #include "monitor/monitor.h" #include "hw/ppc/spapr_xive.h" +#include "hw/ppc/xics.h" =20 #include "xive-internal.h" =20 +struct sPAPRXiveNVT { + DeviceState parent_obj; + + CPUState *cs; + qemu_irq output; + + /* Registers for all rings but sPAPR can only access the OS ring */ + uint8_t regs[TM_RING_COUNT * TM_RING_SIZE]; + + /* Shortcut to the OS ring */ + uint8_t *ring_os; +}; + +static uint64_t spapr_xive_nvt_accept(sPAPRXiveNVT *nvt) +{ + return 0; +} + +static void spapr_xive_nvt_set_cppr(sPAPRXiveNVT *nvt, uint8_t cppr) +{ + if (cppr > XIVE_PRIORITY_MAX) { + cppr =3D 0xff; + } + + nvt->ring_os[TM_CPPR] =3D cppr; +} + +/* + * Thread Interrupt Management Area MMIO + */ +static uint64_t spapr_xive_tm_read_special(sPAPRXiveNVT *nvt, hwaddr offse= t, + unsigned size) +{ + uint64_t ret =3D -1; + + if (offset =3D=3D TM_SPC_ACK_OS_REG && size =3D=3D 2) { + ret =3D spapr_xive_nvt_accept(nvt); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid TIMA read @%" + HWADDR_PRIx" size %d\n", offset, size); + } + + return ret; +} + +#define TM_RING(offset) ((offset) & 0xf0) + +static uint64_t spapr_xive_tm_os_read(void *opaque, hwaddr offset, + unsigned size) +{ + PowerPCCPU *cpu =3D POWERPC_CPU(current_cpu); + sPAPRXiveNVT *nvt =3D SPAPR_XIVE_NVT(cpu->intc); + uint64_t ret =3D -1; + int i; + + if (offset >=3D TM_SPC_ACK_EBB) { + return spapr_xive_tm_read_special(nvt, offset, size); + } + + if (TM_RING(offset) !=3D TM_QW1_OS) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid access to non-OS rin= g @%" + HWADDR_PRIx"\n", offset); + return ret; + } + + ret =3D 0; + for (i =3D 0; i < size; i++) { + ret |=3D nvt->regs[offset + i] << (8 * i); + } + + return ret; +} + +static bool spapr_xive_tm_is_readonly(uint8_t offset) +{ + return offset !=3D TM_QW1_OS + TM_CPPR; +} + +static void spapr_xive_tm_write_special(sPAPRXiveNVT *nvt, hwaddr offset, + uint64_t value, unsigned size) +{ + /* TODO: support TM_SPC_SET_OS_PENDING */ + + /* TODO: support TM_SPC_ACK_OS_EL */ +} + +static void spapr_xive_tm_os_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + PowerPCCPU *cpu =3D POWERPC_CPU(current_cpu); + sPAPRXiveNVT *nvt =3D SPAPR_XIVE_NVT(cpu->intc); + int i; + + if (offset >=3D TM_SPC_ACK_EBB) { + spapr_xive_tm_write_special(nvt, offset, value, size); + return; + } + + if (TM_RING(offset) !=3D TM_QW1_OS) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid access to non-OS rin= g @%" + HWADDR_PRIx"\n", offset); + return; + } + + switch (size) { + case 1: + if (offset =3D=3D TM_QW1_OS + TM_CPPR) { + spapr_xive_nvt_set_cppr(nvt, value & 0xff); + } + break; + case 4: + case 8: + for (i =3D 0; i < size; i++) { + if (!spapr_xive_tm_is_readonly(offset + i)) { + nvt->regs[offset + i] =3D (value >> (8 * i)) & 0xff; + } + } + break; + default: + g_assert_not_reached(); + } +} + +static const MemoryRegionOps spapr_xive_tm_os_ops =3D { + .read =3D spapr_xive_tm_os_read, + .write =3D spapr_xive_tm_os_write, + .endianness =3D DEVICE_BIG_ENDIAN, + .valid =3D { + .min_access_size =3D 1, + .max_access_size =3D 8, + }, + .impl =3D { + .min_access_size =3D 1, + .max_access_size =3D 8, + }, +}; + +static uint64_t spapr_xive_tm_user_read(void *opaque, hwaddr offset, + unsigned size) +{ + qemu_log_mask(LOG_UNIMP, "XIVE: invalid access to User TIMA @%" + HWADDR_PRIx"\n", offset); + return -1; +} + +static void spapr_xive_tm_user_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + qemu_log_mask(LOG_UNIMP, "XIVE: invalid access to User TIMA @%" + HWADDR_PRIx"\n", offset); +} + + +static const MemoryRegionOps spapr_xive_tm_user_ops =3D { + .read =3D spapr_xive_tm_user_read, + .write =3D spapr_xive_tm_user_write, + .endianness =3D DEVICE_BIG_ENDIAN, + .valid =3D { + .min_access_size =3D 1, + .max_access_size =3D 8, + }, + .impl =3D { + .min_access_size =3D 1, + .max_access_size =3D 8, + }, +}; + static void spapr_xive_irq(sPAPRXive *xive, int lisn) { =20 @@ -358,6 +526,22 @@ static void spapr_xive_realize(DeviceState *dev, Error= **errp) &spapr_xive_esb_ops, xive, "xive.esb", (1ull << ESB_SHIFT) * xive->nr_irqs); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &xive->esb_iomem); + + /* The Thread Interrupt Management Area has the same address for + * each chip. On sPAPR, we only need to expose the User and OS + * level views of the TIMA. + */ + xive->tm_base =3D (P9_MMIO_BASE | TM_BAR_DEFAULT); + + memory_region_init_io(&xive->tm_iomem_user, OBJECT(xive), + &spapr_xive_tm_user_ops, xive, "xive.tima.user", + 1ull << TM_SHIFT); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &xive->tm_iomem_user); + + memory_region_init_io(&xive->tm_iomem_os, OBJECT(xive), + &spapr_xive_tm_os_ops, xive, "xive.tima.os", + 1ull << TM_SHIFT); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &xive->tm_iomem_os); } =20 static const VMStateDescription vmstate_spapr_xive_ive =3D { @@ -413,9 +597,106 @@ static const TypeInfo spapr_xive_info =3D { .class_init =3D spapr_xive_class_init, }; =20 +void spapr_xive_nvt_pic_print_info(sPAPRXiveNVT *nvt, Monitor *mon) +{ + int cpu_index =3D nvt->cs ? nvt->cs->cpu_index : -1; + + monitor_printf(mon, "CPU %d CPPR=3D%02x IPB=3D%02x PIPR=3D%02x NSR=3D%= 02x\n", + cpu_index, nvt->ring_os[TM_CPPR], nvt->ring_os[TM_IPB], + nvt->ring_os[TM_PIPR], nvt->ring_os[TM_NSR]); +} + +static void spapr_xive_nvt_reset(void *dev) +{ + sPAPRXiveNVT *nvt =3D SPAPR_XIVE_NVT(dev); + + memset(nvt->regs, 0, sizeof(nvt->regs)); +} + +static void spapr_xive_nvt_realize(DeviceState *dev, Error **errp) +{ + sPAPRXiveNVT *nvt =3D SPAPR_XIVE_NVT(dev); + PowerPCCPU *cpu; + CPUPPCState *env; + Object *obj; + Error *err =3D NULL; + + obj =3D object_property_get_link(OBJECT(dev), ICP_PROP_CPU, &err); + if (!obj) { + error_propagate(errp, err); + error_prepend(errp, "required link '" ICP_PROP_CPU "' not found: "= ); + return; + } + + cpu =3D POWERPC_CPU(obj); + nvt->cs =3D CPU(obj); + + env =3D &cpu->env; + switch (PPC_INPUT(env)) { + case PPC_FLAGS_INPUT_POWER7: + nvt->output =3D env->irq_inputs[POWER7_INPUT_INT]; + break; + + default: + error_setg(errp, "XIVE interrupt controller does not support " + "this CPU bus model"); + return; + } + + qemu_register_reset(spapr_xive_nvt_reset, dev); +} + +static void spapr_xive_nvt_unrealize(DeviceState *dev, Error **errp) +{ + qemu_unregister_reset(spapr_xive_nvt_reset, dev); +} + +static void spapr_xive_nvt_init(Object *obj) +{ + sPAPRXiveNVT *nvt =3D SPAPR_XIVE_NVT(obj); + + nvt->ring_os =3D &nvt->regs[TM_QW1_OS]; +} + +static bool vmstate_spapr_xive_nvt_needed(void *opaque) +{ + /* TODO check machine XIVE support */ + return true; +} + +static const VMStateDescription vmstate_spapr_xive_nvt =3D { + .name =3D TYPE_SPAPR_XIVE_NVT, + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D vmstate_spapr_xive_nvt_needed, + .fields =3D (VMStateField[]) { + VMSTATE_BUFFER(regs, sPAPRXiveNVT), + VMSTATE_END_OF_LIST() + }, +}; + +static void spapr_xive_nvt_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D spapr_xive_nvt_realize; + dc->unrealize =3D spapr_xive_nvt_unrealize; + dc->desc =3D "sPAPR XIVE Interrupt Presenter"; + dc->vmsd =3D &vmstate_spapr_xive_nvt; +} + +static const TypeInfo xive_nvt_info =3D { + .name =3D TYPE_SPAPR_XIVE_NVT, + .parent =3D TYPE_DEVICE, + .instance_size =3D sizeof(sPAPRXiveNVT), + .instance_init =3D spapr_xive_nvt_init, + .class_init =3D spapr_xive_nvt_class_init, +}; + static void spapr_xive_register_types(void) { type_register_static(&spapr_xive_info); + type_register_static(&xive_nvt_info); } =20 type_init(spapr_xive_register_types) diff --git a/hw/intc/xive-internal.h b/hw/intc/xive-internal.h index 872648dd96a2..49f4b7c5f393 100644 --- a/hw/intc/xive-internal.h +++ b/hw/intc/xive-internal.h @@ -26,6 +26,96 @@ #define VC_BAR_SIZE 0x08000000000ull #define ESB_SHIFT 16 /* One 64k page. OPAL has two */ =20 +/* Thread Interrupt Management Area */ +#define TM_BAR_DEFAULT 0x30203180000ull +#define TM_SHIFT 16 + +/* + * Thread Management (aka "TM") registers + */ +#define TM_RING_COUNT 4 +#define TM_RING_SIZE 0x10 + +/* TM register offsets */ +#define TM_QW0_USER 0x000 /* All rings */ +#define TM_QW1_OS 0x010 /* Ring 0..2 */ +#define TM_QW2_HV_POOL 0x020 /* Ring 0..1 */ +#define TM_QW3_HV_PHYS 0x030 /* Ring 0..1 */ + +/* Byte offsets inside a QW QW0 QW1 QW2 QW3 */ +#define TM_NSR 0x0 /* + + - + */ +#define TM_CPPR 0x1 /* - + - + */ +#define TM_IPB 0x2 /* - + + + */ +#define TM_LSMFB 0x3 /* - + + + */ +#define TM_ACK_CNT 0x4 /* - + - - */ +#define TM_INC 0x5 /* - + - + */ +#define TM_AGE 0x6 /* - + - + */ +#define TM_PIPR 0x7 /* - + - + */ + +#define TM_WORD0 0x0 +#define TM_WORD1 0x4 + +/* + * QW word 2 contains the valid bit at the top and other fields + * depending on the QW. + */ +#define TM_WORD2 0x8 +#define TM_QW0W2_VU PPC_BIT32(0) +#define TM_QW0W2_LOGIC_SERV PPC_BITMASK32(1, 31) /* XX 2,31 ? */ +#define TM_QW1W2_VO PPC_BIT32(0) +#define TM_QW1W2_OS_CAM PPC_BITMASK32(8, 31) +#define TM_QW2W2_VP PPC_BIT32(0) +#define TM_QW2W2_POOL_CAM PPC_BITMASK32(8, 31) +#define TM_QW3W2_VT PPC_BIT32(0) +#define TM_QW3W2_LP PPC_BIT32(6) +#define TM_QW3W2_LE PPC_BIT32(7) +#define TM_QW3W2_T PPC_BIT32(31) + +/* + * In addition to normal loads to "peek" and writes (only when invalid) + * using 4 and 8 bytes accesses, the above registers support these + * "special" byte operations: + * + * - Byte load from QW0[NSR] - User level NSR (EBB) + * - Byte store to QW0[NSR] - User level NSR (EBB) + * - Byte load/store to QW1[CPPR] and QW3[CPPR] - CPPR access + * - Byte load from QW3[TM_WORD2] - Read VT||00000||LP||LE on thrd 0 + * otherwise VT||0000000 + * - Byte store to QW3[TM_WORD2] - Set VT bit (and LP/LE if present) + * + * Then we have all these "special" CI ops at these offset that trigger + * all sorts of side effects: + */ +#define TM_SPC_ACK_EBB 0x800 /* Load8 ack EBB to reg*/ +#define TM_SPC_ACK_OS_REG 0x810 /* Load16 ack OS irq to reg */ +#define TM_SPC_PUSH_USR_CTX 0x808 /* Store32 Push/Validate user cont= ext */ +#define TM_SPC_PULL_USR_CTX 0x808 /* Load32 Pull/Invalidate user + * context */ +#define TM_SPC_SET_OS_PENDING 0x812 /* Store8 Set OS irq pending bit */ +#define TM_SPC_PULL_OS_CTX 0x818 /* Load32/Load64 Pull/Invalidate OS + * context to reg */ +#define TM_SPC_PULL_POOL_CTX 0x828 /* Load32/Load64 Pull/Invalidate P= ool + * context to reg*/ +#define TM_SPC_ACK_HV_REG 0x830 /* Load16 ack HV irq to reg */ +#define TM_SPC_PULL_USR_CTX_OL 0xc08 /* Store8 Pull/Inval usr ctx to odd + * line */ +#define TM_SPC_ACK_OS_EL 0xc10 /* Store8 ack OS irq to even line = */ +#define TM_SPC_ACK_HV_POOL_EL 0xc20 /* Store8 ack HV evt pool to even + * line */ +#define TM_SPC_ACK_HV_EL 0xc30 /* Store8 ack HV irq to even line = */ +/* XXX more... */ + +/* NSR fields for the various QW ack types */ +#define TM_QW0_NSR_EB PPC_BIT8(0) +#define TM_QW1_NSR_EO PPC_BIT8(0) +#define TM_QW3_NSR_HE PPC_BITMASK8(0, 1) +#define TM_QW3_NSR_HE_NONE 0 +#define TM_QW3_NSR_HE_POOL 1 +#define TM_QW3_NSR_HE_PHYS 2 +#define TM_QW3_NSR_HE_LSI 3 +#define TM_QW3_NSR_I PPC_BIT8(2) +#define TM_QW3_NSR_GRP_LVL PPC_BIT8(3, 7) + /* IVE/EAS * * One per interrupt source. Targets that interrupt to a given EQ @@ -46,6 +136,8 @@ typedef struct XiveIVE { #define IVE_EQ_DATA PPC_BITMASK(33, 63) /* Data written to the EQ= */ } XiveIVE; =20 +#define XIVE_PRIORITY_MAX 7 + XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn); =20 #endif /* _INTC_XIVE_INTERNAL_H */ diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index a7e59fd601d7..dcaa69025878 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -14,10 +14,15 @@ =20 typedef struct sPAPRXive sPAPRXive; typedef struct XiveIVE XiveIVE; +typedef struct sPAPRXiveNVT sPAPRXiveNVT; =20 #define TYPE_SPAPR_XIVE "spapr-xive" #define SPAPR_XIVE(obj) OBJECT_CHECK(sPAPRXive, (obj), TYPE_SPAPR_XIVE) =20 +#define TYPE_SPAPR_XIVE_NVT "spapr-xive-nvt" +#define SPAPR_XIVE_NVT(obj) \ + OBJECT_CHECK(sPAPRXiveNVT, (obj), TYPE_SPAPR_XIVE_NVT) + struct sPAPRXive { SysBusDevice parent; =20 @@ -38,6 +43,11 @@ struct sPAPRXive { /* ESB memory region */ hwaddr esb_base; MemoryRegion esb_iomem; + + /* TIMA memory regions */ + hwaddr tm_base; + MemoryRegion tm_iomem_user; + MemoryRegion tm_iomem_os; }; =20 static inline bool spapr_xive_irq_is_lsi(sPAPRXive *xive, int lisn) @@ -48,5 +58,6 @@ static inline bool spapr_xive_irq_is_lsi(sPAPRXive *xive,= int lisn) bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn, bool lsi); bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn); void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); +void spapr_xive_nvt_pic_print_info(sPAPRXiveNVT *nvt, Monitor *mon); =20 #endif /* PPC_SPAPR_XIVE_H */ --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512809417432961.1379783854567; Sat, 9 Dec 2017 00:50:17 -0800 (PST) Received: from localhost ([::1]:40441 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNapp-00068H-Vp for importer@patchew.org; Sat, 09 Dec 2017 03:50:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45360) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNakQ-00016S-Km for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNakM-000707-M2 for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:38 -0500 Received: from 10.mo6.mail-out.ovh.net ([87.98.157.236]:52903) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNakM-0006zm-CH for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:34 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 411A01277A1 for ; Sat, 9 Dec 2017 09:44:33 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 1701716009E; Sat, 9 Dec 2017 09:44:27 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:25 +0100 Message-Id: <20171209084338.29395-7-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11705136908806490963 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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.157.236 Subject: [Qemu-devel] [PATCH v2 06/19] spapr: introduce the XIVE Event Queues 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The Event Queue Descriptor (EQD) table, also known as Event Notification Descriptor (END), is an internal table of the XIVE virtualization routing engine. It specifies on which Event Queue the event data should be posted when an exception occurs (later on pulled by the OS) and which Virtual Processor to notify. The Event Queue is a much more complex structure but we start with a simple model for the sPAPR machine. There is one XiveEQ per priority and the model chooses to store them under the XIVE virtualization presenter model (sPAPRXiveNVT) to save an extra table. EQs are simply indexed with : (server << 3) | (priority & 0x7) This is not in the XIVE architecture but as the EQ index is never exposed to the guest, in the hcalls or in the device tree, we are free to use what fits best the current model. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: - removed spapr_xive_eq_for_server() which did the EQ indexing. - changed spapr_xive_get_eq() to use a server and a priority parameter - introduced a couple of macro for the EQ indexing.=20 - improved 'info pic' output hw/intc/spapr_xive.c | 48 ++++++++++++++++++++++++++++++++++++++++++-- hw/intc/xive-internal.h | 53 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 53f0e698e135..8e990d58ecf4 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -15,6 +15,7 @@ #include "sysemu/dma.h" #include "monitor/monitor.h" #include "hw/ppc/spapr_xive.h" +#include "hw/ppc/spapr.h" #include "hw/ppc/xics.h" =20 #include "xive-internal.h" @@ -30,6 +31,8 @@ struct sPAPRXiveNVT { =20 /* Shortcut to the OS ring */ uint8_t *ring_os; + + XiveEQ eqt[XIVE_PRIORITY_MAX + 1]; }; =20 static uint64_t spapr_xive_nvt_accept(sPAPRXiveNVT *nvt) @@ -186,6 +189,13 @@ static const MemoryRegionOps spapr_xive_tm_user_ops = =3D { }, }; =20 +static sPAPRXiveNVT *spapr_xive_nvt_get(sPAPRXive *xive, int server) +{ + PowerPCCPU *cpu =3D spapr_find_cpu(server); + + return cpu ? SPAPR_XIVE_NVT(cpu->intc) : NULL; +} + static void spapr_xive_irq(sPAPRXive *xive, int lisn) { =20 @@ -461,19 +471,22 @@ void spapr_xive_pic_print_info(sPAPRXive *xive, Monit= or *mon) for (i =3D 0; i < xive->nr_irqs; i++) { XiveIVE *ive =3D &xive->ivt[i]; uint8_t pq; + uint32_t eq_idx; =20 if (!(ive->w & IVE_VALID)) { continue; } =20 pq =3D spapr_xive_pq_get(xive, i); + eq_idx =3D GETFIELD(IVE_EQ_INDEX, ive->w); =20 - monitor_printf(mon, " %4x %s %s %c%c %08x %08x\n", i, + monitor_printf(mon, " %4x %s %s %c%c server:%d prio:%d %08x\n", i, spapr_xive_irq_is_lsi(xive, i) ? "LSI" : "MSI", ive->w & IVE_MASKED ? "M" : " ", pq & XIVE_ESB_VAL_P ? 'P' : '-', pq & XIVE_ESB_VAL_Q ? 'Q' : '-', - (int) GETFIELD(IVE_EQ_INDEX, ive->w), + XIVE_EQ_INDEX_SERVER(eq_idx), + XIVE_EQ_INDEX_PRIO(eq_idx), (int) GETFIELD(IVE_EQ_DATA, ive->w)); } } @@ -611,6 +624,8 @@ static void spapr_xive_nvt_reset(void *dev) sPAPRXiveNVT *nvt =3D SPAPR_XIVE_NVT(dev); =20 memset(nvt->regs, 0, sizeof(nvt->regs)); + + memset(nvt->eqt, 0, sizeof(nvt->eqt)); } =20 static void spapr_xive_nvt_realize(DeviceState *dev, Error **errp) @@ -658,6 +673,23 @@ static void spapr_xive_nvt_init(Object *obj) nvt->ring_os =3D &nvt->regs[TM_QW1_OS]; } =20 +static const VMStateDescription vmstate_spapr_xive_nvt_eq =3D { + .name =3D TYPE_SPAPR_XIVE_NVT "/eq", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField []) { + VMSTATE_UINT32(w0, XiveEQ), + VMSTATE_UINT32(w1, XiveEQ), + VMSTATE_UINT32(w2, XiveEQ), + VMSTATE_UINT32(w3, XiveEQ), + VMSTATE_UINT32(w4, XiveEQ), + VMSTATE_UINT32(w5, XiveEQ), + VMSTATE_UINT32(w6, XiveEQ), + VMSTATE_UINT32(w7, XiveEQ), + VMSTATE_END_OF_LIST() + }, +}; + static bool vmstate_spapr_xive_nvt_needed(void *opaque) { /* TODO check machine XIVE support */ @@ -671,6 +703,8 @@ static const VMStateDescription vmstate_spapr_xive_nvt = =3D { .needed =3D vmstate_spapr_xive_nvt_needed, .fields =3D (VMStateField[]) { VMSTATE_BUFFER(regs, sPAPRXiveNVT), + VMSTATE_STRUCT_ARRAY(eqt, sPAPRXiveNVT, (XIVE_PRIORITY_MAX + 1), 1, + vmstate_spapr_xive_nvt_eq, XiveEQ), VMSTATE_END_OF_LIST() }, }; @@ -731,3 +765,13 @@ bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t = lisn) xive->status[lisn] =3D 0; return true; } + +XiveEQ *spapr_xive_get_eq(sPAPRXive *xive, uint32_t server, uint8_t priori= ty) +{ + sPAPRXiveNVT *nvt =3D spapr_xive_nvt_get(xive, server); + + if (!nvt || priority > XIVE_PRIORITY_MAX) { + return NULL; + } + return &nvt->eqt[priority]; +} diff --git a/hw/intc/xive-internal.h b/hw/intc/xive-internal.h index 49f4b7c5f393..fcd740d276f7 100644 --- a/hw/intc/xive-internal.h +++ b/hw/intc/xive-internal.h @@ -136,8 +136,61 @@ typedef struct XiveIVE { #define IVE_EQ_DATA PPC_BITMASK(33, 63) /* Data written to the EQ= */ } XiveIVE; =20 +/* EQ */ +typedef struct XiveEQ { + uint32_t w0; +#define EQ_W0_VALID PPC_BIT32(0) +#define EQ_W0_ENQUEUE PPC_BIT32(1) +#define EQ_W0_UCOND_NOTIFY PPC_BIT32(2) +#define EQ_W0_BACKLOG PPC_BIT32(3) +#define EQ_W0_PRECL_ESC_CTL PPC_BIT32(4) +#define EQ_W0_ESCALATE_CTL PPC_BIT32(5) +#define EQ_W0_END_OF_INTR PPC_BIT32(6) +#define EQ_W0_QSIZE PPC_BITMASK32(12, 15) +#define EQ_W0_SW0 PPC_BIT32(16) +#define EQ_W0_FIRMWARE EQ_W0_SW0 /* Owned by FW */ +#define EQ_QSIZE_4K 0 +#define EQ_QSIZE_64K 4 +#define EQ_W0_HWDEP PPC_BITMASK32(24, 31) + uint32_t w1; +#define EQ_W1_ESn PPC_BITMASK32(0, 1) +#define EQ_W1_ESn_P PPC_BIT32(0) +#define EQ_W1_ESn_Q PPC_BIT32(1) +#define EQ_W1_ESe PPC_BITMASK32(2, 3) +#define EQ_W1_ESe_P PPC_BIT32(2) +#define EQ_W1_ESe_Q PPC_BIT32(3) +#define EQ_W1_GENERATION PPC_BIT32(9) +#define EQ_W1_PAGE_OFF PPC_BITMASK32(10, 31) + uint32_t w2; +#define EQ_W2_MIGRATION_REG PPC_BITMASK32(0, 3) +#define EQ_W2_OP_DESC_HI PPC_BITMASK32(4, 31) + uint32_t w3; +#define EQ_W3_OP_DESC_LO PPC_BITMASK32(0, 31) + uint32_t w4; +#define EQ_W4_ESC_EQ_BLOCK PPC_BITMASK32(4, 7) +#define EQ_W4_ESC_EQ_INDEX PPC_BITMASK32(8, 31) + uint32_t w5; +#define EQ_W5_ESC_EQ_DATA PPC_BITMASK32(1, 31) + uint32_t w6; +#define EQ_W6_FORMAT_BIT PPC_BIT32(8) +#define EQ_W6_NVT_BLOCK PPC_BITMASK32(9, 12) +#define EQ_W6_NVT_INDEX PPC_BITMASK32(13, 31) + uint32_t w7; +#define EQ_W7_F0_IGNORE PPC_BIT32(0) +#define EQ_W7_F0_BLK_GROUPING PPC_BIT32(1) +#define EQ_W7_F0_PRIORITY PPC_BITMASK32(8, 15) +#define EQ_W7_F1_WAKEZ PPC_BIT32(0) +#define EQ_W7_F1_LOG_SERVER_ID PPC_BITMASK32(1, 31) +} XiveEQ; + #define XIVE_PRIORITY_MAX 7 =20 XiveIVE *spapr_xive_get_ive(sPAPRXive *xive, uint32_t lisn); +XiveEQ *spapr_xive_get_eq(sPAPRXive *xive, uint32_t server, uint8_t priori= ty); + +#define XIVE_EQ_INDEX(server, prio) (((server) << 3) | ((prio) & 0x7)) +#define XIVE_EQ_INDEX_SERVER(eq_idx) ((eq_idx) >> 3) +#define XIVE_EQ_INDEX_PRIO(eq_idx) ((eq_idx) & 0x7) + =20 #endif /* _INTC_XIVE_INTERNAL_H */ --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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 15128092491471023.3303477923554; Sat, 9 Dec 2017 00:47:29 -0800 (PST) Received: from localhost ([::1]:40426 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNan4-0002f7-G2 for importer@patchew.org; Sat, 09 Dec 2017 03:47:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45399) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNakX-0001Be-3O for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNakT-00072U-5z for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:45 -0500 Received: from 16.mo6.mail-out.ovh.net ([87.98.139.208]:35874) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNakS-00071a-Sl for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:41 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 6D9741276E5 for ; Sat, 9 Dec 2017 09:44:39 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 42692160087; Sat, 9 Dec 2017 09:44:33 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:26 +0100 Message-Id: <20171209084338.29395-8-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11706825757597666131 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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.139.208 Subject: [Qemu-devel] [PATCH v2 07/19] spapr: push the XIVE EQ data in OS event queue 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" If a triggered event is let through by the XIVE virtualization routing engine, the Event Queue data defined in the associated IVE is pushed in the in-memory event queue. The latter is a circular buffer provided by the OS using the H_INT_SET_QUEUE_CONFIG hcall, one per server and priority couple. Each Event Queue entry is 4 bytes long, the first bit being a 'generation' bit and the 31 following bits the EQ Data field. The EQ Data field provides a way to set an invariant logical event source number for an IRQ. It is set with the H_INT_SET_SOURCE_CONFIG hcall when the EISN flag is used. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: - replaced dma_memory_write() by stl_be_dma() - improved 'info pic' output hw/intc/spapr_xive.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 8e990d58ecf4..629563d01998 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -196,9 +196,87 @@ static sPAPRXiveNVT *spapr_xive_nvt_get(sPAPRXive *xiv= e, int server) return cpu ? SPAPR_XIVE_NVT(cpu->intc) : NULL; } =20 +static void spapr_xive_pic_print_info_eq(XiveEQ *eq, Monitor *mon) +{ + uint64_t qaddr_base =3D (((uint64_t)(eq->w2 & 0x0fffffff)) << 32) | eq= ->w3; + uint32_t qindex =3D GETFIELD(EQ_W1_PAGE_OFF, eq->w1); + uint32_t qgen =3D GETFIELD(EQ_W1_GENERATION, eq->w1); + uint32_t qsize =3D GETFIELD(EQ_W0_QSIZE, eq->w0); + uint32_t qentries =3D 1 << (qsize + 10); + + monitor_printf(mon, "eq:@%08" PRIx64"% 6d/%5d ^%d", qaddr_base, + qindex, qentries, qgen); +} + +static void spapr_xive_eq_push(XiveEQ *eq, uint32_t data) +{ + uint64_t qaddr_base =3D (((uint64_t)(eq->w2 & 0x0fffffff)) << 32) | eq= ->w3; + uint32_t qsize =3D GETFIELD(EQ_W0_QSIZE, eq->w0); + uint32_t qindex =3D GETFIELD(EQ_W1_PAGE_OFF, eq->w1); + uint32_t qgen =3D GETFIELD(EQ_W1_GENERATION, eq->w1); + + uint64_t qaddr =3D qaddr_base + (qindex << 2); + uint32_t qdata =3D (qgen << 31) | (data & 0x7fffffff); + uint32_t qentries =3D 1 << (qsize + 10); + + if (stl_be_dma(&address_space_memory, qaddr, qdata)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to write EQ data @0x%" + HWADDR_PRIx "\n", qaddr); + return; + } + + qindex =3D (qindex + 1) % qentries; + if (qindex =3D=3D 0) { + qgen ^=3D 1; + eq->w1 =3D SETFIELD(EQ_W1_GENERATION, eq->w1, qgen); + } + eq->w1 =3D SETFIELD(EQ_W1_PAGE_OFF, eq->w1, qindex); +} + static void spapr_xive_irq(sPAPRXive *xive, int lisn) { + XiveIVE *ive; + XiveEQ *eq; + uint32_t eq_idx; + uint8_t priority; + + ive =3D spapr_xive_get_ive(xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid LISN %d\n", lisn); + return; + } =20 + if (ive->w & IVE_MASKED) { + return; + } + + /* Find our XiveEQ */ + eq_idx =3D GETFIELD(IVE_EQ_INDEX, ive->w); + eq =3D spapr_xive_get_eq(xive, XIVE_EQ_INDEX_SERVER(eq_idx), + XIVE_EQ_INDEX_PRIO(eq_idx)); + if (!eq) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No EQ for LISN %d\n", lisn); + return; + } + + if (eq->w0 & EQ_W0_ENQUEUE) { + spapr_xive_eq_push(eq, GETFIELD(IVE_EQ_DATA, ive->w)); + } + + if (!(eq->w0 & EQ_W0_UCOND_NOTIFY)) { + qemu_log_mask(LOG_UNIMP, "XIVE: !UCOND_NOTIFY not implemented\n"); + } + + if (GETFIELD(EQ_W6_FORMAT_BIT, eq->w6) =3D=3D 0) { + priority =3D GETFIELD(EQ_W7_F0_PRIORITY, eq->w7); + + /* The EQ is masked. Can this happen ? */ + if (priority =3D=3D 0xff) { + g_assert_not_reached(); + } + } else { + qemu_log_mask(LOG_UNIMP, "XIVE: w7 format1 not implemented\n"); + } } =20 /* @@ -480,14 +558,28 @@ void spapr_xive_pic_print_info(sPAPRXive *xive, Monit= or *mon) pq =3D spapr_xive_pq_get(xive, i); eq_idx =3D GETFIELD(IVE_EQ_INDEX, ive->w); =20 - monitor_printf(mon, " %4x %s %s %c%c server:%d prio:%d %08x\n", i, + monitor_printf(mon, " %4x %s %s %c%c server:%d prio:%d ", i, spapr_xive_irq_is_lsi(xive, i) ? "LSI" : "MSI", ive->w & IVE_MASKED ? "M" : " ", pq & XIVE_ESB_VAL_P ? 'P' : '-', pq & XIVE_ESB_VAL_Q ? 'Q' : '-', XIVE_EQ_INDEX_SERVER(eq_idx), - XIVE_EQ_INDEX_PRIO(eq_idx), - (int) GETFIELD(IVE_EQ_DATA, ive->w)); + XIVE_EQ_INDEX_PRIO(eq_idx)); + + if (!(ive->w & IVE_MASKED)) { + XiveEQ *eq; + + eq =3D spapr_xive_get_eq(xive, XIVE_EQ_INDEX_SERVER(eq_idx), + XIVE_EQ_INDEX_PRIO(eq_idx)); + if (eq) { + spapr_xive_pic_print_info_eq(eq, mon); + monitor_printf(mon, " data:%08x", + (int) GETFIELD(IVE_EQ_DATA, ive->w)); + } else { + monitor_printf(mon, "no eq ?!"); + } + } + monitor_printf(mon, "\n"); } } =20 --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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 1512809595736673.6137639850702; Sat, 9 Dec 2017 00:53:15 -0800 (PST) Received: from localhost ([::1]:40461 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNasf-0008Vl-02 for importer@patchew.org; Sat, 09 Dec 2017 03:53:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45460) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNakc-0001HY-UM for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNakY-000786-Vm for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:50 -0500 Received: from 10.mo6.mail-out.ovh.net ([87.98.157.236]:34636) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNakY-00077Q-Mq for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:46 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 9A8AD1277C6 for ; Sat, 9 Dec 2017 09:44:45 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 6E99316009E; Sat, 9 Dec 2017 09:44:39 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:27 +0100 Message-Id: <20171209084338.29395-9-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11708514606667172691 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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.157.236 Subject: [Qemu-devel] [PATCH v2 08/19] spapr: notify the CPU when the XIVE interrupt priority is more privileged 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Once an event has been routed, the XIVE virtualization presenter engine raises the bit corresponding to the priority of the pending interrupt in the register IBP (Interrupt Pending Buffer). The Pending Interrupt Priority Register (PIPR) is also updated using the IPB. It contains the priority of the most favored pending notification. The PIPR is then compared to the the Current Processor Priority Register (CPPR). If it is more favored (numerically less than), the CPU interrupt line is raised and the EO bit of the Notification Source Register (NSR) is updated to notify the presence of an exception for the O/S. The check needs to be done whenever the PIPR or the CPPR are changed. The O/S acknowledges the interrupt with a special load in the Thread Interrupt Management Area. If the EO bit of the NSR is set, the CPPR takes the value of PIPR. The bit number in the IBP corresponding to the priority of the pending interrupt is reseted and so is the EO bit of the NSR. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: - set initial TM_PIPR to 0xFF hw/intc/spapr_xive.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 629563d01998..a8acfee740d9 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -35,9 +35,68 @@ struct sPAPRXiveNVT { XiveEQ eqt[XIVE_PRIORITY_MAX + 1]; }; =20 +/* Convert a priority number to an Interrupt Pending Buffer (IPB) + * register, which indicates a pending interrupt at the priority + * corresponding to the bit number + */ +static uint8_t priority_to_ipb(uint8_t priority) +{ + return priority > XIVE_PRIORITY_MAX ? + 0 : 1 << (XIVE_PRIORITY_MAX - priority); +} + +/* Convert an Interrupt Pending Buffer (IPB) register to a Pending + * Interrupt Priority Register (PIPR), which contains the priority of + * the most favored pending notification. + */ +static uint8_t ipb_to_pipr(uint8_t ibp) +{ + return ibp ? clz32((uint32_t)ibp << 24) : 0xff; +} + +/* + * TODO: + * + * Ben says: " + * + * PIPR is clamped to CPPR. So the value in the PIPR is: + * + * v =3D leftmost_bit_of(ipb) (or 0xff); + * pipr =3D v < cppr ? v : cppr; + * + * which means it's never actually 0xff ... surprise !". + * + * But, the CPPR is set to 0xFF by the OS and so the PIPR will always + * be more favored ... I am confused ... + */ static uint64_t spapr_xive_nvt_accept(sPAPRXiveNVT *nvt) { - return 0; + uint8_t nsr =3D nvt->ring_os[TM_NSR]; + + qemu_irq_lower(nvt->output); + + if (nvt->ring_os[TM_NSR] & TM_QW1_NSR_EO) { + uint8_t cppr =3D nvt->ring_os[TM_PIPR]; + + nvt->ring_os[TM_CPPR] =3D cppr; + + /* Reset the pending buffer bit */ + nvt->ring_os[TM_IPB] &=3D ~priority_to_ipb(cppr); + nvt->ring_os[TM_PIPR] =3D ipb_to_pipr(nvt->ring_os[TM_IPB]); + + /* Drop Exception bit for OS */ + nvt->ring_os[TM_NSR] &=3D ~TM_QW1_NSR_EO; + } + + return (nsr << 8) | nvt->ring_os[TM_CPPR]; +} + +static void spapr_xive_nvt_notify(sPAPRXiveNVT *nvt) +{ + if (nvt->ring_os[TM_PIPR] < nvt->ring_os[TM_CPPR]) { + nvt->ring_os[TM_NSR] |=3D TM_QW1_NSR_EO; + qemu_irq_raise(nvt->output); + } } =20 static void spapr_xive_nvt_set_cppr(sPAPRXiveNVT *nvt, uint8_t cppr) @@ -47,6 +106,10 @@ static void spapr_xive_nvt_set_cppr(sPAPRXiveNVT *nvt, = uint8_t cppr) } =20 nvt->ring_os[TM_CPPR] =3D cppr; + + /* CPPR has changed, check if we need to redistribute a pending + * exception */ + spapr_xive_nvt_notify(nvt); } =20 /* @@ -239,6 +302,8 @@ static void spapr_xive_irq(sPAPRXive *xive, int lisn) XiveEQ *eq; uint32_t eq_idx; uint8_t priority; + uint32_t server; + sPAPRXiveNVT *nvt; =20 ive =3D spapr_xive_get_ive(xive, lisn); if (!ive || !(ive->w & IVE_VALID)) { @@ -267,6 +332,13 @@ static void spapr_xive_irq(sPAPRXive *xive, int lisn) qemu_log_mask(LOG_UNIMP, "XIVE: !UCOND_NOTIFY not implemented\n"); } =20 + server =3D GETFIELD(EQ_W6_NVT_INDEX, eq->w6); + nvt =3D spapr_xive_nvt_get(xive, server); + if (!nvt) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVT for server %d\n", ser= ver); + return; + } + if (GETFIELD(EQ_W6_FORMAT_BIT, eq->w6) =3D=3D 0) { priority =3D GETFIELD(EQ_W7_F0_PRIORITY, eq->w7); =20 @@ -274,9 +346,18 @@ static void spapr_xive_irq(sPAPRXive *xive, int lisn) if (priority =3D=3D 0xff) { g_assert_not_reached(); } + + /* Update the IPB (Interrupt Pending Buffer) with the priority + * of the new notification and inform the NVT, which will + * decide to raise the exception, or not, depending the CPPR. + */ + nvt->ring_os[TM_IPB] |=3D priority_to_ipb(priority); + nvt->ring_os[TM_PIPR] =3D ipb_to_pipr(nvt->ring_os[TM_IPB]); } else { qemu_log_mask(LOG_UNIMP, "XIVE: w7 format1 not implemented\n"); } + + spapr_xive_nvt_notify(nvt); } =20 /* @@ -717,6 +798,12 @@ static void spapr_xive_nvt_reset(void *dev) =20 memset(nvt->regs, 0, sizeof(nvt->regs)); =20 + /* + * Initialize PIPR to 0xFF to avoid phantom interrupts when the + * CPPR is first set. + */ + nvt->ring_os[TM_PIPR] =3D ipb_to_pipr(nvt->ring_os[TM_IPB]); + memset(nvt->eqt, 0, sizeof(nvt->eqt)); } =20 --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512809432605790.0795822574199; Sat, 9 Dec 2017 00:50:32 -0800 (PST) Received: from localhost ([::1]:40443 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNaq6-0006Kp-Um for importer@patchew.org; Sat, 09 Dec 2017 03:50:31 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45612) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNakn-0001NO-5A for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNakf-0007BE-3B for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:57 -0500 Received: from 17.mo6.mail-out.ovh.net ([46.105.36.150]:39640) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNake-0007AT-Tu for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:44:53 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id C4E921276E5 for ; Sat, 9 Dec 2017 09:44:51 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 9A84C160087; Sat, 9 Dec 2017 09:44:45 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:28 +0100 Message-Id: <20171209084338.29395-10-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11710203457154812755 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 46.105.36.150 Subject: [Qemu-devel] [PATCH v2 09/19] spapr: add support for the SET_OS_PENDING command (XIVE) 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This command offers the possibility for the O/S to adjust the IPB to allow a CPU to process event queues of other priorities during one physical interrupt cycle. This is not currently used by the XIVE support for sPAPR in Linux but it is by the hypervisor. More from Ben : It's a way to avoid the SW replay on EOI. IE, assume you have 2 interrupts in the queue. You take the exception, ack the first one, process it etc... Then you EOI, the HW won't send a second notification. You need to look at the queue and continue consuming until it's empty. Today Linux checks the queue on EOI and use a SW mechanism to synthesize a new pseudo-external interrupt. This MMIO command would allow the OS to instead set back the corresponding priority bit to 1 in the IPB and cause the HW to re-emit the interrupt instead of SW. Linux doesn't use this today because DD1 didn't support it for the HV level, but other OSes might and we also might use it when we do groups, thus allowing redistribution. Signed-off-by: C=C3=A9dric Le Goater --- hw/intc/spapr_xive.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index a8acfee740d9..38e1f569ea82 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -166,9 +166,23 @@ static bool spapr_xive_tm_is_readonly(uint8_t offset) static void spapr_xive_tm_write_special(sPAPRXiveNVT *nvt, hwaddr offset, uint64_t value, unsigned size) { - /* TODO: support TM_SPC_SET_OS_PENDING */ + switch (offset) { + case TM_SPC_SET_OS_PENDING: + if (size =3D=3D 1) { + nvt->ring_os[TM_IPB] |=3D priority_to_ipb(value & 0xff); + nvt->ring_os[TM_PIPR] =3D ipb_to_pipr(nvt->ring_os[TM_IPB]); + spapr_xive_nvt_notify(nvt); + } + break; + case TM_SPC_ACK_OS_EL: /* TODO */ + qemu_log_mask(LOG_UNIMP, "XIVE: no command to acknowledge O/S " + "Interrupt to even O/S reporting line\n"); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid TIMA write @%" + HWADDR_PRIx" size %d\n", offset, size); + } =20 - /* TODO: support TM_SPC_ACK_OS_EL */ } =20 static void spapr_xive_tm_os_write(void *opaque, hwaddr offset, --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151280973708227.276595634979458; Sat, 9 Dec 2017 00:55:37 -0800 (PST) Received: from localhost ([::1]:40475 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNauy-0002Dc-JX for importer@patchew.org; Sat, 09 Dec 2017 03:55:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45701) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNakr-0001So-J8 for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNakn-0007NL-Gf for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:05 -0500 Received: from 3.mo6.mail-out.ovh.net ([178.33.253.26]:33328) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNakn-0007HZ-An for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:01 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id F17221277CF for ; Sat, 9 Dec 2017 09:44:57 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id C61D4160087; Sat, 9 Dec 2017 09:44:51 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:29 +0100 Message-Id: <20171209084338.29395-11-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11711892308233456467 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 178.33.253.26 Subject: [Qemu-devel] [PATCH v2 10/19] spapr: introduce a 'xive_exploitation' boolean to enable XIVE 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The XIVE exploitation interrupt mode will be enabled for newer machines and disabled for older ones. Also provide a command line machine option to switch XIVE off on newer machines if needed. Signed-off-by: C=C3=A9dric Le Goater --- hw/intc/spapr_xive.c | 10 ++++++---- hw/ppc/spapr.c | 35 +++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 1 + 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 38e1f569ea82..bf30edc87bee 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -756,8 +756,9 @@ static const VMStateDescription vmstate_spapr_xive_ive = =3D { =20 static bool vmstate_spapr_xive_needed(void *opaque) { - /* TODO check machine XIVE support */ - return true; + sPAPRMachineState *spapr =3D SPAPR_MACHINE(qdev_get_machine()); + + return spapr->xive_exploitation; } =20 static const VMStateDescription vmstate_spapr_xive =3D { @@ -885,8 +886,9 @@ static const VMStateDescription vmstate_spapr_xive_nvt_= eq =3D { =20 static bool vmstate_spapr_xive_nvt_needed(void *opaque) { - /* TODO check machine XIVE support */ - return true; + sPAPRMachineState *spapr =3D SPAPR_MACHINE(qdev_get_machine()); + + return spapr->xive_exploitation; } =20 static const VMStateDescription vmstate_spapr_xive_nvt =3D { diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 306875e12320..b5b9e7f1b3b6 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2820,6 +2820,29 @@ static void spapr_set_vsmt(Object *obj, Visitor *v, = const char *name, visit_type_uint32(v, name, (uint32_t *)opaque, errp); } =20 +static bool spapr_get_xive_exploitation(Object *obj, Error **errp) +{ + sPAPRMachineState *spapr =3D SPAPR_MACHINE(obj); + + return spapr->xive_exploitation; +} + +static void spapr_set_xive_exploitation(Object *obj, bool value, + Error **errp) +{ + sPAPRMachineState *spapr =3D SPAPR_MACHINE(obj); + + if (value) { + /* Don't let older machines activate XIVE */ + if (!spapr->xive_exploitation) { + error_setg(errp, "\"xive-exploitation\" option can not be " + "switched on"); + } + } else { + spapr->xive_exploitation =3D false; + } +} + static void spapr_machine_initfn(Object *obj) { sPAPRMachineState *spapr =3D SPAPR_MACHINE(obj); @@ -2855,6 +2878,15 @@ static void spapr_machine_initfn(Object *obj) object_property_set_description(obj, "vsmt", "Virtual SMT: KVM behaves as if this w= ere" " the host's SMT mode", &error_abort); + + spapr->xive_exploitation =3D true; + object_property_add_bool(obj, "xive-exploitation", + spapr_get_xive_exploitation, + spapr_set_xive_exploitation, + NULL); + object_property_set_description(obj, "xive-exploitation", + "XIVE exploitation mode POWER9", + NULL); } =20 static void spapr_machine_finalizefn(Object *obj) @@ -3890,7 +3922,10 @@ DEFINE_SPAPR_MACHINE(2_12, "2.12", true); =20 static void spapr_machine_2_11_instance_options(MachineState *machine) { + sPAPRMachineState *spapr =3D SPAPR_MACHINE(machine); + spapr_machine_2_12_instance_options(machine); + spapr->xive_exploitation =3D false; } =20 static void spapr_machine_2_11_class_options(MachineClass *mc) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 14757b805e84..1d6d2c690d7f 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -127,6 +127,7 @@ struct sPAPRMachineState { MemoryHotplugState hotplug_memory; =20 const char *icp_type; + bool xive_exploitation; }; =20 #define H_SUCCESS 0 --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151280990179258.703371627511956; Sat, 9 Dec 2017 00:58:21 -0800 (PST) Received: from localhost ([::1]:40499 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNaxe-0007gV-8F for importer@patchew.org; Sat, 09 Dec 2017 03:58:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45748) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNakv-0001YK-LL for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNakr-0007U4-Op for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:09 -0500 Received: from 20.mo6.mail-out.ovh.net ([178.32.124.17]:53945) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNakr-0007TB-FA for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:05 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 4506712645A for ; Sat, 9 Dec 2017 09:45:04 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id F21DF160087; Sat, 9 Dec 2017 09:44:57 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:30 +0100 Message-Id: <20171209084338.29395-12-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11713862631932332883 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 178.32.124.17 Subject: [Qemu-devel] [PATCH v2 11/19] spapr: add a sPAPRXive object to 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The sPAPRXive object is designed to be always available, so it is created unconditionally on newer machines. Depending on the configuration and the guest capabilities, the CAS negotiation process will decide which interrupt mode to activate: legacy or XIVE exploitation. The XIVE model makes use of the full range of the IRQ number space. The IRQ numbers for the CPU IPIs in XIVE are allocated at the bottom of this space, below XICS_IRQ_BASE, to preserve compatibility with XICS which does not use that range. That leaves us with 4K possible IPIs. This should be enough for sometime given that the maximum number of CPUs is 1024 for the sPAPR machine under QEMU. For the record, the biggest POWER8 or POWER9 system has a maximum of 1536 HW threads (16 sockets, 192 cores, SMT8). Also make sure that the allocated IRQ numbers are kept in sync between XICS and XIVE, when available. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: - conditioned the creation of the sPAPRXive object to the xive_exploitation bool which false on older pseries machine. - merged in the IPI allocation patch - parented the sPAPRXive object to sysbus. hw/ppc/spapr.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++= ++++ include/hw/ppc/spapr.h | 2 ++ 2 files changed, 52 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b5b9e7f1b3b6..195a48399e4b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -56,6 +56,7 @@ #include "hw/ppc/spapr_vio.h" #include "hw/pci-host/spapr.h" #include "hw/ppc/xics.h" +#include "hw/ppc/spapr_xive.h" #include "hw/pci/msi.h" =20 #include "hw/pci/pci.h" @@ -204,6 +205,30 @@ static void xics_system_init(MachineState *machine, in= t nr_irqs, Error **errp) } } =20 +static sPAPRXive *spapr_xive_create(sPAPRMachineState *spapr, int nr_irqs, + Error **errp) +{ + Error *local_err =3D NULL; + Object *obj; + + obj =3D object_new(TYPE_SPAPR_XIVE); + object_property_add_child(OBJECT(spapr), "xive", obj, &error_abort); + object_property_set_int(obj, nr_irqs, "nr-irqs", &local_err); + if (local_err) { + goto error; + } + object_property_set_bool(obj, true, "realized", &local_err); + if (local_err) { + goto error; + } + + qdev_set_parent_bus(DEVICE(obj), sysbus_get_default()); + return SPAPR_XIVE(obj); +error: + error_propagate(errp, local_err); + return NULL; +} + static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu, int smt_threads) { @@ -2390,6 +2415,25 @@ static void ppc_spapr_init(MachineState *machine) /* Set up Interrupt Controller before we create the VCPUs */ xics_system_init(machine, XICS_IRQS_SPAPR, &error_fatal); =20 + if (spapr->xive_exploitation) { + /* We don't have KVM support yet, so check for irqchip=3Don */ + if (kvm_enabled() && machine_kernel_irqchip_required(machine)) { + error_report("kernel_irqchip requested. no XIVE support"); + exit(1); + } else { + /* XIVE uses the full range of IRQ numbers. The CPU IPIs + * will use the range below XICS_IRQ_BASE, unused by XICS. */ + spapr->xive =3D + spapr_xive_create(spapr, XICS_IRQ_BASE + XICS_IRQS_SPAPR, + &error_fatal); + + /* Allocate the first IRQ numbers for the XIVE IPIs */ + for (i =3D 0; i < xics_max_server_number(); ++i) { + spapr_xive_irq_enable(spapr->xive, i, false); + } + } + } + /* Set up containers for ibm,client-architecture-support negotiated op= tions */ spapr->ov5 =3D spapr_ovec_new(); @@ -3647,6 +3691,9 @@ static int ics_find_free_block(ICSState *ics, int num= , int alignnum) static void spapr_irq_set_lsi(sPAPRMachineState *spapr, int irq, bool lsi) { ics_set_irq_type(spapr->ics, irq - spapr->ics->offset, lsi); + if (spapr->xive_exploitation) { + spapr_xive_irq_enable(spapr->xive, irq, lsi); + } } =20 int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, @@ -3737,6 +3784,9 @@ void spapr_irq_free(sPAPRMachineState *spapr, int irq= , int num) memset(&ics->irqs[i], 0, sizeof(ICSIRQState)); } } + if (spapr->xive_exploitation) { + spapr_xive_irq_disable(spapr->xive, irq); + } } =20 qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 1d6d2c690d7f..addc31dba497 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -14,6 +14,7 @@ struct sPAPRNVRAM; typedef struct sPAPREventLogEntry sPAPREventLogEntry; typedef struct sPAPREventSource sPAPREventSource; typedef struct sPAPRPendingHPT sPAPRPendingHPT; +typedef struct sPAPRXive sPAPRXive; =20 #define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL #define SPAPR_ENTRY_POINT 0x100 @@ -128,6 +129,7 @@ struct sPAPRMachineState { =20 const char *icp_type; bool xive_exploitation; + sPAPRXive *xive; }; =20 #define H_SUCCESS 0 --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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 1512809888451533.6618820924332; Sat, 9 Dec 2017 00:58:08 -0800 (PST) Received: from localhost ([::1]:40493 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNaxN-00060Z-Ib for importer@patchew.org; Sat, 09 Dec 2017 03:58:01 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45808) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNal2-0001h7-3p for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNakx-0007jw-Ss for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:16 -0500 Received: from 11.mo6.mail-out.ovh.net ([188.165.38.119]:40117) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNakx-0007gJ-Es for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:11 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 5B5D912645A for ; Sat, 9 Dec 2017 09:45:10 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 2941816009E; Sat, 9 Dec 2017 09:45:04 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:31 +0100 Message-Id: <20171209084338.29395-13-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11715551484316453715 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 188.165.38.119 Subject: [Qemu-devel] [PATCH v2 12/19] spapr: add hcalls support for the XIVE exploitation interrupt mode 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The different XIVE virtualization engines (sources and event queues) are configured with a set of Hypervisor calls : - H_INT_GET_SOURCE_INFO used to obtain the address of the MMIO page of the Event State Buffer (PQ bits) entry associated with the source. - H_INT_SET_SOURCE_CONFIG assigns a source to a "target". - H_INT_GET_SOURCE_CONFIG determines which "target" and "priority" is assigned to a source - H_INT_GET_QUEUE_INFO returns the address of the notification management page associated with the specified "target" and "priority". - H_INT_SET_QUEUE_CONFIG sets or resets the event queue for a given "target" and "priority". It is also used to set the notification configuration associated with the queue, only unconditional notification is supported for the moment. Reset is performed with a queue size of 0 and queueing is disabled in that case. - H_INT_GET_QUEUE_CONFIG returns the queue settings for a given "target" and "priority". - H_INT_RESET resets all of the guest's internal interrupt structures to their initial state, losing all configuration set via the hcalls H_INT_SET_SOURCE_CONFIG and H_INT_SET_QUEUE_CONFIG. - H_INT_SYNC issue a synchronisation on a source to make sure all notifications have reached their queue. Calls that still need to be addressed : H_INT_SET_OS_REPORTING_LINE H_INT_GET_OS_REPORTING_LINE See the code for more documentation on each hcall. All sources are emulated under the main XIVE object and share the same characteristics : XIVE_SRC_TRIGGER | XIVE_SRC_STORE_EOI; Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: - simplified priority_is_valid() routine (to its minimum) - used PPC_BIT() macros to define the hcall flags - removed useless casts - defined the default characteristic of the single XIVE interrupt source to be : *XIVE_SRC_TRIGGER | XIVE_SRC_STORE_EOI* - made use of the new spapr_xive_get_eq() prototype - removed EQ_W0_UCOND_NOTIFY when the EQ is reseted - fixed XIVE_EQ_DEBUG support. Offset for the generation bit was wrong hw/intc/Makefile.objs | 2 +- hw/intc/spapr_xive_hcall.c | 859 ++++++++++++++++++++++++++++++++++++++++= ++++ hw/ppc/spapr.c | 2 + include/hw/ppc/spapr.h | 15 +- include/hw/ppc/spapr_xive.h | 4 + 5 files changed, 880 insertions(+), 2 deletions(-) create mode 100644 hw/intc/spapr_xive_hcall.c diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 49e13e7aeeee..122e2ec77e8d 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -35,7 +35,7 @@ obj-$(CONFIG_SH4) +=3D sh_intc.o obj-$(CONFIG_XICS) +=3D xics.o obj-$(CONFIG_XICS_SPAPR) +=3D xics_spapr.o obj-$(CONFIG_XICS_KVM) +=3D xics_kvm.o -obj-$(CONFIG_XIVE_SPAPR) +=3D spapr_xive.o +obj-$(CONFIG_XIVE_SPAPR) +=3D spapr_xive.o spapr_xive_hcall.o obj-$(CONFIG_POWERNV) +=3D xics_pnv.o obj-$(CONFIG_ALLWINNER_A10_PIC) +=3D allwinner-a10-pic.o obj-$(CONFIG_S390_FLIC) +=3D s390_flic.o diff --git a/hw/intc/spapr_xive_hcall.c b/hw/intc/spapr_xive_hcall.c new file mode 100644 index 000000000000..86dec6c02401 --- /dev/null +++ b/hw/intc/spapr_xive_hcall.c @@ -0,0 +1,859 @@ +/* + * QEMU PowerPC sPAPR XIVE interrupt controller model + * + * Copyright (c) 2017, IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "cpu.h" +#include "hw/ppc/spapr.h" +#include "hw/ppc/spapr_xive.h" +#include "hw/ppc/fdt.h" +#include "monitor/monitor.h" + +#include "xive-internal.h" + +/* + * OPAL uses the priority 7 queue to automatically escalate interrupts + * for all other queues (DD2.X POWER9). So only priorities [0..6] are + * allowed for the guest. + */ +static bool priority_is_valid(uint8_t priority) +{ + switch (priority) { + case 0 ... 6: + return true; + case 7: /* OPAL escalation queue */ + default: + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid priority %d requeste= d\n", + priority); + return false; + } +} + +/* + * The H_INT_GET_SOURCE_INFO hcall() is used to obtain the logical + * real address of the MMIO page through which the Event State Buffer + * entry associated with the value of the "lisn" parameter is managed. + * + * Parameters: + * Input + * - "flags" + * Bits 0-63 reserved + * - "lisn" is per "interrupts", "interrupt-map", or + * "ibm,xive-lisn-ranges" properties, or as returned by the + * ibm,query-interrupt-source-number RTAS call, or as returned + * by the H_ALLOCATE_VAS_WINDOW hcall + * + * Output + * - R4: "flags" + * Bits 0-59: Reserved + * Bit 60: H_INT_ESB must be used for Event State Buffer + * management + * Bit 61: 1 =3D=3D LSI 0 =3D=3D MSI + * Bit 62: the full function page supports trigger + * Bit 63: Store EOI Supported + * - R5: Logical Real address of full function Event State Buffer + * management page, -1 if ESB hcall flag is set to 1. + * - R6: Logical Real Address of trigger only Event State Buffer + * management page or -1. + * - R7: Power of 2 page size for the ESB management pages returned in + * R5 and R6. + */ + +#define XIVE_SRC_H_INT_ESB PPC_BIT(60) +#define XIVE_SRC_LSI PPC_BIT(61) +#define XIVE_SRC_TRIGGER PPC_BIT(62) +#define XIVE_SRC_STORE_EOI PPC_BIT(63) + +static target_ulong h_int_get_source_info(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + sPAPRXive *xive =3D spapr->xive; + XiveIVE *ive; + target_ulong flags =3D args[0]; + target_ulong lisn =3D args[1]; + hwaddr mmio_base; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + ive =3D spapr_xive_get_ive(spapr->xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + mmio_base =3D xive->esb_base + (1ull << ESB_SHIFT) * lisn; + + /* All sources are emulated under the main XIVE object and share + * the same characteristics. + */ + args[0] =3D XIVE_SRC_TRIGGER | XIVE_SRC_STORE_EOI; + if (spapr_xive_irq_is_lsi(xive, lisn)) { + args[0] |=3D XIVE_SRC_LSI; + } + + /* Match XIVE_SRC_TRIGGER characteristic */ + args[1] =3D mmio_base; + args[2] =3D -1; /* No specific trigger page */ + args[3] =3D ESB_SHIFT; + + return H_SUCCESS; +} + +/* + * The H_INT_SET_SOURCE_CONFIG hcall() is used to assign a Logical + * Interrupt Source to a target. The Logical Interrupt Source is + * designated with the "lisn" parameter and the target is designated + * with the "target" and "priority" parameters. Upon return from the + * hcall(), no additional interrupts will be directed to the old EQ. + * + * TODO: The old EQ should be investigated for interrupts that + * occurred prior to or during the hcall(). + * + * Parameters: + * Input: + * - "flags" + * Bits 0-61: Reserved + * Bit 62: set the "eisn" in the EA + * Bit 63: masks the interrupt source in the hardware interrupt + * control structure. An interrupt masked by this mechanism will + * be dropped, but it's source state bits will still be + * set. There is no race-free way of unmasking and restoring the + * source. Thus this should only be used in interrupts that are + * also masked at the source, and only in cases where the + * interrupt is not meant to be used for a large amount of time + * because no valid target exists for it for example + * - "lisn" is per "interrupts", "interrupt-map", or + * "ibm,xive-lisn-ranges" properties, or as returned by the + * ibm,query-interrupt-source-number RTAS call, or as returned by + * the H_ALLOCATE_VAS_WINDOW hcall + * - "target" is per "ibm,ppc-interrupt-server#s" or + * "ibm,ppc-interrupt-gserver#s" + * - "priority" is a valid priority not in + * "ibm,plat-res-int-priorities" + * - "eisn" is the guest EISN associated with the "lisn" + * + * Output: + * - None + */ + +#define XIVE_SRC_SET_EISN PPC_BIT(62) +#define XIVE_SRC_MASK PPC_BIT(63) + +static target_ulong h_int_set_source_config(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + XiveIVE *ive; + uint64_t new_ive; + target_ulong flags =3D args[0]; + target_ulong lisn =3D args[1]; + target_ulong target =3D args[2]; + target_ulong priority =3D args[3]; + target_ulong eisn =3D args[4]; + uint32_t eq_idx; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags & ~(XIVE_SRC_SET_EISN | XIVE_SRC_MASK)) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + ive =3D spapr_xive_get_ive(spapr->xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + /* priority 0xff is used to reset the IVE */ + if (priority =3D=3D 0xff) { + new_ive =3D IVE_VALID | IVE_MASKED; + goto out; + } + + if (flags & XIVE_SRC_MASK) { + new_ive =3D ive->w | IVE_MASKED; + } else { + new_ive =3D ive->w & ~IVE_MASKED; + } + + if (!priority_is_valid(priority)) { + return H_P4; + } + + /* TODO: If the partition thread count is greater than the + * hardware thread count, validate the "target" has a + * corresponding hardware thread else return H_NOT_AVAILABLE. + */ + + /* Validate that "target" is part of the list of threads allocated + * to the partition. For that, find the EQ corresponding to the + * target. + */ + if (!spapr_xive_get_eq(spapr->xive, target, priority)) { + return H_P3; + } + + eq_idx =3D XIVE_EQ_INDEX(target, priority); + + new_ive =3D SETFIELD(IVE_EQ_BLOCK, new_ive, 0ul); + new_ive =3D SETFIELD(IVE_EQ_INDEX, new_ive, eq_idx); + + if (flags & XIVE_SRC_SET_EISN) { + new_ive =3D SETFIELD(IVE_EQ_DATA, new_ive, eisn); + } + +out: + /* TODO: handle syncs ? */ + + /* And update */ + ive->w =3D new_ive; + + return H_SUCCESS; +} + +/* + * The H_INT_GET_SOURCE_CONFIG hcall() is used to determine to which + * target/priority pair is assigned to the specified Logical Interrupt + * Source. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63 Reserved + * - "lisn" is per "interrupts", "interrupt-map", or + * "ibm,xive-lisn-ranges" properties, or as returned by the + * ibm,query-interrupt-source-number RTAS call, or as + * returned by the H_ALLOCATE_VAS_WINDOW hcall + * + * Output: + * - R4: Target to which the specified Logical Interrupt Source is + * assigned + * - R5: Priority to which the specified Logical Interrupt Source is + * assigned + * - R6: EISN for the specified Logical Interrupt Source (this will be + * equivalent to the LISN if not changed by H_INT_SET_SOURCE_CONFIG) + */ +static target_ulong h_int_get_source_config(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags =3D args[0]; + target_ulong lisn =3D args[1]; + XiveIVE *ive; + XiveEQ *eq; + uint32_t eq_idx; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + ive =3D spapr_xive_get_ive(spapr->xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + eq_idx =3D GETFIELD(IVE_EQ_INDEX, ive->w); + eq =3D spapr_xive_get_eq(spapr->xive, XIVE_EQ_INDEX_SERVER(eq_idx), + XIVE_EQ_INDEX_PRIO(eq_idx)); + if (!eq) { + /* Not sure what to return here */ + return H_HARDWARE; + } + + args[0] =3D GETFIELD(EQ_W6_NVT_INDEX, eq->w6); + + if (ive->w & IVE_MASKED) { + args[1] =3D 0xff; + } else { + args[1] =3D GETFIELD(EQ_W7_F0_PRIORITY, eq->w7); + } + + args[2] =3D GETFIELD(IVE_EQ_DATA, ive->w); + + return H_SUCCESS; +} + +/* + * The H_INT_GET_QUEUE_INFO hcall() is used to get the logical real + * address of the notification management page associated with the + * specified target and priority. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63 Reserved + * - "target" is per "ibm,ppc-interrupt-server#s" or + * "ibm,ppc-interrupt-gserver#s" + * - "priority" is a valid priority not in + * "ibm,plat-res-int-priorities" + * + * Output: + * - R4: Logical real address of notification page + * - R5: Power of 2 page size of the notification page + */ +static target_ulong h_int_get_queue_info(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags =3D args[0]; + target_ulong target =3D args[1]; + target_ulong priority =3D args[2]; + XiveEQ *eq; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + if (!priority_is_valid(priority)) { + return H_P3; + } + + /* TODO: If the partition thread count is greater than the + * hardware thread count, validate the "target" has a + * corresponding hardware thread else return H_NOT_AVAILABLE. + */ + + /* Validate that "target" is part of the list of threads allocated + * to the partition. For that, find the EQ corresponding to the + * target. + */ + eq =3D spapr_xive_get_eq(spapr->xive, target, priority); + if (!eq) { + return H_P2; + } + + args[0] =3D -1; /* TODO: return ESn page */ + if (eq->w0 & EQ_W0_ENQUEUE) { + args[1] =3D GETFIELD(EQ_W0_QSIZE, eq->w0) + 12; + } else { + args[1] =3D 0; + } + + return H_SUCCESS; +} + +/* + * The H_INT_SET_QUEUE_CONFIG hcall() is used to set or reset a EQ for + * a given "target" and "priority". It is also used to set the + * notification config associated with the EQ. An EQ size of 0 is + * used to reset the EQ config for a given target and priority. If + * resetting the EQ config, the END associated with the given "target" + * and "priority" will be changed to disable queueing. + * + * Upon return from the hcall(), no additional interrupts will be + * directed to the old EQ (if one was set). The old EQ (if one was + * set) should be investigated for interrupts that occurred prior to + * or during the hcall(). + * + * Parameters: + * Input: + * - "flags" + * Bits 0-62: Reserved + * Bit 63: Unconditional Notify (n) per the XIVE spec + * - "target" is per "ibm,ppc-interrupt-server#s" or + * "ibm,ppc-interrupt-gserver#s" + * - "priority" is a valid priority not in + * "ibm,plat-res-int-priorities" + * - "eventQueue": The logical real address of the start of the EQ + * - "eventQueueSize": The power of 2 EQ size per "ibm,xive-eq-sizes" + * + * Output: + * - None + */ + +#define XIVE_EQ_ALWAYS_NOTIFY PPC_BIT(63) + +static target_ulong h_int_set_queue_config(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags =3D args[0]; + target_ulong target =3D args[1]; + target_ulong priority =3D args[2]; + target_ulong qpage =3D args[3]; + target_ulong qsize =3D args[4]; + XiveEQ *old_eq; + XiveEQ eq; + uint32_t qdata; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags & ~XIVE_EQ_ALWAYS_NOTIFY) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + if (!priority_is_valid(priority)) { + return H_P3; + } + + /* TODO: If the partition thread count is greater than the + * hardware thread count, validate the "target" has a + * corresponding hardware thread else return H_NOT_AVAILABLE. + */ + + /* Validate that "target" is part of the list of threads allocated + * to the partition. For that, find the EQ corresponding to the + * target. + */ + old_eq =3D spapr_xive_get_eq(spapr->xive, target, priority); + if (!old_eq) { + return H_P2; + } + + eq =3D *old_eq; + + switch (qsize) { + case 12: + case 16: + case 21: + case 24: + eq.w3 =3D ((uint64_t)qpage) & 0xffffffff; + eq.w2 =3D (((uint64_t)qpage)) >> 32 & 0x0fffffff; + eq.w0 |=3D EQ_W0_ENQUEUE; + eq.w0 =3D SETFIELD(EQ_W0_QSIZE, eq.w0, qsize - 12); + break; + case 0: + /* reset queue and disable queueing */ + eq.w2 =3D eq.w3 =3D 0; + eq.w0 &=3D ~EQ_W0_ENQUEUE; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid EQ size %"PRIx64"\n", + qsize); + return H_P5; + } + + if (qsize) { + /* + * Let's validate the EQ address with a read of the first EQ + * entry. We could also check that the full queue has been + * zeroed by the OS. + */ + if (address_space_read(&address_space_memory, qpage, + MEMTXATTRS_UNSPECIFIED, + (uint8_t *) &qdata, sizeof(qdata))) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to read EQ data @= 0x%" + HWADDR_PRIx "\n", qpage); + return H_P4; + } + } + + /* Ensure the priority and target are correctly set (they will not + * be right after allocation) + */ + eq.w6 =3D SETFIELD(EQ_W6_NVT_BLOCK, 0ul, 0ul) | + SETFIELD(EQ_W6_NVT_INDEX, 0ul, target); + eq.w7 =3D SETFIELD(EQ_W7_F0_PRIORITY, 0ul, priority); + + /* TODO: depends on notitification page (ESn) from H_INT_GET_QUEUE_INF= O */ + if (flags & XIVE_EQ_ALWAYS_NOTIFY) { + eq.w0 |=3D EQ_W0_UCOND_NOTIFY; + } else { + eq.w0 &=3D ~EQ_W0_UCOND_NOTIFY; + } + + /* The generation bit for the EQ starts at 1 and The EQ page + * offset counter starts at 0. + */ + eq.w1 =3D EQ_W1_GENERATION | SETFIELD(EQ_W1_PAGE_OFF, 0ul, 0ul); + eq.w0 |=3D EQ_W0_VALID; + + /* TODO: issue syncs required to ensure all in-flight interrupts + * are complete on the old EQ */ + + /* Update EQ */ + *old_eq =3D eq; + + return H_SUCCESS; +} + +/* + * The H_INT_GET_QUEUE_CONFIG hcall() is used to get a EQ for a given + * target and priority. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-62: Reserved + * Bit 63: Debug: Return debug data + * - "target" is per "ibm,ppc-interrupt-server#s" or + * "ibm,ppc-interrupt-gserver#s" + * - "priority" is a valid priority not in + * "ibm,plat-res-int-priorities" + * + * Output: + * - R4: "flags": + * Bits 0-61: Reserved + * Bit 62: The value of Event Queue Generation Number (g) per + * the XIVE spec if "Debug" =3D 1 + * Bit 63: The value of Unconditional Notify (n) per the XIVE spec + * - R5: The logical real address of the start of the EQ + * - R6: The power of 2 EQ size per "ibm,xive-eq-sizes" + * - R7: The value of Event Queue Offset Counter per XIVE spec + * if "Debug" =3D 1, else 0 + * + */ + +#define XIVE_EQ_DEBUG PPC_BIT(63) + +static target_ulong h_int_get_queue_config(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags =3D args[0]; + target_ulong target =3D args[1]; + target_ulong priority =3D args[2]; + XiveEQ *eq; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags & ~XIVE_EQ_DEBUG) { + return H_PARAMETER; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + if (!priority_is_valid(priority)) { + return H_P3; + } + + /* TODO: If the partition thread count is greater than the + * hardware thread count, validate the "target" has a + * corresponding hardware thread else return H_NOT_AVAILABLE. + */ + + /* Validate that "target" is part of the list of threads allocated + * to the partition. For that, find the EQ corresponding to the + * target. + */ + eq =3D spapr_xive_get_eq(spapr->xive, target, priority); + if (!eq) { + return H_P2; + } + + args[0] =3D 0; + if (eq->w0 & EQ_W0_UCOND_NOTIFY) { + args[0] |=3D XIVE_EQ_ALWAYS_NOTIFY; + } + + if (eq->w0 & EQ_W0_ENQUEUE) { + args[1] =3D + (((uint64_t)(eq->w2 & 0x0fffffff)) << 32) | eq->w3; + args[2] =3D GETFIELD(EQ_W0_QSIZE, eq->w0) + 12; + } else { + args[1] =3D 0; + args[2] =3D 0; + } + + /* TODO: do we need any locking on the EQ ? */ + if (flags & XIVE_EQ_DEBUG) { + /* Load the event queue generation number into the return flags */ + args[0] |=3D (uint64_t)GETFIELD(EQ_W1_GENERATION, eq->w1) << 62; + + /* Load R7 with the event queue offset counter */ + args[3] =3D GETFIELD(EQ_W1_PAGE_OFF, eq->w1); + } else { + args[3] =3D 0; + } + + return H_SUCCESS; +} + +/* + * The H_INT_SET_OS_REPORTING_LINE hcall() is used to set the + * reporting cache line pair for the calling thread. The reporting + * cache lines will contain the OS interrupt context when the OS + * issues a CI store byte to @TIMA+0xC10 to acknowledge the OS + * interrupt. The reporting cache lines can be reset by inputting -1 + * in "reportingLine". Issuing the CI store byte without reporting + * cache lines registered will result in the data not being accessible + * to the OS. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63: Reserved + * - "reportingLine": The logical real address of the reporting cache + * line pair + * + * Output: + * - None + */ +static target_ulong h_int_set_os_reporting_line(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + /* TODO: H_INT_SET_OS_REPORTING_LINE */ + return H_FUNCTION; +} + +/* + * The H_INT_GET_OS_REPORTING_LINE hcall() is used to get the logical + * real address of the reporting cache line pair set for the input + * "target". If no reporting cache line pair has been set, -1 is + * returned. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63: Reserved + * - "target" is per "ibm,ppc-interrupt-server#s" or + * "ibm,ppc-interrupt-gserver#s" + * - "reportingLine": The logical real address of the reporting cache + * line pair + * + * Output: + * - R4: The logical real address of the reporting line if set, else -1 + */ +static target_ulong h_int_get_os_reporting_line(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + /* TODO: H_INT_GET_OS_REPORTING_LINE */ + return H_FUNCTION; +} + +/* + * The H_INT_ESB hcall() is used to issue a load or store to the ESB + * page for the input "lisn". This hcall is only supported for LISNs + * that have the ESB hcall flag set to 1 when returned from hcall() + * H_INT_GET_SOURCE_INFO. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-62: Reserved + * bit 63: Store: Store=3D1, store operation, else load operation + * - "lisn" is per "interrupts", "interrupt-map", or + * "ibm,xive-lisn-ranges" properties, or as returned by the + * ibm,query-interrupt-source-number RTAS call, or as + * returned by the H_ALLOCATE_VAS_WINDOW hcall + * - "esbOffset" is the offset into the ESB page for the load or store ope= ration + * - "storeData" is the data to write for a store operation + * + * Output: + * - R4: R4: The value of the load if load operation, else -1 + */ + +#define XIVE_ESB_STORE PPC_BIT(63) + +static target_ulong h_int_esb(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + sPAPRXive *xive =3D spapr->xive; + XiveIVE *ive; + target_ulong flags =3D args[0]; + target_ulong lisn =3D args[1]; + target_ulong offset =3D args[2]; + target_ulong data =3D args[3]; + hwaddr esb_base; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags & ~XIVE_ESB_STORE) { + return H_PARAMETER; + } + + ive =3D spapr_xive_get_ive(xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + if (offset > (1ull << ESB_SHIFT)) { + return H_P3; + } + + esb_base =3D xive->esb_base + (1ull << ESB_SHIFT) * lisn; + esb_base +=3D offset; + + if (dma_memory_rw(&address_space_memory, esb_base, &data, 8, + (flags & XIVE_ESB_STORE))) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to access ESB @0x%" + HWADDR_PRIx "\n", esb_base); + return H_HARDWARE; + } + args[0] =3D (flags & XIVE_ESB_STORE) ? -1 : data; + return H_SUCCESS; +} + +/* + * The H_INT_SYNC hcall() is used to issue hardware syncs that will + * ensure any in flight events for the input lisn are in the event + * queue. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63: Reserved + * - "lisn" is per "interrupts", "interrupt-map", or + * "ibm,xive-lisn-ranges" properties, or as returned by the + * ibm,query-interrupt-source-number RTAS call, or as + * returned by the H_ALLOCATE_VAS_WINDOW hcall + * + * Output: + * - None + */ +static target_ulong h_int_sync(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + XiveIVE *ive; + target_ulong flags =3D args[0]; + target_ulong lisn =3D args[1]; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags) { + return H_PARAMETER; + } + + ive =3D spapr_xive_get_ive(spapr->xive, lisn); + if (!ive || !(ive->w & IVE_VALID)) { + return H_P2; + } + + /* + * H_STATE should be returned if a H_INT_RESET is in progress. + * This is not needed when running the emulation under QEMU + */ + + /* This is not real hardware. Nothing to be done */ + return H_SUCCESS; +} + +/* + * The H_INT_RESET hcall() is used to reset all of the partition's + * interrupt exploitation structures to their initial state. This + * means losing all previously set interrupt state set via + * H_INT_SET_SOURCE_CONFIG and H_INT_SET_QUEUE_CONFIG. + * + * Parameters: + * Input: + * - "flags" + * Bits 0-63: Reserved + * + * Output: + * - None + */ +static target_ulong h_int_reset(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags =3D args[0]; + + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return H_FUNCTION; + } + + if (flags) { + return H_PARAMETER; + } + + device_reset(DEVICE(spapr->xive)); + return H_SUCCESS; +} + +void spapr_xive_hcall_init(sPAPRMachineState *spapr) +{ + spapr_register_hypercall(H_INT_GET_SOURCE_INFO, h_int_get_source_info); + spapr_register_hypercall(H_INT_SET_SOURCE_CONFIG, h_int_set_source_con= fig); + spapr_register_hypercall(H_INT_GET_SOURCE_CONFIG, h_int_get_source_con= fig); + spapr_register_hypercall(H_INT_GET_QUEUE_INFO, h_int_get_queue_info); + spapr_register_hypercall(H_INT_SET_QUEUE_CONFIG, h_int_set_queue_confi= g); + spapr_register_hypercall(H_INT_GET_QUEUE_CONFIG, h_int_get_queue_confi= g); + spapr_register_hypercall(H_INT_SET_OS_REPORTING_LINE, + h_int_set_os_reporting_line); + spapr_register_hypercall(H_INT_GET_OS_REPORTING_LINE, + h_int_get_os_reporting_line); + spapr_register_hypercall(H_INT_ESB, h_int_esb); + spapr_register_hypercall(H_INT_SYNC, h_int_sync); + spapr_register_hypercall(H_INT_RESET, h_int_reset); +} diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 195a48399e4b..1a71bf613b9e 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -222,6 +222,8 @@ static sPAPRXive *spapr_xive_create(sPAPRMachineState *= spapr, int nr_irqs, goto error; } =20 + spapr_xive_hcall_init(spapr); + qdev_set_parent_bus(DEVICE(obj), sysbus_get_default()); return SPAPR_XIVE(obj); error: diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index addc31dba497..ad923e668946 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -388,7 +388,20 @@ struct sPAPRMachineState { #define H_INVALIDATE_PID 0x378 #define H_REGISTER_PROC_TBL 0x37C #define H_SIGNAL_SYS_RESET 0x380 -#define MAX_HCALL_OPCODE H_SIGNAL_SYS_RESET + +#define H_INT_GET_SOURCE_INFO 0x3A8 +#define H_INT_SET_SOURCE_CONFIG 0x3AC +#define H_INT_GET_SOURCE_CONFIG 0x3B0 +#define H_INT_GET_QUEUE_INFO 0x3B4 +#define H_INT_SET_QUEUE_CONFIG 0x3B8 +#define H_INT_GET_QUEUE_CONFIG 0x3BC +#define H_INT_SET_OS_REPORTING_LINE 0x3C0 +#define H_INT_GET_OS_REPORTING_LINE 0x3C4 +#define H_INT_ESB 0x3C8 +#define H_INT_SYNC 0x3CC +#define H_INT_RESET 0x3D0 + +#define MAX_HCALL_OPCODE H_INT_RESET =20 /* The hcalls above are standardized in PAPR and implemented by pHyp * as well. diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index dcaa69025878..0385df69b028 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -60,4 +60,8 @@ bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lis= n); void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); void spapr_xive_nvt_pic_print_info(sPAPRXiveNVT *nvt, Monitor *mon); =20 +typedef struct sPAPRMachineState sPAPRMachineState; + +void spapr_xive_hcall_init(sPAPRMachineState *spapr); + #endif /* PPC_SPAPR_XIVE_H */ --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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 1512810003704154.85686294342486; Sat, 9 Dec 2017 01:00:03 -0800 (PST) Received: from localhost ([::1]:40508 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNaz6-0000Vk-6J for importer@patchew.org; Sat, 09 Dec 2017 03:59:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45848) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNal8-0001kw-R0 for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNal3-0007tX-UX for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:22 -0500 Received: from 13.mo6.mail-out.ovh.net ([188.165.56.124]:58932) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNal3-0007sK-Kt for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:17 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 892BE1277C9 for ; Sat, 9 Dec 2017 09:45:16 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 5D4A4160087; Sat, 9 Dec 2017 09:45:10 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:32 +0100 Message-Id: <20171209084338.29395-14-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11717240333959465811 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 188.165.56.124 Subject: [Qemu-devel] [PATCH v2 13/19] spapr: add device tree support for the XIVE interrupt mode 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The XIVE interface for the guest is described in the device tree under the "interrupt-controller" node. A couple of new properties are specific to XIVE : - "reg" contains the base address and size of the thread interrupt managnement areas (TIMA), also called rings, for the User level and for the Guest OS level. Only the Guest OS level is taken into account today. - "ibm,xive-eq-sizes" the size of the event queues. One cell per size supported, contains log2 of size, in ascending order. - "ibm,xive-lisn-ranges" the IRQ interrupt number ranges assigned to the guest for the IPIs. and also under the root node : - "ibm,plat-res-int-priorities" contains a list of priorities that the hypervisor has reserved for its own use. OPAL uses the priority 7 queue to automatically escalate interrupts for all other queues (DD2.X POWER9). So only priorities [0..6] are allowed for the guest. When the XIVE exploitation interrupt mode is activated after the CAS negotiation, the machine will perform a reboot to rebuild the device tree. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: - added a unit id to the nodename - added properties for the LSIs - simplified the array for the "ibm,plat-res-int-priorities" property - renamed to spapr_dt_xive() hw/intc/spapr_xive_hcall.c | 64 +++++++++++++++++++++++++++++++++++++++++= ++++ hw/ppc/spapr.c | 7 ++++- hw/ppc/spapr_hcall.c | 6 +++++ include/hw/ppc/spapr_xive.h | 2 ++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive_hcall.c b/hw/intc/spapr_xive_hcall.c index 86dec6c02401..8aa2fb8a32d1 100644 --- a/hw/intc/spapr_xive_hcall.c +++ b/hw/intc/spapr_xive_hcall.c @@ -857,3 +857,67 @@ void spapr_xive_hcall_init(sPAPRMachineState *spapr) spapr_register_hypercall(H_INT_SYNC, h_int_sync); spapr_register_hypercall(H_INT_RESET, h_int_reset); } + +void spapr_dt_xive(sPAPRMachineState *spapr, int nr_servers, + void *fdt, uint32_t phandle) +{ + sPAPRXive *xive =3D spapr->xive; + int node; + uint64_t timas[2 * 2]; + /* Interrupt number ranges for the IPIs */ + uint32_t lisn_ranges[] =3D { + cpu_to_be32(0), + cpu_to_be32(nr_servers), + }; + uint32_t eq_sizes[] =3D { + cpu_to_be32(12), /* 4K */ + cpu_to_be32(16), /* 64K */ + cpu_to_be32(21), /* 2M */ + cpu_to_be32(24), /* 16M */ + }; + /* The following array is in sync with the 'priority_is_valid' + * routine above. Linux is expected to choose priority 6. + */ + uint32_t plat_res_int_priorities[] =3D { + cpu_to_be32(7), /* start */ + cpu_to_be32(0xf8), /* count */ + }; + int i; + gchar *nodename; + + /* Thread Interrupt Management Area : User and OS views */ + for (i =3D 0; i < 2; i++) { + timas[i * 2] =3D cpu_to_be64(xive->tm_base + i * (1ull << TM_SHIFT= )); + timas[i * 2 + 1] =3D cpu_to_be64(1ull << TM_SHIFT); + } + + nodename =3D g_strdup_printf("interrupt-controller@%" PRIx64, xive->tm= _base); + _FDT(node =3D fdt_add_subnode(fdt, 0, nodename)); + g_free(nodename); + + _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe")); + _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas))); + + _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe")); + _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes, + sizeof(eq_sizes))); + _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges, + sizeof(lisn_ranges))); + + /* For Linux to link the LSIs to the main interrupt controller. + * These properties are not in XIVE exploitation mode sPAPR + * specs + */ + _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0)); + _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2)); + + /* For SLOF */ + _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle)); + _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle)); + + /* The "ibm,plat-res-int-priorities" property defines the priority + * ranges reserved by the hypervisor + */ + _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities", + plat_res_int_priorities, sizeof(plat_res_int_prioriti= es))); +} diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 1a71bf613b9e..2e15ee8a9333 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1155,7 +1155,12 @@ static void *spapr_build_fdt(sPAPRMachineState *spap= r, _FDT(fdt_setprop_cell(fdt, 0, "#size-cells", 2)); =20 /* /interrupt controller */ - spapr_dt_xics(xics_max_server_number(), fdt, PHANDLE_XICP); + if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_dt_xics(xics_max_server_number(), fdt, PHANDLE_XICP); + } else { + /* Populate device tree for XIVE */ + spapr_dt_xive(spapr, xics_max_server_number(), fdt, PHANDLE_XICP); + } =20 ret =3D spapr_populate_memory(spapr, fdt); if (ret < 0) { diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index be22a6b2895f..e2a1665beee9 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1646,6 +1646,12 @@ static target_ulong h_client_architecture_support(Po= werPCCPU *cpu, (spapr_h_cas_compose_response(spapr, args[1], args[2], ov5_updates) !=3D 0); } + + /* We need to rebuild the device tree for XIVE, generate a reset */ + if (!spapr->cas_reboot) { + spapr->cas_reboot =3D spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOI= T); + } + spapr_ovec_cleanup(ov5_updates); =20 if (spapr->cas_reboot) { diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 0385df69b028..8c3b9cb194a9 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -63,5 +63,7 @@ void spapr_xive_nvt_pic_print_info(sPAPRXiveNVT *nvt, Mon= itor *mon); typedef struct sPAPRMachineState sPAPRMachineState; =20 void spapr_xive_hcall_init(sPAPRMachineState *spapr); +void spapr_dt_xive(sPAPRMachineState *spapr, int nr_servers, void *fdt, + uint32_t phandle); =20 #endif /* PPC_SPAPR_XIVE_H */ --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512809662695743.7931572316917; Sat, 9 Dec 2017 00:54:22 -0800 (PST) Received: from localhost ([::1]:40466 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNatn-00016e-5h for importer@patchew.org; Sat, 09 Dec 2017 03:54:19 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45900) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNalE-0001q9-B0 for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNalA-0007ve-Dl for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:28 -0500 Received: from 5.mo6.mail-out.ovh.net ([46.105.54.31]:38295) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNalA-0007v8-5W for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:24 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id B396612775C for ; Sat, 9 Dec 2017 09:45:22 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 88B53160087; Sat, 9 Dec 2017 09:45:16 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:33 +0100 Message-Id: <20171209084338.29395-15-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11718929184644762451 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 46.105.54.31 Subject: [Qemu-devel] [PATCH v2 14/19] spapr: introduce a helper to map the XIVE memory regions 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" When the XIVE exploitation interrupt mode is activated, the machine needs to expose to the guest the MMIO regions used by the controller : - Event State Buffers - Thread Interrupt Management Area for the OS and User views Migration will also need to reflect the current interrupt mode in use. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: =20 - moved the mapping of the XIVE memory region under the machine reset handler. hw/intc/spapr_xive.c | 10 ++++++++++ hw/ppc/spapr.c | 10 ++++++++++ include/hw/ppc/spapr_xive.h | 1 + 3 files changed, 21 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index bf30edc87bee..fcdadf727f9d 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -970,3 +970,13 @@ XiveEQ *spapr_xive_get_eq(sPAPRXive *xive, uint32_t se= rver, uint8_t priority) } return &nvt->eqt[priority]; } + +void spapr_xive_mmio_map(sPAPRXive *xive) +{ + /* ESBs */ + sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->esb_base); + + /* Thread Management Interrupt Area: User and OS views */ + sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->tm_base); + sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base + (1 << TM_SHIF= T)); +} diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 2e15ee8a9333..73df038a9e8b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1537,6 +1537,11 @@ static void ppc_spapr_reset(void) ppc_set_compat_all(spapr->max_compat_pvr, &error_fatal); } =20 + /* Setup XIVE resources if required by CAS */ + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_xive_mmio_map(spapr->xive); + } + fdt =3D spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size); =20 spapr_load_rtas(spapr, fdt, rtas_addr); @@ -1644,6 +1649,11 @@ static int spapr_post_load(void *opaque, int version= _id) } } =20 + /* Restore XIVE resources if required by CAS */ + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_xive_mmio_map(spapr->xive); + } + return err; } =20 diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 8c3b9cb194a9..5d0c178a4984 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -59,6 +59,7 @@ bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn= , bool lsi); bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn); void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); void spapr_xive_nvt_pic_print_info(sPAPRXiveNVT *nvt, Monitor *mon); +void spapr_xive_mmio_map(sPAPRXive *xive); =20 typedef struct sPAPRMachineState sPAPRMachineState; =20 --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512810038909560.860245258128; Sat, 9 Dec 2017 01:00:38 -0800 (PST) Received: from localhost ([::1]:40511 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNazt-0000yy-8N for importer@patchew.org; Sat, 09 Dec 2017 04:00:37 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45948) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNalK-0001w1-DO for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNalG-000801-GB for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:34 -0500 Received: from 1.mo6.mail-out.ovh.net ([46.105.56.136]:55923) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNalG-0007zG-9u for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:30 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id E0D811277CF for ; Sat, 9 Dec 2017 09:45:28 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id B4811160087; Sat, 9 Dec 2017 09:45:22 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:34 +0100 Message-Id: <20171209084338.29395-16-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11720618033203350355 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 46.105.56.136 Subject: [Qemu-devel] [PATCH v2 15/19] spapr: add XIVE support to spapr_qirq() 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The XIVE object has its own set of qirqs which is to be used when the XIVE exploitation interrupt mode is activated. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: =20 - introduced a spapr_xive_qirq() helper hw/intc/spapr_xive.c | 12 ++++++++++++ hw/ppc/spapr.c | 4 ++++ include/hw/ppc/spapr_xive.h | 1 + 3 files changed, 17 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index fcdadf727f9d..e650ed69eb70 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -980,3 +980,15 @@ void spapr_xive_mmio_map(sPAPRXive *xive) sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->tm_base); sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base + (1 << TM_SHIF= T)); } + +qemu_irq spapr_xive_qirq(sPAPRXive *xive, int lisn) +{ + XiveIVE *ive =3D spapr_xive_get_ive(xive, lisn); + + if (!ive || !(ive->w & IVE_VALID)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid LISN %d\n", lisn); + return NULL; + } + + return xive->qirqs[lisn]; +} diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 73df038a9e8b..d117fbd5ce9d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3810,6 +3810,10 @@ qemu_irq spapr_qirq(sPAPRMachineState *spapr, int ir= q) { ICSState *ics =3D spapr->ics; =20 + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return spapr_xive_qirq(spapr->xive, irq); + } + if (ics_valid_irq(ics, irq)) { return ics->qirqs[irq - ics->offset]; } diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 5d0c178a4984..8eefb09999de 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -60,6 +60,7 @@ bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lis= n); void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); void spapr_xive_nvt_pic_print_info(sPAPRXiveNVT *nvt, Monitor *mon); void spapr_xive_mmio_map(sPAPRXive *xive); +qemu_irq spapr_xive_qirq(sPAPRXive *xive, int lisn); =20 typedef struct sPAPRMachineState sPAPRMachineState; =20 --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512810159209689.3665695925783; Sat, 9 Dec 2017 01:02:39 -0800 (PST) Received: from localhost ([::1]:40537 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNb1p-0002q7-Mu for importer@patchew.org; Sat, 09 Dec 2017 04:02:37 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45981) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNalQ-0001zE-CZ for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNalM-00081q-FM for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:40 -0500 Received: from 16.mo6.mail-out.ovh.net ([87.98.139.208]:33071) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNalM-00081e-7e for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:36 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 1B6121277DB for ; Sat, 9 Dec 2017 09:45:35 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id E0572160087; Sat, 9 Dec 2017 09:45:28 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:35 +0100 Message-Id: <20171209084338.29395-17-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11722588356634184531 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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.139.208 Subject: [Qemu-devel] [PATCH v2 16/19] spapr: introduce a spapr_icp_create() helper 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" On sPAPR, the creation of the interrupt presenter depends on some of the machine attributes. When the XIVE exploitation interrupt mode is available, this will get more complex. So provide a machine-level helper to isolate the process and hide the details to the sPAPR core realize function. Signed-off-by: C=C3=A9dric Le Goater Reviewed-by: Greg Kurz --- hw/ppc/spapr.c | 14 ++++++++++++++ hw/ppc/spapr_cpu_core.c | 3 +-- include/hw/ppc/spapr.h | 2 ++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d117fbd5ce9d..65fca10e5b30 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3821,6 +3821,20 @@ qemu_irq spapr_qirq(sPAPRMachineState *spapr, int ir= q) return NULL; } =20 +Object *spapr_icp_create(sPAPRMachineState *spapr, Object *cpu, Error **er= rp) +{ + Error *local_err =3D NULL; + Object *obj; + + obj =3D icp_create(cpu, spapr->icp_type, XICS_FABRIC(spapr), &local_er= r); + if (local_err) { + error_propagate(errp, local_err); + return NULL; + } + + return obj; +} + static void spapr_pic_print_info(InterruptStatsProvider *obj, Monitor *mon) { diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 032438b9ce70..1bfe3ff55058 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -121,8 +121,7 @@ static void spapr_cpu_core_realize_child(Object *child, goto error; } =20 - cpu->intc =3D icp_create(child, spapr->icp_type, XICS_FABRIC(spapr), - &local_err); + cpu->intc =3D spapr_icp_create(spapr, child, &local_err); if (local_err) { goto error; } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index ad923e668946..40bda1a34607 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -740,4 +740,6 @@ int spapr_irq_alloc_block(sPAPRMachineState *spapr, int= num, bool lsi, void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num); qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq); =20 +Object *spapr_icp_create(sPAPRMachineState *spapr, Object *cpu, Error **er= rp); + #endif /* HW_SPAPR_H */ --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512809476756802.0640322587873; Sat, 9 Dec 2017 00:51:16 -0800 (PST) Received: from localhost ([::1]:40451 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNaqo-0006xv-UQ for importer@patchew.org; Sat, 09 Dec 2017 03:51:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46051) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNalW-00026T-Le for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNalS-00088y-MC for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:46 -0500 Received: from 15.mo6.mail-out.ovh.net ([188.165.39.161]:49440) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNalS-00086z-C2 for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:42 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 46FAE1277CF for ; Sat, 9 Dec 2017 09:45:41 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 1C4CB16009E; Sat, 9 Dec 2017 09:45:35 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:36 +0100 Message-Id: <20171209084338.29395-18-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11724277206780316499 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 188.165.39.161 Subject: [Qemu-devel] [PATCH v2 17/19] spapr: toggle the ICP depending on the selected interrupt mode 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Each interrupt mode has its own specific interrupt presenter object, that we store under the CPU object, one for XICS and one for XIVE. The active presenter, corresponding to the current interrupt mode, is simply selected with a lookup on the children of the CPU. Migration and CPU hotplug also need to reflect the current interrupt mode in use. Signed-off-by: C=C3=A9dric Le Goater --- Changes since v1: =20 - conditioned the creation of the sPAPRXiveNVT object to the xive_exploitation bool which false on older pseries machine. - moved the setting of the ICP under the machine reset handler. - introduced a spapr_xive_nvt_create() helper - handled errors in spapr_post_load() to return EINVAL hw/intc/spapr_xive.c | 19 +++++++++++++++++++ hw/ppc/spapr.c | 29 +++++++++++++++++++++++++++++ hw/ppc/spapr_cpu_core.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_cpu_core.h | 1 + include/hw/ppc/spapr_xive.h | 1 + 5 files changed, 84 insertions(+) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index e650ed69eb70..8e6997bb1deb 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -992,3 +992,22 @@ qemu_irq spapr_xive_qirq(sPAPRXive *xive, int lisn) =20 return xive->qirqs[lisn]; } + +Object *spapr_xive_nvt_create(Object *cpu, const char *type, Error **errp) +{ + Error *local_err =3D NULL; + Object *obj; + + obj =3D object_new(type); + object_property_add_child(cpu, type, obj, &error_abort); + object_unref(obj); + object_property_add_const_link(obj, ICP_PROP_CPU, cpu, &error_abort); + object_property_set_bool(obj, true, "realized", &local_err); + if (local_err) { + object_unparent(obj); + error_propagate(errp, local_err); + obj =3D NULL; + } + + return obj; +} diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 65fca10e5b30..4d7a3d64e51e 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1539,7 +1539,10 @@ static void ppc_spapr_reset(void) =20 /* Setup XIVE resources if required by CAS */ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_cpu_core_set_icp(TYPE_SPAPR_XIVE_NVT, &error_fatal); spapr_xive_mmio_map(spapr->xive); + } else { + spapr_cpu_core_set_icp(spapr->icp_type, &error_fatal); } =20 fdt =3D spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size); @@ -1651,7 +1654,13 @@ static int spapr_post_load(void *opaque, int version= _id) =20 /* Restore XIVE resources if required by CAS */ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + Error *local_err =3D NULL; + spapr_xive_mmio_map(spapr->xive); + spapr_cpu_core_set_icp(TYPE_SPAPR_XIVE_NVT, &local_err); + if (local_err) { + return -EINVAL; + } } =20 return err; @@ -3832,6 +3841,26 @@ Object *spapr_icp_create(sPAPRMachineState *spapr, O= bject *cpu, Error **errp) return NULL; } =20 + if (spapr->xive_exploitation) { + Object *obj_xive; + + /* Add a XIVE interrupt presenter. The machine will switch + * the CPU ICP depending on the interrupt model negotiated + * at CAS time. + */ + obj_xive =3D spapr_xive_nvt_create(cpu, TYPE_SPAPR_XIVE_NVT, &loca= l_err); + if (local_err) { + object_unparent(obj); + error_propagate(errp, local_err); + return NULL; + } + + /* when hotplugged, the CPU should have the correct ICP */ + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + return obj_xive; + } + } + return obj; } =20 diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 1bfe3ff55058..e5c39cdec998 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -253,3 +253,37 @@ static const TypeInfo spapr_cpu_core_type_infos[] =3D { }; =20 DEFINE_TYPES(spapr_cpu_core_type_infos) + +typedef struct ForeachFindICPArgs { + const char *icp_type; + Object *icp; +} ForeachFindICPArgs; + +static int spapr_cpu_core_find_icp(Object *child, void *opaque) +{ + ForeachFindICPArgs *args =3D opaque; + + if (object_dynamic_cast(child, args->icp_type)) { + args->icp =3D child; + } + + return args->icp !=3D NULL; +} + +void spapr_cpu_core_set_icp(const char *icp_type, Error **errp) +{ + CPUState *cs; + + CPU_FOREACH(cs) { + ForeachFindICPArgs args =3D { icp_type, NULL }; + PowerPCCPU *cpu =3D POWERPC_CPU(cs); + + object_child_foreach(OBJECT(cs), spapr_cpu_core_find_icp, &args); + if (!args.icp) { + error_setg(errp, "Couldn't find a '%s' icp", icp_type); + return; + } + + cpu->intc =3D args.icp; + } +} diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_cor= e.h index 1129f344aa0c..916aea6137a6 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -38,4 +38,5 @@ typedef struct sPAPRCPUCoreClass { } sPAPRCPUCoreClass; =20 const char *spapr_get_cpu_core_type(const char *cpu_type); +void spapr_cpu_core_set_icp(const char *icp_type, Error **errp); #endif diff --git a/include/hw/ppc/spapr_xive.h b/include/hw/ppc/spapr_xive.h index 8eefb09999de..22eb6e8a4d01 100644 --- a/include/hw/ppc/spapr_xive.h +++ b/include/hw/ppc/spapr_xive.h @@ -59,6 +59,7 @@ bool spapr_xive_irq_enable(sPAPRXive *xive, uint32_t lisn= , bool lsi); bool spapr_xive_irq_disable(sPAPRXive *xive, uint32_t lisn); void spapr_xive_pic_print_info(sPAPRXive *xive, Monitor *mon); void spapr_xive_nvt_pic_print_info(sPAPRXiveNVT *nvt, Monitor *mon); +Object *spapr_xive_nvt_create(Object *cpu, const char *type, Error **errp); void spapr_xive_mmio_map(sPAPRXive *xive); qemu_irq spapr_xive_qirq(sPAPRXive *xive, int lisn); =20 --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 15128096364453.9213127499108396; Sat, 9 Dec 2017 00:53:56 -0800 (PST) Received: from localhost ([::1]:40464 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNatO-0000l1-Ru for importer@patchew.org; Sat, 09 Dec 2017 03:53:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46071) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNalZ-000299-KT for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNalY-0008IM-Nv for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:49 -0500 Received: from 15.mo6.mail-out.ovh.net ([188.165.39.161]:46536) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNalY-0008Hj-Ho for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:48 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id 760181277DB for ; Sat, 9 Dec 2017 09:45:47 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 48381160087; Sat, 9 Dec 2017 09:45:41 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:37 +0100 Message-Id: <20171209084338.29395-19-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11725966056647592787 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 188.165.39.161 Subject: [Qemu-devel] [PATCH v2 18/19] spapr: add support to dump XIVE information 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Modify the InterruptStatsProvider output to reflect the interrupt mode currently in use by the machine. Signed-off-by: C=C3=A9dric Le Goater --- hw/ppc/spapr.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 4d7a3d64e51e..867c9d759f3b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3873,10 +3873,18 @@ static void spapr_pic_print_info(InterruptStatsProv= ider *obj, CPU_FOREACH(cs) { PowerPCCPU *cpu =3D POWERPC_CPU(cs); =20 - icp_pic_print_info(ICP(cpu->intc), mon); + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_xive_nvt_pic_print_info(SPAPR_XIVE_NVT(cpu->intc), mon); + } else { + icp_pic_print_info(ICP(cpu->intc), mon); + } } =20 - ics_pic_print_info(spapr->ics, mon); + if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { + spapr_xive_pic_print_info(spapr->xive, mon); + } else { + ics_pic_print_info(spapr->ics, mon); + } } =20 int spapr_vcpu_id(PowerPCCPU *cpu) --=20 2.13.6 From nobody Sun May 5 09:00:10 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1512809825142964.021380291198; Sat, 9 Dec 2017 00:57:05 -0800 (PST) Received: from localhost ([::1]:40490 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNawO-0003S1-JN for importer@patchew.org; Sat, 09 Dec 2017 03:57:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46204) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eNalj-0002Gg-0U for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:46:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eNalf-0008Mm-3s for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:59 -0500 Received: from 19.mo6.mail-out.ovh.net ([188.165.56.177]:40941) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eNale-0008M3-Tk for qemu-devel@nongnu.org; Sat, 09 Dec 2017 03:45:55 -0500 Received: from player735.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo6.mail-out.ovh.net (Postfix) with ESMTP id A08751277E1 for ; Sat, 9 Dec 2017 09:45:53 +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 player735.ha.ovh.net (Postfix) with ESMTPSA id 762FF160087; Sat, 9 Dec 2017 09:45:47 +0100 (CET) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson , Benjamin Herrenschmidt , Greg Kurz Date: Sat, 9 Dec 2017 09:43:38 +0100 Message-Id: <20171209084338.29395-20-clg@kaod.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171209084338.29395-1-clg@kaod.org> References: <20171209084338.29395-1-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 11727654907947748179 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtuddrvddugdduvdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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: 188.165.56.177 Subject: [Qemu-devel] [PATCH v2 19/19] spapr: advertise XIVE exploitation mode in CAS 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_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Signed-off-by: C=C3=A9dric Le Goater --- hw/ppc/spapr.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 867c9d759f3b..e52c510812d9 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -989,10 +989,11 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, v= oid *fdt) spapr_dt_rtas_tokens(fdt, rtas); } =20 -/* Prepare ibm,arch-vec-5-platform-support, which indicates the MMU featur= es - * that the guest may request and thus the valid values for bytes 24..26 of - * option vector 5: */ -static void spapr_dt_ov5_platform_support(void *fdt, int chosen) +/* Prepare ibm,arch-vec-5-platform-support, which indicates the MMU + * and the XIVE features that the guest may request and thus the valid + * values for bytes 23..26 of option vector 5: */ +static void spapr_dt_ov5_platform_support(sPAPRMachineState *spapr, void *= fdt, + int chosen) { PowerPCCPU *first_ppc_cpu =3D POWERPC_CPU(first_cpu); =20 @@ -1015,7 +1016,16 @@ static void spapr_dt_ov5_platform_support(void *fdt,= int chosen) } else { val[3] =3D 0x00; /* Hash */ } + /* TODO: introduce a kvmppc_has_cap_xive() ? Works with + * irqchip=3Doff for now + */ + if (spapr->xive_exploitation) { + val[1] =3D 0x80; /* OV5_XIVE_BOTH */ + } } else { + if (spapr->xive_exploitation) { + val[1] =3D 0x80; /* OV5_XIVE_BOTH */ + } /* V3 MMU supports both hash and radix in tcg (with dynamic switch= ing) */ val[3] =3D 0xC0; } @@ -1076,7 +1086,7 @@ static void spapr_dt_chosen(sPAPRMachineState *spapr,= void *fdt) _FDT(fdt_setprop_string(fdt, chosen, "linux,stdout-path", stdout_p= ath)); } =20 - spapr_dt_ov5_platform_support(fdt, chosen); + spapr_dt_ov5_platform_support(spapr, fdt, chosen); =20 g_free(stdout_path); g_free(bootlist); @@ -2487,6 +2497,11 @@ static void ppc_spapr_init(MachineState *machine) spapr_ovec_set(spapr->ov5, OV5_HPT_RESIZE); } =20 + /* advertise XIVE if not disabled by the user */ + if (spapr->xive_exploitation) { + spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT); + } + /* init CPUs */ spapr_set_vsmt_mode(spapr, &error_fatal); =20 --=20 2.13.6