From 67afe7759df4c3dec8abfc373b98d1a8d108ff66 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 15 Feb 2019 17:16:47 +0100 Subject: target/ppc: Add POWER9 external interrupt model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support for the Hypervisor directed interrupts in addition to the OS ones. Signed-off-by: Benjamin Herrenschmidt [clg: - modified the icp_realize() and xive_tctx_realize() to take into account explicitely the POWER9 interrupt model - introduced a specific power9_set_irq for POWER9 ] Signed-off-by: Cédric Le Goater Message-Id: <20190215161648.9600-10-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xics.c | 3 +++ hw/intc/xive.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'hw/intc') diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 3009fa7..767fdeb 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -338,6 +338,9 @@ static void icp_realize(DeviceState *dev, Error **errp) case PPC_FLAGS_INPUT_POWER7: icp->output = env->irq_inputs[POWER7_INPUT_INT]; break; + case PPC_FLAGS_INPUT_POWER9: /* For SPAPR xics emulation */ + icp->output = env->irq_inputs[POWER9_INPUT_INT]; + break; case PPC_FLAGS_INPUT_970: icp->output = env->irq_inputs[PPC970_INPUT_INT]; diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 2e9b8ef..425aa97 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -484,6 +484,9 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp) case PPC_FLAGS_INPUT_POWER7: tctx->output = env->irq_inputs[POWER7_INPUT_INT]; break; + case PPC_FLAGS_INPUT_POWER9: + tctx->output = env->irq_inputs[POWER9_INPUT_INT]; + break; default: error_setg(errp, "XIVE interrupt controller does not support " -- cgit v1.1 From 6cead90c5c9c462c56ddc41a0bd0b4cfef9f62a8 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Tue, 19 Feb 2019 18:18:03 +0100 Subject: xics: Write source state to KVM at claim time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pseries machine only uses LSIs to support legacy PCI devices. Every PHB claims 4 LSIs at realize time. When using in-kernel XICS (or upcoming in-kernel XIVE), QEMU synchronizes the state of all irqs, including these LSIs, later on at machine reset. In order to support PHB hotplug, we need a way to tell KVM about the LSIs that doesn't require a machine reset. An easy way to do that is to always inform KVM when an interrupt is claimed, which really isn't a performance path. Signed-off-by: Greg Kurz Message-Id: <155059668360.1466090.5969630516627776426.stgit@bahia.lab.toulouse-stg.fr.ibm.com> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 4 +++ hw/intc/xics_kvm.c | 74 +++++++++++++++++++++++++++++++----------------------- 2 files changed, 47 insertions(+), 31 deletions(-) (limited to 'hw/intc') diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 767fdeb..af7dc70 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -758,6 +758,10 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi) ics->irqs[srcno].flags |= lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI; + + if (kvm_irqchip_in_kernel()) { + ics_set_kvm_state_one(ics, srcno); + } } static void xics_register_types(void) diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index a00d0a7..c6e1b63 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -213,45 +213,57 @@ void ics_synchronize_state(ICSState *ics) ics_get_kvm_state(ics); } -int ics_set_kvm_state(ICSState *ics) +int ics_set_kvm_state_one(ICSState *ics, int srcno) { uint64_t state; - int i; Error *local_err = NULL; + ICSIRQState *irq = &ics->irqs[srcno]; + int ret; - for (i = 0; i < ics->nr_irqs; i++) { - ICSIRQState *irq = &ics->irqs[i]; - int ret; - - state = irq->server; - state |= (uint64_t)(irq->saved_priority & KVM_XICS_PRIORITY_MASK) - << KVM_XICS_PRIORITY_SHIFT; - if (irq->priority != irq->saved_priority) { - assert(irq->priority == 0xff); - state |= KVM_XICS_MASKED; - } + state = irq->server; + state |= (uint64_t)(irq->saved_priority & KVM_XICS_PRIORITY_MASK) + << KVM_XICS_PRIORITY_SHIFT; + if (irq->priority != irq->saved_priority) { + assert(irq->priority == 0xff); + state |= KVM_XICS_MASKED; + } - if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) { - state |= KVM_XICS_LEVEL_SENSITIVE; - if (irq->status & XICS_STATUS_ASSERTED) { - state |= KVM_XICS_PENDING; - } - } else { - if (irq->status & XICS_STATUS_MASKED_PENDING) { - state |= KVM_XICS_PENDING; - } + if (irq->flags & XICS_FLAGS_IRQ_LSI) { + state |= KVM_XICS_LEVEL_SENSITIVE; + if (irq->status & XICS_STATUS_ASSERTED) { + state |= KVM_XICS_PENDING; } - if (irq->status & XICS_STATUS_PRESENTED) { - state |= KVM_XICS_PRESENTED; - } - if (irq->status & XICS_STATUS_QUEUED) { - state |= KVM_XICS_QUEUED; + } else { + if (irq->status & XICS_STATUS_MASKED_PENDING) { + state |= KVM_XICS_PENDING; } + } + if (irq->status & XICS_STATUS_PRESENTED) { + state |= KVM_XICS_PRESENTED; + } + if (irq->status & XICS_STATUS_QUEUED) { + state |= KVM_XICS_QUEUED; + } + + ret = kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES, + srcno + ics->offset, &state, true, &local_err); + if (local_err) { + error_report_err(local_err); + return ret; + } + + return 0; +} + +int ics_set_kvm_state(ICSState *ics) +{ + int i; + + for (i = 0; i < ics->nr_irqs; i++) { + int ret; - ret = kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES, - i + ics->offset, &state, true, &local_err); - if (local_err) { - error_report_err(local_err); + ret = ics_set_kvm_state_one(ics, i); + if (ret) { return ret; } } -- cgit v1.1 From 743ed566c1d80991ab22fb404be706bb8b742335 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Tue, 19 Feb 2019 18:18:08 +0100 Subject: spapr: Expose the name of the interrupt controller node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be needed by PHB hotplug in order to access the "phandle" property of the interrupt controller node. Reviewed-by: Cédric Le Goater Signed-off-by: Greg Kurz Reviewed-by: David Gibson Message-Id: <155059668867.1466090.6339199751719123386.stgit@bahia.lab.toulouse-stg.fr.ibm.com> Signed-off-by: David Gibson --- hw/intc/spapr_xive.c | 9 ++++----- hw/intc/xics_spapr.c | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'hw/intc') diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 290a290..06e3c9f 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -317,6 +317,9 @@ static void spapr_xive_realize(DeviceState *dev, Error **errp) /* Map all regions */ spapr_xive_map_mmio(xive); + xive->nodename = g_strdup_printf("interrupt-controller@%" PRIx64, + xive->tm_base + XIVE_TM_USER_PAGE * (1 << TM_SHIFT)); + qemu_register_reset(spapr_xive_reset, dev); } @@ -1448,7 +1451,6 @@ void spapr_dt_xive(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt, cpu_to_be32(7), /* start */ cpu_to_be32(0xf8), /* count */ }; - gchar *nodename; /* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */ timas[0] = cpu_to_be64(xive->tm_base + @@ -1458,10 +1460,7 @@ void spapr_dt_xive(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt, XIVE_TM_OS_PAGE * (1ull << TM_SHIFT)); timas[3] = cpu_to_be64(1ull << TM_SHIFT); - nodename = g_strdup_printf("interrupt-controller@%" PRIx64, - xive->tm_base + XIVE_TM_USER_PAGE * (1 << TM_SHIFT)); - _FDT(node = fdt_add_subnode(fdt, 0, nodename)); - g_free(nodename); + _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename)); _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe")); _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas))); diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index e2d8b38..53bda66 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -254,7 +254,7 @@ void spapr_dt_xics(sPAPRMachineState *spapr, uint32_t nr_servers, void *fdt, }; int node; - _FDT(node = fdt_add_subnode(fdt, 0, "interrupt-controller")); + _FDT(node = fdt_add_subnode(fdt, 0, XICS_NODENAME)); _FDT(fdt_setprop_string(fdt, node, "device_type", "PowerPC-External-Interrupt-Presentation")); -- cgit v1.1 From 3dbe65c17890e4beefe9812590c723e17e611852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 19 Feb 2019 15:25:30 +0100 Subject: ppc/xive: xive does not have a POWER7 interrupt model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch "target/ppc: Add POWER9 external interrupt model" should have removed the section covering PPC_FLAGS_INPUT_POWER7. Signed-off-by: Cédric Le Goater Message-Id: <20190219142530.17807-1-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'hw/intc') diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 425aa97..daa7bad 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -481,9 +481,6 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp) env = &cpu->env; switch (PPC_INPUT(env)) { - case PPC_FLAGS_INPUT_POWER7: - tctx->output = env->irq_inputs[POWER7_INPUT_INT]; - break; case PPC_FLAGS_INPUT_POWER9: tctx->output = env->irq_inputs[POWER9_INPUT_INT]; break; -- cgit v1.1 From f6d4dca807d853516fc307519f3260a432818bdc Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 21 Feb 2019 12:24:48 +0100 Subject: hw/ppc: Use object_initialize_child for correct reference counting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both functions, object_initialize() and object_property_add_child() increase the reference counter of the new object, so one of the references has to be dropped afterwards to get the reference counting right. Otherwise the child object will not be properly cleaned up when the parent gets destroyed. Thus let's use now object_initialize_child() instead to get the reference counting here right. Suggested-by: Eduardo Habkost Signed-off-by: Thomas Huth Message-Id: <1550748288-30598-1-git-send-email-thuth@redhat.com> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/spapr_xive.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'hw/intc') diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 06e3c9f..e0e5cb5 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -244,13 +244,12 @@ static void spapr_xive_instance_init(Object *obj) { sPAPRXive *xive = SPAPR_XIVE(obj); - object_initialize(&xive->source, sizeof(xive->source), TYPE_XIVE_SOURCE); - object_property_add_child(obj, "source", OBJECT(&xive->source), NULL); + object_initialize_child(obj, "source", &xive->source, sizeof(xive->source), + TYPE_XIVE_SOURCE, &error_abort, NULL); - object_initialize(&xive->end_source, sizeof(xive->end_source), - TYPE_XIVE_END_SOURCE); - object_property_add_child(obj, "end_source", OBJECT(&xive->end_source), - NULL); + object_initialize_child(obj, "end_source", &xive->end_source, + sizeof(xive->end_source), TYPE_XIVE_END_SOURCE, + &error_abort, NULL); } static void spapr_xive_realize(DeviceState *dev, Error **errp) -- cgit v1.1